Commit Graph

366 Commits

Author SHA1 Message Date
Ferywir 483da9fb18 Refactor(sendunitsComplete): extract resolveResourcesAfterBattle() [#155] (#229) 2026-06-16 10:57:55 +03:00
Ferywir 6d46c76dfb Refactor(sendunitsComplete): extract calculateHeroXpAndPoints() [#155] (#228) 2026-06-16 09:42:12 +03:00
Ferywir 509a4d4137 Refactor(sendunitsComplete): extract resolveVillageTarget()/resolveOasisTarget() [#155]
Extract the per-branch defender target resolution and battle-environment
setup into two private helpers: resolveVillageTarget() and
resolveOasisTarget(). Each returns the target owner (tribe/alliance), map
info, conquest flag and the battle parameters (wall, armory/blacksmith
tech, residence, siege masonry); the village helper also returns the
evasion inputs. Both are read-only (no DB writes).

The foreach body keeps handleEvasion(), buildDefenderUnits() and
buildAttackerUnits() as explicit, ordered calls, so the village and oasis
branches are now symmetric orchestration.

Behaviour-preserving. The building/tech reads now run inside the helper
before handleEvasion(); they read buildings and technology only (never the
troops handleEvasion() may move), so the result is unchanged. A few
dead locals are dropped (playerunit, wallgid, w; the redundant
DefenderUnit/def_ab re-inits).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-15 18:13:19 +03:00
Ferywir 4ba2507f9d Refactor(sendunitsComplete): extract resolveAttackContext() [#155]
Extract the per-attack, target-independent context resolution (attacker
village/owner tribe and alliance, war references, base flags) into a
private helper. Read-only, behaviour-preserving: the three repeated
getCachedUser() lookups on the attacker owner are collapsed into one
(the user cache makes them idempotent).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-15 17:40:04 +03:00
Ferywir 89b0fa50f5 Refactor(sendunitsComplete): extract buildDefenderUnits() [#155]
The defender's units were gathered by two near-identical inline blocks
(village and oasis targets). Extract them into a single private method
buildDefenderUnits() returning the defender's own troops (normalised to
non-negative ints), the aggregated reinforcement totals (enforDefender) and
the raw reinforcement rows (enforcementarray).

Pure behaviour-preserving extraction:
- Both call sites assign the returned bundle; all downstream usages unchanged.
- The oasis reinforcement aggregation now uses the same isset-guarded loop as
  the village one: identical numeric result, minus a latent PHP 8.3
  "undefined array key" notice.
- The dead `$def_ab[$i] = 0` init that lived in the village normalisation loop
  is dropped: it was unconditionally wiped by the later `$def_ab = []` before
  any use.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-15 16:41:14 +03:00
Ferywir a2f5cfdbac Refactor(sendunitsComplete): extract buildAttackerUnits() [#155]
The attacking army was built by two near-identical inline blocks (village
and oasis targets). Extract them into a single private method
buildAttackerUnits() that returns the Attacker unit array (u<start..end> +
uhero) together with the catapult / ram / chief / scout unit ids used in the
report. The oasis target keeps its Nature siege/chief slots (37/38/39) via
the $isoasis flag.

Pure behaviour-preserving extraction: both call sites now assign the returned
bundle, so all downstream usages remain unchanged. The unit-id picks are
initialised to null (they are always set for the real attacker tribes 1/2/3/5;
only the unreachable Nature-attacker case differs, which silences a latent
PHP 8.3 undefined-variable notice).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-15 15:27:09 +03:00
Ferywir 76aa781ee6 Refactor(sendunitsComplete): extract applyRamDamage() [#155]
Move the ram-damage handling out of sendunitsComplete() into a dedicated
private method applyRamDamage(). For a normal attack (type 3) with rams, it
computes the new wall level, updates it in the database (recounting the
village population when the wall is destroyed), builds the report fragment,
and recalculates the battle when the wall level changed.

Pure behaviour-preserving extraction: the battle-recalc context is passed in
a single $ctx array; the call site keeps the t7 guard and assigns the
returned battlepart / info_ram, so all downstream usages remain unchanged.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-15 13:33:38 +03:00
Ferywir c97fa6c71a Refactor(sendunitsComplete): extract calculateTrappedUnits() [#155]
Move the trapper resolution block out of sendunitsComplete() into a
dedicated private method calculateTrappedUnits(). It computes how many
incoming attacker units are caught in the defender's traps (Gaul trapper
or Natar capital), updates the trap counters and the prisoners table, and
subtracts the trapped troops from the attacking army.

Pure behaviour-preserving extraction: the inline `${'traped'.$i}`
variables are rehydrated at the call site from the returned bundle, so all
downstream usages remain unchanged.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-15 12:53:34 +03:00
Ferywir 7ec51902fd Refactor(sendunitsComplete): extract calculatePopulations() [#155]
Move the attacker/defender total-population computation (and the two
getProfileVillages() lookups that feed it) out of the per-attack loop into a
dedicated private method. Behaviour-preserving: the method takes the initial
$defpop/$attpop (0 for villages, 500 for the oasis branch) and accumulates onto
them exactly as before, and returns the village lists ($varray/$varray1) used
later for the can-destroy check and handleConquest().

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-15 10:32:41 +03:00
Ferywir 8398265641 Refactor(sendunitsComplete): extract collectReinforcementReport() [#155]
Extract the pre-casualty defender report block into a new private method
collectReinforcementReport(): reset and rebuild the reinforcement unit totals
($DefenderEnf) and per-tribe hero totals from a fresh re-select, fold
reinforcement heroes into the defender's hero count, build the "units sent"
report rows (own troops + reinforcements and their masked variants), and
(re)initialise the per-tribe dead-hero accumulator. The bundle is returned to
the caller and the defender's folded hero count is reassigned at the call site.

Pure behaviour-preserving extraction. Method name matches the maintainer's
roadmap for #155.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-15 07:52:36 +03:00
Ferywir ae0ab66099 Refactor(sendunitsComplete): extract applyReinforcementCasualties() [#155]
Extract the "kill other defence in village" block (reinforcement casualties)
into a new private method applyReinforcementCasualties(): compute each
reinforcement's dead units/hero, persist them (modifyEnforce), notify the
reinforcing players, and delete fully-wiped reinforcements. Dead counts are
accumulated into $alldead and dead heroes into $DefenderHeroesDeadArray (both
passed by reference); the tribe-presence flags (rom/ger/gal/nat/natar) are
returned to the caller.

Pure behaviour-preserving extraction. Also drops two dead recomputations of
$totalsend_att/$totaldead_att that sat inside the loop and were immediately
overwritten right after it.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-14 21:38:43 +03:00
Ferywir e167322d12 Refactor(sendunitsComplete): extract applyOwnDefenceCasualties() [#155]
Move the in-village defender casualty handling (kill ratio applied to the
defender's own troops + hero, persisted via modifyUnit) out of the giant
sendunitsComplete() loop into a dedicated private method returning the
$owndead map. Pure behaviour-preserving extraction; also drops a dead $u
variable that was assigned but never read.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-14 11:39:26 +03:00
Ferywir af1b8c7ce7 fix(report): restore field separator in combat report data [#203]
The #155 refactor that extracted buildCombatReport() turned one comma
into a literal dot in the non-scout data2 string:

    ...$info_chief.'.'.(isset($info_spy) ? ...   // was ','

That dropped one CSV field, shifting every following field left by one
(hero troops t11, casualties, prisoners 182-192) and injecting a stray
"." into a numeric cell. Visible attack reports rendered with misplaced
hero/prisoner data, and the shifted text in the prisoner slots is what
made Templates/Notice/1.tpl array_sum() warn under PHP 8.

Restore the comma so the layout matches what the report template
(Notice/1.tpl) and the pre-refactor code expect. Reports stored before
this fix keep their corrupted string; the int-cast guard added in the
previous commit keeps them from re-emitting the warning.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-12 16:35:50 +03:00
Ferywir 6030727a0d fix(php8): silence warnings raised by the attack/report flow [#203]
PHP 8.x turned several long-standing implicit accesses into runtime
warnings that flooded the error log during attacks and report viewing:

- Battle.report (Templates/Notice/1.tpl): the prisoner check ran
  array_sum() over slots that may hold non-numeric text (the
  "Information" line can shift indices), raising
  "Addition is not supported on type string". Sum int-cast values.
- Database::getUnitsNumber(): movement/reinforcement arrays can be null
  or miss tribe-specific unit keys, raising "Undefined array key" and
  "Trying to access array offset on null". Null-coalesce to 0.
- Automation (combat resolver): $scout was only defined for scouting
  attacks (type 1) yet always passed to buildCombatReport(), raising
  "Undefined variable $scout". Initialize it for every attack type.
- Automation: the destroy-village check read $to['natar'] which is not
  always set, raising "Undefined array key". Use empty().

Pure null-safety / behaviour-preserving changes; no gameplay logic
altered.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-12 16:35:50 +03:00
Ferywir 8d46fc78ae feat(preferences): apply report filter (suppress merchant-transfer reports) [#198]
Honour the per-user report-filter checkboxes in marketComplete():
  - v4: recipient gets no report for transfers between own villages
  - v6: recipient gets no report for transfers from foreign villages
  - v5: sender gets no report for transfers to foreign villages

The user row is already fully loaded by getUserFields(), so the prefs
are read without extra queries. Removes the "not coded yet" tag from
the report-filter section in the preferences form.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-12 06:31:13 +03:00
Ferywir 33da9fdad5 refactor(sendunitsComplete): extract handlePrisoners() and buildCombatReport() [#155]
Phase C of the sendunitsComplete() refactor (issue #155).

- handlePrisoners(): extracts the ~100-line block that releases troops
  trapped in the defender's traps during a conquest attack (type 3),
  sends them home with 25% casualties, repairs destroyed traps, and
  returns the HTML fragment for the battle-report trap line.

- buildCombatReport(): extracts the assembly of the $data2 (main report)
  and $data_fail (all-attacker-dead fallback) CSV strings, including the
  "village destroyed" annotation in $info_cat and the final appending of
  $info_trap / $info_troop / $info_hero.

Pure behaviour-preserving extractions — no logic change.
Validated by deterministic A/B harness (infantry, evasion, conquest).

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-11 17:28:54 +03:00
Ferywir 71d4385fd3 Refactor(sendunitsComplete): extract applyCatapults() [#155] (#193) 2026-06-10 02:17:19 +03:00
Ferywir dad574be1a feat: reports for settling - new village founded & valley occupied (#178) (#190) 2026-06-09 16:47:29 +03:00
Ferywir a787929604 Refactor(sendunitsComplete): wire up buildScoutReport(), drop duplicate [#155] (#183)
The #182 merge resolution left buildScoutReport() defined but never called,
while the original inline scout-report block was kept at the call site — so
the method was dead code and the scout-report logic was duplicated.

This wires it up: the inline block in the `if (!empty($scout))` branch is
replaced by a single `$info_spy = $this->buildScoutReport(...)` call. The
method already exists and its body is identical to the removed inline block,
so behaviour is unchanged — this just removes the duplication and makes the
extraction actually take effect. Brace balance even (634/634).

Co-authored-by: TravianZ Patcher <patcher@localhost>
Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-08 06:45:51 +03:00
Ferywir 0b563849bf Fix fatal parse error in Automation.php (broken #180/#181 merge) [#155] (#182)
The merge of #180 (applyBounty) and #181 (buildScoutReport) — both of which
inserted a new private method just before sendunitsComplete() — dropped the
closing brace of buildScoutReport(). As a result applyBounty() was declared
INSIDE buildScoutReport(), producing:

  PHP Parse error: syntax error, unexpected token "private"
  in GameEngine/Automation.php

This crashes Automation.php entirely (HTTP 500), so the whole game automation
stops: troop movements never resolve, buildings never finish, etc.

Fix: restore the missing `}` closing buildScoutReport() before the applyBounty()
docblock. Brace balance is now even again (634/634). One-character structural
fix, no logic change.

Co-authored-by: TravianZ Patcher <patcher@localhost>
Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com>
Co-authored-by: Catalin Novgorodschi <cata7007@gmail.com>
2026-06-07 19:23:56 +03:00
Catalin Novgorodschi fd19a6a875 Update Automation.php
Revert last commit
2026-06-07 18:13:46 +03:00
Ferywir 4beb386dfc Refactor(sendunitsComplete): extract buildScoutReport() [#155] (#181)
Phase B — pure behaviour-preserving extraction (issue #155).

buildScoutReport(): extracts the scout-report (info_spy) HTML assembly
(~25 lines) into a helper returning the info_spy string. Handles both
spy modes: resources (spy=1) and defence/buildings (spy=2). The block's
body is moved verbatim (multi-line strings with their exact embedded
whitespace preserved). The reassigned $walllevel/$residencelevel/
$palacelevel were local to this block and never read downstream. No
logic change.

Co-authored-by: TravianZ Patcher <patcher@localhost>
Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com>
Co-authored-by: Catalin Novgorodschi <cata7007@gmail.com>
2026-06-07 16:48:55 +03:00
Ferywir 004f101c23 Refactor(sendunitsComplete): extract applyBounty() [#155] (#180) 2026-06-07 16:34:49 +03:00
Ferywir d55f6cad9e Refactor(sendunitsComplete): extract handleEvasion() and handleConquest() [#155] (#177) 2026-06-05 07:00:32 +03:00
Ferywir f89877210f Refactor/sendunitscomplete extract (#176) 2026-06-04 20:51:29 +03:00
novgorodschi catalin 05bfde9063 Remove some unused code and some fix
Remove some unused code and some fix
2026-05-21 13:12:21 +03:00
novgorodschi catalin 3f32e21333 Fix bug in General Stats
Fix bug in General Stats - now troops appear !
2026-05-20 07:47:02 +03:00
novgorodschi catalin 55e6dd60b5 Refactor + BugFix
1. Fix a bug in Admin Panel that you can edit by yourself your rank, now you cannot edit your rank anymore.

2. Now Alliance Leader can edit his own Position

3. Fix negative value on Demolition Building, now in database at lvl is appear new level not -1

4. Refactor Ajax map, now all is alligned (Ajax folder and Map folder)

5. Fix bug from Palace (when change capital now Automation recount population automaticaly on old capital and new capital)
2026-05-18 09:18:35 +03:00
Catalin Novgorodschi 3804498ad9 Incremental Refactor Automation & Database (cache)
Incremental Refactor Automation (starvation split in more methods) & Database (cache & checkAllianceEmbassiesStatus refactor), Fix a bug in Alliance.php (now you cannot kick alliance leader)
2026-05-14 15:05:32 +03:00
Catalin Novgorodschi a3cf00c0f9 Incremental Refactor Market/Message/Profile
Incremental Refactor Market/Message/Profile
2026-05-13 12:20:10 +03:00
Emerson Freitas a7bdac8392 fix: harden troop processing race conditions (#98) (#138) 2026-03-17 20:13:14 +02:00
levi a0ef06a35f chore: harden php8 compatibility, optimize installer/croppers, and refresh docs/admin ux 2026-03-14 16:50:27 -03:00
hdmaniak2 89e170abe8 Fix WW build task cancelled after Natar attack with 0 damage 2026-02-24 16:26:07 +01:00
Catalin Novgorodschi 260896570e Revert "vulnerability fixed and cleanup and refactor"
This reverts commit 2a44e76414.
2026-02-11 15:22:16 +02:00
Catalin Novgorodschi 2a44e76414 vulnerability fixed and cleanup and refactor 2026-02-11 15:11:43 +02:00
Catalin Novgorodschi 59c1114b1c Change some text on license TravianZ 2025-02-11 11:22:22 +02:00
Hubert Walczak f560ddf7be Fix for infinite refreshing 2023-07-09 12:03:15 +02:00
Shadow 4c68d8dd39 Update to version 8.3.5
Many Fixes
2022-02-18 13:56:17 +02:00
Shadow 4c116aefea update 2019-05-06 09:18:20 +03:00
Vladyslav e3c2a28d71 Minor bug fixes
WW villages cannot be destroyed. Thank @iopietro for your help.
2018-08-28 01:42:35 +03:00
iopietro f032523e1c Generale fixes
+Fixed a bug that didn't return reinforcements in counquered oasis, if
it was released by the owner, or from the admin panel
+Changed the catapults and rams formulas (still not completed at 100%),
thanks to Kirilloid!
+Changed the Natars' capital default coordinates
2018-07-28 15:07:52 +02:00
iopietro b9a442b423 General fixes
+Fixed a bug that would have killed all troops by starvation, if added
through the admin panel
2018-07-25 17:17:52 +02:00
iopietro 84b00790a6 General fixes
+Fixed a bug that showed "The village has been destroyed" two times, if
an artifact was conquered from Natars (or from a 0 popped village) and
there were catapults in the attack
2018-07-25 02:43:29 +02:00
iopietro 77136a9784 Artifacts update and optimizations
+Added the "Artifacts" section in the Admin Panel, which contains two
options: return a deleted artifact to the Natars and create new
Artifacts, assigned to a specified player
+Return to Natars coded, in the village section of the Admin Panel
+Moved a lot of functions and costants from Automation.php to the "new"
class Artifacts.php
+Optimized a lot the whole Natars creation process, decreased the number
of query of about 600
+Optimized a lot the function which deletes a player's account, it's now
executed almost instantly, even with players with a lot of villages
+Redesigned the map spawn system, using a more Travian-like village
distribution
+Fixed a bug that did show a broken village in the artifact chronology,
if that village was destroyed
+Reduced the amount of redundant code (about 230 lines) for
27_1.tpl/27_2.tpl and 27_3.tpl
+Fixed a bug that permitted to build the Great Granary and the Great
Warehouse in the whole account, with only a village effect artifact
+Fixed a bug in the Admin Panel map that didn't permit to show village
informations, if that village contained single quotes in its name
2018-07-24 03:04:25 +02:00
Vladyslav b13879e619 General fixes
+Changed the issuance of medals. Thanks @iopietro
2018-07-01 00:39:17 +03:00
Vladyslav 963471825a General fixes
+Redesigned set of buildings during the appearance of the WW village

NOTE: To use this change, you must recreate all the WW villages
2018-06-27 15:25:50 +03:00
iopietro c574a71b3a General fixes
+Fixed a bug that didn't delete artifacts when a player deleted his
account
+Added "(artifact)" if a village has an artifact in the village overview
+Added the artifact section in the multihunter panel (return to natars
doesn't work yet)

NOTE: To play this version of the game, you have to run this query first
(where "s1_" is the prefix of your server):

ALTER TABLE `s1_artefacts` ADD `del` TINYINT(1) NULL DEFAULT '0' AFTER
`lastupdate`;
ALTER TABLE `testtravian`.`s1_artefacts` ADD INDEX
`active-owner-conquered-del` (`active`, `owner`, `conquered`, `del`);
2018-06-21 14:43:47 +02:00
iopietro 8861a578e4 General fixes
+Fixed a bug that didn't update the starvation correctly, when
starvation data was updated (for example: troops in training, attacks
completed, etc.)
2018-06-17 01:48:40 +02:00
iopietro d96259afd8 General fixes
+You can no longer build WW if your and your alliance building plans
aren't active yet
+You can no longer remove the WW from the village if you remove it from
the building queue
+Spies from every tribe will now consume crop correctly, when returning
from a scouting attacks
+Spies from every tribe will now be displayed correctly, in the "Troops"
tab of dorf3.php, when returning from a scouting attack
+Building levels will now not be downgraded by 1 level, when conquering
a Natars' village
+Natars' villages with an artifact inside, will now be deleted if the
artifact is conquered (even if the pop isn't 0)
2018-06-09 03:03:01 +02:00
iopietro a8d6b9c357 General fixes
+Fixed a bug that didn't permit to change the name or the Tag of the
alliance individually
+Fixed a bug that didn't count the population growth sometimes
+Fixed a bug that didn't halve the population consumption in WW villages
2018-06-08 19:15:39 +02:00