package gameserver import ( "log" "time" "ananta-ps/pkg/protocol" ) type RacingSession struct { TaskID uint32 VehicleID uint64 CurrentGate uint32 TotalGates uint32 StartTime time.Time IsActive bool } func (s *Server) handleAskAcceptAndSetCurrentTask(sess *Session, pkt *protocol.RpcPacket) error { r := protocol.NewUxReader(pkt.Body) taskId, _ := r.U32() log.Printf("[RACING] AskAcceptAndSetCurrentTask taskId=%d", taskId) if err := sess.ReturnEmptyOk(pkt.InvokeID, pkt.MethodID); err != nil { return err } if taskId == 60000147 { // Ace Driver - City Night Race sess.racing = &RacingSession{ TaskID: taskId, CurrentGate: 0, TotalGates: 12, StartTime: time.Now(), IsActive: true, } log.Printf("[RACING] Ignited City Night Race (12 checkpoint gates) for player %d", sess.pid) // SyncRaceCountdown (3, 2, 1, GO) wRace := protocol.NewUxWriter() wRace.U32(taskId).U32(12).U32(3) // 3 seconds countdown return sess.NotifyData(protocol.MethodGetMethodIDDefault("SyncRaceCountdown", 68582890), wRace.Bytes()) } return nil } func (s *Server) handleAskSetRacingCompetitionVehicle(sess *Session, pkt *protocol.RpcPacket) error { r := protocol.NewUxReader(pkt.Body) vehUnitId, _ := r.U64() log.Printf("[RACING] Bound competition vehicle %d", vehUnitId) if sess.racing != nil { sess.racing.VehicleID = vehUnitId } return sess.ReturnEmptyOk(pkt.InvokeID, pkt.MethodID) } func (s *Server) handleAskSetTaskCounterValue(sess *Session, pkt *protocol.RpcPacket) error { r := protocol.NewUxReader(pkt.Body) taskId, _ := r.U32() counterVal, _ := r.U32() log.Printf("[RACING] Checkpoint passed task=%d gate=%d", taskId, counterVal) if sess.racing != nil { sess.racing.CurrentGate = counterVal if counterVal >= sess.racing.TotalGates { duration := time.Since(sess.racing.StartTime).Seconds() log.Printf("[RACING] Race finished in %.2f seconds!", duration) sess.racing.IsActive = false // SyncRaceFinish wFin := protocol.NewUxWriter() wFin.U32(taskId).F32(float32(duration)).Bool(true) _ = sess.NotifyData(protocol.MethodGetMethodIDDefault("SyncRaceFinish", 68582891), wFin.Bytes()) } } return sess.ReturnEmptyOk(pkt.InvokeID, pkt.MethodID) }