Recover stalled flights locally and fly rejected route approaches
This commit is contained in:
1 parent
f8ee1d0ff6
commit
ba2a4e629c
8 files changed
+573
-4
No files matched your search
@@ -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);
|
||||
|
||||
@@ -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
|
||||
@@ -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.')
|
||||
Reference in new issue
Block a user