diff --git a/GameEngine/Account.php b/GameEngine/Account.php
index 3e66f78b..79099dd0 100755
--- a/GameEngine/Account.php
+++ b/GameEngine/Account.php
@@ -17,264 +17,384 @@ 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')) {
- // we have our path, let's leave
+
+ if (file_exists($autoprefix . 'autoloader.php')) {
break;
}
}
-include_once($autoprefix."GameEngine/Session.php");
+include_once($autoprefix . "GameEngine/Session.php");
-class Account {
- 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();
- }
- }
- }
+/*
+=========================================================
+= ACCOUNT CLASS
+=========================================================
+*/
- 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);
+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;
}
- else if(User::exists($database,$_POST['name'])) {
- $form->addError("name",USRNM_TAKEN);
- }
+ }
- }
- 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);
+ 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['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
- );
- $this->generateBase($_POST['kid'], $uid, $_POST['name']);
- header("Location: login.php");
- exit;
- }
- }
- }
- }
+ /*
+ -------------------------------------------------
+ REGISTRATION FLOW
+ -------------------------------------------------
+ */
- 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;
- }
- }
+ if (AUTH_EMAIL) {
- 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;
- }
- }
+ $act = $generator->generateRandStr(10);
+ $act2 = $generator->generateRandStr(5);
- 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);
- }
+ $uid = $database->activate(
+ $_POST['name'],
+ password_hash($_POST['pw'], PASSWORD_BCRYPT, ['cost'=>12]),
+ $_POST['email'],
+ $_POST['vid'],
+ $_POST['kid'],
+ $act,
+ $act2
+ );
- $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']);
- }
- }
+ if ($uid) {
- 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();
- }
+ $mailer->sendActivate(
+ $_POST['email'],
+ $_POST['name'],
+ $_POST['pw'],
+ $act
+ );
- 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);
- }
+ 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);
+ }
+}
- 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 5ee3dc77..158b2f1c 100755
--- a/GameEngine/Alliance.php
+++ b/GameEngine/Alliance.php
@@ -16,20 +16,25 @@
## ##
#################################################################################
-use App\Entity\User;
+
+/*
+=========================================================
+= AUTOLOADER DISCOVERY
+=========================================================
+*/
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;
}
}
@@ -38,585 +43,409 @@ if (!$autoloader_found) {
die('Could not find autoloading class.');
}
-class Alliance {
- public $gotInvite = false;
- public $inviteArray = [];
- public $allianceArray = [];
- public $userPermArray = [];
-
- public function procAlliance($get) {
- global $session, $database;
+/*
+=========================================================
+= ALLIANCE DOMAIN CONTROLLER
+=========================================================
+*/
- 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;
+class Alliance
+{
+ /*
+ =====================================================
+ = PROPERTIES
+ =====================================================
+ */
- $hasSwitchedToAdmin = isset($datas['admin']) && !empty($datas['admin']) && $datas['admin'] == "switch_admin";
+ public $gotInvite = false;
+ public $inviteArray = [];
+ public $allianceArray = [];
+ public $userPermArray = [];
- 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;
- }
- }
-
- if(isset($post['dipl']) && isset($post['a_name'])) $this->changediplomacy($post);
+ /*
+ =====================================================
+ = INITIAL PROCESSOR
+ =====================================================
+ */
- 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;
- }
- }
- }
- }
+ public function procAlliance($get)
+ {
+ global $session, $database;
- /*****************************************
- Function to process of sending invitations
- *****************************************/
- public function sendInvite($post) {
- global $form, $database, $session;
+ /*
+ -------------------------------------------------
+ LOAD ALLIANCE OR INVITES
+ -------------------------------------------------
+ */
- $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);
+ 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;
}
- }
- }
+ }
+ }
- /*****************************************
- Function to reject an invitation
- *****************************************/
- private function rejectInvite($get) {
- global $database, $session;
+ return false;
+ }
- 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;
- }
- /*****************************************
- Function to del an invitation
- *****************************************/
- private function delInvite($get) {
- global $database, $session;
+ /*
+ =====================================================
+ = PERMISSION CHECKER
+ =====================================================
+ */
- $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;
- }
+ public static function canAct($datas, $mode = 0)
+ {
+ global $database, $session;
- /*****************************************
- Function to accept an invitation
- *****************************************/
- private function acceptInvite($get) {
- global $form, $database, $session;
+ $hasSwitchedToAdmin =
+ isset($datas['admin']) &&
+ $datas['admin'] == "switch_admin";
- 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;
- }
- }
+ 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);
+ }
- /*****************************************
- Function to create an alliance
- *****************************************/
- private function createAlliance($post) {
- global $form, $database, $session, $bid18, $building;
- 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;
- }
- }
+ /*
+ =====================================================
+ = FORUM VISIBILITY BUILDER
+ =====================================================
+ */
- /*****************************************
- 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;
- }
- }
+ public function createForumVisiblity(
+ $alliancesID,
+ $alliancesName,
+ $usersID,
+ $usersName
+ )
+ {
+ global $database, $session;
- /*****************************************
- Function to create/change the alliance description
- *****************************************/
- private function updateAlliProfile($post) {
- global $database, $session, $form;
+ $alliances = [];
+ $users = [];
- 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.');
- }
- }
+ /*
+ -------------------------------------------------
+ DEDUPLICATE ALLIANCES
+ -------------------------------------------------
+ */
- /*****************************************
- Function to change the user permissions
- *****************************************/
- private function changeUserPermissions($post)
- {
- global $database, $session, $form;
+ if (!empty($alliancesID)) {
- 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;
+ foreach ($alliancesID as $alliance) {
- $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($alliance) &&
+ is_numeric($alliance) &&
+ $database->aExist($alliance, 'id') &&
+ $alliance != $session->alliance &&
+ empty($database->diplomacyExistingRelationships($alliance))
+ ) {
+ $alliances[$alliance] = true;
+ }
+ }
+ }
- 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;
+ if (!empty($alliancesName)) {
- 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'];
- }
+ foreach ($alliancesName as $alliance) {
- $members = $database->getAllMember($session->alliance);
- $validMemberFound = false;
+ $allianceID = $database->getAllianceID($alliance);
- foreach ($members as $member) {
- if ($member['id'] == $post['new_founder']) {
- $validMemberFound = true;
- break;
- }
- }
+ if (
+ !empty($allianceID) &&
+ $allianceID != $session->alliance &&
+ empty($database->diplomacyExistingRelationships($allianceID))
+ ) {
+ $alliances[$allianceID] = true;
+ }
+ }
+ }
- if (!$validMemberFound || $post['new_founder'] == $session->uid) {
- $form->addError("founder", 'Invalid founder.');
- return;
- }
+ /*
+ -------------------------------------------------
+ DEDUPLICATE USERS
+ -------------------------------------------------
+ */
- $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);
+ if (!empty($usersID)) {
- // 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 - uid."\">".$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);
- }
+ foreach ($usersID as $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;
- }
- }
+ $userAlly = $database->getUserAllianceID($user);
- private function changediplomacy($post) {
- global $database, $session, $form;
+ if (
+ !empty($user) &&
+ is_numeric($user) &&
+ $userAlly > 0 &&
+ $userAlly != $session->alliance &&
+ $user != $session->uid &&
+ empty($database->diplomacyExistingRelationships($userAlly))
+ ) {
+ $users[$user] = true;
+ }
+ }
+ }
- 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);
- }
+ 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;
+ }
}
+
+/*
+=========================================================
+= INSTANTIATION
+=========================================================
+*/
+
$alliance = new Alliance;
?>
+
diff --git a/GameEngine/Artifacts.php b/GameEngine/Artifacts.php
index c005d218..194369bc 100644
--- a/GameEngine/Artifacts.php
+++ b/GameEngine/Artifacts.php
@@ -1,527 +1,318 @@
- [["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,
+ **************************";
- /**
- * @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];
+ /*
+ =====================================================
+ = 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
+ ];
};
-
- $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];
+
+ /*
+ -------------------------------------------------
+ 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
+ ];
};
-
}
-
- /**
- * Called when Natars account needs to be created, creates his account and capital village
- *
- */
-
- public function createNatars(){
+
+
+ /*
+ =====================================================
+ = NATARS ACCOUNT CREATION
+ =====================================================
+ */
+
+ 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);
-
- //Convert from coordinates to village IDs
+
+ $database->register(
+ TRIBE5,
+ $password,
+ self::NATARS_EMAIL,
+ self::NATARS_TRIBE,
+ null,
+ self::NATARS_UID,
+ self::NATARS_DESC
+ );
+
$possibleWids = $database->getVilWrefs(self::NATARS_CAPITAL_COORDINATES);
-
- //Check if the villages aren't already taken
- $wid = $database->getFreeVillage($possibleWids);
+ $wid = $database->getFreeVillage($possibleWids);
- //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);
+ $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);
}
-
- /**
- * 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) {
+
+
+ /*
+ =====================================================
+ = ACTIVATE ARTIFACTS ENGINE
+ =====================================================
+ */
+
+ public function activateArtifacts()
+ {
global $database;
- //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);
+ $activationTime = 86400 / (
+ SPEED == 2 ? 1.5 :
+ (SPEED == 3 ? 2 : SPEED)
+ );
+
+ $artifacts = $database->getInactiveArtifacts(
+ round(time() - $activationTime)
+ );
+
+ if (empty($artifacts)) {
+ return;
}
- 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']++;
- }
+ /*
+ -------------------------------------------------
+ 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']++;
+
}
}
}
}
- /**
- * 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){
+
+
+ /*
+ =====================================================
+ = RETURN ARTIFACT TO NATARS
+ =====================================================
+ */
+
+ public function returnArtifactToNatars($artifactArray)
+ {
global $database;
-
- //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'];
+
+ $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);
-
- //Set the buildings array
+ $artifactTroops[0] = array_keys($unitsArray);
+
$artifactBuildings[1][] = array_values(self::NATARS_ARTIFACTS_BUILDINGS);
- $artifactBuildings[0] = array_keys(self::NATARS_ARTIFACTS_BUILDINGS);
+ $artifactBuildings[0] = array_keys(self::NATARS_ARTIFACTS_BUILDINGS);
- //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]);
+ $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
+ ]
+ );
}
-
- /**
- * 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 = "-";
- if ( is_array($artifact) ) {
- if($artifact['size'] == 1 && $artifact['type'] != 11){
- $requiredLevel = 10;
- $effectInfluence = VILLAGE;
- }else{
- $requiredLevel = $artifact['type'] != 11 ? 20 : 10;
- $effectInfluence = ACCOUNT;
- }
- 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))));
- }
+ /*
+ =====================================================
+ = ARTIFACT INFO HELPER
+ =====================================================
+ */
- //// 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;
+ public static function getArtifactInfo($artifact)
+ {
+ if (!is_array($artifact)) {
+ return [
+ "requiredLevel" => 0,
+ "active" => 0,
+ "bonus" => 0,
+ "effectInfluence" => 0,
+ "nextEffect" => 0
+ ];
}
-
- return ["requiredLevel" => $requiredLevel, "active" => $active,
- "bonus" => $bonus, "effectInfluence" => $effectInfluence,
- "nextEffect" => $nextEffect];
+
+ $activationTime = 86400 / (
+ SPEED == 2 ? 1.5 :
+ (SPEED == 3 ? 2 : SPEED)
+ );
+
+ $time = time();
+
+ $requiredLevel =
+ ($artifact['size'] == 1 && $artifact['type'] != 11)
+ ? 10
+ : 20;
+
+ $active =
+ $artifact['owner'] == self::NATARS_UID
+ ? "-"
+ : ($artifact['active'] ? "".ACTIVE."" : "-");
+
+ return [
+ "requiredLevel" => $requiredLevel,
+ "active" => $active,
+ "bonus" => $artifact['effect'] ?? '',
+ "effectInfluence" => ACCOUNT,
+ "nextEffect" => $time + $activationTime
+ ];
}
}
-?>
\ No newline at end of file
+?>
diff --git a/GameEngine/Automation.php b/GameEngine/Automation.php
index 1ea28d21..d6e34398 100644
--- a/GameEngine/Automation.php
+++ b/GameEngine/Automation.php
@@ -880,12 +880,29 @@ class Automation {
$totalattackdead = $data_num = 0;
if ($dataarray && count($dataarray)) {
- // preload village data
+ // preload village data
$vilIDs = [];
- foreach($dataarray as $data) {
+ 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
+ // ===============================
$vilIDs[$data['from']] = true;
$vilIDs[$data['to']] = true;
- }
+ }
$vilIDs = array_keys($vilIDs);
$database->getProfileVillages($vilIDs, 5);
$database->getUnit($vilIDs);
@@ -2733,81 +2750,90 @@ class Automation {
}
}
- 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']);
+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
+ );
}
- $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));
+ $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
}
}
+
+ $this->pruneResource();
+}
private function sendSettlersComplete() {
global $database;
@@ -4606,6 +4632,26 @@ class Automation {
$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 822ffe17..0c55ac09 100755
--- a/GameEngine/BBCode.php
+++ b/GameEngine/BBCode.php
@@ -1,255 +1,178 @@
- 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
+ =============================== */
$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] = "
";
-$replace[4] = "
";
-$replace[5] = "
";
-$replace[6] = "
";
-$replace[7] = "
";
-$replace[8] = "
";
-$replace[9] = "
";
-$replace[10] = "
";
-$replace[11] = "
";
-$replace[12] = "
";
-$replace[13] = "
";
-$replace[14] = "
";
-$replace[15] = "
";
-$replace[16] = "
";
-$replace[17] = "
";
-$replace[18] = "
";
-$replace[19] = "
";
-$replace[20] = "
";
-$replace[21] = "
";
-$replace[22] = "
";
-$replace[23] = "
";
-$replace[24] = "
";
-$replace[25] = "
";
-$replace[26] = "
";
-$replace[27] = "
";
-$replace[28] = "
";
-$replace[29] = "
";
-$replace[30] = "
";
-$replace[31] = "
";
-$replace[32] = "
";
-$replace[33] = "
";
-$replace[34] = "
";
-$replace[35] = "
";
-$replace[36] = "
";
-$replace[37] = "
";
-$replace[38] = "
";
-$replace[39] = "
";
-$replace[40] = "
";
-$replace[41] = "
";
-$replace[42] = "
";
-$replace[43] = "
";
-$replace[44] = "
";
-$replace[45] = "
";
-$replace[46] = "
";
-$replace[47] = "
";
-$replace[48] = "
";
-$replace[49] = "
";
-$replace[50] = "
";
-$replace[51] = "
";
-$replace[52] = "
";
-$replace[53] = "
";
-$replace[54] = "
";
-$replace[55] = "
";
-$replace[56] = "
";
-$replace[57] = "
";
-$replace[54] = "
";
-$replace[55] = "
";
-$replace[56] = "
";
-$replace[57] = "
";
-$replace[58] = "
";
-$replace[59] = "
";
-$replace[60] = "
";
-$replace[61] = "
";
-$replace[62] = "
";
-$replace[63] = "
";
-$replace[64] = "
";
-$replace[65] = "
";
-$replace[66] = "
";
-$replace[67] = "
";
-$replace[68] = "
";
-$replace[69] = "
";
-$replace[70] = "
";
-$replace[71] = "
";
-$replace[72] = "
";
-$replace[73] = "
";
-$replace[74] = "
";
-$replace[75] = "
";
-$replace[76] = "
";
-$replace[77] = "
";
-$replace[78] = "
";
-$replace[79] = "
";
-$replace[80] = "
";
-$replace[81] = "
";
-$replace[82] = "
";
-$replace[83] = "
";
-$replace[84] = "
";
-$replace[85] = "
";
-$replace[86] = "
";
-$replace[87] = "
";
-$replace[88] = "
";
-// replace alliance placeholders
+/* -------- 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[] = "
";
+}
+
+/* -------- HERO -------- */
+$pattern[] = "/\[hero\]/i";
+$replace[] = "
";
+
+/* -------- 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[] = "
";
+}
+
+/* -------- 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[] = "
";
+}
+
+/* basic emoticons */
+$basic = [":D"=>"grin",":)"=>"happy",":("=>"sad",";)"=>"wink"];
+foreach ($basic as $code => $class) {
+ $pattern[] = "/" . preg_quote($code, '/') . "/";
+ $replace[] = "
";
+}
+
+/* ===============================
+ SECURE PLACEHOLDER CALLBACKS
+ =============================== */
+
+/* -------- ALLIANCE -------- */
$input = preg_replace_callback(
- "/\[alliance(\d{0,20})\]([^\]]*)\[\/alliance\d{0,20}\]/is",
- function($matches) {
+ "/\[alliance(\d{1,20})\]([0-9]{1,20})\[\/alliance\d{1,20}\]/i",
+ static function ($m) {
global $database;
-
- $aname = $database->getAllianceName($matches[2]);
- if (!empty($aname)) return "".$aname."";
- else return "Alliance not found!";
+ $aid = (int)$m[2];
+ $aname = $database->getAllianceName($aid);
+ return $aname
+ ? "".bb_e($aname).""
+ : "Alliance not found!";
},
- $input);
+ $input
+);
-// replace player placeholders
+/* -------- PLAYER -------- */
$input = preg_replace_callback(
- "/\[player(\d{0,20})\]([^\]]*)\[\/player\d{0,20}\]/is",
- function($matches) {
+ "/\[player(\d{1,20})\]([0-9]{1,20})\[\/player\d{1,20}\]/i",
+ static function ($m) {
global $database;
-
- $uname = $database->getUserField((int) $matches[2], "username", 0);
- if (!empty($uname) && $uname != "[?]") return "".$uname."";
- else return "Player not found!";
+ $uid = (int)$m[2];
+ $uname = $database->getUserField($uid, "username", 0);
+ return ($uname && $uname !== "[?]")
+ ? "".bb_e($uname).""
+ : "Player not found!";
},
- $input);
+ $input
+);
-// replace report placeholders
+/* -------- REPORT -------- */
$input = preg_replace_callback(
- "/\[report(\d{0,20})\]([^\]]*)\[\/report\d{0,20}\]/is",
- function($matches) {
+ "/\[report(\d{1,20})\]([0-9]{0,20})\[\/report\d{1,20}\]/i",
+ static function ($m) {
global $database;
-
- $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!";
+ $rid = (int)($m[1] ?: $m[2]);
+ $report = $database->getNotice2($rid, null, false);
+ return $report
+ ? "".bb_e($report['topic']).""
+ : "Report not found!";
},
- $input);
+ $input
+);
-// replace coordinate placeholders
+/* -------- COORDINATES -------- */
$input = preg_replace_callback(
- "/\[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);
+ "/\[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);
$state = $database->getVillageType($wRef);
- if($state > 0){
- if($database->getVillageState($wRef)) $name = $database->getVillageField($wRef, 'name');
- else $name = ABANDVALLEY;
- }
- else $name = $database->getOasisInfo($wRef)['name'];
-
- if(!empty($name)) return "".$name." (".$coordinates[0]."|".$coordinates[1].")"."";
- return "Village not found!";
- },
- $input);
-$input = preg_replace('/\[message\]/', '', $input);
-$input = preg_replace('/\[\/message\]/', '', $input);
+ if ($state > 0) {
+ $name = $database->getVillageState($wRef)
+ ? $database->getVillageField($wRef, 'name')
+ : ABANDVALLEY;
+ } else {
+ $oasis = $database->getOasisInfo($wRef);
+ $name = $oasis['name'] ?? '';
+ }
+
+ return $name
+ ? "".bb_e($name)." ({$x}|{$y})"
+ : "Village not found!";
+ },
+ $input
+);
+
+/* -------- REMOVE MESSAGE TAGS -------- */
+$input = preg_replace('/\[\/?message\]/i', '', $input);
+
+/* ===============================
+ FINAL BBCode REPLACE
+ =============================== */
+
$bbcoded = preg_replace($pattern, $replace, $input);
-?>
diff --git a/GameEngine/Battle.php b/GameEngine/Battle.php
index c90da0a6..fb77b9a0 100755
--- a/GameEngine/Battle.php
+++ b/GameEngine/Battle.php
@@ -18,772 +18,324 @@
## ##
#################################################################################
+/*
+=========================================================
+= 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 {
+class Battle
+{
+ /*
+ =====================================================
+ = INTERNAL MATH ENGINE
+ =====================================================
+ */
- /**
- *
- * @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()
+ {
+ // 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
+ =================================================
*/
-
- 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];
- }
- }
- $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);
+ $attackPoints = $this->calculateAttackPoints($Attacker, $att_tribe);
+ $defensePoints = $this->calculateDefensePoints($Defender);
- if (!count($heroarray)) return ['heroid' => 0, 'unit' =>'','atk' => 0,'di' => 0,'dc' => 0,'ob' => 0,'db' => 0,'health' => 0];
+ /*
+ =================================================
+ = 2. WALL & RESIDENCE BONUS
+ =================================================
+ */
- $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);
+ $defensePoints = $this->applyWallBonus(
+ $defensePoints,
+ $def_wall,
+ $def_tribe,
+ $residence
+ );
- 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']];
- }
+ /*
+ =================================================
+ = 3. FINAL RAP / RDP
+ =================================================
+ */
- private function getBattleHeroSim($attbonus) {
- $h_atk = 0;
- $h_ob = 1 + 0.010 * $attbonus;
+ $rap = round($attackPoints);
+ $rdp = round($defensePoints);
- return ['unit' => 16,'atk' => $h_atk,'ob' => $h_ob];
- }
+ $winner = $rap > $rdp;
- 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;
- }
+ /*
+ =================================================
+ = 4. CASUALTY FACTOR
+ =================================================
+ */
- $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;
+ $ratio = $rap > 0
+ ? pow(($rdp / $rap), 1.5)
+ : 1;
- if(empty($post['kata'])) $post['kata'] = 0;
+ if ($ratio > 1) $ratio = 1;
- // 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 = [];
- $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);
+ $result['Attack_points'] = $rap;
+ $result['Defend_points'] = $rdp;
+ $result['Winner'] = $winner ? "attacker" : "defender";
+ $result[1] = $ratio;
+ $result[2] = 1 - $ratio;
- 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);
+ /*
+ =================================================
+ = 5. CASUALTIES
+ =================================================
+ */
- foreach($DefendersAll as $defenders) {
- for ($i = 1; $i <= 50; $i++) $def_ab[$i] = 0;
- $fromvillage = $defenders['from'];
+ $result['casualties_attacker'] =
+ $this->calculateCasualties($Attacker, $ratio, $att_tribe);
- $userdataCache[$fromvillage] = $database->getUserArray($database->getVillageField($fromvillage, "owner"), 1);
+ /*
+ =================================================
+ = 6. BOUNTY
+ =================================================
+ */
- $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;
+ $result['bounty'] =
+ $this->calculateBounty($Attacker, $result['casualties_attacker'], $att_tribe);
- 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;
}
- 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};
+ /*
+ =====================================================
+ = ATTACK / DEFENSE HELPERS
+ =====================================================
+ */
- 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];
- }
+ 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'];
}
- $datadef['dp'] = $dp;
- $datadef['cdp'] = $cdp;
- $datadef['detect'] = $detected;
- $datadef['involve'] = $invol;
- return $datadef;
+ return $points;
}
- 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'];
- }
+ private function calculateDefensePoints($Defender)
+ {
+ $points = 0;
- }
- $invol += $defenders['u'.$y]; //total troops
- $units['Def_unit'][$y] = $defenders['u'.$y];
+ for ($i = 1; $i <= 50; $i++) {
+ global ${'u'.$i};
+ $points += (int)$Defender['u'.$i] * ${'u'.$i}['di'];
}
- $datadef['dp'] = $dp;
- $datadef['cdp'] = $cdp;
- $datadef['involve'] = $invol;
- return $datadef;
+
+ return $points;
}
-
- /**
- * @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 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 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 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;
}
-};
+
+ 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 b71624c5..04e50c0e 100755
--- a/GameEngine/Chat.php
+++ b/GameEngine/Chat.php
@@ -4,6 +4,7 @@
## --------------------------------------------------------------------------- ##
## Filename Chat.php ##
## Developed by: TTMMTT ##
+## Refactored by: Shadow ##
## License: TravianZ Project ##
## Copyright: TravianZ (c) 2010-2025. All rights reserved. ##
## ##
@@ -11,377 +12,196 @@
if (!isset($SAJAX_INCLUDED)) {
- $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'] = '';
+ $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'] = '';
+ /* ==============================
+ SECURITY HELPERS
+ ============================== */
- function sajax_init() {
- }
+ function sajax_safe_string($value) {
+ return htmlspecialchars((string)$value, ENT_QUOTES | ENT_SUBSTITUTE, 'UTF-8');
+ }
- function sajax_get_my_uri() {
- return $_SERVER["REQUEST_URI"];
- }
- $sajax_remote_uri = sajax_get_my_uri();
+ function sajax_validate_function($func_name) {
+ global $sajax_export_list;
+ return in_array($func_name, $sajax_export_list, true);
+ }
+ /* ==============================
+ CLIENT REQUEST HANDLER (HARDENED)
+ ============================== */
- function sajax_get_js_repr($value) {
- $type = gettype($value);
+ function sajax_handle_client_request() {
- 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" ) {
+ global $sajax_export_list;
- $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;
- }
- }
+ $mode = '';
- function sajax_handle_client_request() {
- global $sajax_export_list;
+ if (isset($_GET['rs'])) $mode = 'get';
+ if (isset($_POST['rs'])) $mode = 'post';
- $mode = "";
+ if (!$mode) return;
- if (! empty($_GET["rs"]))
- $mode = "get";
+ header("Cache-Control: no-store, no-cache, must-revalidate");
+ header("Pragma: no-cache");
- if (!empty($_POST["rs"]))
- $mode = "post";
+ $func_name = $mode === 'get'
+ ? (string)$_GET['rs']
+ : (string)$_POST['rs'];
- if (empty($mode))
- return;
+ $args = $mode === 'get'
+ ? ($_GET['rsargs'] ?? [])
+ : ($_POST['rsargs'] ?? []);
- $target = "";
+ if (!is_array($args)) {
+ $args = [$args];
+ }
- if ($mode == "get") {
+ if (!sajax_validate_function($func_name) || !function_exists($func_name)) {
+ echo "-:Function not callable";
+ exit;
+ }
- header ("Expires: Mon, 26 Jul 1997 05:00:00 GMT");
- header ("Last-Modified: " . gmdate("D, d M Y H:i:s") . " GMT");
+ echo "+:";
+ $result = call_user_func_array($func_name, $args);
+ echo "var res = " . trim(sajax_get_js_repr($result)) . "; res;";
+ exit;
+ }
- 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();
- }
+ /* ==============================
+ SAFE JS ENCODER
+ ============================== */
- 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;
- }
+ function sajax_get_js_repr($value) {
- function sajax_get_common_js() {
- global $sajax_debug_mode;
- global $sajax_request_type;
- global $sajax_remote_uri;
- global $sajax_failure_redirect;
+ if (is_bool($value)) {
+ return $value ? "Boolean(true)" : "Boolean(false)";
+ }
- $t = strtoupper($sajax_request_type);
- if ($t != "" && $t != "GET" && $t != "POST")
- return "// Invalid type: $t.. \n\n";
+ if (is_int($value)) {
+ return "parseInt($value)";
+ }
- ob_start();
- ?>
+ if (is_float($value)) {
+ return "parseFloat($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 = "";
+ if (is_array($value) || is_object($value)) {
- function sajax_debug(text) {
- if (sajax_debug_mode)
- alert(text);
- }
+ $value = (array)$value;
+ $pairs = [];
- function sajax_init_object() {
- sajax_debug("sajax_init_object() called..")
+ 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);
+ }
- var A;
+ return "{ " . implode(', ', $pairs) . " }";
+ }
- 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;
- }
- }
+ return "'" . sajax_safe_string($value) . "'";
+ }
- if(!A && typeof XMLHttpRequest != "undefined")
- A = new XMLHttpRequest();
- if (!A)
- sajax_debug("Could not create connection object.");
- return A;
- }
+ function sajax_export() {
+ global $sajax_export_list;
+ foreach (func_get_args() as $func) {
+ if (is_string($func)) {
+ $sajax_export_list[] = $func;
+ }
+ }
+ }
- 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);
+function add_data($data) {
- 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);
- }
- }
+ global $session, $database;
- function get_data() {
- global $session,$database;
+ if (!$session->uid) return;
- $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;
- }
+ $msg = is_array($data) ? ($data[1] ?? '') : $data;
+ $msg = trim((string)$msg);
- $sajax_request_type = "GET";
- sajax_init();
- sajax_export("add_data","get_data");
- sajax_handle_client_request();
+ if ($msg === '') return;
-?>
+ $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 e4f19f62..262de472 100755
--- a/GameEngine/Database.php
+++ b/GameEngine/Database.php
@@ -1037,6 +1037,24 @@ class MYSQLi_DB implements IDbConnection {
$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 2196c091..2b7d2e4b 100755
--- a/GameEngine/Form.php
+++ b/GameEngine/Form.php
@@ -9,67 +9,107 @@
## ##
#################################################################################
-class Form {
+class Form
+{
+ private array $errorarray = [];
+ public array $valuearray = [];
+ private int $errorcount = 0;
- private $errorarray = array();
- public $valuearray = array();
- private $errorcount;
+ public function __construct()
+ {
+ if (
+ isset($_SESSION['errorarray'], $_SESSION['valuearray']) &&
+ is_array($_SESSION['errorarray']) &&
+ is_array($_SESSION['valuearray'])
+ ) {
- public function __construct() {
- if(isset($_SESSION['errorarray']) && isset($_SESSION['valuearray'])) {
- $this->errorarray = $_SESSION['errorarray'];
- $this->valuearray = $_SESSION['valuearray'];
- $this->errorcount = count($this->errorarray);
+ // Defensive copy (avoid reference issues)
+ $this->errorarray = $this->sanitizeArray($_SESSION['errorarray']);
+ $this->valuearray = $this->sanitizeArray($_SESSION['valuearray']);
+ $this->errorcount = count($this->errorarray);
- unset($_SESSION['errorarray']);
- unset($_SESSION['valuearray']);
- }
- else $this->errorcount = 0;
- }
+ unset($_SESSION['errorarray'], $_SESSION['valuearray']);
+ }
+ }
- public function addError($field,$error) {
- $this->errorarray[$field] = $error;
- $this->errorcount = count($this->errorarray);
- }
+ /* ==============================
+ INTERNAL SANITIZER
+ ============================== */
- public function getError($field) {
- if(array_key_exists($field,$this->errorarray)) {
- return $this->errorarray[$field];
- }
- else return "";
- }
+ private function sanitizeArray(array $array): array
+ {
+ $clean = [];
- 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;
- }
+ foreach ($array as $key => $value) {
- public function getDiff($field,$cookie) {
- if(array_key_exists($field,$this->valuearray) && $this->valuearray[$field] != $cookie) {
- return $this->valuearray[$field];
- }
- else return $cookie;
- }
+ // Force string keys
+ $safeKey = (string)$key;
- public function getRadio($field,$value) {
- if(array_key_exists($field,$this->valuearray) && $this->valuearray[$field] == $value) {
- return "checked";
- }
- else return "";
- }
+ // Prevent object injection / unexpected types
+ if (is_scalar($value) || is_null($value)) {
+ $clean[$safeKey] = $value;
+ } else {
+ $clean[$safeKey] = '';
+ }
+ }
- public function returnErrors() {
- return $this->errorcount;
- }
+ return $clean;
+ }
- public function getErrors() {
- return $this->errorarray;
- }
-};
-?>
\ No newline at end of file
+ /* ==============================
+ 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;
+ }
+}
diff --git a/GameEngine/Generator.php b/GameEngine/Generator.php
index 65900738..729eb7bb 100755
--- a/GameEngine/Generator.php
+++ b/GameEngine/Generator.php
@@ -9,136 +9,193 @@
## ##
#################################################################################
-class MyGenerator {
+class MyGenerator
+{
+ /* ===============================
+ RANDOM GENERATORS
+ =============================== */
- public function generateRandID(){
- return md5($this->generateRandStr(16));
- }
+ public function generateRandID()
+ {
+ return md5($this->generateRandStr(16));
+ }
- 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;
- }
+ public function generateRandStr($length)
+ {
+ $length = (int)$length;
+ if ($length <= 0) return '';
- public function encodeStr($str, $length) {
- $encode = md5($str);
- return substr($encode, 0 ,$length);
- }
+ // Hard cap to prevent abuse
+ if ($length > 256) $length = 256;
- public function procDistanceTime($coor, $thiscoor, $ref, $mode, $vid = 0) {
- global $database, $bid28, $bid14, $village;
+ $randstr = '';
- 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);
- }
+ for ($i = 0; $i < $length; $i++) {
+ $randnum = random_int(0, 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;
- }
+ if ($randnum < 10) {
+ $randstr .= chr($randnum + 48);
+ } elseif ($randnum < 36) {
+ $randstr .= chr($randnum + 55);
+ } else {
+ $randstr .= chr($randnum + 61);
+ }
+ }
- 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);
- }
+ return $randstr;
+ }
+ public function encodeStr($str, $length)
+ {
+ $length = (int)$length;
+ if ($length <= 0) return '';
- public function getBaseID($x, $y){
- return ((WORLD_MAX - $y) * (WORLD_MAX * 2 + 1)) + (WORLD_MAX + $x + 1);
- }
+ $hash = md5((string)$str);
- public function getMapCheck($wref){
- return substr(md5($wref), 5, 2);
- }
+ if ($length > 32) $length = 32;
- 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];
- }
+ return substr($hash, 0, $length);
+ }
- public function pageLoadTimeEnd(){
- $endtime = microtime(true);
- $endarray = explode(" ", $endtime);
- //$endtime = $endarray[1] + $endarray[0];
- return $endarray[0];
- }
+ /* ===============================
+ DISTANCE / TIME CALCULATIONS
+ =============================== */
-};
-$generator = new MyGenerator;
+ 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();
diff --git a/GameEngine/Logging.php b/GameEngine/Logging.php
index d8d763d1..9730a306 100755
--- a/GameEngine/Logging.php
+++ b/GameEngine/Logging.php
@@ -5,106 +5,187 @@
## --------------------------------------------------------------------------- ##
## Filename Logging.php ##
## License: TravianZ Project ##
+## Refactor by: Shadow ##
## Copyright: TravianZ (c) 2010-2025. All rights reserved. ##
## ##
#################################################################################
class Logging {
- 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);
- }
- }
+ /* ==============================
+ INTERNAL SAFE EXECUTOR
+ ============================== */
- 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);
- }
- }
+ private function safeInsert($query, $types, $params) {
+ global $database;
- 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);
- }
- }
+ $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 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);
- }
- }
+ /* ==============================
+ ILLEGAL LOG
+ ============================== */
- 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);
- }
- }
+ public function addIllegal($uid, $ref, $type) {
+ if (!LOG_ILLEGAL) return;
- public function addAdminLog() {
- global $database;
- }
+ $uid = (int)$uid;
+ $ref = (string)$ref;
+ $type = (int)$type;
- 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);
- }
- }
+ $log = "Attempted to ";
+ if ($type === 1) {
+ $log .= "access village " . $ref;
+ }
- public function addWarLog() {
- global $database;
- }
+ $this->safeInsert(
+ "INSERT INTO ".TB_PREFIX."illegal_log (user, log) VALUES (?, ?)",
+ "is",
+ array($uid, $log)
+ );
+ }
- public function clearLogs() {
- global $database;
- }
+ /* ==============================
+ LOGIN LOG
+ ============================== */
- public static function debug($debug_info, $time = 0) {
- global $database, $generator;
- list($debug_info) = $database->escape_input($debug_info);
-
- echo '';
- }
-};
+ public function addLoginLog($id, $ip) {
+ if (!LOG_LOGIN) return;
-$logging = new Logging;
-?>
+ $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();
diff --git a/GameEngine/Mailer.php b/GameEngine/Mailer.php
index ca35c36a..ade3148d 100755
--- a/GameEngine/Mailer.php
+++ b/GameEngine/Mailer.php
@@ -1,10 +1,9 @@
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."
Thank you for your registration.
@@ -32,38 +66,69 @@ Click the following link in order to activate your account:
Greetings,
Travian adminision";
- $headers = "From: ".ADMIN_EMAIL."\n";
+ $headers = "From: " . $this->sanitizeHeader(ADMIN_EMAIL);
- mail($email, $subject, $message, $headers);
- }
+ return mail($email, $subject, $message, $headers);
+ }
- function sendInvite($email,$uid,$text) {
+ /* =====================================================
+ SEND INVITE (BACKWARD COMPATIBLE)
+ ====================================================== */
- $subject = "".SERVER_NAME." registeration";
+ public function sendInvite($email, $uid, $text, $username = null) {
- $message = "Hello ".$username."
+ $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."
Try the new ".SERVER_NAME."!
-
Link: ".SERVER."anmelden.php?id=ref".$uid."
".$text."
-
Greetings,
Travian";
- $headers = "From: ".ADMIN_EMAIL."\n";
+ $headers = "From: " . $this->sanitizeHeader(ADMIN_EMAIL);
- mail($email, $subject, $message, $headers);
- }
+ return mail($email, $subject, $message, $headers);
+ }
- function sendPassword($email,$uid,$username,$npw,$cpw) {
+ /* =====================================================
+ SEND PASSWORD RESET
+ ====================================================== */
- $subject = "Password forgotten";
+ public function sendPassword($email, $uid, $username, $npw, $cpw) {
- $message = "Hello ".$username."
+ $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."
You have requested a new password for Travian.
@@ -75,21 +140,20 @@ Password: ".$npw."
Please click this link to activate your new password. The old password then
becomes invalid:
-http://${_SERVER['HTTP_HOST']}/password.php?cpw=$cpw&npw=$uid
+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: ".ADMIN_EMAIL."\n";
+ $headers = "From: " . $this->sanitizeHeader(ADMIN_EMAIL);
- mail($email, $subject, $message, $headers);
- }
+ return mail($email, $subject, $message, $headers);
+ }
+}
-};
-$mailer = new Mailer;
-?>
\ No newline at end of file
+$mailer = new Mailer();
+?>
diff --git a/GameEngine/Market.php b/GameEngine/Market.php
index 75ad7bf2..8f89ea7b 100755
--- a/GameEngine/Market.php
+++ b/GameEngine/Market.php
@@ -5,6 +5,7 @@
## Filename Market.php ##
## Developed by: Dzoki ##
## Some fixes: aggenkeech ##
+## Refactor: Shadow ##
## License: TravianZ Project ##
## Copyright: TravianZ (c) 2010-2025. All rights reserved. ##
## ##
@@ -12,377 +13,532 @@
class Market
{
- public $onsale, $onmarket, $sending, $recieving, $return = [];
- public $maxcarry, $merchant, $used;
+ 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 function procMarket($post)
{
$this->loadMarket();
- if(isset($_SESSION['loadMarket']))
- {
+
+ if(isset($_SESSION['loadMarket'])) {
$this->loadOnsale();
unset($_SESSION['loadMarket']);
}
- 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;
- }
+
+ 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;
}
}
+ /* =========================================================
+ REMOVE / ACCEPT HANDLER
+ ========================================================== */
+
public function procRemove($get)
{
global $database, $village, $session;
- if(isset($get['t']) && $get['t'] == 1)
- {
+ 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) {
$this->filterNeed($get);
}
- else if(isset($get['t']) && $get['t'] == 2 && isset($get['a']) && $get['a'] == 5 && isset($get['del']))
+
+ if($t === 2
+ && isset($get['a'])
+ && $this->int($get['a']) === 5
+ && isset($get['del']))
{
- //GET ALL FIELDS FROM MARKET
- $type = $database->getMarketField($village->wid, $get['del'], "gtype");
- $amt = $database->getMarketField($village->wid, $get['del'], "gamt");
+ $del = $this->int($get['del']);
+
+ $type = $database->getMarketField($village->wid, $del, "gtype");
+ $amt = $database->getMarketField($village->wid, $del, "gamt");
+
$database->getResourcesBack($village->wid, $type, $amt);
- $database->addMarket($village->wid, $get['del'], 0, 0, 0, 0, 0, 0, 1);
- header("Location: build.php?id=".$get['id']."&t=2");
- exit;
+ $database->addMarket($village->wid, $del, 0,0,0,0,0,0,1);
+
+ $this->safeRedirect("build.php?id=".$id."&t=2");
}
- if(isset($get['t']) && $get['t'] == 1 && isset($get['a']) && $get['a'] == $session->mchecker && !isset($get['del']))
+
+ if($t === 1
+ && isset($get['a'])
+ && $this->int($get['a']) === $session->mchecker
+ && !isset($get['del']))
{
$session->changeChecker();
- $this->acceptOffer($get);
+ $this->acceptOffer($get);
}
}
+ /* =========================================================
+ MERCHANTS
+ ========================================================== */
+
public function merchantAvail()
{
- return $this->merchant - $this->used;
+ return max(0, $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);
- $this->merchant = ($building->getTypeLevel(17) > 0)? $bid17[$building->getTypeLevel(17)]['attri'] : 0;
- $this->used = $database->totalMerchantUsed($village->wid);
+ $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->onmarket = $database->getMarket($village->wid,0);
- $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;
+
+ $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;
}
}
+ /* =========================================================
+ SEND RESOURCE (FULL HARDENED)
+ ========================================================== */
+
private function sendResource($post)
{
global $database, $village, $session, $generator, $logging, $form;
- $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
+ 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;
+ }
+
$database->getVillage($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);
+ $availableWood = (int)$database->getWoodAvailable($village->wid);
+ $availableClay = (int)$database->getClayAvailable($village->wid);
+ $availableIron = (int)$database->getIronAvailable($village->wid);
+ $availableCrop = (int)$database->getCropAvailable($village->wid);
- 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);
+ if(
+ $availableWood < $r1 ||
+ $availableClay < $r2 ||
+ $availableIron < $r3 ||
+ $availableCrop < $r4
+ ) {
+ $form->addError("error", TOO_FEW_RESOURCES);
+ return;
}
- else $form->addError("error", TOO_FEW_RESOURCES);
+
+ $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);
}
+ /* =========================================================
+ ADD OFFER (ANTI EXPLOIT HARDENED)
+ ========================================================== */
+
private function addOffer($post)
{
global $database,$village,$session;
+ if(!is_array($post)) return;
- if($post['rid1'] == $post['rid2'])
- {
- // Trading res for res of same type (invalid)
- header("Location: build.php?id=".$post['id']."&t=2&e2");
- exit;
+ $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");
}
- 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($rid1 === $rid2 || $m1 <= 0 || $m2 <= 0) {
+ $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;
+
+ if($m1 > (2 * $m2) || $m2 > (2 * $m1)) {
+ $this->safeRedirect("build.php?id=".$buildId."&t=2&e2");
}
- 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;
+
+ $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['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;
+
+ $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");
}
- 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;
- // preload all village data, since we're retrieving some of those separately below
- $database->getVillage($village->wid);
+ if($database->modifyResource($village->wid,$wood,$clay,$iron,$crop,0)) {
- $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;
+ $time = 0;
+ if(isset($post['d2'])) {
+ $time = $this->int($post['d2']) * 3600;
}
+
+ $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;
- $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;
- }
+ 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");
}
-
- // 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;
- }
-
- $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);
- $timestamp = time();
- $database->addMovement(
- [0, 0],
- [$village->wid, $infoarray['vref']],
- [$infoarray['vref'], $village->wid],
- [$mysendid, $hissendid],
- [$timestamp, $timestamp],
- [$mytime + $timestamp, $histime + $timestamp]
+
+ $reqMerc = ceil(($infoarray['wamt'] - 0.1) / $this->maxcarry);
+
+ $myResources = array(
+ 1 => $village->awood,
+ 2 => $village->aclay,
+ 3 => $village->airon,
+ 4 => $village->acrop
);
- $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;
+
+ if($infoarray['wamt'] > $myResources[$infoarray['wtype']]) {
+ $this->safeRedirect("build.php?id=".$buildId."&t=1&e1");
+ }
+
+ 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
+ );
+
+ $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
+ );
+
+ $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)
+ );
+
+ $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);
}
+ /* =========================================================
+ LOAD ONSALE (SAFE FILTERED)
+ ========================================================== */
+
private function loadOnsale()
{
global $database,$village,$session,$multisort,$generator;
$displayarray = $database->getMarket($village->wid,1);
- $holderarray = [];
- foreach($displayarray as $value)
- {
+ $holderarray = array();
+
+ 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;
- array_push($holderarray,$value);
+ $holderarray[] = $value;
}
}
+
$this->onsale = $multisort->sorte($holderarray, "duration", true, 2);
}
+ /* =========================================================
+ FILTER NEED (SAFE)
+ ========================================================== */
+
private function filterNeed($get)
{
- 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;
+ 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;
}
- else $this->loadOnsale();
+
+ $this->onsale = $holder;
}
+ /* =========================================================
+ GOLD TRADE (HARDENED)
+ ========================================================== */
+
private function tradeResource($post)
{
global $session,$database,$village;
- $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;
- }
+ if(!is_array($post) || !isset($post['m2']) || !is_array($post['m2'])) return;
- //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;
- }
+ $buildId = isset($post['id']) ? $this->int($post['id']) : 0;
+
+ if($session->userinfo['gold'] < 3) {
+ $this->safeRedirect("build.php?id=".$buildId."&t=3");
}
+
+ $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 f8e40995..399738c3 100755
--- a/GameEngine/Message.php
+++ b/GameEngine/Message.php
@@ -5,682 +5,960 @@
+---------------------------------------------------------+
| Credits: All the developers including the leaders: |
| Advocaite & Dzoki & Donnchadh |
+| Refactored by : Shadow |
| |
| Copyright: TravianZ Project All rights reserved |
\** --------------------------------------------------- **/
class Message {
- public $unread, $nunread = false;
- public $note;
- public $inbox, $inbox1, $sent, $sent1, $reading, $reply, $archived, $archived1, $noticearray, $readingNotice = [];
- private $totalMessage;
+ 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;
- 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'){
- 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 == 'nachrichten.php') {
- if ($req_file == 'berichte.php') $this->getNotice();
+ $t = isset($_GET['t']) ? trim($_GET['t']) : 1;
- if(isset($_SESSION['reply'])) {
- $this->reply = $_SESSION['reply'];
- unset($_SESSION['reply']);
- }
- }
+ switch($t) {
- public function procMessage($post) {
+ case 2:
+ case '2a':
+ $this->getMessages(2);
+ break;
- 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;
- }
- }
- }
+ case 3:
+ $this->getMessages(3);
+ 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
- */
-
- 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);
- }
-
- if($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;
- }
- }
+ default:
+ $this->getMessages(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);
}
- }
- public function sendWelcome($uid, $username) {
- global $database;
+ if($req_file == 'berichte.php') {
+ $this->getNotice();
+ }
- $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]";
+ if(isset($_SESSION['reply'])) {
+ $this->reply = $_SESSION['reply'];
+ unset($_SESSION['reply']);
+ }
+ }
- return $database->sendMessage($uid, 1, WEL_TOPIC, addslashes($welcomemsg), 0, 0, 0, 0, 0);
- }
+ /* ===================================================== */
+ /* ================= SAFE HELPERS ====================== */
+ /* ===================================================== */
- private function wordCensor($text) {
- $censorarray = explode(",", CENSORED);
- foreach($censorarray as $key => $value) {
- $censorarray[$key] = "/" . $value . "/i";
- }
- return preg_replace($censorarray, "****", $text);
- }
+ private function sanitizeText($text) {
+ return htmlspecialchars(trim($text), ENT_QUOTES, 'UTF-8');
+ }
- private function checkUnread() {
- global $database, $session;
+ private function sanitizeInt($value) {
+ return (int)$value;
+ }
- return $database->getUnreadMessagesCount($session->uid);
- }
+ 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() {
- private function checkNUnread() {
global $database, $session;
- return $database->getUnreadNoticesCount($session->uid);
- }
+ $all = $database->getNotice($session->uid);
+ $this->noticearray = $this->filter_by_value_except($all, "ntype", 9);
+ }
- private function findInbox($id) {
- if(!empty($this->inbox)){
- foreach($this->inbox as $message){
- if($message['id'] == $id) return true;
- }
- }
- return false;
- }
+ private function getReadNotice($id) {
- private function findSent($id){
- if(!empty($this->sent)){
- foreach($this->sent as $message){
- if($message['id'] == $id) return true;
- }
- }
- return false;
- }
+ global $database, $session;
- private function findArchive($id){
- if(!empty($this->archived)){
- foreach($this->archived as $message){
- if($message['id'] == $id) return true;
- }
- }
-
- return false;
- }
+ $id = (int)$id;
+ if($id <= 0) return null;
- 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();
- }
+ $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 = "";
+ }
+ }
+
+ /* ===================================================== */
+ /* ================= 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')) {
+ $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');
+
+ $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;
+ }
+ }
+
+ break;
+ }
+ }
+ }
+
+ $this->safeRedirect("nachrichten.php?t=1");
+ }
+
+ /* ===================================================== */
+ /* ================= LOAD MESSAGES ===================== */
+ /* ===================================================== */
+
+ private function getMessages($which) {
+
+ global $database, $session;
+
+ $uid = (int)$session->uid;
+ if($uid <= 0) return;
+
+ switch((int)$which) {
+
+ case 1:
+ // Inbox
+ $this->inbox = $database->getMessage($uid, 1);
+ $this->inbox1 = $database->getMessage($uid, 9);
+ break;
+
+ case 2:
+ // Sent
+ $this->sent = $database->getMessage($uid, 2);
+ $this->sent1 = $database->getMessage($uid, 10);
+ break;
+
+ case 3:
+ // Archived (Plus only)
+ if(!empty($session->plus)) {
+ $this->archived = $database->getMessage($uid, 6);
+ $this->archived1 = $database->getMessage($uid, 11);
+ }
+ break;
+ }
+ }
+
+}
diff --git a/GameEngine/Profile.php b/GameEngine/Profile.php
index 6401d868..21ab83f0 100755
--- a/GameEngine/Profile.php
+++ b/GameEngine/Profile.php
@@ -5,187 +5,292 @@
## --------------------------------------------------------------------------- ##
## Filename Profile.php ##
## License: TravianZ Project ##
+## Refactor: Shadow ##
## Copyright: TravianZ (c) 2010-2025. All rights reserved. ##
## ##
#################################################################################
-
class Profile {
- 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;
- }
- }
- }
+ /* ===================================================== */
+ /* ================= MAIN PROCESS ====================== */
+ /* ===================================================== */
- 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;
- }
+ public function procProfile($post) {
- 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
- */
+ if(!isset($post['ft'])) return;
- private function setvactionmode($post){
- global $database, $session, $form;
+ switch($post['ft']) {
- 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;
- }
-
- }
+ case "p1":
+ $this->updateProfile($post);
+ break;
- /**
- * Function to vacation mode - by advocaite and Shadow
- *
- * @param array $post The $_POST array
- */
+ case "p3":
+ $this->updateAccount($post);
+ break;
- private function updateAccount($post) {
- global $database, $session, $form;
+ case "p4":
+ $this->setVacationMode($post);
+ break;
+ }
- 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(isset($post['s']) && (int)$post['s'] === 4) {
+ $this->gpack($post);
+ }
+ }
- 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;
- }
+ public function procSpecial($get) {
- private function removeSitter($get) {
- global $database,$session;
+ if(!isset($get['e'])) return;
- if($get['a'] == $session->checker) {
- if($session->userinfo['sit'.$get['type']] == $get['id']) {
- $database->updateUserField($session->uid,"sit".$get['type'],0,1);
- }
- $session->changeChecker();
- }
+ switch((int)$get['e']) {
- header("Location: spieler.php?s=".$get['s']);
- exit;
- }
+ case 2:
+ $this->removeMeSit($get);
+ break;
- private function cancelDeleting($get) {
- global $database, $session;
-
- $database->setDeleting($session->uid,1);
- header("Location: spieler.php?s=".$get['s']);
- exit;
- }
+ case 3:
+ $this->removeSitter($get);
+ break;
- private function removeMeSit($get) {
- global $database, $session;
+ case 4:
+ $this->cancelDeleting($get);
+ break;
+ }
+ }
- if($get['a'] == $session->checker) {
- $database->removeMeSit($get['id'],$session->uid);
- $session->changeChecker();
- }
+ /* ===================================================== */
+ /* ================= UPDATE PROFILE ==================== */
+ /* ===================================================== */
- header("Location: spieler.php?s=".$get['s']);
- exit;
- }
-};
+ 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;
+ }
+
+}
$profile = new Profile;
-?>
diff --git a/GameEngine/Protection.php b/GameEngine/Protection.php
index c295b420..442288c1 100755
--- a/GameEngine/Protection.php
+++ b/GameEngine/Protection.php
@@ -5,22 +5,97 @@
## 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. ##
-## ##
#################################################################################
-//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);
- }
+/*
+|--------------------------------------------------------------------------
+| 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;
}
- $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 008549e8..2a6b3dec 100755
--- a/GameEngine/Ranking.php
+++ b/GameEngine/Ranking.php
@@ -9,584 +9,678 @@
| Copyright: TravianZ Project All rights reserved |
\** --------------------------------------------------- **/
- class Ranking {
+class Ranking {
- public $rankarray = [];
- private $rlastupdate;
+ public $rankarray = array();
+ private $rlastupdate = 0;
- public function getRank() {
- return $this->rankarray;
- }
+ public function getRank() {
+ return $this->rankarray;
+ }
- 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;
- }
+ public function getUserRank($id) {
+ global $database;
- 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"));
- }
- }
+ $id = (int)$id;
+ $ranking = $this->getRank();
- 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;
- }
- }
- }
+ $usersQuery = "SELECT Count(*) as Total FROM " . TB_PREFIX . "users
+ WHERE access < " . (INCLUDE_ADMIN ? "10" : "8");
- 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);
- }
- }
+ $usersResult = mysqli_query($database->dblink, $usersQuery);
+ if(!$usersResult) return 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;
- }
- }
- }
+ $usersRow = mysqli_fetch_array($usersResult, MYSQLI_ASSOC);
+ $totalUsers = isset($usersRow['Total']) ? (int)$usersRow['Total'] : 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;
- }
-
- }
- }
+ $limit = $totalUsers + 1;
+ $myrank = 0;
- 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'];
+ 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;
}
- $data = $database->getVSumField($memberIDs,"pop");
+ }
+ }
+ }
- if (count($data)) {
- foreach ($data as $row) {
- $totalpop += $row['Total'];
+ 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'];
}
}
+ }
+ }
- $value['players'] = count($memberlist);
- $value['totalpop'] = $totalpop;
- if(!isset($value['avg'])) {
- $value['avg'] = @round($totalpop / count($memberlist));
- } else {
- $value['avg'] = 0;
- }
+ $value['players'] = count($memberlist);
+ $value['totalpop'] = $totalpop;
- 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;
- }
+ if(count($memberlist) > 0) {
+ $value['avg'] = (int)round($totalpop / count($memberlist));
+ } else {
+ $value['avg'] = 0;
+ }
- 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'];
+ $holder[] = $value;
+ }
- 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;
- }
+ if(is_array($holder) && count($holder) > 0) {
+ $holder = $multisort->sorte($holder, "totalpop", false, 2);
+ }
- 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;
- }
+ $newholder = array("pad");
+ foreach($holder as $row) {
+ $newholder[] = $row;
+ }
- 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;
- }
+ $this->rankarray = $newholder;
+ }
+ public function procHeroRankArray() {
+ global $multisort;
- 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;
- }
+ $array = $GLOBALS['db']->getHeroRanking();
+ $holder = array();
- 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;
- }
- }
- ;
+ if(!is_array($array)) {
+ $this->rankarray = array("pad");
+ return;
+ }
- $ranking = new Ranking;
+ 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;
?>
diff --git a/GameEngine/Session.php b/GameEngine/Session.php
index 8d4d0235..abdc0117 100755
--- a/GameEngine/Session.php
+++ b/GameEngine/Session.php
@@ -8,26 +8,25 @@ 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 ##
+## Fixed by: Shadow - STARVATION , HERO FIXED COMPL. ##
+## Fixed by: InCube - double troops ##
+## Refactored TravianZ Enterprise Hardened Core by Shadow ##
## 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;
}
}
@@ -38,6 +37,7 @@ 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,324 +60,440 @@ 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 = [];
- var $checker, $mchecker;
- public $userinfo = [];
- private $userarray = [];
- var $villages = [];
+ 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();
- function __construct() {
- global $database; //TienTN fix
+ function __construct() {
+ global $database;
- $this->time = time();
- if (!isset($_SESSION)) {
- session_start();
- }
+ $this->time = time();
- $this->logged_in = $this->checkLogin();
+ if (session_status() == PHP_SESSION_NONE) {
+ session_start();
+ }
- 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();
- }
+ session_regenerate_id(true); // 🔒 Session fixation protection
- 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);
+ $this->logged_in = $this->checkLogin();
- $userFields = $database->getUserFields($user_sanitized, "quest, id", 1, true);
- $_SESSION['qst'] = $userFields["quest"];
+ if($this->logged_in && TRACK_USR) {
+ $database->updateActiveUser($this->username, $this->time);
+ }
- $dbarray = $database->getUserFields($user_sanitized, 'id, village_select', 1);
- $selected_village=(int) $dbarray['village_select'];
+ $this->referrer = isset($_SESSION['url']) ? $_SESSION['url'] : "/";
+ $this->url = $_SESSION['url'] = $_SERVER['PHP_SELF'];
- 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();
+ $this->SurfControl();
+ }
+ public function Login($user) {
+ global $database, $generator, $logging;
- $database->updateActiveUser($user_sanitized, $this->time);
- $database->updateUserField($user_sanitized, "sessid", $_SESSION['sessid'], 0);
- }
+ if(empty($user)) {
+ header("Location: login.php");
+ exit;
+ }
- $logging->addLoginLog($dbarray['id'], $_SERVER['REMOTE_ADDR']);
+ $this->logged_in = true;
- if ($dbarray['id'] == 1) {
- header("Location: nachrichten.php");
- exit;
- } else {
- header("Location: dorf1.php");
- exit;
- }
- }
+ $_SESSION['sessid'] = $generator->generateRandID();
+ $_SESSION['username'] = $user;
+ $_SESSION['checker'] = $generator->generateRandStr(3);
+ $_SESSION['mchecker'] = $generator->generateRandStr(5);
- 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();
- }
+ // 🔒 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 changeChecker() {
- global $generator;
-
- $this->checker = $_SESSION['checker'] = $generator->generateRandStr(3);
- $this->mchecker = $_SESSION['mchecker'] = $generator->generateRandStr(5);
- }
+ if(!$dbarray) {
+ $this->Logout();
+ header("Location: login.php");
+ exit;
+ }
- private function checkLogin(){
- global $database;
-
- $user = $id = '';
- $admin = false;
- $inAdmin = (strpos($_SERVER['REQUEST_URI'], '/Admin') !== false);
+ $_SESSION['id_user'] = (int)$dbarray['id'];
+ $_SESSION['qst'] = $dbarray['quest'];
- 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;
- }
+ $selected_village = (int)$dbarray['village_select'];
- 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(!isset($_SESSION['wid']) || empty($_SESSION['wid'])) {
- //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(!empty($selected_village)) {
+ $data = $database->getVillage($selected_village);
+ } else {
+ $data = $database->getVillage($dbarray['id']);
+ }
- /**
- * 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
- *
- */
+ if(isset($data['wref'])) {
+ $_SESSION['wid'] = (int)$data['wref'];
+ }
+ }
- function CheckHeroReal () {
- global $database,$link;
+ $this->PopulateVar();
- $villageIDs = implode(', ', $this->villages);
- if (!count($this->villages)) {
- $this->Logout();
- header('login.php');
- exit;
- }
+ $database->updateActiveUser($user, $this->time);
+ $database->updateUserField($user, "sessid", $_SESSION['sessid'], 0);
- // 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'];
+ $logging->addLoginLog($dbarray['id'], $_SERVER['REMOTE_ADDR']);
- // check if the actual hero is alive or being trained/revived into a living state
- $isHeroLivingOrRaising = $database->getHeroDeadReviveOrInTraining($this->uid);
+ if ($dbarray['id'] == 1) {
+ header("Location: nachrichten.php");
+ } else {
+ header("Location: dorf1.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);
+ 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;
}
}
- 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;
+ // Populate user data
+ $this->PopulateVar();
- 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];
+ // Ban check
+ $this->isBanned();
- }
- $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;
- }
- }
+ $database->updateActiveUser($user, $this->time);
- }
- }
-};
-$session = new Session;
-$form = new Form;
+ return true;
+ }
-// 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;
+ return false;
+ }
- // 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);
+ /**
+ * 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);
}
-?>
diff --git a/GameEngine/Units.php b/GameEngine/Units.php
index b80ccaac..33ff82a5 100755
--- a/GameEngine/Units.php
+++ b/GameEngine/Units.php
@@ -88,13 +88,6 @@ 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;
@@ -234,584 +227,1006 @@ class Units {
$database->deleteReinf($enforce['id']);
}
- private function sendTroops($post) {
- global $form, $database, $village, $session;
+ private function sendTroops($post){
+ global $form, $database, $village, $session;
- $data = $database->getA2b($post['timestamp_checksum']);
- $Gtribe = ($session->tribe == 1) ? "" : $session->tribe - 1;
+ /*
+ =========================================================
+ = 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
+ -----------------------------------------------------
+ */
for ($i = 1; $i < 10; $i++) {
- 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");
+
+ 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");
break;
}
- if ($data['u'.$i] < 0) {
- $form->addError("error", "You can't send negative units.");
+ if ($post['t'.$i] < 0) {
+ $form->addError("error", "You can't send back negative units.");
break;
}
+
+ } else {
+ $post['t'.$i] = '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){
+ /*
+ -----------------------------------------------------
+ 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) {
+
$_SESSION['errorarray'] = $form->getErrors();
$_SESSION['valuearray'] = $_POST;
- 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");
+
+ 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();
- }
+ /*
+ -----------------------------------------------------
+ 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;
}
+}
+
- public function Settlers($post) {
- global $form, $database, $village, $session;
+/*
+=========================================================
+= SETTLERS - FOUND NEW VILLAGE
+=========================================================
+*/
- $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;
+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
+ );
}
+
+ 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;
}
- public function Hero($uid, $all = 0, $include_dead = false) {
- global $database;
- $heroarray = $database->getHero($uid, $all, $include_dead);
+ /*
+ -----------------------------------------------------
+ SINGLE HERO MODE
+ -----------------------------------------------------
+ */
+
+ if (!$all) {
+
$herodata = false;
$singleHeroArrayID = 0;
- // no hero data found
- if (!count($heroarray)) {
- return false;
+ foreach ($heroarray as $id => $hero) {
+
+ if (!$herodata && $hero['dead'] != 1) {
+ $herodata = $GLOBALS["h".$hero['unit']];
+ $singleHeroArrayID = $id;
+ break;
+ }
}
- // 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;
+ 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;
break;
}
}
- // 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']];
- }
+ if ($canSend) {
- $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']];
+ $ckey = $generator->generateRandStr(6);
- $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']
- ];
+ $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);
}
-
- 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;
- $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();
- }
+ header("Location: build.php?id=39&t=99");
+ exit();
+}
};
$units = new Units;
diff --git a/GameEngine/index.php b/GameEngine/index.php
index a81240cd..bb8da7d4 100755
--- a/GameEngine/index.php
+++ b/GameEngine/index.php
@@ -8,12 +8,22 @@
## 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");
+}
?>

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.

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.