def globalFormater(df): packetTypes = df["packetId"] packets = df["packet"] packetIDs = df["pkt_id"] sessionIDs = df["sessionUID"] motionArr = [] sessionArr = [] lapDataArr = [] eventArr = [] participantsArr = [] carSetupsArr = [] carTelemetryArr = [] carStatusArr = [] finalClassificationArr = [] lobbyInfoArr = [] for i in range(len(packetTypes)): packetType = packetTypes[i] packetIDrelation = packetIDs[i] packetSessionRelation = sessionIDs[i] packet = unpackUDPpacket(packets[i]) formatted_info = localFormat(packet, packetType) if packetType == 0: motionArr.append(formatted_info.arr) elif packetType == 1: sessionArr.append(formatted_info.arr) elif packetType == 2: lapDataArr.append(formatted_info.arr) elif packetType == 3: eventArr.append(formatted_info.arr) elif packetType == 4: participantsArr.append(formatted_info.arr) elif packetType == 5: carSetupsArr.append(formatted_info.arr) elif packetType == 6: carTelemetryArr.append(formatted_info.arr) elif packetType == 7: carStatusArr.append(formatted_info.arr) elif packetType == 8: finalClassificationArr.append(formatted_info.arr) elif packetType == 9: lobbyInfoArr.append(formatted_info.arr) motionDF = pd.DataFrame(motionArr) sessionDF = pd.DataFrame(sessionArr) lapDataDF = pd.DataFrame(lapDataArr) eventDF = pd.DataFrame(eventArr) participantsDF = pd.DataFrame(participantsArr) carSetupsDF = pd.DataFrame(carSetupsArr) carTelemetryDF = pd.DataFrame(carTelemetryArr) carStatusDF = pd.DataFrame(carStatusArr) finalClassificationDF = pd.DataFrame(finalClassificationArr) lobbyInfoDF = pd.DataFrame(lobbyInfoArr) motionDF, sessionDF, lapDataDF, eventDF, carSetupsDF, carTelemetryDF, carStatusDF = addColumnNames( motionDF, sessionDF, lapDataDF, eventDF, carSetupsDF, carTelemetryDF, carStatusDF) return motionDF, sessionDF, lapDataDF, eventDF, carSetupsDF, carTelemetryDF, carStatusDF
def accept_packet(self, packet): type_to_function = { 0: "motion", 1: "session", 2: "lap", 3: "event", 4: "participants", 5: "setup", 6: "telemetry", 7: "status", 8: "finalClassification", 9: "lobbyInfo" } self.packet = unpackUDPpacket(packet) self.type = self.packet.header.packetId getattr(live_storage, type_to_function[self.type])(self)
def process_incoming_packets(self, timestamped_packets): """Process incoming packets by recording them into the correct database file. The incoming 'timestamped_packets' is a list of timestamped raw UDP packets. We process them to a variable 'same_session_packets', which is a list of consecutive packets having the same 'sessionUID' field. In this list, each packet is a 11-element tuple that can be inserted into the 'packets' table of the database. The 'same_session_packets' are then passed on to the '_process_same_session_packets' method that writes them into the appropriate database file. """ t1 = time.monotonic() # Invariant to be guaranteed: all packets in 'same_session_packets' have the same 'sessionUID' field. same_session_packets = [] for (timestamp, packet) in timestamped_packets: if len(packet) < ctypes.sizeof(PacketHeader): logging.error( "Dropped bad packet of size {} (too short).".format( len(packet))) continue header = PacketHeader.from_buffer_copy(packet) packet_type_tuple = ( header.packetFormat, header.packetVersion, header.packetId, ) packet_type = HeaderFieldsToPacketType.get(packet_type_tuple) if packet_type is None: logging.error( "Dropped unrecognized packet (format, version, id) = %r.", packet_type_tuple, ) continue if len(packet) != ctypes.sizeof(packet_type): logging.error( "Dropped packet with unexpected size; " "(format, version, id) = %r packet, size = %d, expected %d.", packet_type_tuple, len(packet), ctypes.sizeof(packet_type), ) continue if header.packetId == PacketID.EVENT: # Log Event packets event_packet = unpackUDPpacket(packet) logging.info( "Recording event packet: %s", event_packet.eventStringCode.decode(), ) # NOTE: the sessionUID is not reliable at the start of a session (in F1 2018, need to check for F1 2019). # See: http://forums.codemasters.com/discussion/138130/bug-f1-2018-pc-v1-0-4-udp-telemetry-bad-session-uid-in-first-few-packets-of-a-session # Create an INSERT-able tuple for the data in this packet. # # Note that we convert the sessionUID to a 16-digit hex string here. # SQLite3 can store 64-bit numbers, but only signed ones. # To prevent any issues, we represent the sessionUID as a 16-digit hex string instead. session_packet = SessionPacket( timestamp, header.packetFormat, header.gameMajorVersion, header.gameMinorVersion, header.packetVersion, header.packetId, f"{header.sessionUID:016x}", header.sessionTime, header.frameIdentifier, header.playerCarIndex, packet, ) if (len(same_session_packets) > 0 and same_session_packets[0].sessionUID != session_packet.sessionUID): # Write 'same_session_packets' collected so far to the correct session database, then forget about them. self._process_same_session_packets(same_session_packets) same_session_packets.clear() same_session_packets.append(session_packet) # Write 'same_session_packets' to the correct session database, then forget about them. # The 'same_session_packets.clear()' is not strictly necessary here, because 'same_session_packets' is about to # go out of scope; but we make it explicit for clarity. self._process_same_session_packets(same_session_packets) same_session_packets.clear() t2 = time.monotonic() duration = t2 - t1 logging.info( "Recorded %d packets in %.3f ms.", len(timestamped_packets), duration * 1000.0, )