mirror of
https://github.com/Shadowss/TravianZ.git
synced 2026-08-11 13:51:00 +00:00
Add sitter permission
Add sitter permission
This commit is contained in:
+25
-2
@@ -360,19 +360,42 @@ class Account {
|
||||
// Vacation mode by Shadow
|
||||
$database->removevacationmode($userData['id']);
|
||||
|
||||
/**
|
||||
* Marcam sesiunea ca fiind de SITTER si retinem CARE sitter e.
|
||||
*
|
||||
* Pana acum, dupa autentificare sesiunea unui sitter era identica cu a
|
||||
* proprietarului - nu exista nimic in $_SESSION care sa spuna ca cel din
|
||||
* spatele tastaturii e altcineva. Flagul "sit" din tabela online nu ajuta:
|
||||
* e per cont (nu per sesiune), se scrie cu INSERT IGNORE (deci nu se
|
||||
* actualizeaza daca randul exista deja) si nu spune care dintre cei doi
|
||||
* sitteri s-a conectat.
|
||||
*
|
||||
* $_SESSION['sitter_uid'] e sursa de adevar pentru permisiuni.
|
||||
*/
|
||||
$sitterUid = 0;
|
||||
|
||||
if ($database->login($username, $password)) {
|
||||
$database->UpdateOnline("login", $username, time(), $userData['id']);
|
||||
} elseif ($database->sitterLogin($username, $password)) {
|
||||
$database->UpdateOnline("sitter", $username, time(), $userData['id']);
|
||||
} else {
|
||||
$sitterUid = (int) $database->sitterLogin($username, $password);
|
||||
|
||||
if ($sitterUid > 0) {
|
||||
$database->UpdateOnline("sitter", $username, time(), $userData['id']);
|
||||
}
|
||||
}
|
||||
|
||||
setcookie("COOKUSR", $username, time() + COOKIE_EXPIRE, COOKIE_PATH);
|
||||
$session->login($username);
|
||||
|
||||
// dupa Login(), ca sa nu fie suprascris de initializarea sesiunii
|
||||
$_SESSION['sitter_uid'] = $sitterUid;
|
||||
}
|
||||
|
||||
private function Logout() {
|
||||
global $session, $database;
|
||||
unset($_SESSION['wid']);
|
||||
// altfel un login normal facut imediat dupa ar mosteni flagul de sitter
|
||||
unset($_SESSION['sitter_uid']);
|
||||
// actualizează statusul "activ" al utilizatorului
|
||||
$database->activeModify($database->escape($session->username), 1);
|
||||
// actualizează ultima activitate online
|
||||
|
||||
@@ -556,8 +556,17 @@ class AllianceBonus
|
||||
|
||||
if ($triple) {
|
||||
$cost = defined('ALLIANCE_BONUS_TRIPLE_GOLD') ? (int) ALLIANCE_BONUS_TRIPLE_GOLD : 3;
|
||||
$database->modifyGold($uid, $cost, 0);
|
||||
$session->gold -= $cost;
|
||||
|
||||
// PERMISIUNI SITTER: donatia tripla costa aur. Daca sitterul nu are
|
||||
// dreptul, donatia simpla (deja inregistrata mai sus) ramane valida,
|
||||
// doar bonusul platit nu se aplica.
|
||||
if (!isset($session) || !method_exists($session, 'sitterCan')
|
||||
|| $session->sitterCan(SITTER_PERM_GOLD)) {
|
||||
|
||||
if ($database->spendGold($uid, $cost, 'Alliance bonus triple donation')) {
|
||||
$session->gold -= $cost;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
mysqli_query($this->db, "COMMIT");
|
||||
|
||||
+19
-2
@@ -1604,9 +1604,26 @@ class Building {
|
||||
}
|
||||
|
||||
$spent = ($countMasterGold && $countPlus2Gold) ? 3 : 2;
|
||||
$newgold = $this->sess->gold - $spent;
|
||||
|
||||
$this->db->updateUserField($this->sess->uid, 'gold', $newgold, 1);
|
||||
/**
|
||||
* PERMISIUNI SITTER: "cheltuie aur".
|
||||
* Verificam inainte de scadere; daca nu are voie, nu se ia nimic.
|
||||
*/
|
||||
if (isset($this->sess) && method_exists($this->sess, 'sitterCan')
|
||||
&& !$this->sess->sitterCan(SITTER_PERM_GOLD)) {
|
||||
return;
|
||||
}
|
||||
|
||||
/**
|
||||
* spendGold() in loc de scriere absoluta: scaderea e relativa si atomica,
|
||||
* deci dispare riscul de dubla cheltuire descris in comentariul de mai jos
|
||||
* (soldul din sesiune putea fi vechi de pana la 30 de secunde).
|
||||
*/
|
||||
if (!$this->db->spendGold($this->sess->uid, $spent, 'Finish all constructions')) {
|
||||
return;
|
||||
}
|
||||
|
||||
$newgold = $this->sess->gold - $spent;
|
||||
|
||||
$this->db->addGoldFinLog(
|
||||
$this->vil->wid,
|
||||
|
||||
@@ -382,9 +382,32 @@ trait DatabaseUserQueries {
|
||||
return $cachedResult;
|
||||
}
|
||||
|
||||
/** @var array cache per request: username => uid-ul sitterului care s-a potrivit */
|
||||
private static $sitterLoginCache = array();
|
||||
|
||||
/**
|
||||
* Autentificare ca sitter pe contul $username.
|
||||
*
|
||||
* INTOARCE ACUM UID-UL SITTERULUI (0 = esec), nu doar true/false.
|
||||
* Fara asta nu se putea sti CARE dintre cei doi sitteri s-a conectat,
|
||||
* deci nu aveai cum sa aplici permisiuni diferite pentru sit1 si sit2.
|
||||
* Un uid e mereu > 0, iar 0 e falsy, deci apelurile vechi de forma
|
||||
* "if ($database->sitterLogin(...))" continua sa functioneze identic.
|
||||
*
|
||||
* Account.php o cheama de doua ori pe acelasi login (o data la validare,
|
||||
* o data ca sa scrie in tabela online). Cache-ul de mai jos face ca a
|
||||
* doua verificare de parola sa nu se mai execute - password_verify e
|
||||
* intentionat lent, deci conteaza.
|
||||
*/
|
||||
function sitterLogin($username, $password) {
|
||||
list($username, $password) = $this->escape_input($username, $password);
|
||||
|
||||
$cacheKey = $username . '|' . md5($password);
|
||||
|
||||
if (isset(self::$sitterLoginCache[$cacheKey])) {
|
||||
return self::$sitterLoginCache[$cacheKey];
|
||||
}
|
||||
|
||||
$q = "SELECT sit1,sit2 FROM " . TB_PREFIX . "users where username = '$username' and access != " . BANNED ." LIMIT 1";
|
||||
$result = mysqli_query($this->dblink,$q);
|
||||
$dbarray = mysqli_fetch_array($result);
|
||||
@@ -395,7 +418,7 @@ trait DatabaseUserQueries {
|
||||
* null". Iesim din start - oricum nu are cine sa fie sitter.
|
||||
*/
|
||||
if (!is_array($dbarray)) {
|
||||
return false;
|
||||
return self::$sitterLoginCache[$cacheKey] = 0;
|
||||
}
|
||||
|
||||
$dbarray2 = null;
|
||||
@@ -412,16 +435,19 @@ trait DatabaseUserQueries {
|
||||
$dbarray3 = mysqli_fetch_array($result3);
|
||||
}
|
||||
if($dbarray['sit1'] != 0 || $dbarray['sit2'] != 0) {
|
||||
// Verificam separat, ca sa stim CARE sitter s-a potrivit.
|
||||
// sit1/sit2 pot fi setati independent, deci unul dintre randuri
|
||||
// poate lipsi; fara ?? '' iesea acelasi warning pe null.
|
||||
if(password_verify($password, (string) ($dbarray2['password'] ?? ''))
|
||||
|| password_verify($password, (string) ($dbarray3['password'] ?? ''))) {
|
||||
return true;
|
||||
// poate lipsi; fara ?? '' iesea warning pe null.
|
||||
if (password_verify($password, (string) ($dbarray2['password'] ?? ''))) {
|
||||
return self::$sitterLoginCache[$cacheKey] = (int) $dbarray['sit1'];
|
||||
} else if (password_verify($password, (string) ($dbarray3['password'] ?? ''))) {
|
||||
return self::$sitterLoginCache[$cacheKey] = (int) $dbarray['sit2'];
|
||||
} else {
|
||||
return false;
|
||||
return self::$sitterLoginCache[$cacheKey] = 0;
|
||||
}
|
||||
} else {
|
||||
return false;
|
||||
// contul nu are niciun sitter definit
|
||||
return self::$sitterLoginCache[$cacheKey] = 0;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -446,6 +472,50 @@ trait DatabaseUserQueries {
|
||||
return isset($dbarray['timestamp']) ? (int)$dbarray['timestamp'] : 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* PUNCTUL UNIC DE CHELTUIRE A AURULUI.
|
||||
*
|
||||
* Scade $amount aur de la $uid, ATOMIC: conditia "gold >= amount" e in
|
||||
* acelasi UPDATE, deci doua cereri simultane nu pot scoate soldul pe minus.
|
||||
* Intoarce true doar daca s-a scazut efectiv.
|
||||
*
|
||||
* De ce exista: pana acum cheltuirea era imprastiata in ~11 locuri, iar
|
||||
* o parte scriau ABSOLUT ("gold = $session->gold - 2"). Scrierea absoluta
|
||||
* porneste de la soldul din sesiune, care poate fi vechi de pana la 30 de
|
||||
* secunde (cache-ul din Session::PopulateVar) - de aici riscul de dubla
|
||||
* cheltuire pe care il semnalau si comentariile din Building.php si
|
||||
* build.php. Scaderea relativa nu are problema asta.
|
||||
*
|
||||
* NU verifica permisiunile de sitter: gardul se pune in stratul de mai sus,
|
||||
* unde exista context pentru mesajul de eroare si pentru redirect.
|
||||
*/
|
||||
function spendGold($uid, $amount, $reason = '') {
|
||||
|
||||
$uid = (int) $uid;
|
||||
$amount = (int) $amount;
|
||||
|
||||
if ($uid <= 0 || $amount <= 0) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$q = "UPDATE " . TB_PREFIX . "users SET gold = gold - " . $amount
|
||||
. " WHERE id = " . $uid . " AND gold >= " . $amount;
|
||||
|
||||
mysqli_query($this->dblink, $q);
|
||||
|
||||
if (mysqli_affected_rows($this->dblink) != 1) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// soldul s-a schimbat in baza de date; cache-ul de sesiune trebuie
|
||||
// invalidat, altfel urmatoarea cerere ar reciti vechea valoare
|
||||
if (isset($_SESSION['username'])) {
|
||||
unset($_SESSION['cache_user_' . $_SESSION['username']]);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
function modifyGold($userid, $amt, $mode) {
|
||||
list($userid, $amt, $mode) = $this->escape_input((int) $userid, (int) $amt, $mode);
|
||||
|
||||
|
||||
@@ -4383,3 +4383,13 @@ tz_def('HERO_HEADER_RETURN_HOME', 'Hero returning home');
|
||||
tz_def('HERO_HEADER_PER_HOUR', 'per hour');
|
||||
tz_def('TZ_HEALTH', 'Health');
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
// PERMISIUNI SITTER
|
||||
//////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
tz_def('SITTER_P_ATTACK', 'send attacks');
|
||||
tz_def('SITTER_P_RAID', 'send raids');
|
||||
tz_def('SITTER_P_REINF', 'send reinforcements');
|
||||
tz_def('SITTER_P_RES', 'send resources to other players');
|
||||
tz_def('SITTER_P_GOLD', 'spend Gold');
|
||||
tz_def('SITTER_P_DENIED', 'Your sitter permissions do not allow this action.');
|
||||
|
||||
|
||||
@@ -4325,3 +4325,13 @@ tz_def('HERO_HEADER_RETURN_ADV', 'Le heros revient de l\'aventure');
|
||||
tz_def('HERO_HEADER_RETURN_HOME', 'Le heros rentre chez lui');
|
||||
tz_def('HERO_HEADER_PER_HOUR', 'par heure');
|
||||
tz_def('TZ_HEALTH', 'Sante');
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
// PERMISSIONS DU SITTER
|
||||
//////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
tz_def('SITTER_P_ATTACK', 'envoyer des attaques');
|
||||
tz_def('SITTER_P_RAID', 'envoyer des raids');
|
||||
tz_def('SITTER_P_REINF', 'envoyer des renforts');
|
||||
tz_def('SITTER_P_RES', 'envoyer des ressources à d’autres joueurs');
|
||||
tz_def('SITTER_P_GOLD', 'dépenser de l’or');
|
||||
tz_def('SITTER_P_DENIED', 'Vos permissions de sitter ne vous permettent pas d’effectuer cette action.');
|
||||
@@ -4119,3 +4119,14 @@ tz_def('HERO_HEADER_ATTACK', 'Eroul este plecat cu armata');
|
||||
tz_def('HERO_HEADER_REINFORCE', 'Eroul este intr-o intarire');
|
||||
tz_def('HERO_HEADER_IN', 'in');
|
||||
tz_def('TZ_HEALTH', 'Sanatate');
|
||||
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
// PERMISIUNI SITTER
|
||||
//////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
tz_def('SITTER_P_ATTACK', 'trimite atacuri');
|
||||
tz_def('SITTER_P_RAID', 'trimite raiduri');
|
||||
tz_def('SITTER_P_REINF', 'trimite intariri');
|
||||
tz_def('SITTER_P_RES', 'trimite resurse altor jucatori');
|
||||
tz_def('SITTER_P_GOLD', 'cheltuie aur');
|
||||
tz_def('SITTER_P_DENIED', 'Permisiunile tale de sitter nu iti permit aceasta actiune.');
|
||||
+60
-2
@@ -290,9 +290,50 @@ class Market
|
||||
// Keeping logic safe while preserving compatibility.
|
||||
$id = isset($post['getwref']) ? (int)$post['getwref'] : 0;
|
||||
|
||||
// Check vacation mode
|
||||
/**
|
||||
* PERMISIUNI SITTER: "trimite resurse altor jucatori".
|
||||
*
|
||||
* Restrictia se aplica DOAR catre alte conturi. Mutarea resurselor
|
||||
* intre satele proprii ramane permisa - altfel un sitter n-ar mai putea
|
||||
* administra contul deloc, ceea ce nu e scopul.
|
||||
*
|
||||
* Verificam proprietarul satului tinta, nu numele lui: un jucator poate
|
||||
* avea oricate sate, iar comparatia pe uid e singura de incredere.
|
||||
*/
|
||||
if ($id > 0 && isset($session) && is_object($session) && method_exists($session, 'sitterCan')) {
|
||||
|
||||
$targetOwner = (int) $database->getVillageField($id, 'owner');
|
||||
|
||||
if ($targetOwner > 0
|
||||
&& $targetOwner !== (int) $session->uid
|
||||
&& !$session->sitterCan(SITTER_PERM_RES)) {
|
||||
|
||||
$form->addError('error', defined('SITTER_P_DENIED')
|
||||
? SITTER_P_DENIED
|
||||
: 'Your sitter permissions do not allow this action.');
|
||||
|
||||
/**
|
||||
* "return", nu doar addError: mai jos urmeaza un lant
|
||||
* if/elseif care ajunge la ramura de trimitere indiferent de
|
||||
* erorile adaugate inainte. Fara iesire explicita, resursele
|
||||
* ar fi plecat oricum, iar mesajul de eroare ar fi fost doar
|
||||
* decorativ.
|
||||
*/
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* BUG PREEXISTENT: modul vacanta era doar semnalat, nu si blocat.
|
||||
*
|
||||
* Eroarea se adauga aici, dar mai jos urmeaza un lant if/elseif care
|
||||
* ajunge la ramura de trimitere indiferent de erorile de dinainte.
|
||||
* Rezultatul: mesajul "utilizatorul e in vacanta" aparea pe ecran, dar
|
||||
* resursele plecau oricum catre contul protejat. Iesim explicit.
|
||||
*/
|
||||
if ($database->getvacmodexy($id)) {
|
||||
$form->addError('error', USER_ON_VACATION);
|
||||
return;
|
||||
}
|
||||
|
||||
if (!$database->checkVilExist($post['getwref'])) {
|
||||
@@ -878,6 +919,21 @@ class Market
|
||||
exit;
|
||||
}
|
||||
|
||||
/**
|
||||
* PERMISIUNI SITTER: schimbul NPC costa 3 aur.
|
||||
*
|
||||
* Gardul TREBUIE sa fie aici, nu langa plata de la finalul functiei:
|
||||
* redistribuirea resurselor (setVillageField) se executa INAINTE de
|
||||
* scaderea aurului, deci un garda pus doar pe plata ar fi oferit
|
||||
* sitterului NPC gratuit.
|
||||
*/
|
||||
if (isset($session) && method_exists($session, 'sitterCan')
|
||||
&& !$session->sitterCan(SITTER_PERM_GOLD)) {
|
||||
|
||||
header('Location: build.php?id=' . $post['id'] . '&t=3');
|
||||
exit;
|
||||
}
|
||||
|
||||
// Sanitize the requested distribution: never negative, never above the
|
||||
// warehouse / granary capacity. Guards against a forged or NaN-corrupted
|
||||
// POST (issue #211: NPC distribution).
|
||||
@@ -917,7 +973,9 @@ class Market
|
||||
]
|
||||
);
|
||||
$this->forget();
|
||||
$database->modifyGold($session->uid, 3, 0);
|
||||
|
||||
// permisiunea a fost verificata la intrarea in functie
|
||||
$database->spendGold($session->uid, 3, 'NPC merchant');
|
||||
|
||||
header('Location: build.php?id=' . $post['id'] . '&t=3&c');
|
||||
exit;
|
||||
|
||||
@@ -448,6 +448,31 @@ class Profile {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Transforma un set de casute bifate intr-o masca de biti.
|
||||
*
|
||||
* Acceptam doar valorile din SITTER_PERM_ALL: orice altceva venit prin
|
||||
* POST e ignorat, ca un jucator sa nu-si poata inventa biti noi.
|
||||
* Un array gol inseamna "niciun drept" - stare perfect valida, deci NU
|
||||
* cadem pe SITTER_PERM_ALL cand lipseste continutul.
|
||||
*/
|
||||
$sitterMaskFromPost = function ($raw) {
|
||||
|
||||
$mask = 0;
|
||||
|
||||
if (is_array($raw)) {
|
||||
foreach ($raw as $bit) {
|
||||
$bit = (int) $bit;
|
||||
|
||||
if ($bit > 0 && ($bit & SITTER_PERM_ALL) === $bit) {
|
||||
$mask |= $bit;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return $mask;
|
||||
};
|
||||
|
||||
// Sitter assignment
|
||||
if (!empty($post['v1'])) {
|
||||
|
||||
@@ -458,15 +483,55 @@ class Profile {
|
||||
|
||||
} else if ($sitid != $session->uid) {
|
||||
|
||||
// permisiunile cu care intra noul sitter
|
||||
$newPerm = $sitterMaskFromPost($post['perm_new'] ?? null);
|
||||
|
||||
if ($session->userinfo['sit1'] == 0) {
|
||||
$database->updateUserField($session->uid, "sit1", $sitid, 1);
|
||||
$database->updateUserField($session->uid, "sit1_perm", $newPerm, 1);
|
||||
|
||||
} else if ($session->userinfo['sit2'] == 0) {
|
||||
$database->updateUserField($session->uid, "sit2", $sitid, 1);
|
||||
$database->updateUserField($session->uid, "sit2_perm", $newPerm, 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Actualizarea permisiunilor pentru sitterii deja existenti.
|
||||
*
|
||||
* Casutele sunt in acelasi formular cu restul setarilor de cont, deci
|
||||
* ajung aici la orice salvare. Scriem doar pentru sloturile ocupate -
|
||||
* altfel am seta permisiuni pentru un sitter inexistent.
|
||||
*
|
||||
* Atentie: casutele nebifate NU se trimit prin POST. De aceea ne uitam
|
||||
* dupa cheia campului, nu dupa continutul ei: daca perm1 lipseste cu
|
||||
* totul inseamna ca formularul nu continea sectiunea (nu ca sitterul
|
||||
* si-a pierdut toate drepturile).
|
||||
*/
|
||||
foreach (array(1 => 'sit1', 2 => 'sit2') as $slot => $key) {
|
||||
|
||||
if ((int) $session->userinfo[$key] === 0) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$field = 'perm' . $slot;
|
||||
|
||||
// slotul e afisat in formular doar cand e ocupat; daca butonul de
|
||||
// salvare a fost apasat, campul exista chiar si gol (vezi hidden-ul
|
||||
// din account.tpl)
|
||||
if (!isset($post[$field . '_sent'])) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$database->updateUserField(
|
||||
$session->uid,
|
||||
$key . '_perm',
|
||||
$sitterMaskFromPost($post[$field] ?? null),
|
||||
1
|
||||
);
|
||||
}
|
||||
|
||||
// Persist errors if any
|
||||
if ($form->returnErrors() > 0) {
|
||||
$_SESSION['errorarray'] = $form->getErrors();
|
||||
|
||||
+121
-1
@@ -1,5 +1,17 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* Permisiuni sitter - masca de biti. Definite aici, nu in config, ca sa fie
|
||||
* disponibile oriunde e incarcat Session.php (adica pe orice pagina de joc).
|
||||
*/
|
||||
if (!defined('SITTER_PERM_ATTACK')) define('SITTER_PERM_ATTACK', 1);
|
||||
if (!defined('SITTER_PERM_RAID')) define('SITTER_PERM_RAID', 2);
|
||||
if (!defined('SITTER_PERM_REINF')) define('SITTER_PERM_REINF', 4);
|
||||
if (!defined('SITTER_PERM_RES')) define('SITTER_PERM_RES', 8);
|
||||
if (!defined('SITTER_PERM_GOLD')) define('SITTER_PERM_GOLD', 16);
|
||||
if (!defined('SITTER_PERM_ALL')) define('SITTER_PERM_ALL', 31);
|
||||
|
||||
|
||||
#################################################################################
|
||||
## -= YOU MAY NOT REMOVE OR CHANGE THIS NOTICE =- ##
|
||||
## --------------------------------------------------------------------------- ##
|
||||
@@ -94,6 +106,26 @@ class Session {
|
||||
var $sit;
|
||||
var $sit1;
|
||||
var $sit2;
|
||||
|
||||
/**
|
||||
* PERMISIUNI SITTER (masca de biti, salvata in users.sit1_perm / sit2_perm)
|
||||
*
|
||||
* 1 SITTER_PERM_ATTACK - trimite atacuri normale
|
||||
* 2 SITTER_PERM_RAID - trimite raiduri
|
||||
* 4 SITTER_PERM_REINF - trimite intariri
|
||||
* 8 SITTER_PERM_RES - trimite resurse altor jucatori
|
||||
* 16 SITTER_PERM_GOLD - cheltuie aur
|
||||
* 31 SITTER_PERM_ALL - toate (valoarea implicita)
|
||||
*
|
||||
* 31 e default in baza de date ca sitterii existenti sa nu-si piarda
|
||||
* drepturile in momentul migrarii.
|
||||
*/
|
||||
|
||||
/** uid-ul sitterului conectat; 0 = sesiune normala, a proprietarului */
|
||||
public $sitterUid = 0;
|
||||
|
||||
/** masca de permisiuni valabila pentru sesiunea curenta */
|
||||
public $sitterPerm = 31;
|
||||
var $cp;
|
||||
function __construct() {
|
||||
global $database;
|
||||
@@ -511,10 +543,59 @@ function __construct() {
|
||||
$this->checker = $_SESSION['checker'];
|
||||
$this->mchecker = $_SESSION['mchecker'];
|
||||
|
||||
$this->sit = $database->GetOnline($this->uid);
|
||||
/**
|
||||
* $this->sit (0 = proprietar, 1 = sitter) se calculeaza acum din
|
||||
* sesiune, nu din tabela "online".
|
||||
*
|
||||
* GetOnline() citea flagul scris de UpdateOnline() cu INSERT IGNORE -
|
||||
* adica flagul NU se actualiza daca randul exista deja. In practica:
|
||||
* - proprietarul care se loga dupa un sitter mostenea sit = 1 si era
|
||||
* blocat sa cumpere Plus pe propriul cont;
|
||||
* - sitterul care se loga dupa proprietar primea sit = 0 si trecea de
|
||||
* toate gardurile.
|
||||
* Flagul din sesiune e per-sesiune si mereu corect, deci il folosim ca
|
||||
* sursa. Toti consumatorii existenti de $session->sit (a2b.php,
|
||||
* alli_menu.tpl, Profile/overview.tpl, Templates/Plus/*) se repara
|
||||
* automat, fara sa fie atinsi.
|
||||
*
|
||||
* Nota: sesiunile deschise INAINTE de acest update nu au sitter_uid,
|
||||
* deci un sitter deja conectat va aparea ca proprietar pana la
|
||||
* urmatoarea autentificare.
|
||||
*/
|
||||
$this->sit = (isset($_SESSION['sitter_uid']) && (int) $_SESSION['sitter_uid'] > 0) ? 1 : 0;
|
||||
$this->sit1 = $this->userarray['sit1'];
|
||||
$this->sit2 = $this->userarray['sit2'];
|
||||
|
||||
/**
|
||||
* Permisiunile sesiunii curente.
|
||||
*
|
||||
* Recitim sit1/sit2 din contul proprietarului la FIECARE cerere, nu
|
||||
* doar la login: daca proprietarul retrage un sitter sau ii taie un
|
||||
* drept in timp ce acesta e conectat, modificarea se aplica imediat.
|
||||
*
|
||||
* Daca sitterul conectat nu mai apare in sit1/sit2 (a fost sters
|
||||
* intre timp), masca devine 0 - adica nu mai are voie nimic.
|
||||
*/
|
||||
$this->sitterUid = isset($_SESSION['sitter_uid']) ? (int) $_SESSION['sitter_uid'] : 0;
|
||||
$this->sitterPerm = SITTER_PERM_ALL;
|
||||
|
||||
if ($this->sitterUid > 0) {
|
||||
|
||||
if ((int) $this->userarray['sit1'] === $this->sitterUid) {
|
||||
$this->sitterPerm = isset($this->userarray['sit1_perm'])
|
||||
? (int) $this->userarray['sit1_perm']
|
||||
: SITTER_PERM_ALL;
|
||||
|
||||
} else if ((int) $this->userarray['sit2'] === $this->sitterUid) {
|
||||
$this->sitterPerm = isset($this->userarray['sit2_perm'])
|
||||
? (int) $this->userarray['sit2_perm']
|
||||
: SITTER_PERM_ALL;
|
||||
|
||||
} else {
|
||||
$this->sitterPerm = 0;
|
||||
}
|
||||
}
|
||||
|
||||
$this->cp = floor($this->userarray['cp']);
|
||||
$this->gold = $this->userarray['gold'];
|
||||
$this->oldrank = $this->userarray['oldrank'];
|
||||
@@ -606,6 +687,45 @@ function __construct() {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Sesiunea curenta apartine unui sitter, nu proprietarului contului?
|
||||
*/
|
||||
public function isSitterSession()
|
||||
{
|
||||
return $this->sitterUid > 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Are sesiunea curenta dreptul $perm (una din constantele SITTER_PERM_*)?
|
||||
*
|
||||
* Proprietarul primeste mereu true. Se verifica la EXECUTIE, pe server -
|
||||
* nu e suficient sa ascunzi butoanele, fiindca un sitter poate trimite
|
||||
* POST-ul direct.
|
||||
*/
|
||||
/**
|
||||
* Scurtatura pentru cel mai des folosit drept.
|
||||
* Intoarce mesajul de eroare gata de afisat, sau "" daca are voie.
|
||||
*/
|
||||
public function sitterGoldError()
|
||||
{
|
||||
if ($this->sitterCan(SITTER_PERM_GOLD)) {
|
||||
return "";
|
||||
}
|
||||
|
||||
return defined('SITTER_P_DENIED')
|
||||
? SITTER_P_DENIED
|
||||
: 'Your sitter permissions do not allow this action.';
|
||||
}
|
||||
|
||||
public function sitterCan($perm)
|
||||
{
|
||||
if (!$this->isSitterSession()) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return ((int) $this->sitterPerm & (int) $perm) === (int) $perm;
|
||||
}
|
||||
}
|
||||
|
||||
$session = new Session;
|
||||
|
||||
@@ -76,6 +76,47 @@ class Units {
|
||||
* @return string Returns the errors, or empty if no errors was found
|
||||
*/
|
||||
|
||||
/**
|
||||
* PERMISIUNI SITTER - misiune -> drept necesar.
|
||||
*
|
||||
* Codurile de misiune vin din formularul de trimitere (Templates/a2b/):
|
||||
* 1 = spionaj -> permis mereu (nu e in lista din Travian)
|
||||
* 2 = intarire -> SITTER_PERM_REINF
|
||||
* 3 = atac normal -> SITTER_PERM_ATTACK
|
||||
* 4 = raid -> SITTER_PERM_RAID
|
||||
* 5 = colonizare -> permis mereu
|
||||
*
|
||||
* Intoarce mesajul de eroare, sau "" daca actiunea e permisa.
|
||||
* Proprietarul contului primeste mereu "".
|
||||
*/
|
||||
private function sitterMissionError($missionType) {
|
||||
global $session;
|
||||
|
||||
if (!isset($session) || !is_object($session) || !method_exists($session, 'sitterCan')) {
|
||||
return "";
|
||||
}
|
||||
|
||||
$map = array(
|
||||
2 => SITTER_PERM_REINF,
|
||||
3 => SITTER_PERM_ATTACK,
|
||||
4 => SITTER_PERM_RAID,
|
||||
);
|
||||
|
||||
$missionType = (int) $missionType;
|
||||
|
||||
if (!isset($map[$missionType])) {
|
||||
return "";
|
||||
}
|
||||
|
||||
if ($session->sitterCan($map[$missionType])) {
|
||||
return "";
|
||||
}
|
||||
|
||||
return defined('SITTER_P_DENIED')
|
||||
? SITTER_P_DENIED
|
||||
: 'Your sitter permissions do not allow this action.';
|
||||
}
|
||||
|
||||
public function checkErrors(&$post){
|
||||
global $database, $generator, $session;
|
||||
|
||||
@@ -87,6 +128,9 @@ class Units {
|
||||
if(!empty($disabled) && $post['c'] == 3) return "You can't attack this village/oasis with normal attack";
|
||||
if($post['c'] < 2 || $post['c'] > 4) return "Invalid attack type.";
|
||||
|
||||
// sitterul fara dreptul respectiv nu ajunge nici macar la confirmare
|
||||
if(($error = $this->sitterMissionError($post['c'])) !== "") return $error;
|
||||
|
||||
//check if at least one troops has been selected
|
||||
$selectedTroops = 0;
|
||||
for($i = 1; $i <= 11; $i++) $selectedTroops += empty($post['t'.$i]) ? 0 : $post['t'.$i];
|
||||
@@ -344,6 +388,22 @@ class Units {
|
||||
$data = $database->getA2b($post['timestamp_checksum']);
|
||||
$Gtribe = ($session->tribe == 1) ? "" : $session->tribe - 1;
|
||||
|
||||
/**
|
||||
* A DOUA verificare, cea care conteaza cu adevarat.
|
||||
*
|
||||
* checkErrors() ruleaza pe formular, dar un sitter poate trimite POST-ul
|
||||
* de confirmare direct, sarind peste el. Aici e ultimul punct inainte ca
|
||||
* trupele sa fie scazute din sat, deci verificam din nou - pe tipul REAL
|
||||
* al misiunii, citit din baza de date ($data['type']), nu din $_POST.
|
||||
*/
|
||||
if (($sitterError = $this->sitterMissionError($data['type'] ?? 0)) !== "") {
|
||||
$form->addError("error", $sitterError);
|
||||
$_SESSION['errorarray'] = $form->getErrors();
|
||||
$_SESSION['valuearray'] = $_POST;
|
||||
header("Location: a2b.php");
|
||||
exit;
|
||||
}
|
||||
|
||||
for ($i = 1; $i < 10; $i++) {
|
||||
if (isset($data['u'.$i])) {
|
||||
if ($data['u'.$i] > $village->unitarray['u'.$Gtribe.$i]) {
|
||||
@@ -965,6 +1025,17 @@ class Units {
|
||||
public function startRaidList($post){
|
||||
global $database, $generator, $session;
|
||||
|
||||
/**
|
||||
* Lista de ferme trimite raiduri, deci intra tot sub SITTER_PERM_RAID.
|
||||
* Fara garda aici, un sitter caruia i s-ai taiat raidurile le-ar fi
|
||||
* putut porni oricum din Punctul de Adunare.
|
||||
*/
|
||||
if (($sitterError = $this->sitterMissionError(4)) !== "") {
|
||||
$_SESSION['errorarray'] = array($sitterError);
|
||||
header("Location: build.php?id=39&t=99");
|
||||
exit();
|
||||
}
|
||||
|
||||
$slots = $post['slot'] ?? [];
|
||||
if(empty($slots)){
|
||||
header("Location: build.php?id=39&t=99");
|
||||
|
||||
@@ -18,7 +18,11 @@
|
||||
## --------------------------------------------------------------------------- ##
|
||||
#################################################################################
|
||||
|
||||
if($session->sit == 0) {
|
||||
// PERMISIUNI SITTER: cumparaturile cu aur.
|
||||
// Inlocuieste vechiul "$session->sit", care citea un flag din tabela online
|
||||
// scris cu INSERT IGNORE - deci nu se actualiza daca randul exista deja.
|
||||
// sitterCan() se bazeaza pe sesiune, deci e mereu corect.
|
||||
if($session->sitterCan(SITTER_PERM_GOLD)) {
|
||||
$uid = (int)$session->uid;
|
||||
$wid = (int)$village->wid;
|
||||
$now = time();
|
||||
|
||||
@@ -18,7 +18,11 @@
|
||||
## --------------------------------------------------------------------------- ##
|
||||
#################################################################################
|
||||
|
||||
if($session->sit == 0) {
|
||||
// PERMISIUNI SITTER: cumparaturile cu aur.
|
||||
// Inlocuieste vechiul "$session->sit", care citea un flag din tabela online
|
||||
// scris cu INSERT IGNORE - deci nu se actualiza daca randul exista deja.
|
||||
// sitterCan() se bazeaza pe sesiune, deci e mereu corect.
|
||||
if($session->sitterCan(SITTER_PERM_GOLD)) {
|
||||
$uid = (int)$session->uid;
|
||||
$wid = (int)$village->wid;
|
||||
$now = time();
|
||||
|
||||
@@ -18,7 +18,11 @@
|
||||
## --------------------------------------------------------------------------- ##
|
||||
#################################################################################
|
||||
|
||||
if($session->sit == 0) {
|
||||
// PERMISIUNI SITTER: cumparaturile cu aur.
|
||||
// Inlocuieste vechiul "$session->sit", care citea un flag din tabela online
|
||||
// scris cu INSERT IGNORE - deci nu se actualiza daca randul exista deja.
|
||||
// sitterCan() se bazeaza pe sesiune, deci e mereu corect.
|
||||
if($session->sitterCan(SITTER_PERM_GOLD)) {
|
||||
$uid = (int)$session->uid;
|
||||
$wid = (int)$village->wid;
|
||||
$now = time();
|
||||
|
||||
@@ -24,7 +24,11 @@ $wid = (int)$village->wid;
|
||||
$now = time();
|
||||
$cost = 100;
|
||||
|
||||
if($session->sit != 0) {
|
||||
// PERMISIUNI SITTER: cumparaturile cu aur.
|
||||
// Inlocuieste vechiul "$session->sit", care citea un flag din tabela online
|
||||
// scris cu INSERT IGNORE - deci nu se actualiza daca randul exista deja.
|
||||
// sitterCan() se bazeaza pe sesiune, deci e mereu corect.
|
||||
if(!$session->sitterCan(SITTER_PERM_GOLD)) {
|
||||
header("Location: plus.php?id=3"); exit;
|
||||
}
|
||||
|
||||
|
||||
@@ -18,7 +18,11 @@
|
||||
## --------------------------------------------------------------------------- ##
|
||||
#################################################################################
|
||||
|
||||
if($session->sit == 0) {
|
||||
// PERMISIUNI SITTER: cumparaturile cu aur.
|
||||
// Inlocuieste vechiul "$session->sit", care citea un flag din tabela online
|
||||
// scris cu INSERT IGNORE - deci nu se actualiza daca randul exista deja.
|
||||
// sitterCan() se bazeaza pe sesiune, deci e mereu corect.
|
||||
if($session->sitterCan(SITTER_PERM_GOLD)) {
|
||||
$now = time();
|
||||
$uid = (int)$session->uid;
|
||||
$wid = (int)$village->wid;
|
||||
|
||||
@@ -18,7 +18,11 @@
|
||||
## --------------------------------------------------------------------------- ##
|
||||
#################################################################################
|
||||
|
||||
if($session->sit == 0) {
|
||||
// PERMISIUNI SITTER: cumparaturile cu aur.
|
||||
// Inlocuieste vechiul "$session->sit", care citea un flag din tabela online
|
||||
// scris cu INSERT IGNORE - deci nu se actualiza daca randul exista deja.
|
||||
// sitterCan() se bazeaza pe sesiune, deci e mereu corect.
|
||||
if($session->sitterCan(SITTER_PERM_GOLD)) {
|
||||
$uid = (int)$session->uid;
|
||||
$wid = (int)$village->wid;
|
||||
$now = time();
|
||||
|
||||
@@ -46,6 +46,23 @@ if(empty($_POST['plus'])) {
|
||||
</form>
|
||||
<?php
|
||||
} else {
|
||||
|
||||
/**
|
||||
* PERMISIUNI SITTER: aici se cumpara Plus si bonusurile de productie.
|
||||
*
|
||||
* Acest sablon nu avea NICIO verificare de sitter - spre deosebire de
|
||||
* 8/9/10/11/12/15.tpl, care aveau (chiar daca pe un flag nesigur). Un
|
||||
* sitter putea cheltui aurul proprietarului de aici, oricat.
|
||||
*/
|
||||
if (isset($session) && method_exists($session, 'sitterCan')
|
||||
&& !$session->sitterCan(SITTER_PERM_GOLD)) {
|
||||
|
||||
die('<div align="center"><font color="red"><b>'
|
||||
. (defined('SITTER_P_DENIED') ? SITTER_P_DENIED
|
||||
: 'Your sitter permissions do not allow this action.')
|
||||
. '</b></font><br><button onclick="history.back()">' . BACK . '</button></div>');
|
||||
}
|
||||
|
||||
$reward = $_POST['reward'] ?? '';
|
||||
|
||||
// whitelist
|
||||
|
||||
@@ -32,6 +32,48 @@ $sitterError = $form->getError("sit");
|
||||
$count = 0;
|
||||
if ($session->userinfo['sit1'] != 0) $count += 1;
|
||||
if ($session->userinfo['sit2'] != 0) $count += 1;
|
||||
|
||||
/**
|
||||
* PERMISIUNI SITTER
|
||||
*
|
||||
* Lista e definita o singura data si folosita si la sitterii existenti, si la
|
||||
* casuta de adaugare, ca sa nu se desincronizeze. Cheile din $_POST sunt
|
||||
* perm1[], perm2[] si perm_new[], fiecare continand valorile bitilor bifati.
|
||||
*/
|
||||
$sitterPermList = array(
|
||||
SITTER_PERM_ATTACK => defined('SITTER_P_ATTACK') ? SITTER_P_ATTACK : 'send attacks',
|
||||
SITTER_PERM_RAID => defined('SITTER_P_RAID') ? SITTER_P_RAID : 'send raids',
|
||||
SITTER_PERM_REINF => defined('SITTER_P_REINF') ? SITTER_P_REINF : 'send reinforcements',
|
||||
SITTER_PERM_RES => defined('SITTER_P_RES') ? SITTER_P_RES : 'send resources to other players',
|
||||
SITTER_PERM_GOLD => defined('SITTER_P_GOLD') ? SITTER_P_GOLD : 'spend Gold',
|
||||
);
|
||||
|
||||
/**
|
||||
* Casutele pentru un slot. $mask = permisiunile curente, $field = numele
|
||||
* campului din formular.
|
||||
*/
|
||||
function sitterPermBoxes($mask, $field, $list) {
|
||||
|
||||
/**
|
||||
* Marcaj ascuns: o casuta nebifata nu se trimite deloc prin POST, deci
|
||||
* "toate debifate" ar arata identic cu "sectiunea nu a fost afisata".
|
||||
* Campul asta e mereu trimis, asa ca Profile.php poate deosebi cele doua
|
||||
* situatii si nu reseteaza permisiunile din greseala.
|
||||
*/
|
||||
$out = '<input type="hidden" name="' . $field . '_sent" value="1" />';
|
||||
$out .= '<div class="sitterPerm">';
|
||||
|
||||
foreach ($list as $bit => $label) {
|
||||
|
||||
$checked = (((int) $mask & $bit) === $bit) ? ' checked' : '';
|
||||
|
||||
$out .= '<label><input type="checkbox" class="checkbox" name="' . $field . '[]"'
|
||||
. ' value="' . (int) $bit . '"' . $checked . ' /> '
|
||||
. htmlspecialchars($label, ENT_QUOTES, 'UTF-8') . '</label>';
|
||||
}
|
||||
|
||||
return $out . '</div>';
|
||||
}
|
||||
?>
|
||||
|
||||
<form action="spieler.php" method="POST">
|
||||
@@ -110,6 +152,19 @@ if (!empty($emailError)) {
|
||||
}
|
||||
?>
|
||||
|
||||
<style type="text/css">
|
||||
/* casutele de permisiuni pentru sitteri */
|
||||
#sitter .sitterPerm { margin: 4px 0 8px 18px; }
|
||||
#sitter .sitterPerm label {
|
||||
display: block;
|
||||
padding: 1px 0;
|
||||
font-weight: normal;
|
||||
white-space: nowrap;
|
||||
cursor: pointer;
|
||||
}
|
||||
#sitter .sitterPerm input { margin-right: 5px; vertical-align: -1px; }
|
||||
</style>
|
||||
|
||||
<!-- =========================
|
||||
SITTERS
|
||||
========================= -->
|
||||
@@ -133,6 +188,10 @@ if (!empty($emailError)) {
|
||||
<td>
|
||||
<input class="text" type="text" name="v1" maxlength="15">
|
||||
<span class="count">(<?php echo $count; ?>/2)</span>
|
||||
<?php
|
||||
// permisiunile cu care intra noul sitter; implicit toate bifate
|
||||
echo sitterPermBoxes(SITTER_PERM_ALL, 'perm_new', $sitterPermList);
|
||||
?>
|
||||
</td>
|
||||
</tr>
|
||||
<?php } ?>
|
||||
@@ -160,6 +219,14 @@ foreach ($sitSlots as $type => $key) {
|
||||
echo "<img class=\"del\" src=\"img/x.gif\" title=\"Remove sitters\" alt=\"Remove sitters\" />";
|
||||
echo "</a>";
|
||||
echo "<a href=\"spieler.php?uid=".$uid."\">".$uname."</a>";
|
||||
|
||||
// permisiunile curente ale acestui sitter
|
||||
$permField = 'perm' . $type;
|
||||
$permMask = isset($session->userinfo[$key . '_perm'])
|
||||
? (int) $session->userinfo[$key . '_perm']
|
||||
: SITTER_PERM_ALL;
|
||||
|
||||
echo sitterPermBoxes($permMask, $permField, $sitterPermList);
|
||||
echo "</div>";
|
||||
}
|
||||
}
|
||||
|
||||
@@ -116,8 +116,15 @@ if ( isset( $_GET['id'] ) ) {
|
||||
if ($session->goldclub == 1 && count($session->villages) > 1) {
|
||||
if (isset($_POST['routeid'])) $routeid = $_POST['routeid'];
|
||||
|
||||
/**
|
||||
* PERMISIUNI SITTER: rutele comerciale costa 2 aur (creare si prelungire).
|
||||
* Gardul e aici, inaintea ambelor actiuni, nu in fiecare ramura.
|
||||
*/
|
||||
$sitterGoldBlocked = (isset($session) && method_exists($session, 'sitterCan')
|
||||
&& !$session->sitterCan(SITTER_PERM_GOLD));
|
||||
|
||||
if (isset($_POST['action']) && $_POST['action'] == 'addRoute') {
|
||||
if ($session->gold >= 2 && $session->goldclub == 1) {
|
||||
if ($session->gold >= 2 && $session->goldclub == 1 && !$sitterGoldBlocked) {
|
||||
for ($i = 1; $i <= 4; $i ++) {
|
||||
if (empty($_POST['r'.$i])) $_POST['r'.$i] = 0;
|
||||
}
|
||||
@@ -147,17 +154,20 @@ if ($session->goldclub == 1 && count($session->villages) > 1) {
|
||||
}
|
||||
|
||||
if (isset($_POST['routeid']) && isset($_POST['action']) && $_POST['action'] == 'extendRoute') {
|
||||
if ($session->gold >= 2 && $session->goldclub == 1) {
|
||||
if ($session->gold >= 2 && $session->goldclub == 1 && !$sitterGoldBlocked) {
|
||||
$traderoute = $database->getTradeRouteUid($_POST['routeid']);
|
||||
if ($traderoute == $session->uid) {
|
||||
$database->editTradeRoute($_POST['routeid'], "timeleft", 604800, 1);
|
||||
$newgold = $session->gold - 2;
|
||||
$database->updateUserField($session->uid, 'gold', $newgold, 1);
|
||||
$session->gold = $newgold;
|
||||
// Invalidate the 30s session user-cache (see Session::PopulateVar) so
|
||||
// the gold balance is fresh next request; the write is absolute
|
||||
// ($session->gold - 2), so a stale cache could double-spend.
|
||||
unset($_SESSION['cache_user_' . ($_SESSION['username'] ?? '')]);
|
||||
/**
|
||||
* spendGold() scade relativ si atomic, apoi invalideaza singur
|
||||
* cache-ul de sesiune. Inainte se scria absolut pornind de la
|
||||
* $session->gold, care putea fi vechi de 30 de secunde - exact
|
||||
* riscul de dubla cheltuire semnalat in comentariul de aici.
|
||||
* Prelungirea se face DOAR daca plata a reusit.
|
||||
*/
|
||||
if ($database->spendGold($session->uid, 2, 'Extend trade route')) {
|
||||
$database->editTradeRoute($_POST['routeid'], "timeleft", 604800, 1);
|
||||
$session->gold -= 2;
|
||||
}
|
||||
}
|
||||
}
|
||||
$route = 1;
|
||||
|
||||
@@ -1995,7 +1995,9 @@ CREATE TABLE IF NOT EXISTS `%PREFIX%users` (
|
||||
`b3` int(11) DEFAULT '0',
|
||||
`b4` int(11) DEFAULT '0',
|
||||
`sit1` int(11) DEFAULT '0',
|
||||
`sit1_perm` int(11) NOT NULL DEFAULT '31',
|
||||
`sit2` int(11) DEFAULT '0',
|
||||
`sit2_perm` int(11) NOT NULL DEFAULT '31',
|
||||
`alliance` int(11) DEFAULT '0',
|
||||
`alliance_joined` int(11) NOT NULL DEFAULT '0',
|
||||
`sessid` varchar(100) DEFAULT NULL,
|
||||
|
||||
Reference in New Issue
Block a user