Some fixes

Some fixes
This commit is contained in:
novgorodschi catalin
2026-08-03 07:58:30 +03:00
parent 613d800e29
commit c06c13f3e8
6 changed files with 248 additions and 1 deletions
+57
View File
@@ -340,6 +340,63 @@ if (!function_exists('admin_config_template_path')) {
$text = str_replace($placeholder, (string) $value, $text);
}
/**
* PLASA DE SIGURANTA: orice placeholder ramas se rezolva din constanta
* pe care o defineste chiar linia lui.
*
* De ce e nevoie: fiecare pagina din panou regenereaza INTREG config.php
* din acelasi sablon, dar rezolva doar setarile ei. O setare noua,
* tratata de un singur modul, ramanea literala cand salvai din alta
* pagina:
* define("NEW_FUNCTIONS_ALLIANCE_BONUSES", %ALLIANCEBONUSES%);
* adica eroare de parsare si 500 pe tot serverul, pana la reparare
* manuala a fisierului. Ni s-a intamplat de trei ori: %GP%,
* %ALLIANCEBONUSES% si %NATARS_WW_START_DELAY%.
*
* Listele de mai sus raman - sunt explicite si mai lizibile. Blocul asta
* prinde ce scapa, ca urmatoarea setare adaugata sa nu mai poata sparge
* serverul. Ruleaza ULTIMUL, deci nu suprascrie nimic rezolvat inainte.
*/
if (preg_match_all('/^\s*define\(\s*["\']([A-Z0-9_]+)["\']\s*,\s*(.*?%[A-Z0-9_]+%.*?)\s*\)\s*;/m',
$text, $leftovers, PREG_SET_ORDER)) {
foreach ($leftovers as $row) {
$constant = $row[1];
if (!preg_match('/%[A-Z0-9_]+%/', $row[2], $ph)) {
continue;
}
if (!defined($constant)) {
// Constanta nu exista inca (prima instalare, sau setare noua
// adaugata in sablon dar nu si in config-ul curent). Punem o
// valoare neutra, ca fisierul sa ramana PHP valid.
$value = 'false';
} else {
$current = constant($constant);
if (is_bool($current)) {
$value = $current ? 'true' : 'false';
} elseif (is_int($current) || is_float($current)) {
$value = (string) $current;
} else {
// Sir: pastram ghilimelele din sablon daca exista deja,
// altfel le adaugam noi.
$quoted = (strpos($row[2], '"' . $ph[0] . '"') !== false)
|| (strpos($row[2], "'" . $ph[0] . "'") !== false);
$safe = addcslashes((string) $current, "\"\\\$");
$value = $quoted ? $safe : '"' . $safe . '"';
}
}
$text = str_replace($ph[0], $value, $text);
error_log('[TravianZ] config: placeholder ' . $ph[0]
. ' nerezolvat de niciun modul, completat din ' . $constant);
}
}
return $text;
}
}
+101
View File
@@ -670,6 +670,107 @@ class HeroItems
return self::USE_OK;
}
/* ---- Bandaje: readuc in viata o parte din trupele ranite ---- */
if (isset($bonus[HB_HEAL_TROOP])) {
/**
* Bandajele scot trupe din spital si le pun inapoi in sat.
*
* Un bandaj vindeca un procent din raniti (25% cel mic, 33% cel
* mare). Se aplica pe satul in care e folosit itemul, deci
* jucatorul alege unde conteaza.
*
* Se consuma DOAR daca a avut ce vindeca - altfel itemul s-ar
* pierde degeaba.
*/
global $database;
$vid = (int) $vid;
if ($vid <= 0) {
return self::USE_INVALID;
}
// satul trebuie sa fie al jucatorului
$owner = (int) $database->getVillageField($vid, 'owner');
if ($owner !== (int) $uid) {
return self::USE_INVALID;
}
$wounded = $database->getWounded($vid);
if (!$wounded) {
return self::USE_INVALID;
}
$pct = max(1, min(100, (int) $bonus[HB_HEAL_TROOP]));
$units = array();
$heals = array();
$total = 0;
for ($i = 1; $i <= 90; $i++) {
$have = isset($wounded['u' . $i]) ? (int) $wounded['u' . $i] : 0;
if ($have <= 0) {
continue;
}
// cel putin unul, daca exista raniti de tipul asta
$heal = max(1, (int) floor($have * $pct / 100));
$heal = min($heal, $have);
$units[] = $i;
$heals[] = $heal;
$total += $heal;
}
if ($total <= 0) {
return self::USE_INVALID;
}
// scoatem din spital si punem in sat, intr-o tranzactie
mysqli_query($this->db, "START TRANSACTION");
$ok = true;
foreach ($units as $k => $u) {
$q = "UPDATE " . TB_PREFIX . "hospital
SET u" . (int) $u . " = GREATEST(0, u" . (int) $u . " - " . (int) $heals[$k] . ")
WHERE vref = " . $vid . " LIMIT 1";
if (!mysqli_query($this->db, $q)) {
$ok = false;
break;
}
$q2 = "UPDATE " . TB_PREFIX . "units
SET u" . (int) $u . " = u" . (int) $u . " + " . (int) $heals[$k] . "
WHERE vref = " . $vid . " LIMIT 1";
if (!mysqli_query($this->db, $q2)) {
$ok = false;
break;
}
}
if (!$ok) {
mysqli_query($this->db, "ROLLBACK");
error_log('[TravianZ] bandaj: vindecarea a esuat: '
. mysqli_error($this->db));
return self::USE_INVALID;
}
mysqli_query($this->db, "COMMIT");
// un bandaj per folosire: procentul se aplica o singura data
$this->removeItem($uid, $rowId, 1);
return self::USE_OK;
}
/* ---- Scroll: +10 XP each ---- */
if (isset($bonus[HB_SCROLL])) {
$hero = $this->getLivingHeroRow($uid);
+6 -1
View File
@@ -4317,7 +4317,7 @@ tz_def('TZ_WS_VS_NATARS', 'Against Natars');
//////////////////////////////////////////////////////////////////////////////////////////////////////
// MESAJ DE SISTEM - previzualizare
//////////////////////////////////////////////////////////////////////////////////////////////////////
tz_def('ADM_PREVIEW', 'Preview');
tz_def('ADM_PREVIEW', 'Previzualizare');
//////////////////////////////////////////////////////////////////////////////////////////////////////
// REGULI DE INREGISTRARE (Server Configuration)
@@ -4328,3 +4328,8 @@ tz_def('CONF_SERV_PW_MIN', 'Minimum password length');
tz_def('CONF_SERV_USRNM_SPECIAL', 'Allow . - _ in usernames');
tz_def('CONF_SERV_USRNM_SPECIAL_TOOLTIP', 'With True, usernames may contain a dot, hyphen or underscore, and single spaces between words. With False, only letters and digits are accepted.');
tz_def('CONF_SERV_REGRULES_TOOLTIP', 'Rules checked when a player registers. Changing them does not affect existing accounts.');
//////////////////////////////////////////////////////////////////////////////////////////////////////
// STATISTICI - sectiunea de alianta
//////////////////////////////////////////////////////////////////////////////////////////////////////
tz_def('PLUSSTATS_ALLIANCE', 'Your alliance');
+5
View File
@@ -4271,3 +4271,8 @@ tz_def('CONF_SERV_PW_MIN', 'Longueur minimale du mot de passe');
tz_def('CONF_SERV_USRNM_SPECIAL', 'Autoriser . - _ dans les noms');
tz_def('CONF_SERV_USRNM_SPECIAL_TOOLTIP', 'Avec True, les noms peuvent contenir un point, un tiret ou un underscore, et des espaces simples entre les mots. Avec False, seules les lettres et les chiffres sont acceptes.');
tz_def('CONF_SERV_REGRULES_TOOLTIP', 'Regles verifiees lors de l\'inscription. Les modifier n\'affecte pas les comptes existants.');
//////////////////////////////////////////////////////////////////////////////////////////////////////
// STATISTICI - sectiunea de alianta
//////////////////////////////////////////////////////////////////////////////////////////////////////
tz_def('PLUSSTATS_ALLIANCE', 'Votre alliance');
+5
View File
@@ -4068,3 +4068,8 @@ tz_def('CONF_SERV_PW_MIN', 'Lungimea minima a parolei');
tz_def('CONF_SERV_USRNM_SPECIAL', 'Permite . - _ in nume');
tz_def('CONF_SERV_USRNM_SPECIAL_TOOLTIP', 'Cu True, numele pot contine punct, liniuta sau underscore, si spatii simple intre cuvinte. Cu False, se accepta doar litere si cifre.');
tz_def('CONF_SERV_REGRULES_TOOLTIP', 'Reguli verificate la inregistrare. Schimbarea lor nu afecteaza conturile existente.');
//////////////////////////////////////////////////////////////////////////////////////////////////////
// STATISTICI - sectiunea de alianta
//////////////////////////////////////////////////////////////////////////////////////////////////////
tz_def('PLUSSTATS_ALLIANCE', 'Alianta ta');
+74
View File
@@ -258,6 +258,80 @@ echo '<div class="ps-chart">'
'#d9822b')
. '</div>';
// -------------------------------------------------
// ALIANTA: aceleasi instantanee, adunate pe membri
// -------------------------------------------------
//
// Nu e nevoie de date noi: totalurile aliantei se obtin adunand instantaneele
// membrilor ei, pe aceleasi momente.
//
// ATENTIE: gruparea se face dupa alianta CURENTA a fiecarui jucator, fiindca
// instantaneele nu retin alianta de la momentul respectiv. Daca cineva schimba
// alianta, istoricul lui pleaca odata cu el. Pentru graficul de evolutie al
// unei aliante stabile diferenta e neglijabila.
$psAlliance = (int) ($session->alliance ?? 0);
$psAllySeries = array('population' => array(), 'villages' => array(), 'troop_upkeep' => array());
$psAllyName = '';
if ($psAlliance > 0) {
$psAq = @mysqli_query($database->dblink,
"SELECT h.recorded_at,
SUM(h.population) AS population,
SUM(h.villages) AS villages,
SUM(h.troop_upkeep) AS troop_upkeep,
COUNT(*) AS members
FROM " . TB_PREFIX . "player_statistics_history h
JOIN " . TB_PREFIX . "users u ON u.id = h.uid
WHERE u.alliance = " . $psAlliance . "
GROUP BY h.recorded_at
ORDER BY h.recorded_at ASC
LIMIT 400");
while ($psAq && ($psAr = mysqli_fetch_assoc($psAq))) {
$t = (int) $psAr['recorded_at'];
$psAllySeries['population'][] = array($t, (int) $psAr['population']);
$psAllySeries['villages'][] = array($t, (int) $psAr['villages']);
$psAllySeries['troop_upkeep'][] = array($t, (int) $psAr['troop_upkeep']);
}
$psAn = @mysqli_query($database->dblink,
"SELECT tag, name FROM " . TB_PREFIX . "alidata WHERE id = " . $psAlliance . " LIMIT 1");
$psAnr = $psAn ? mysqli_fetch_assoc($psAn) : null;
if ($psAnr) {
$psAllyName = $psAnr['tag'] . ' - ' . $psAnr['name'];
}
}
if (count($psAllySeries['population']) >= 2) {
?>
<h4 class="ps-ally-head">
<?php echo defined('PLUSSTATS_ALLIANCE') ? PLUSSTATS_ALLIANCE : 'Your alliance'; ?>
<?php if ($psAllyName !== '') { ?>
<span class="ps-ally-name"><?php echo htmlspecialchars($psAllyName, ENT_QUOTES, 'UTF-8'); ?></span>
<?php } ?>
</h4>
<?php
echo '<div class="ps-chart">'
. ps_line_chart($psAllySeries['population'],
defined('PLUSSTATS_POP') ? PLUSSTATS_POP : 'Population',
'#7db72f')
. '</div>';
echo '<div class="ps-chart">'
. ps_line_chart($psAllySeries['villages'],
defined('PLUSSTATS_VILLAGES') ? PLUSSTATS_VILLAGES : 'Villages',
'#8e6fc4')
. '</div>';
echo '<div class="ps-chart">'
. ps_line_chart($psAllySeries['troop_upkeep'],
defined('PLUSSTATS_ARMY') ? PLUSSTATS_ARMY : 'Army strength',
'#d9822b')
. '</div>';
}
// -------------------------------------------------
// REZUMAT: acum fata de primul instantaneu
// -------------------------------------------------