Recover stalled flights locally and fly rejected route approaches
clang PCH / build (push) Waiting to run
GCC PCH / build (push) Waiting to run

This commit is contained in:
Nico committed 2026-11-04 01:14:02 +01:00
1 parent f8ee1d0ff6
commit ba2a4e629c
8 files changed
+573 -4

No files matched your search

+377
View File
@@ -1,3 +1,380 @@
# 2026-11-04 – Lokale Commits auf Nutzerwunsch
Instanzgruppen-Schutz separat committed als f8ee1d0ff6. Flugfortschritts-
überwachung (60s echter Stillstand, native Dauerdiagnose, lokale Recovery vor
Rückkehr) und Fluganschluss zum bestehenden Routenpunkt werden zusammen mit
Tests und diesem Checkpoint im folgenden Navigationscommit gesichert.
Build/Test/Deploymentzustand siehe Eintrag darunter, unverändert. Keine neuen
Builds/Neustarts nötig, keine Pushes. Große Dumps/Binaries und operative
Snapshotverzeichnisse bleiben außerhalb der Commits erhalten.
---
# 2026-11-04 01:13 – Flugfortschritt und lokaler Fluganschluss installiert
Voriges Checkpoint ergänzt: Build installiert und Neustart verifiziert.
Alter Shutdown löste bekannten SIGSEGV GameObject::RemoveFromWorld:651
(m_zoneScript callback) aus, NOCH altes Binary; passiver GDB schrieb Core
/server/debug/crash/worldserver-20261103-231350.core und Backtrace. Passendes
Binary checkpoints/2026-11-04-flight-progress/worldserver-before-flight-fix
bewahrt. Erst nach Ende Worldserver+GDB installiert. 1.Startlauncher scheiterte
fehlendem Execute-Bit (kein Server gestartet); 2.Start explizit via bash klappt.
Neuer PID128950, Bereitschaft im FRISCHEN Server.log (Appender w; Console
Loglevel3 zeigt INFO-ready nicht), Ports8085+8087 verifiziert, Prozess stabil.
Nach 5min sicherer Logoutdrain verbliebene Roster+Probes vorShutdown gesichert
(26Rosterzeilen; native28Sessions im zeitversetzten Sampling, ggfRemoving).
Alle ursprünglichen118Bots wiederonline, Scheduleon, SafeLogoutresume,
Loader wieder1. Nachlogin Restbots erneut auf Bewegung/Flight/Transport geprüft:
36Edwin und99Shadra standen ohne Fortschritt auf alter ungestützter Position,
nativer FlightFailed/0Segmente/flying0; nachOrgrimmar teleportiert und native
Bodenposition bestätigt. Andere aktiveTaxi/Flüge erhalten, keineZwangslogouts.
ROUTE_APPROACH_FLIGHT im Livebetrieb bereits aufgetreten (u.a166), keine
vollständigeGameplayabnahme/erzwungene60sStallprobe, Nutzer prüft imSpiel.
10gezielteTests bestanden; bekannterBaselinefehler test_flight_departure
separat aufHEAD bestätigt. Ergebnis/Recovery/Ready/Tests/Build/Install im
Checkpointverzeichnis. Keine Commits/Pushes. Früherer AFK/Entfernungsschutz-WIP
weiter erhalten und deployed. Neue Quellheader+Tests teils untracked: NICHT
vergessen beim späteren gewünschten Commit.
---
# 2026-11-04 01:07 – Flugfortschritt und lokaler Fluganschluss implementiert, Installation ausstehend
Autorisiert: echte Stillstandserkennung+60s pro Segment, erwartete native
Flugdauer berücksichtigen, lokal wiederherstellen vor Rückkehr; außerdem
vorgemerkten Bodenanschluss/Flug-Fallback bei gleicher Gruppenroute umsetzen.
Source: ClientlessFlightProgress.h (0.5yd kumulierter Distanzfortschritt zum
3D-Segmentziel, 60s ohne Fortschritt; native Spline-Dauer als Erwartung/Diagnose,
KEIN hartes Laufzeitlimit für fortschreitenden Flug). FlightMgr misst jeden Tick,
versucht bei Stillstand bis zu2 lokale Neuplanungen mit beibehaltenem Following,
Ziel, Breadcrumbs, Start und Departurezustand. Erst erneuter Stillstand nach
2Versuchen oder ungültiger lokaler Korridor löst bestehenden sicheren Fail aus.
ActionExecutor versucht bei abgelehntem lokalen Start/Bridgebodenweg zuerst
FlightMgr::Start zum GLEICHEN Routenpunkt; Route/Step/Modalprofil bleiben.
Native Flugberechtigung, Korridor, solide Landung+MMAP-Anschluss bleiben aktiv.
Ein Versuch proRoutenpunkt, kein Bypass von aufgezeichneten Straßen/Transport.
Build -j10 abgeschlossen erfolgreich; gezielte Tests10/11 bestanden, neues
Produktionsmethoden-Harness test_route_approach_flight und erweiterter
Update-Harness test_flight_handoff bestanden (60s/jitter/vertikal/weiteFlüge/
2RecoveryVersuche/Leadertrail erhalten). test_flight_departure scheitert
unordered_map::at bereits unverändert auf HEAD (separat reproduziert), veraltete
Erwartung für overhead/openFromFeet-Zulassung, NICHT durch diese Änderungen.
Bestehende WIP des AFK/Entfernungsschutzes unangetastet, keine Commits/Pushes.
Loader1->0, sichere Logouts angefordert 2026-11-04T01:03:26.709253+01:00.
Operation/Roster/Build/Tests in checkpoints/2026-11-04-flight-progress/.
Original118Bots. 01:06 noch33Sessions,25Flug,6Kampf. 5min-Schutdownausnahme
frühestens01:08:27; VORHER NICHT installieren oder neustarten. Verbliebene
Bots vorShutdown erneut sichern (Roster/frischeFlightProbes/Transportstatus/
verfügbare Telemetrie). PassiveGDB-Crashlauncher erhalten. Nach Installation
Startbereitschaft+Ports prüfen, Loader durchStart pausiert lassen; erfasste
Restbots nachRelog prüfen, bei Transport/Flugrest ggf Kapitalteleport und
verifizieren. Danach vorherigen Botbetrieb118 wiederherstellen, SafeLogout
resume/Scheduleon/Loader1. Aktuelle Welt läuft noch PID106171. Kein Gameplay-
Akzeptanznachweis für neue Builds vor Installation.
---
# 2026-11-04 – Vorgemerkte Flug-/Bodenprüfung und Winienwi-Diagnose
Nutzer ausdrücklich: merken, Flug kann Höhenunterschiede überwinden; 1.75yd
Bodenpfadtoleranz darf nicht Flugbewegung begrenzen. Getrennte Prüfungen für
freien Flugkorridor, sichere erreichbare Landung und tatsächlichen Bodenweg.
Bei abgelehntem lokalem Bodenanschluss fliegerische Alternative prüfen, bevor
Makroroute wechseln. Unterirdische Ziele benötigen erreichbaren Eingang und
Bodenanschluss. Vorgemerkt, noch NICHT implementiert.
Winienwi163 benutzt SW-TH-Portal00:42:26 erfolgreich. Problem danach am Flug
zur Bastion: Start00:42:28, gemeinsamer Trail Leader160. 00:45:31 Abbruch
'flight segment made no confirmed progress' bei(-4897.04,-4485.46,668.396),
ca263yd horizontal/159yd unter Ziel. Letzter Segmentstart00:45:20. Code prüft
hier nur SegmentElapsed>10000 bei aktiver Spline, keine gemessene Bewegungs-
oder Distanzentwicklung! Exakte Ursache warum Spline dort nicht fertig wird
nicht belegt; Meldung beweist keinen blockierten Korridor. Shared-Wait und
Handoff können ebenfalls ohne neues Segment zurückkehren. Rückkehr bis
00:49:44 zum Abflugort, Neuversuch00:49:58, Landung00:53:21 auf Plattform
(-4905.67,-4232.752,827.766), Bodenanschluss12yd erfolgreich. Eintritt00:53:34
map671 instance4. Nativ action Completed / waiting just inside private instance
entrance bestätigt. Kein Eingriff/Build; nur Diagnose und Checkpoint.
---
# 2026-11-04 – Renrens Portalroute und abweichende Recovery rekonstruiert
Nur Diagnose auf Nutzerfrage, keine Code- oder Laufzeitänderung. Renren159
übernimmt zunächst den Flug von Leader160 zum Schattenhochlandportal200627
(00:37:57). Leader scheitert am Anflug, landet nach Airborne-Recovery lokal
und startet 00:38:34 einen Flug zu anderem Ziel/Anker220366. FlightMgr::Store
bricht alte Published-Spur ab; Replacement nur bei gleichem Ziel (<1yd).
Renren versucht deshalb lokale Landung, findet keine sichere und kehrt entlang
validierter Flugspur zurück (00:38:34; Rückkehr Handelszentrum00:39:22).
Konkrete geometrische Ablehnung dieser ersten lokalen Landung nicht geloggt.
Leader benutzt TH-Portal erfolgreich00:39:24 (PORTAL_USE_START1801/200627).
Renren hat somit keine protokollierte Portalbenutzungs-/Berechtigungsablehnung.
00:41:13 nochmals TRAVEL_SHARED_ROUTE159 leader160 steps5 belegt. Bei lokaler
Annäherung scheitert Bodenpfad; Recovery versucht TH-Portal nochmals direkt.
00:41:17 GROUP_GROUND_REJECT bei(-8275.555,454.338,115.548), floor113.391:
heightError2.157 > allowed1.750. Recovery sperrt fehlgeschlagene Startanker,
plant eigenständig via PlanAdaptiveRoute mit beibehaltenen JourneyCosts, ruft
AdoptRoute NICHT erneut auf. Danach auch Vashjir-Anker abgelehnt, Recovery3
führt zum Freiflug auf portal_at_2171_target (unterirdischer Trameingang).
Dies erklärt Abweichen trotz anfänglicher Leaderroute. Kein Nachweis, dass
die vollständige Route tatsächlich Tramtransport benutzt; Knoten ist Anker.
Nutzer bestätigt Untergrund als Hindernis des Sinkflugs. Ungelöst: Erreichbarkeit
unterirdischer Fluganker, Oszillation und gruppenerhaltende lokale Recovery.
Belege in adventurebot-navigation.log und Rotation .2026-11-04_00-40-33.
---
# 2026-11-04 00:42 – Renren hängt in Sturmwinder Flugausweichschleife
Nutzer meldetRenren159verlässtSturmwindnicht. Nativgroup6leader160,
RaidzielBastionweiteraktiv. AktuellerMakroschritt free_flight zu
portal_at_2171_target = Stormwind-TramExitTarget001(-8359.27,517.585,84.4087).
Landesucheverschiebtauf(-8399.27,586.87,92.69). KeingeplanterTramtransport
belegt: KanteistFreiflug, KnotennamealleinsagtkeinVerkehrsmittel.
Start00:41:19 bei(-8303.14,475.129,123.352), ReplanwegenAusweichanteil00:41:23
(12Segmente/12Avoid). Ab00:41:31abwechselndSinkflugziel(-8347,534,138) und
Ausweichziel(-8380,567,159), vielevorzeitigeHandoffs. Nach40sec145Segmente,
weiterhinengerSturmwindbereichstattFortschritt. NativeStatus00:41:33Pos
(-8361.517,551.054,146.645),mounted1/flying1. KeinSharedLandingWait,
keinBerechtigungsproblem. GreedyLokalausweichen+vorzeitigeSpline-Neuplanung
oszilliert; konkretegeometrischeAblehnungdesjeweiligenSinkkorridorsnochNICHT
mitDetailprobeisoliert. EinmaligeAirborneRecoverybereitsverbraucht,weitere
OszillationwirdnurspätdurchgesamtTravelBudget/Timeoutbegrenzt.
NurDiagnose,keineSourceänderung/Teleport/Reset. NutzerentscheidetFix/Recovery.
---
# 2026-11-04 00:31 – Botbetrieb wieder aktiv, 00/01-Uhr-Test eingerichtet
Nutzer verlangt alleBots wiederonline und exaktbekannten10erTest erneut:
00:00Gruppenbildung anGoldenerRose,01:00RaidBastiondesZwielichts normal10.
Auftragkam00:26;00Uhr istlaufenderStundenblock, keine rückwirkendeAusführung.
SafeLogout mit clientless logout resume aufgehoben (Allfalse/Pendingleer),
118ursprünglicheBotsaus Lag-Checkpoint wiederangemeldet. Tagespläneauchfür
nochverwalteteStop-Bots wiederScheduleon. Loaderwieder1+populationreload,
nativ pending0/sessions118 geprüft. Lagpause ist AUSDRÜCKLICHAUFGEHOBEN;
nicht beimnächstenTurnerneutpausieren ohne neuenAnlass. Lagursache bleibt offen.
BekannteTestgruppe159–167 und176,alle85,2Tanks167/176,2Heiler161/162,6DPS.
VorReset altePlan-/Instanz-/Handoffzuständegesichert. ZuerstPlänefürheute
20261104 Stunde0 groupformation/the_gilded_rose und1 raid/
instance_visit_at_6354_d0 gesetzt. DanngezielterTestlogout, alteVisit-/Handoff-
Datennurdieser10bereinigt, offlineSturmwindGoldeneRosepositiongesetzt.
NachRelogkurzBehaviorStop+nativeLeave (außerhalbInstanz), alteGruppenleer
geprüft, Scheduleonfüralle10. KeineanderenBotplänegeändert.
Alle20Planzeilenverifiziert. NativALLE10 groupformation/GoldeneRose,Schedule1,
Deadline01:00 bestätigt, PositioneninSW/Gasthausumfeld. ReguläreGruppensuchgänge
könnenkurzvorderTaverneführen. NativeGruppenmanagerübernimmtZuteilung, keine
künstlicheRaidfüllung. ServerPID106171läuft,keinBuild/Restart/Codechange.
KeineDauerbeobachtung/keineAuswertungsautomatik eingerichtet.
Artefakte checkpoints/2026-11-04-0100-raid-test/:Manifest,Originalroster,
VorherSnapshots,20verifiziertePläne,OfflineRosepositionen undNativeFormation.
OffeneSource-WIPdesAFK-/Entfernungsschutzes unverändertuncommittet erhalten.
KeinCommit/Push in diesemTurnangefordert.
---
# 2026-11-04 00:02 – Heftige Lags, Botbetrieb zur Entlastung pausiert
Nutzer meldet starke Lags. ServerPID106171 aktiv. Logs: wiederholte teure
Routenplanung, Sessionticks bis571ms, CPC slowGuid60 bis743ms. Keine großen
Gitprozesse (nur normale kleine UI-Diffs), vmstat kein akuter Swap-/IO-Stau,
ca4GiRAM verfügbar trotz2.1Gi belegtemSwap. Route-/Flight-/Actionlast belegt,
alleinige Ursache noch nicht abschließend isoliert. Mitternachtswechsel als
Auslöser möglich, aber nicht belegt.
Zur reversiblen Entlastung Loader1->0,populationreload,safeLogoutall angefordert,
KEIN Build/Restart/ForceLogout. Vorher118Bots, ursprünglicherRoster/Configstatus
checkpoints/2026-11-04-lag/ gesichert. NativeSessionzahl nimmt rasch ab;
letztePhase42aktiveBots,981Ticks/30s gegenüber118Bots/691Ticks zuvor.
Loader und SafeLogoutAll vorerst AKTIV PAUSIERT LASSEN, nicht automatisch
wieder118Bots einschalten solangeLagursache offen/NutzerkeineEntwarnung gibt.
Kämpfe/Flüge/Taxi/Transport dürfen natürlich abschließen. Bei nächster
Wiederaufnahme aktuellen logoutstatus abfragen (DBonline kann kurzfristig
von NativeSessions abweichen). Genauere CPU-/Planungsdiagnose bleibt offen.
---
# 2026-11-03 – Instanzgruppen gegen AFK-/Entfernungsaustritte geschützt
Auf Nutzerauftrag implementiert und installiert. AdventureBehaviorMgr prüft
mit ProtectInstanceGroupLeave gruppenweit Online-Mitglieder: tatsächlicher
Dungeon/Raid-Aufenthalt (auch menschlicher Leader ohne Botdatensatz), aktiver
Instanzbesuch auf Anreise/Vorbereitung/Eintritt/Inside/Returning oder gültiger
Raid-/Dungeon-Anreiseintent vor Beginn des Visits. Beendete Rest-Phase und
Offline-Mitglieder halten Schutz nicht dauerhaft aktiv. IsInWorld-Absicherung
verhindert Zugriff auf noch nicht initialisierte Maps beim Login.
AdventureInteractionMgr unterdrückt damit ausschließlich leader-afk und
leader-distance und setzt währenddessen die Idle-/AFK-Uhren zurück. Nach Ende
beginnt die10min-Frist neu. Intentwechsel, manuelle Austritte und bestehende
Kampf-/Transport-/Formationsregeln bleiben unverändert.
Gezielte Tests test_instance_group_protection.py und erweiterter
test_adventure_interactions.py bestanden: Raid-/Dungeon-Reisephasen,
menschlicher Leader bereits innen, verspätetes Mitglied draußen, Offline,
Besuchsende, ungültige/abgelaufene Intents, Entfernungs-/AFK-Sperre, neue Frist
und weiterhin erlaubter Intentwechsel. Build -j10 und Installation PASS.
Gameplayabnahme im nächsten Nutzerlauf noch offen; keinen10min-Livetest behaupten.
Loader vor beiden Builds pausiert, SafeLogoutall angefordert. Letzte Anfrage
23:05:19, Shutdown erst deutlich nach23:10:19. Restliste inkl. Positionen,
Fraktion und verfügbaren Native-Flags gesichert. Generierte Online-Bots vor
Shutdown zusätzlich ohne Ready-Filter abgefragt; menschlicher Test6 durch
nativeInfo als nichtclientless identifiziert und nicht als Recoverybot behandelt.
Bekannter separater Shutdownfehler GameObject::RemoveFromWorld651 erneut
aufgetreten; Core worldserver-20261103-194258.core und passende alte Executable
worldserver-before-fix im Checkpoint gesichert. Nicht behoben.
Neuer Server PID106171, frische ready-Meldung, Ports8085/8087 und Fortbestand
geprüft. Alle118 ursprünglichen Adventure-Bots online, Loader1,pending0.
Nach wirklichem Online Restbots geprüft; aktuelle Koordinaten bei schwierigen
Mehrfachflächen nochmals geprobt. Fehlgeschlagene/stationäre abgerissene Flüge
36Edwin/74Nimbin/83Mahuwa/102Corren/104Lillini/112Aeliriel/132Braneron/
166Corric/168Elanora/169Bromdan nativ in Fraktionshauptstadt zurückgesetzt,
Ergebnispositionen bestätigt.112 und166 danach bereits wieder regulär fliegend.
Laufende Flüge161/186, normale Taxifahrten und bereits weiterbewegte84/109/163
nicht unterbrochen. Keine neue Testzeit oder Dauerbeobachtung eingerichtet.
Artefakte checkpoints/2026-11-03-instance-group-protection/ (Roster,
Operation, Visitbackup, verbleibende Native-Zustände, Build/Install/Start,
Recovery/result.json). Neuer Test test_instance_group_protection.py noch
untracked; Sourceänderungen noch uncommittet, in diesem Turn kein Commit/Push
angefordert. Alle vorherigen Änderungen erhalten. Separater Admission-Retry-
Fehler nach bereits erfolgter Ablehnung und Wartungs-Resume bleiben offen;
diese Aufgabe betrifft gezielt Gruppenerhalt bei aktiver Instanzreise.
---
# 2026-11-03 – AFK-/Entfernungsregeln bei Instanzreise in Arbeit
Nutzer beauftragt: 10-Minuten-AFK und leader-distance sollen nicht gelten,
wenn Gruppe zur Instanz reist oder ein Mitglied bereits drinnen ist.
ProtectInstanceGroupLeave prüft gruppenweit Online-Mitglieder: tatsächlicher
Dungeon/Raid-Aufenthalt (auch menschlicher Leader ohne Botrecord), aktiver
Visit in Travel/Preparing/Entering/Inside/Returning, oder gültiger noch nicht
abgelaufener Raid-/Instanz-Anreiseintent. Rest/abgeschlossene Besuche und
Offline-Mitglieder schützen nicht dauerhaft. Keine Änderung anderer
Austrittsgründe. InteractionMgr setzt dabei Idle/AFK-Uhren zurück und sperrt
nur leader-distance/leader-afk, nicht intent-change/manuellen Austritt.
Produktionscode-Regressionsprüfung test_instance_group_protection.py PASS;
erweiterter test_adventure_interactions.py PASS (Entfernung+AFK während Reise,
neue10min-Frist nach Ende, Entfernung danach aktiv, Intentwechsel unverändert).
Build1 PASS. Build-final läuft nach zusätzlicher IsInWorld-Absicherung und
kompiliert AdventureBehaviorMgr.cpp erneut (keine alte Objektdatei verwenden).
Loader0+safeLogoutall vor JEDEM Build angefordert. Operation/Roster/Visitbackup
unter checkpoints/2026-11-03-instance-group-protection/.
VorBuild war22Uhr-Test bereits beendet: nur einandererVisitStageTravel gespeichert,
keine Inside-Sitzungen mehr. LetzteSafeLogout-Frist ausoperation.json beachten:
volle5min vorShutdown bei Restbots. Noch35Sessions beiZweitbuild. Installation,
Neustart,Recovery undLoaderRestore nochOFFEN. SeparateZoneScript-Crash-Dumps
weiteraufzeichnen,keineanderenDiensteberühren. KeinCommit/Pushbeauftragt.
---
# 22:39 – Eintrittsablehnung beider Bots geklärt
Beide Denial-Traces belegen group0/leader0: Winienwi16322:17:59 imrotierten
Navlog adventurebot-navigation.log.2026-11-03_22-22-06, Taliaarnora16422:30:33
imaktuellenLog. Instance.IgnoreRaid0, nativeMap::PlayerCannotEnter verlangt
für671eineRaidgruppe (CANNOT_ENTER_NOT_IN_RAID). Achtanderekonntenhinein.
Serverlogbelegt fürbeide zuvor INTERACTION_GROUP_LEAVE reasonleader-afk.
AdventureInteractionMgr prüft10minLeaderExpired, Bewegungs-/Aktionslosigkeit
zählt; SchutzForming/Travel greift nichtmehr überall während verspäteterAnreise.
Aruendas162wartetalsLeaderderAchtergruppeplanmäßiginnen; dieserperformative
Wartezustand wird fürNachzüglernichtalsaktiveRaidteilnahmegeschützt.
SpäterGruppe4aus163/164gebildet, aberbeideBesuche nachDeniedbereitsRest5:
keinautomatischerneuerEintrittnachGruppenbildung. Somit Gruppenerhalt+
AdmissionRetry, keinNavigations-/Rollen-/Bindungsproblem. ExakterDenyEnum
nichtimLog, aberSolozustand+nativgeltendeRegel belegen Zugangsbedingung.
KeineDaten-/Codeänderung, nurweiterführendeDiagnose. UserentscheidetFix.
---
# 2026-11-03 22:36 – Teststatus: acht drinnen, zwei am Eingang abgewiesen
22Uhr-Test:159/160/161/162/165/166/167/176 warten korrekt in Bastion671,
Instanz3,PhaseInside3,injury0,schedule1. Winienwi163 undTaliaarnora164 sind
aufEingangsplattform(-4899.67,-4222.36,827.764) angekommen, FlugArrived und
RouteCompleted; BesuchPhaseRest5,instance_id0,injury0 => NICHTwiederausgetreten,
sondernEintrittabgewiesen. INSTANCE_ENTRY_DENIED beider imServerlog.
Taliaarnora konkret22:30:33 imTracegroup0/leader0(allein) amEintritt. Aktuell
nativeGruppenaufgeteilt: Gruppe1Leader162Aruendas hat8Bots; Gruppe4Leader163
Winienwi hat163+164, beidegroupsType2(Raid),normalSchwierigkeit0. Keinen
fehlendenHeiler/Tank alsZugangsvoraussetzung behaupten (performativeRaids!).
Gruppenbildung nicht zumgewünschteneinheitlichen10erRaid zusammengeführt.
Keinepersönlichencharacter_instance-Bindungenfür163/164 an671gefunden,
Gruppe4nochkeineInstanzbindung; Gruppe1boundInstanz3. ExakternativeDenyReason
nichtgeloggt,keinenBindungskonfliktbehaupten. BeiTaliaarnoraNoGroupamVersuch
belegt; fürWinienwientsprechendenZeitpunktnochgesondertprüfen.
RaidblockEnde23:00,regulärerReturn22:55. Read-onlyStatus,keineBewegung/Änderung.
Snapshot checkpoints/2026-11-03-2200-raid-test/status-2236/. NavigationbisEingang
aller10gelungen; alsvollständigen10erTest NICHTerfolgreichwerten, solange
Gruppen-/Eintrittszustand2Botsausgrenzt. NutzerentscheidetnächsteSchritte.
---
# 2026-11-03 21:36 – Neuer Test 21/22 Uhr vollständig eingerichtet
Nutzer meldete Unterbrechung des vorherigen20/21-Tests und verlangte erneut
Vorbereitung, jetzt21:00Gruppenbildung und22:00Raid. AktuelleServerzeit bei
Beginn21:34, daher21Uhr ist der laufendeStundenblock. Bekannte zehn85er:
159Renren,160Marndra,161Marnda,162Aruendas,163Winienwi,164Taliaarnora,
165Brynda,166Corric,167Ragnorli,176Ashaelri;2Tanks167/176,2Heiler161/162,6DPS.
Vorher neun noch inRaid671, Renren schonSturmwind. ZuerstPläne21formation/
the_gilded_rose und22raid/instance_visit_at_6354_d0 gesetzt und20Zeilen geprüft,
danngezielterTestlogout/PositionsresetGoldeneRose. AlteInstanceVisit-/Handoff-
Zustände nurdieser10gelöscht;keineNativeRaidbindungen/anderenBots verändert.
RequestLeaveinderInstanzwurdekorrektabgelehnt;nachLogininSWkurzBehaviorStop,
dannnativeLeavefüralle10. AlteGruppenmitgliedschaften danachleer geprüft,
Schedulefüralle10wiederon. ZuletztALLE10nativ groupformation/GoldeneRose,
Schedule1 undDeadline22:00 bestätigt, Positionen imGasthaus/Umfeld. Winienwi
läuft vomkurzenGruppensuchgangzurückzurTaverne, keinFernflug/alteAnreise.
Loadernurkurzpausiert, jetztwieder1+populationreload. ServerPID84679läuft,
keinBuild/Restart/Codechange. Nutzer beobachtet, KEINE Dauerbeobachtung oder
Auswertungsautomatik. AktuellesManifest/Backups/Offlinepositionen/20verifizierte
Planzeilen undformation-verified.log unter
checkpoints/2026-11-03-2200-raid-test/. Vorherige20/21-Planung ist fürdiesen
Testüberschrieben. NichtbehauptenStartbereits21:00gemessen;Setuperst21:35/36.
---
# 20:02 – Raidgruppe nach Wartungsrestart in Innen-/Außengruppe geteilt
Nutzer fragt warum sechs wieder draußen. Snapshot: draußen159Renren/161Marnda/
164Taliaarnora/165Brynda/166Corric/167Ragnorli, PhaseRest5,injury_applied1,
schedule0; drinnen160Marndra/162Aruendas/163Winienwi/176Ashaelri, PhaseInside3,
injury_applied0,schedule1. Alle derselbeRaid671/Instanz6,Blockende21:00,
regulärerReturnAt20:55, somit kein geplantes20:00-Raidende.
Die sechs waren schon vor Navigationsbuild inInstanz6 (Roster19:30belegt).
SafeLogout ruft adventure stop auf, setztSchedulefalse und beiInstanz
Abort=true. OfflineSave speichertSchedulefalse+PhaseInside. NachRestart
INSTANCE_RESUME diesersechs zeigt gespeichertePhase3, aber tatsächlichen
Playermap0/instance0. InstanzUpdate wertet diesen Kartenmismatch alsRückkehr,
führtReturning->Rest aus und wendet performativenHealthverlust an; dadurch
keinWiedereintrittbisBlockende. Die vier anderen kamen erstnachRestart hinein
und warten korrektinnen. NativeLoadFromDB kann beiInstanz-Loginablehnung oder
fehlendemSave zumEingangsetzen; welcher denyReason hier genau vorlag, wurde
nichtgeloggt und ist nichtbelegt. Nichtbehaupten dieBots hätten sich wegen
Kampf/Unvollständigkeit/Timer bewusstzurückgezogen.
Fehler ist Wartungslogout-/Wiederaufnahmebehandlung: Stop verliertSchedule und
Resume behandelt gespeicherteInside+tatsächlichOutside als regulärabgeschlossenen
Besuch. KünftigpausierenstattIntentabbrechen; Resume muss dieselbeInstanzreise
sauberwiederaufnehmen stattInjury/Rest. NochNICHTbeauftragt/implementiert.
NurRead-onlyDiagnose, keineBotsbewegt. Artefakteinstance-resume-split/.
---
# Navigationskorrektur zum lokalen Commit freigegeben
Der Nutzer hat den lokalen Commit der installierten Shared-flight-Korrektur
@@ -1563,6 +1563,8 @@ bool ClientlessActionExecutorMgr::StartRouteStep(
portalSourceApproach))
{
record.Status.State = ClientlessActionExecutionState::Failed;
if (TryRouteApproachFlight(player, characterGuid, record))
return true;
record.Status.Detail = "travel start failed for route node " + step.NodeKey;
record.Active = false;
return false;
@@ -2256,6 +2258,42 @@ bool ClientlessActionExecutorMgr::TryRescueTravel(Player* player,uint32 characte
return StartRouteStep(player,characterGuid,record);
}
bool ClientlessActionExecutorMgr::TryRouteApproachFlight(Player* player, uint32 characterGuid, Record& record)
{
if (record.RouteStep >= record.Route.size())
return false;
auto const& step = record.Route[record.RouteStep];
// A local connector may be flown without changing the group's macro route.
// Recorded roads and transport edges retain their own execution semantics.
if (step.MapId != player->GetMapId() || step.EdgeDatabaseId ||
(step.EdgeType != "start" && step.EdgeType != "local_bridge") ||
player->GetExactDist(step.X, step.Y, step.Z) < 5.0f)
return false;
std::string const key = "approach-flight:" + step.NodeKey;
if (!record.FailedBridgeKeys.insert(key).second)
return false;
Position target;
target.Relocate(step.X, step.Y, step.Z, step.O);
std::string error;
// Start validates native flying permissions, collision, solid landing and
// an MMAP connection from the landing to the actual (possibly indoor) node.
if (!sClientlessFlightMgr->Start(player, target, error, true))
{
TC_LOG_INFO("server.adventurebot.navigation", "ROUTE_APPROACH_FLIGHT_REJECT guid=%u node='%s' reason='%s'",
characterGuid, step.NodeKey.c_str(), error.c_str());
return false;
}
record.DeferredStartActive = false;
record.EdgePath.clear();
record.FlightActive = true;
record.Active = true;
record.Status.State = ClientlessActionExecutionState::Moving;
record.Status.Detail = "flying to existing route node after rejected ground approach";
TC_LOG_INFO("server.adventurebot.navigation", "ROUTE_APPROACH_FLIGHT guid=%u node='%s' step=%u",
characterGuid, step.NodeKey.c_str(), uint32(record.RouteStep));
return true;
}
bool ClientlessActionExecutorMgr::RecoverTravel(
Player* player,
uint32 characterGuid,
@@ -2268,6 +2306,9 @@ bool ClientlessActionExecutorMgr::RecoverTravel(
if (!player || !player->IsInWorld())
return false;
if (reason.rfind("route-local-", 0) == 0 && TryRouteApproachFlight(player, characterGuid, record))
return true;
if(record.RescueActive)
{record.RescueActive=false;record.RescueWalkFailed=true;}
if (failedEdgeDatabaseId)
@@ -143,6 +143,7 @@ private:
bool StartRecordedEdgePath(Player* player, uint32 characterGuid, Record& record);
bool GetTravelGoal(Record const& record, ClientlessTravelNode& goal) const;
bool TryFallbackFlight(Player* player, uint32 characterGuid, Record& record);
bool TryRouteApproachFlight(Player* player, uint32 characterGuid, Record& record);
bool TryRescueTravel(Player* player, uint32 characterGuid, Record& record);
void CheckGroundExit(Player* player, uint32 characterGuid, Record& record);
void UpdateGroundExit(Player* player, uint32 characterGuid, Record& record);
+25 -3
View File
@@ -780,7 +780,8 @@ bool ClientlessFlightMgr::Advance(Player * player, Record & record, bool handoff
init.SetFly();
init.SetWalk(false);
init.SetVelocity(player->GetSpeed(MOVE_FLIGHT));
if (init.Launch() <= 0)
int32 const duration = init.Launch();
if (duration <= 0)
{
Fail(player, record, "flight spline rejected");
return false;
@@ -790,6 +791,7 @@ bool ClientlessFlightMgr::Advance(Player * player, Record & record, bool handoff
record.SegmentUnderOverhang=next.UnderOverhang;
record.Moving = true;
record.SegmentElapsed = 0;
record.Progress.Begin(Distance(current, next.Next), uint32(duration));
++ record.Status.Segments;
record.Status.Avoidances += next.Avoiding ? 1 : 0;
if (handoff) ++record.Status.Handoffs;
@@ -837,6 +839,8 @@ void ClientlessFlightMgr::Update(uint32 diff)
// Count actual motion, not overlapping issued spline lengths.
record.Status.Travelled += Distance(PointOf(record.LastPosition), PointOf(*player));
record.LastPosition.Relocate(player);
if (record.Status.State == ClientlessFlightState::Flying && record.Moving)
record.Progress.Observe(Distance(PointOf(*player), PointOf(record.Segment)), diff);
if (record.Status.State == ClientlessFlightState::Mounting)
{
if (player->IsMounted() && player->CanFly()) record.Status.State = ClientlessFlightState::Flying;
@@ -882,9 +886,27 @@ void ClientlessFlightMgr::Update(uint32 diff)
}
if (record.Moving && player->IsSplineEnabled())
{
if (record.SegmentElapsed > 10000)
if (record.Progress.Stalled())
{
Fail(player, record, "flight segment made no confirmed progress");
TC_LOG_WARN("server.adventurebot.navigation",
"FLIGHT_STALLED guid=%u idleMs=%u segmentMs=%u expectedMs=%u overdue=%u recovery=%u",
guid, record.Progress.IdleMs, record.Progress.ElapsedMs, record.Progress.ExpectedMs,
record.Progress.Overdue()?1u:0u, record.StallRecoveries);
if (record.Returning || record.StallRecoveries >= 2)
{
Fail(player, record, "flight stalled for 60 seconds; local recovery exhausted");
continue;
}
++record.StallRecoveries;
player->StopMoving();
record.Moving = false;
// Keep the leader trail and destination. Re-evaluate the local
// join/corridor; never replace the macro route or return yet.
record.Join = {};
bool const departed = record.Memory.Departed;
record.Memory = {};
record.Memory.Departed = departed;
Advance(player, record);
continue;
}
auto ray =[&](Point const & a, Point const & b)
@@ -3,6 +3,7 @@
#include "Common.h"
#include "Position.h"
#include "ClientlessFlightPath.h"
#include "ClientlessFlightProgress.h"
#include <string>
#include <memory>
#include <unordered_map>
@@ -57,6 +58,8 @@ class TC_GAME_API ClientlessFlightMgr
Position Departure;
uint32 TargetUpdated = 0, FormationDelay = 0;
uint32 DetachedRecoveryCount = 0;
ClientlessFlightProgress::Watch Progress;
uint32 StallRecoveries = 0;
bool ActionOwned = false;
std::string AbortReason;
std::vector < Position > Breadcrumbs;
@@ -0,0 +1,36 @@
#ifndef VCORE_CLIENTLESS_FLIGHT_PROGRESS_H
#define VCORE_CLIENTLESS_FLIGHT_PROGRESS_H
#include <algorithm>
#include <cmath>
#include <cstdint>
// Progress is measured against a fixed segment endpoint, not issued splines.
namespace ClientlessFlightProgress
{
struct Watch
{
unsigned IdleMs = 0, ElapsedMs = 0, ExpectedMs = 0;
float BestDistance = 0;
void Begin(float distance, unsigned expectedMs)
{
BestDistance = distance;
ExpectedMs = expectedMs;
IdleMs = ElapsedMs = 0;
}
void Observe(float distance, unsigned diff)
{
ElapsedMs += std::min(diff, 30000u);
// Accumulate sub-tick motion; jitter or moving away is not progress.
if (std::isfinite(distance) && BestDistance - distance >= 0.5f)
{
BestDistance = distance;
IdleMs = 0;
}
else
IdleMs = std::min(60000u, IdleMs + std::min(diff, 30000u));
}
bool Stalled() const { return IdleMs >= 60000; }
// Duration overruns are diagnostic only: a progressing flight is healthy.
bool Overdue() const { return ElapsedMs > ExpectedMs + 5000u; }
};
}
#endif
+35 -1
View File
@@ -10,6 +10,7 @@ b = source.index('bool ClientlessFlightMgr::Command(', a)
update = source[a:b]
harness = r'''
#include "ClientlessFlightPath.h"
#include "ClientlessFlightProgress.h"
#include <cassert>
#include <memory>
#include <cstdint>
@@ -44,6 +45,7 @@ auto sWorld=&world;
enum class ClientlessFlightState {Mounting,Flying,Arrived,Failed};
struct Record {
struct {bool FollowingPlayer=false;ClientlessFlightState State=ClientlessFlightState::Flying;uint32 MapId=0;Position Landing{800,0,0},Target{800,0,0};float Travelled=0;uint32 Segments=0,Avoidances=0;std::string Detail;} Status;
ClientlessFlightProgress::Watch Progress;uint32 StallRecoveries=0;SharedJoin Join;
Position LastPosition,Start,Segment{25,0,60};Settings Settings;
std::shared_ptr<int> Following;uint32 FormationDelay=0,TargetUpdated=0,Elapsed=0,SegmentElapsed=0,CheckTimer=0;
bool Moving=true,Returning=false,ApproachingDeparture=false,ActionOwned=false,SegmentUnderOverhang=false;uint32 DetachedRecoveryCount=0;Position Departure;Memory Memory;std::shared_ptr<SharedTrail> Published=std::make_shared<SharedTrail>();std::vector<Position> Breadcrumbs;
@@ -70,7 +72,16 @@ public:
'''.replace('Settings Settings;', 'ClientlessFlightPath::Settings Settings;').replace('Memory Memory;', 'ClientlessFlightPath::Memory Memory;')
harness += update + r'''
int main(){
// Small real movements accumulate; oscillating distance does not reset best progress.
ClientlessFlightProgress::Watch watch;watch.Begin(100,120000);
for(int i=0;i<59;++i)watch.Observe(100+(i%2?0.1f:-0.1f),1000);
assert(!watch.Stalled());watch.Observe(100,1000);assert(watch.Stalled());
watch.Observe(99.4f,200);assert(!watch.Stalled()&&watch.IdleMs==0);
// Vertical movement is measured with the same 3D distance as horizontal flight.
watch.Begin(Distance({0,0,0},{0,0,200}),20000);
watch.Observe(Distance({0,0,1},{0,0,200}),1000);assert(watch.IdleMs==0);
ClientlessFlightMgr mgr;mgr._records[26]={};
mgr._records[26].Progress.Begin(25,2000);
// Begin replacement while the existing spline is still active: no stop.
mgr.Update(50);assert(mgr.handoffs==1&&mgr.advances==1&&player.stops==0);
// The 200ms collision cadence must not launch a replacement each tick.
@@ -90,6 +101,18 @@ int main(){
assert(player.stops==1&&mgr.advances==2&&mgr.handoffs==1);
// A completed spline continues via the normal non-handoff path.
clear=true;r.CheckTimer=0;mgr.Update(50);assert(mgr.advances==3);
// Long flights keep running when actual progress continues, even overdue.
r.Returning=false;r.Moving=true;player.running=true;player.spline.remaining=3000;
r.Progress.Begin(1000,20000);r.Segment={1007,0,60};
for(int i=0;i<90;++i){player.x+=1;r.CheckTimer=0;mgr.Update(1000);}
assert(mgr.failures==0&&r.Progress.Overdue()&&r.Progress.IdleMs==0);
// A genuinely stuck spline survives 59s, then replans locally at 60s.
r.Progress.Begin(Distance(PointOf(player),PointOf(r.Segment)),20000);r.StallRecoveries=0;
int before=mgr.advances;
for(int i=0;i<59;++i){r.CheckTimer=0;mgr.Update(1000);}
assert(mgr.advances==before&&mgr.failures==0);
r.CheckTimer=0;mgr.Update(1000);
assert(mgr.advances==before+1&&r.StallRecoveries==1&&mgr.failures==0);
player.fly=false;mgr.Update(50);assert(mgr.failures==1);
// A ground departure approach must wait for actual arrival before mounting.
r.Status.State=ClientlessFlightState::Mounting;r.ApproachingDeparture=true;
@@ -106,6 +129,17 @@ int main(){
r.ApproachingDeparture=true;r.Status.State=ClientlessFlightState::Mounting;
// A stale Arrived flag cannot permit mounting away from the selected spot.
r.Departure.x=player.x+10;mgr.Update(50);assert(mgr.failures==2&&mgr.begins==1);
// Repeated genuine stalls exhaust local recovery, without dropping the leader trail.
ClientlessFlightMgr stuck;auto& sr=stuck._records[77];
sr.Following=std::make_shared<int>(1);auto leaderTrail=sr.Following;
sr.Segment={player.x+100,0,60};player.fly=true;player.spline.remaining=3000;
for(int attempt=0;attempt<3;++attempt){
sr.Moving=true;player.running=true;sr.Progress.Begin(100,4000);
for(int i=0;i<60;++i){sr.CheckTimer=0;stuck.Update(1000);}
assert(sr.Following==leaderTrail);
assert(stuck.failures==(attempt==2?1:0));
}
assert(stuck.advances==2&&sr.StallRecoveries==2);
}
'''
with tempfile.TemporaryDirectory(prefix='vcore-flight-handoff-') as folder:
@@ -114,4 +148,4 @@ with tempfile.TemporaryDirectory(prefix='vcore-flight-handoff-') as folder:
cpp.write_text(harness)
subprocess.run(['c++', '-std=c++17', '-I', str(root/'src/server/game/World'), str(cpp), '-o', str(binary)], check=True)
subprocess.run([str(binary)], check=True)
print('Flight handoff before spline end, terminal landing, return corners, collision stop and actual distance passed.')
print('Flight handoff, collision, 60s measured stall, jitter, vertical progress, long-flight overrun and local recovery passed.')
@@ -0,0 +1,55 @@
"""Run the production local-flight adapter; preserve macro route and native checks."""
from pathlib import Path
import subprocess
import tempfile
root = Path(__file__).resolve().parents[2]
src = (root/'src/server/game/World/ClientlessActionExecutorMgr.cpp').read_text()
a = src.index('bool ClientlessActionExecutorMgr::TryRouteApproachFlight(')
b = src.index('bool ClientlessActionExecutorMgr::RecoverTravel(', a)
method = src[a:b]
harness = r'''
#include <cassert>
#include <cmath>
#include <string>
#include <vector>
#include <set>
using uint32=unsigned;
struct Position {float x=0,y=0,z=0;void Relocate(float a,float b,float c,float){x=a;y=b;z=c;}};
struct Player {unsigned GetMapId(){return 0;}float GetExactDist(float x,float y,float z){return std::sqrt(x*x+y*y+z*z);}};
struct Step {std::string NodeKey="portal",EdgeType="start";unsigned MapId=0,EdgeDatabaseId=0;float X=100,Y=0,Z=10,O=0;};
enum class ClientlessActionExecutionState{Moving,Failed};
struct Record {std::vector<Step> Route{Step{},Step{}};unsigned RouteStep=0;std::set<std::string> FailedBridgeKeys;bool DeferredStartActive=true,FlightActive=false,Active=false;std::vector<int> EdgePath{1,2};struct {ClientlessActionExecutionState State=ClientlessActionExecutionState::Failed;std::string Detail;}Status;};
struct Flight {bool available=true;unsigned calls=0;Position last;bool Start(Player*,Position const&p,std::string&error,bool owned){assert(owned);++calls;last=p;if(!available)error="no safe landing";return available;}}flight;
auto sClientlessFlightMgr=&flight;
#define TC_LOG_INFO(...) ((void)0)
struct ClientlessActionExecutorMgr {bool TryRouteApproachFlight(Player*,uint32,Record&);};
'''
harness += method + r'''
int main(){
Player p;Record r;ClientlessActionExecutorMgr mgr;
// Fly to the rejected connector, preserving the following portal edge.
assert(mgr.TryRouteApproachFlight(&p,163,r));
assert(r.FlightActive&&r.Active&&!r.DeferredStartActive&&r.EdgePath.empty());
assert(r.RouteStep==0&&r.Route.size()==2&&r.Route[0].EdgeType=="start");
assert(flight.last.x==100&&flight.last.z==10&&flight.calls==1);
assert(!mgr.TryRouteApproachFlight(&p,163,r)&&flight.calls==1);
// No flight permission/solid landing/ground connection means no fallback.
r=Record{};flight.available=false;
assert(!mgr.TryRouteApproachFlight(&p,163,r)&&!r.FlightActive&&r.Route.size()==2);
r=Record{};flight.available=true;r.Route[0].MapId=1;
assert(!mgr.TryRouteApproachFlight(&p,163,r));
r=Record{};r.Route[0].EdgeDatabaseId=42;
assert(!mgr.TryRouteApproachFlight(&p,163,r));
for(auto type:{"portal_use","taxi","free_flight","ship"}){
r=Record{};r.Route[0].EdgeType=type;assert(!mgr.TryRouteApproachFlight(&p,163,r));
}
r=Record{};r.Route[0].EdgeType="local_bridge";assert(mgr.TryRouteApproachFlight(&p,163,r));
}
'''
with tempfile.TemporaryDirectory(prefix='vcore-route-flight-') as folder:
cpp=Path(folder)/'test.cpp'; exe=Path(folder)/'test'
cpp.write_text(harness)
subprocess.run(['c++','-std=c++17',str(cpp),'-o',str(exe)],check=True)
subprocess.run([str(exe)],check=True)
print('Route approach flight: original route retained, one attempt, native refusal and transport boundaries passed.')