This repository has been archived on 2026-10-31. You can view files and clone it. You cannot open issues or pull requests or push a commit.
Files
Ananta-ps/internal/gameserver/routers/game_router_racing_zone_probe.go
T

116 lines
6.0 KiB
Go

package routers
import (
"context"
"sync"
)
var _ = sync.Mutex{}
var _ = context.Background
//
// ROUTE A race-start experiment (§59.14 §7.9): push a single SyncGameGroundZoneInfo
// (68004609) carrying a RacingZoneInfo and watch what the client does with it.
// The question this answers is the only remaining unknown in the racing chain:
// <code>
// 68004609 → C# GameSceneToClientImpl.SyncGameGroundZoneInfo (dump.cs:184816)
// → lua GameSceneToClientImpl.SyncGameGroundZoneInfo (lua:1135)
// → Racing branch → gChallengeManager:OnSyncRacingZoneInfo (lua:526)
// → ...and then? lua never calls L50.Spoon.CarRaceManager.Instance:SyncCarRaceGame
// </code>
// Either the C# hop stops at the C# CarRaceManager itself (in which case this single packet is
// enough to stage the grid, run the countdown and start the lap clock), or the race only runs when
// a Spoon graph calls SyncCarRaceGame (IDMAP 49071), in which case nothing happens and
// Route A stays blocked on the Spoon md5 problem.
// Observable outcomes (see VEHICLE-RACING-INVESTIGATION.md §7.9):
// • cars appear on the track / countdown panel / AI dots on the minimap (gMapCsApi.OnCarRaceStart)
// ⇒ (a) C#-internal wiring — Route A is unblocked, only participants + settlement remain.
// • absolutely nothing, and no CarRaceManager line in Player.log
// ⇒ (b) Spoon-graph driven — Route A needs the Spoon md5.
// Nothing here is wired into normal gameplay: the only entry point is the debug HTTP API
// (/api/racing/zone-probe), so this is inert until deliberately fired.
//
//
// Options surfaced to the debug panel / HTTP caller. cfgId is a
// RacingDriverTrackInformationConfig Id (the "Id" column, NOT an EventId).
//
func GameRouter_RacingZoneProbe_RacingZoneProbeStatus(ctx context.Context, ) any {
// Router implementation for GameRouter_RacingZoneProbe_RacingZoneProbeStatus
var zero any; return zero
}
//
// Build the AI opponent grid for a racing zone. Returns BOTH:
// • AIVehicleInfos — the plain dict (vehicleInstanceId → cfgId) that drives the minimap
// blue dots (client GetAllVehicleAIIds reads AIVehicleInfos); and
// • ParticipantInfos — real AI opponents, each a GameGroundParticipantInfo4229938
// (0xFF marker + 8 base fields), which is the element shape the client's own
// Auto.WriteRacingZoneInfo uses. (R203: the earlier RacingParticipantInfo/TypeMark=14
// shape desynced the packet by 28 B/participant.)
// Returns empty lists when ≤ 0 (byte-compatible with the pre-AI probe).
// Opponent cfgIds come from the track's HighAI/MiddleAI/LowAI pools (RacingTrackRow); if the row is
// missing or the pools are empty, no AI is produced.
//
func GameRouter_RacingZoneProbe_BuildRacingAiGrid(ctx context.Context, trackCfgId uint32, count int32, realVehicles []any) any {
// Router implementation for GameRouter_RacingZoneProbe_BuildRacingAiGrid
var zero any; return zero
}
//
// One AI opponent entry, typed as the BASE GameGroundParticipantInfo — which is what the
// client's own Auto.WriteRacingZoneInfo writes for this list
// (Base.WriteComplexWrap(Auto.WriteGameGroundParticipantInfo, …)): each element is
// 0xFF (present marker) + 8 base fields, no TypeMark.
// is the SCENE ENTITY id (it is also what the client keys
// AIVehicleInfos by) and is the VehicleConfig the car
// was built from. It lands in VehicleInstanceId / AIAgentInfo.VehicleId; the
// Racing-only extras (AiVehicleCfgId / Lap / RacingTotalTimeMilli …) are NOT
// part of this shape — R203 proved adding them desyncs the packet by 28 B per participant.
//
func GameRouter_RacingZoneProbe_BuildRacingParticipant(ctx context.Context, agentInstanceId uint64, aiCfgId uint32, vehicleCfgId uint32, seatIndex int32) any {
// Router implementation for GameRouter_RacingZoneProbe_BuildRacingParticipant
var zero any; return zero
}
//
// Build the payload the client's Auto.Dispatch[449] expects: the RacingZoneInfo
// discriminator (0x0F, emitted by [UxContract(TypeMark = 15)]) followed by the Racing
// fields and then the GameGroundZoneInfo fields.
// When &gt; 0 the grid is populated with that many AI opponents
// (cfgIds from the track's HighAI/MiddleAI/LowAI pools); when 0 or omitted the grid stays empty,
// which is also the byte-compatible original probe. The LinkAIAgentInfo contract is now declared
// (RacingZoneMethods.cs), so a non-empty grid serialises correctly.
// <para>
// / are unix seconds for
// GameGroundZoneCountDownInfo (dump.cs:1918571). They drive the client's countdown panel
// and therefore the vehicle-control release — an all-zero countdown is what left the player in
// an undrivable car on 2026-09-22 (see GameRouter.RacingAutoStart.cs). Both default to 0 so the
// debug /api/racing/zone-probe payload stays byte-identical to the original 71-byte probe.
// </para>
//
func GameRouter_RacingZoneProbe_BuildRacingZoneProbe(ctx context.Context, cfgId uint32, taskId uint32, zoneState byte, syncReason byte, zoneSessionId any, gadgetUId uint64, startTime uint32, gameTimeEnd uint32, prepareEnd uint32, displayEnd uint32, aiCount int32, realAiVehicles []any) any {
// Router implementation for GameRouter_RacingZoneProbe_BuildRacingZoneProbe
var zero any; return zero
}
//
// Human-readable sanity check for the caller-supplied cfgId, so a bad id is caught before it
// reaches the client (an unknown cfgId would make InitAetherClientData a no-op and
// silently produce a "nothing happened" result that looks like outcome (b)).
//
func GameRouter_RacingZoneProbe_ValidateRacingCfgId(ctx context.Context, cfgId uint32) any {
// Router implementation for GameRouter_RacingZoneProbe_ValidateRacingCfgId
var zero any; return zero
}
//
// A null complex: exactly one 0x00 byte. The client's
// GameSceneToClientImpl.SyncGameGroundZoneInfo treats a nil zone as "tear down the
// current zone", which is also the only way to undo the probe without relogging.
//
func GameRouter_RacingZoneProbe_BuildRacingZoneClearBody(ctx context.Context, ) []byte {
// Router implementation for GameRouter_RacingZoneProbe_BuildRacingZoneClearBody
return nil
}