From 5d91de0e14b640f3dfa929cfc62ba729fcfd3224 Mon Sep 17 00:00:00 2001 From: Martin Ambrus Date: Sun, 29 Oct 2017 23:06:25 +0100 Subject: [PATCH] feat: new Embassy logic for demolitions and alliance quitting --- GameEngine/Alliance.php | 57 +++++++-- GameEngine/Automation.php | 2 +- GameEngine/Database.php | 208 +++++++++++++++++++++++++++++--- Templates/Alliance/quitalli.tpl | 74 +++++++++++- Templates/Build/15_1.tpl | 53 +++++++- 5 files changed, 359 insertions(+), 35 deletions(-) diff --git a/GameEngine/Alliance.php b/GameEngine/Alliance.php index a20a2a8f..9afffff7 100755 --- a/GameEngine/Alliance.php +++ b/GameEngine/Alliance.php @@ -376,7 +376,7 @@ class Alliance { $database->deleteAlliance($session->alliance); // log the notice $database->insertAlliNotice($session->alliance, '' . addslashes($post['a_user']) . ' has quit the alliance.'); - if($database->isAllianceOwner($UserData['id'])){ + 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.""; @@ -435,15 +435,54 @@ class Alliance { } elseif(!password_verify($post['pw'], $session->userinfo['password'])) { $form->addError("pw2", PW_ERR); } else { - $database->updateUserField($session->uid, 'alliance', 0, 1); - if($database->isAllianceOwner($session->uid)){ - $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); - $this->updateMax($newleader); + // 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) { + // 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']; + } + + $members = $database->getAllMember($session->alliance); + $validMemberFound = false; + + foreach ($members as $member) { + if ($member['id'] == $post['new_founder']) { + $validMemberFound = true; + break; + } + } + + if (!$validMemberFound) { + $form->addError("founder2", 'founder is not valid'); + return; + } + + $newleader = $post['new_founder']; + $q = "UPDATE " . TB_PREFIX . "alidata set leader = ".(int) $newleader." where id = ".(int) $session->alliance.""; + $_SESSION['alliance_user'] = 0; + $database->query($q); + $database->updateAlliPermissions($newleader, 1, 1, 1, 1, 1, 1, 1, 1, 1); + $this->updateMax($newleader); + + // send the new founder an in-game message, notifying them of their election + $database->sendMessage( + $newleader, + 1, + 'You are now leader of your alliance', + "Hi!\n\nThis is to inform you that the former leader of your alliance - ".$database->escape($session->username).", has decided to quit and elected you as his replacement. You now gain full access, administration and responsibilities to your alliance.\n\nGood luck!\n\nYours sincerely,\nServer Robot :)", + 0, + 0, + 0, + 0, + 0, + true); } + + $database->updateUserField($session->uid, 'alliance', 0, 1); $database->deleteAlliPermissions($session->uid); // log the notice $database->deleteAlliance($session->alliance); diff --git a/GameEngine/Automation.php b/GameEngine/Automation.php index 98c7b524..e65a2b4b 100755 --- a/GameEngine/Automation.php +++ b/GameEngine/Automation.php @@ -4122,7 +4122,7 @@ $wallimg = "getPop($type,$level-1); $database->modifyPop($vil['vref'],$pop[0],1); $this->procClimbers($database->getVillageField($vil['vref'],'owner')); - $database->delDemolition($vil['vref']); + $database->delDemolition($vil['vref'], true); } } if(file_exists("GameEngine/Prevention/demolition.txt")) { diff --git a/GameEngine/Database.php b/GameEngine/Database.php index aeb4c013..45d9273f 100755 --- a/GameEngine/Database.php +++ b/GameEngine/Database.php @@ -1696,16 +1696,24 @@ class MYSQLi_DB implements IDbConnection { } function isAllianceOwner($id) { - list($id) = $this->escape_input((int) $id); + $id = (int) $id; - $q = "SELECT * from " . TB_PREFIX . "alidata where leader = ". $id; + $q = "SELECT id from " . TB_PREFIX . "alidata where leader = ". $id; $result = mysqli_query($this->dblink,$q); if(mysqli_num_rows($result)) { - return true; + $result = mysqli_fetch_assoc($result); + return $result['id']; } else { return false; } } + + function countAllianceMembers($aid) { + $aid = (int) $aid; + $q = "SELECT Count(*) as Total from ".TB_PREFIX."users WHERE alliance = ".$aid; + $membersCount = $this->query_return($q); + return $membersCount[0]['Total']; + } function aExist($ref, $type) { list($ref, $type) = $this->escape_input($ref, $type); @@ -2131,13 +2139,84 @@ class MYSQLi_DB implements IDbConnection { return $row["f" . $field]; } + function getSingleFieldTypeCount($uid, $field, $lvl = false, $lvlComparisonSign = '=') { + $uid = (int) $uid; + $field = (int) $field; + $lvl = ($lvl === false ? $lvl : (int) $lvl); + + if (!in_array($lvlComparisonSign, ['=', '<', '>', '>=', '<=', '!='])) { + $lvlComparisonSign = '='; + } + + $q = " + SELECT + Count(*) as Total + FROM + ".TB_PREFIX."fdata f + LEFT JOIN ".TB_PREFIX."vdata v ON f.vref = v.wref + LEFT JOIN ".TB_PREFIX."users u ON v.owner = u.id + WHERE + u.id = ".$uid." + AND + ( + (f1t = ".$field.($lvl !== false ? ' AND f1 '.$lvlComparisonSign.' '.$lvl : '').") + OR (f2t = ".$field.($lvl !== false ? ' AND f2 '.$lvlComparisonSign.' '.$lvl : '').") + OR (f3t = ".$field.($lvl !== false ? ' AND f3 '.$lvlComparisonSign.' '.$lvl : '').") + OR (f4t = ".$field.($lvl !== false ? ' AND f4 '.$lvlComparisonSign.' '.$lvl : '').") + OR (f5t = ".$field.($lvl !== false ? ' AND f5 '.$lvlComparisonSign.' '.$lvl : '').") + OR (f6t = ".$field.($lvl !== false ? ' AND f6 '.$lvlComparisonSign.' '.$lvl : '').") + OR (f7t = ".$field.($lvl !== false ? ' AND f7 '.$lvlComparisonSign.' '.$lvl : '').") + OR (f8t = ".$field.($lvl !== false ? ' AND f8 '.$lvlComparisonSign.' '.$lvl : '').") + OR (f9t = ".$field.($lvl !== false ? ' AND f9 '.$lvlComparisonSign.' '.$lvl : '').") + OR (f10t = ".$field.($lvl !== false ? ' AND f10 '.$lvlComparisonSign.' '.$lvl : '').") + OR (f11t = ".$field.($lvl !== false ? ' AND f11 '.$lvlComparisonSign.' '.$lvl : '').") + OR (f12t = ".$field.($lvl !== false ? ' AND f12 '.$lvlComparisonSign.' '.$lvl : '').") + OR (f13t = ".$field.($lvl !== false ? ' AND f13 '.$lvlComparisonSign.' '.$lvl : '').") + OR (f14t = ".$field.($lvl !== false ? ' AND f14 '.$lvlComparisonSign.' '.$lvl : '').") + OR (f15t = ".$field.($lvl !== false ? ' AND f15 '.$lvlComparisonSign.' '.$lvl : '').") + OR (f16t = ".$field.($lvl !== false ? ' AND f16 '.$lvlComparisonSign.' '.$lvl : '').") + OR (f17t = ".$field.($lvl !== false ? ' AND f17 '.$lvlComparisonSign.' '.$lvl : '').") + OR (f18t = ".$field.($lvl !== false ? ' AND f18 '.$lvlComparisonSign.' '.$lvl : '').") + OR (f19t = ".$field.($lvl !== false ? ' AND f19 '.$lvlComparisonSign.' '.$lvl : '').") + OR (f20t = ".$field.($lvl !== false ? ' AND f20 '.$lvlComparisonSign.' '.$lvl : '').") + OR (f21t = ".$field.($lvl !== false ? ' AND f21 '.$lvlComparisonSign.' '.$lvl : '').") + OR (f22t = ".$field.($lvl !== false ? ' AND f22 '.$lvlComparisonSign.' '.$lvl : '').") + OR (f23t = ".$field.($lvl !== false ? ' AND f23 '.$lvlComparisonSign.' '.$lvl : '').") + OR (f24t = ".$field.($lvl !== false ? ' AND f24 '.$lvlComparisonSign.' '.$lvl : '').") + OR (f25t = ".$field.($lvl !== false ? ' AND f25 '.$lvlComparisonSign.' '.$lvl : '').") + OR (f26t = ".$field.($lvl !== false ? ' AND f26 '.$lvlComparisonSign.' '.$lvl : '').") + OR (f27t = ".$field.($lvl !== false ? ' AND f27 '.$lvlComparisonSign.' '.$lvl : '').") + OR (f28t = ".$field.($lvl !== false ? ' AND f28 '.$lvlComparisonSign.' '.$lvl : '').") + OR (f29t = ".$field.($lvl !== false ? ' AND f29 '.$lvlComparisonSign.' '.$lvl : '').") + OR (f30t = ".$field.($lvl !== false ? ' AND f30 '.$lvlComparisonSign.' '.$lvl : '').") + OR (f31t = ".$field.($lvl !== false ? ' AND f31 '.$lvlComparisonSign.' '.$lvl : '').") + OR (f32t = ".$field.($lvl !== false ? ' AND f32 '.$lvlComparisonSign.' '.$lvl : '').") + OR (f33t = ".$field.($lvl !== false ? ' AND f33 '.$lvlComparisonSign.' '.$lvl : '').") + OR (f34t = ".$field.($lvl !== false ? ' AND f34 '.$lvlComparisonSign.' '.$lvl : '').") + OR (f35t = ".$field.($lvl !== false ? ' AND f35 '.$lvlComparisonSign.' '.$lvl : '').") + OR (f36t = ".$field.($lvl !== false ? ' AND f36 '.$lvlComparisonSign.' '.$lvl : '').") + OR (f37t = ".$field.($lvl !== false ? ' AND f37 '.$lvlComparisonSign.' '.$lvl : '').") + OR (f38t = ".$field.($lvl !== false ? ' AND f38 '.$lvlComparisonSign.' '.$lvl : '').") + OR (f39t = ".$field.($lvl !== false ? ' AND f39 '.$lvlComparisonSign.' '.$lvl : '').") + OR (f40t = ".$field.($lvl !== false ? ' AND f40 '.$lvlComparisonSign.' '.$lvl : '').") + )"; + + $result = mysqli_query($this->dblink,$q); + $row = mysqli_fetch_array($result); + return $row["Total"]; + } + function getFieldType($vid, $field) { list($vid, $field) = $this->escape_input((int) $vid, $field); - $q = "SELECT f" . $field . "t from " . TB_PREFIX . "fdata where vref = $vid"; - $result = mysqli_query($this->dblink,$q); - $row = mysqli_fetch_array($result); - return $row["f" . $field . "t"]; + if ($field && $vid) { + $q = "SELECT f" . $field . "t from " . TB_PREFIX . "fdata where vref = $vid"; + $result = mysqli_query($this->dblink,$q); + $row = mysqli_fetch_array($result); + return $row["f" . $field . "t"]; + } else { + return 0; + } } function getFieldDistance($wid) { @@ -2678,12 +2757,36 @@ class MYSQLi_DB implements IDbConnection { function addDemolition($wid, $field) { list($wid, $field) = $this->escape_input((int) $wid, (int) $field); - global $building, $village; + global $building, $village, $session; + + $fLevel = $this->getFieldLevel($wid,$field); + + // check if we're not demolishing an Embassy at level 3 + if ($fLevel == 3 && $this->getFieldType($wid,$field) == 18) { + // check if this user is the founder of the alliance + if ($session->alliance && $this->isAllianceOwner($session->uid) == $session->alliance) { + // check if we have any other players in this alliance left + $membersCount = $this->countAllianceMembers($session->alliance); + if ($membersCount > 1) { + // check if this player has only 1 last Embassy on level 3 + if ($this->getSingleFieldTypeCount($session->uid, 18, 3, '>=') == 1) { + // cannot demolish Embassy further until the player quits the alliance, + // as they are founder and there are still other players in the alliance, + // thus destroying Embassy would evict this player from the alliance + // and leave a new random leader + return 18; + } + } + } + } + $q = "DELETE FROM ".TB_PREFIX."bdata WHERE field=$field AND wid=$wid"; mysqli_query($this->dblink,$q); $uprequire = $building->resourceRequired($field,$village->resarray['f'.$field.'t'],0); - $q = "INSERT INTO ".TB_PREFIX."demolition VALUES (".$wid.",".$field.",".($this->getFieldLevel($wid,$field)-1).",".(time()+floor($uprequire['time']/2)).")"; - return mysqli_query($this->dblink,$q); + $q = "INSERT INTO ".TB_PREFIX."demolition VALUES (".$wid.",".$field.",".($fLevel-1).",".(time()+floor($uprequire['time']/2)).")"; + mysqli_query($this->dblink,$q); + + return true; } @@ -2706,13 +2809,86 @@ class MYSQLi_DB implements IDbConnection { function finishDemolition($wid) { list($wid) = $this->escape_input((int) $wid); - $q = "UPDATE " . TB_PREFIX . "demolition SET timetofinish=" . time() . " WHERE vref=" . $wid; - $result= mysqli_query($this->dblink,$q); - return mysqli_affected_rows(); - } + $q = "UPDATE " . TB_PREFIX . "demolition SET timetofinish=" . time() . " WHERE vref=" . $wid; + $result= mysqli_query($this->dblink,$q); + return mysqli_affected_rows(); + } - function delDemolition($wid) { - list($wid) = $this->escape_input((int) $wid); + function delDemolition($wid, $checkEmbassy = false) { + $wid = (int) $wid; + + if ($checkEmbassy) { + // check if we've demolished an Embassy + // and select the user it belonged to as well, + // so we can potentially disconnect them from the alliance + // and remove it - if they don't have any more Embassies + // or if the they are founder and they have no more lvl 3+ Embassies + $q = ' + SELECT + u.id, u.alliance, d.buildnumber, d.lvl + FROM + '.TB_PREFIX.'demolition d + LEFT JOIN '.TB_PREFIX.'vdata v ON d.vref = v.wref + LEFT JOIN '.TB_PREFIX.'users u ON u.id = v.owner + WHERE d.vref = '.$wid; + + $res = mysqli_fetch_all(mysqli_query($this->dblink, $q), MYSQLI_ASSOC); + foreach ($res as $key) { + // if this building was demolished completely, there is no record of what it was + // therefore, we need to check status of Embassies in case we've just demolished + // an Embassy and should disconnect a player from an alliance + if ($key['lvl'] == 0 && $key['alliance'] > 0 && $this->getSingleFieldTypeCount($key['id'], 18, 1, '>=') == 0) { + // if we have no more Embassies and this player is in an alliance, + // disconnect him from that alliance + mysqli_query($this->dblink, 'UPDATE '.TB_PREFIX.'users SET alliance = 0 WHERE id = '.$key['id']); + $_SESSION['alliance_user'] = 0; + + // notify them via in-game messaging + $this->sendMessage( + $key['id'], + 2, + 'You left the alliance', + "Hi!\n\nThis is to inform you that due to a finished demolition of your last Embassy, you have now successfully left your alliance.\n\nYours sincerely,\nServer Robot :)", + 0, + 0, + 0, + 0, + 0, + true); + } else { + $fType = $this->getFieldType($wid, $key['buildnumber']); + + // we're actually demolishing an Embassy + if ($fType == 18) { + $isOwner = ($key['alliance'] && $this->isAllianceOwner($key['id']) == $key['alliance']); + + // in case the player is an alliance founder, + // we demolished a lvl 3 Embasy + // and there are no more lvl 3+ Embassies left for them + // disconnect them from the alliance and delete it + // because alliance can only be founded with a lvl 3+ Embassy + if ($isOwner && $key['lvl'] == 2 && $this->getSingleFieldTypeCount($key['id'], 18, 3, '>=') == 0) { + mysqli_query($this->dblink, 'UPDATE '.TB_PREFIX.'users SET alliance = 0 WHERE id = '.$key['id']); + $this->deleteAlliance($key['alliance']); + $_SESSION['alliance_user'] = 0; + + // notify them via in-game messaging + $this->sendMessage( + $key['id'], + 2, + 'Your alliance was disbanded', + "Hi!\n\nThis is to inform you that due to a finished demolition of your last Embassy at level 3, and the fact that you were the leader of your alliance, this alliance has been disbanded.\n\n\In order to found a new alliance, please build a level 3 Embassy again in one of your villages.\n\nYours sincerely,\nServer Robot :)", + 0, + 0, + 0, + 0, + 0, + true); + } + } + } + } + } $q = "DELETE FROM " . TB_PREFIX . "demolition WHERE vref=" . $wid; return mysqli_query($this->dblink,$q); diff --git a/Templates/Alliance/quitalli.tpl b/Templates/Alliance/quitalli.tpl index 8e0fe702..6a698295 100644 --- a/Templates/Alliance/quitalli.tpl +++ b/Templates/Alliance/quitalli.tpl @@ -6,6 +6,12 @@ else { $aid = $session->alliance; } $allianceinfo = $database->getAlliance($aid); +$isOwner = ($aid && $database->isAllianceOwner($session->uid) == $aid); + +if ($isOwner) { + $membersCount = $database->countAllianceMembers($aid); +} + echo "

".$allianceinfo['tag']." - ".$allianceinfo['name']."

"; include("alli_menu.tpl"); ?> @@ -20,9 +26,69 @@ include("alli_menu.tpl"); Quit alliance -In order to quit the alliance you have to enter your password again for safety reasons. -password: - - + 0) { +?> + + + Because you are the alliance founder, you need to select a replacement founder before you leave. + + + + + new founder: + + + getAllMember($aid); + ?> + + + + + + +
In order to quit the alliance you have to enter your password again for safety reasons. + + + + + password: + + + + + + + + + + +
+ Unfortunately, there are no members of the alliance with Embassy at level 3 or more. In this case, you will not be able + to reassign the founder role. You can still kick all members and quit the alliance afterwards, + if you wish. +
+

\ No newline at end of file diff --git a/Templates/Build/15_1.tpl b/Templates/Build/15_1.tpl index b0bd2a78..99ee9ea4 100644 --- a/Templates/Build/15_1.tpl +++ b/Templates/Build/15_1.tpl @@ -15,9 +15,13 @@ if(!empty($_REQUEST["demolish"]) && $_REQUEST["c"] == $session->mchecker) { if($session->access != BANNED){ if($_REQUEST["type"] != null) { $type = $_REQUEST['type']; - $database->addDemolition($village->wid,$type); - $session->changeChecker(); - header("Location: build.php?gid=15&ty=$type&cancel=0&demolish=0"); + $demolish_permitted = $database->addDemolition($village->wid,$type); + if ($demolish_permitted === true) { + $session->changeChecker(); + header("Location: build.php?gid=15&ty=$type&cancel=0&demolish=0"); + } else { + header("Location: build.php?gid=15&ty=$type&nodemolish=".$demolish_permitted); + } exit; } }else{ @@ -46,9 +50,21 @@ if($village->resarray['f'.$id] >= DEMOLISH_LEVEL_REQ) { } echo ""; } else { + if (isset($_GET['nodemolish'])) { + switch ($_GET['nodemolish']) { + case 18: + echo '

+ Because you are the founder of your alliance, demolition of a lvl 3 Embassy cannot be started. + You can still quit the alliance, while selecting a new leader + in the "quit alliance" form. +

'; + break; + } + } + echo "
mchecker."\" method=\"POST\" style=\"display:inline\"> -"; for ($i=19; $i<=41; $i++) { $select=($i==$ty)? " SELECTED":""; if ($VillageResourceLevels['f'.$i] >= 1 && !$building->isCurrent($i) && !$building->isLoop($i)) { @@ -61,7 +77,34 @@ if ($village->natar==1) { echo ""; } } -echo "
"; +echo ""; } } ?> + + \ No newline at end of file