/** * @see \Simresults\Data_Reader::getSessions() */ public function getSessions() { // Get data $data = json_decode($this->data, TRUE); // No session data if (!($sessions_data = Helper::arrayGet($data, 'sessions'))) { // Throw exception throw new Exception\Reader('Cannot read the session data'); } // Init sessions array $sessions = array(); // Get extra data for all sessions $extras = array(); foreach (Helper::arrayGet($data, 'extras', array()) as $extras_data) { // Get name $name = Helper::arrayGet($extras_data, 'name'); // Loop all values and add as extra settings foreach ($extras_data as $extra_data_key => $extra_data_value) { // Is name if ($extra_data_key === 'name') { // Skip this continue; } // Add to extras collection $extras[ucfirst($name) . ' ' . $extra_data_key] = $extra_data_value; } } // Gather all sessions foreach ($sessions_data as $session_data) { // Init session $session = new Session(); // Get participants (do for each session to prevent re-used objects // between sessions) $participants = array(); $players_data = Helper::arrayGet($data, 'players', array()); foreach ($players_data as $player_index => $player_data) { // Create driver $driver = new Driver(); $driver->setName(Helper::arrayGet($player_data, 'name')); // Create participant and add driver $participant = new Participant(); $participant->setDrivers(array($driver))->setFinishStatus(Participant::FINISH_NORMAL); // Create vehicle and add to participant $vehicle = new Vehicle(); $vehicle->setName(Helper::arrayGet($player_data, 'car')); $participant->setVehicle($vehicle); // Add participant to collection $participants[] = $participant; } // Practice session by default $type = Session::TYPE_PRACTICE; // Check session name to get type // TODO: Should be checked when full game is released. Also create // tests for it! switch (strtolower($name = Helper::arrayGet($session_data, 'name'))) { case 'qualify session': case 'qualify': $type = Session::TYPE_QUALIFY; break; case 'warmup session': $type = Session::TYPE_WARMUP; break; case 'race session': case 'quick race': case 'race': $type = Session::TYPE_RACE; break; } // Set session values $session->setType($type)->setName($name)->setMaxLaps((int) Helper::arrayGet($session_data, 'lapsCount'))->setMaxMinutes((int) Helper::arrayGet($session_data, 'duration')); // Set game $game = new Game(); $game->setName('Assetto Corsa'); $session->setGame($game); // Set server (we do not know...) $server = new Server(); $server->setName('Unknown or offline'); $session->setServer($server); // Set track $track = new Track(); $track->setVenue(Helper::arrayGet($data, 'track')); $session->setTrack($track); // Get the laps $laps_data = Helper::arrayGet($session_data, 'laps', array()); // No laps data if (!$laps_data) { // Use best laps if possible $laps_data = Helper::arrayGet($session_data, 'bestLaps', array()); } // Process laps foreach ($laps_data as $lap_data) { // Init new lap $lap = new Lap(); // Set participant $lap->setParticipant($lap_participant = $participants[$lap_data['car']]); // Set first driver of participant as lap driver. AC does // not support swapping $lap->setDriver($lap_participant->getDriver()); // Set lap number (+1 because AC is zero based) $lap->setNumber($lap_data['lap'] + 1); // Set lap time in seconds $lap->setTime(round($lap_data['time'] / 1000, 4)); // Set sector times in seconds foreach (Helper::arrayGet($lap_data, 'sectors', array()) as $sector_time) { $lap->addSectorTime(round($sector_time / 1000, 4)); } // Add lap to participant $lap_participant->addLap($lap); } // Session has predefined race result positions if ($race_result = Helper::arrayGet($session_data, 'raceResult')) { // Create new participants order $participants_sorted = array(); foreach ($race_result as $race_position => $race_position_driver) { $participants_sorted[] = $participants[$race_position_driver]; } $participants = $participants_sorted; } elseif ($session->getType() === Session::TYPE_RACE) { // Sort participants by total time $participants = Helper::sortParticipantsByTotalTime($participants); } else { // Sort by best lap $participants = Helper::sortParticipantsByBestLap($participants); } // Fix participant positions foreach ($participants as $key => $part) { $part->setPosition($key + 1); } // Set participants (sorted) $session->setParticipants($participants); // Fix elapsed seconds for all participant laps foreach ($participants as $participant) { $elapsed_time = 0; foreach ($participant->getLaps() as $lap) { // Set elapsed seconds and increment it $lap->setElapsedSeconds($elapsed_time); $elapsed_time += $lap->getTime(); } } // Fix driver positions for laps $session_lasted_laps = $session->getLastedLaps(); // Loop each lap number, beginning from 2, because we can't // figure out positions for lap 1 in AC for ($i = 2; $i <= $session_lasted_laps; $i++) { // Get laps by lap number from session $laps_sorted = $session->getLapsByLapNumberSortedByTime($i); // Sort the laps by elapsed time $laps_sorted = Helper::sortLapsByElapsedTime($laps_sorted); // Loop each lap and fix position data foreach ($laps_sorted as $lap_key => $lap) { // Fix lap position $lap->setPosition($lap_key + 1); } } // Add extras to session $session->setOtherSettings($extras); // Add session to collection $sessions[] = $session; } // Return all sessions return $sessions; }
/** * @see \Simresults\Data_Reader::getSessions() */ public function getSessions() { // Create new session instance $session = new Session(); // Is race session if ($xml_session = $this->dom->getElementsByTagName('Race')->item(0)) { // Set type to race $session->setType(Session::TYPE_RACE); } elseif ($xml_session = $this->dom->getElementsByTagName('Qualify')->item(0)) { // Set type to qualify $session->setType(Session::TYPE_QUALIFY); } elseif ($xml_session = $this->dom->getElementsByTagName('Warmup')->item(0)) { // Set type to warmup $session->setType(Session::TYPE_WARMUP); } elseif ($xml_session = $this->dom->getElementsByTagName('Practice1')->item(0) or $xml_session = $this->dom->getElementsByTagName('Practice2')->item(0) or $xml_session = $this->dom->getElementsByTagName('Practice3')->item(0)) { // Set type to practice $session->setType(Session::TYPE_PRACTICE); } else { // Throw exception throw new Exception\Reader('Cannot read the session data'); } // Using fixed setups? $session->setSetupFixed((bool) $this->dom_value('FixedSetups', $xml_session)); // Get other settings $session->addOtherSetting('MechFailRate', (int) $this->dom_value('MechFailRate'))->addOtherSetting('DamageMult', (int) $this->dom_value('DamageMult'))->addOtherSetting('FuelMult', (int) $this->dom_value('FuelMult'))->addOtherSetting('TireMult', (int) $this->dom_value('TireMult')); // Create session date $date = new \DateTime(date('c', $this->dom_value('DateTime', $xml_session))); // Set UTC timezone by default $date->setTimezone(new \DateTimeZone(self::$default_timezone)); // Set date to session $session->setDate($date); // Max laps is max value if (($max_laps = (int) $this->dom_value('Laps', $xml_session)) === 2147483647) { // Just set it to 0 $max_laps = 0; } // Set max laps and minutes $session->setMaxLaps($max_laps)->setMaxMinutes((int) $this->dom_value('Minutes', $xml_session)); // Set which mod was used $session->setMod($this->dom_value('Mod')); // Set server $session->setServer($this->getServer()); // Set game $session->setGame($this->getGame()); // Set track $session->setTrack($this->getTrack()); // Get participants $participants = $this->getParticipants(); // Find whether we are dealing with position corruption $position_corruption = false; // DNF statusses $dnf_statusses = array(Participant::FINISH_DNF, Participant::FINISH_DQ, Participant::FINISH_NONE); // This is a race session if ($session->getType() === Session::TYPE_RACE) { // Loop each participant to find position corruption foreach ($participants as $part_key => $part) { // There is a previous participant if (isset($participants[$part_key - 1]) and $prev_part = $participants[$part_key - 1]) { // This participant did not finish if (in_array($part->getFinishStatus(), $dnf_statusses)) { // No need to compare to previous, continue to next continue; } // Total time is lower than previous participant and participant // is not lapped, that is not right... if ($part->getTotalTime() < $prev_part->getTotalTime() and $part->getNumberOfLaps() === $prev_part->getNumberOfLaps()) { // We are dealing with corrupted positions $position_corruption = true; } } } // We have position corruption if ($position_corruption) { // Sort participants by total time $participants = Helper::sortParticipantsByTotalTime($participants); } } else { // Loop each participant to find position corruption foreach ($participants as $part_key => $part) { // There is a previous participant if (isset($participants[$part_key - 1]) and $prev_part = $participants[$part_key - 1]) { // This participant has no best lap if (!$part->getBestLap()) { // Just continue to next continue; } // Previous participant has no best lap and this participant // does OR this participant best lap is faster than previous // best lap if (!$prev_part->getBestLap() and $part->getBestLap() or $part->getBestLap()->getTime() < $prev_part->getBestLap()->getTime()) { // We are dealing with corrupted positions $position_corruption = true; } } } // We have position corruption if ($position_corruption) { // Sort by best lap instead of position $participants = Helper::sortParticipantsByBestLap($participants); } } // There is position corruption if ($position_corruption) { // Fix the positions of the participants foreach ($participants as $key => $part) { // Set position $part->setPosition($key + 1); } } // Set participants $session->setParticipants($participants); // Set vehicles allowed $session->setAllowedVehicles($this->getAllowedVehicles()); // Set chats $this->setChats($session); // Set incidents $this->setIncidents($session); // Set penalties $this->setPenalties($session); // Return the session return array($session); }
/** * @see \Simresults\Data_Reader::getSessions() */ public function getSessions() { // Get data $data = json_decode($this->data, TRUE); // Get date preg_match('/\\d{10}/i', $data['Time'], $time_matches); $date = new \DateTime(); $date->setTimestamp($time_matches[0]); $date->setTimezone(new \DateTimeZone(self::$default_timezone)); // Get other settings $other_settings = array(); $known_setting_keys = array('Experience', 'Difficulty', 'FuelUsage', 'MechanicalDamage', 'FlagRules', 'CutRules', 'RaceSeriesFormat', 'WreckerPrevention', 'MandatoryPitstop', 'MandatoryPitstop'); foreach ($known_setting_keys as $setting) { if ($setting_value = Helper::arrayGet($data, $setting)) { $other_settings[$setting] = $setting_value; } } // Init sessions array $sessions = array(); // Gather all sessions foreach ($data['Sessions'] as $session_data) { // Init session $session = new Session(); // Practice session by default $type = Session::TYPE_PRACTICE; // Check session type switch (strtolower($name = $session_data['Type'])) { case 'qualify': $type = Session::TYPE_QUALIFY; break; case 'warmup': $type = Session::TYPE_WARMUP; break; case 'race': $type = Session::TYPE_RACE; break; } // Set session values $session->setType($type)->setDate($date)->setOtherSettings($other_settings); // Set game $game = new Game(); $game->setName('RaceRoom Racing Experience'); $session->setGame($game); // Set server $server = new Server(); $server->setName(Helper::arrayGet($data, 'Server')); $session->setServer($server); // Set track $track = new Track(); $track->setVenue(Helper::arrayGet($data, 'Track')); $session->setTrack($track); // Get participants and their best lap (only lap) $participants = array(); $players_data = Helper::arrayGet($session_data, 'Players', array()); foreach ($players_data as $player_index => $player_data) { // Create driver $driver = new Driver(); $driver->setName(Helper::arrayGet($player_data, 'Username', 'unknown')); // Create participant and add driver $participant = new Participant(); $participant->setDrivers(array($driver))->setPosition(Helper::arrayGet($player_data, 'Position', null))->setFinishStatus(Participant::FINISH_NORMAL); // Create vehicle and add to participant $vehicle = new Vehicle(); $vehicle->setName(Helper::arrayGet($player_data, 'Car')); $participant->setVehicle($vehicle); // Has best lap if (0 < ($best_lap = Helper::arrayGet($player_data, 'BestLapTime'))) { // Init new lap $lap = new Lap(); // Set participant $lap->setParticipant($participant); // Set first driver of participant as lap driver. RR does // not support swapping $lap->setDriver($participant->getDriver()); // Set lap number $lap->setNumber(1); // Set lap time in seconds $lap->setTime(round($best_lap / 1000, 4)); // Add lap to participant $participant->addLap($lap); } // Add participant to collection $participants[] = $participant; } // Add participants to session $session->setParticipants($participants); // Add session to collection $sessions[] = $session; } // Return all sessions return $sessions; }
/** * @see \Simresults\Data_Reader::getSessions() */ public function getSessions() { // Get array data $data = $this->array_data; // Init sessions array $sessions = array(); // Remember last qualify session to make up grid positions $last_qualify_session = null; // Loop each session from data foreach ($data as $session_data) { // Remember which vehicles are parsed $vehicle_names = array(); // Init session $session = new Session(); // Set session type $type = null; switch ($session_data['type']) { case 'qualify': $type = Session::TYPE_QUALIFY; break; case 'practice': $type = Session::TYPE_PRACTICE; break; case 'warmup': $type = Session::TYPE_PRACTICE; break; case 'race': $type = Session::TYPE_RACE; break; } $session->setType($type); // Set session name if (isset($session_data['name'])) { $session->setName($session_data['name']); } // Set max time if (isset($session_data['time'])) { $session->setMaxMinutes($session_data['time']); } // Set max laps if (isset($session_data['laps'])) { $session->setMaxLaps($session_data['laps']); } // Set game $game = new Game(); $game->setName('Assetto Corsa'); $session->setGame($game); // Has track if (isset($session_data['track'])) { $track = new Track(); $track->setVenue($session_data['track']); $session->setTrack($track); } // Has date if (isset($session_data['date'])) { // Set it $session->setDateString($session_data['date']); } // Set server $server = new Server(); $server->setDedicated(true); if (isset($session_data['server'])) { $server->setName($session_data['server']); } else { $server->setName('Unknown'); } $session->setServer($server); // Add allowed vehicles foreach ($session_data['car_list'] as $vehicle_name) { $vehicle = new Vehicle(); $vehicle->setName($vehicle_name); $session->addAllowedVehicle($vehicle); } // Set chats foreach ($session_data['chats'] as $chat_message) { $chat = new Chat(); $chat->setMessage($chat_message); $session->addChat($chat); } // Set participants $participants = array(); foreach ($session_data['participants'] as $part_data) { // No name if (!Helper::arrayGet($part_data, 'name')) { continue; } // Create driver $driver = new Driver(); $driver->setName($part_data['name']); // Total time not greater than 0 if (0 >= ($total_time = Helper::arrayGet($part_data, 'total_time'))) { // Total time is null $total_time = null; } // Create participant and add driver $participant = new Participant(); $participant->setDrivers(array($driver))->setTotalTime($total_time); // Has total time parsed data and should not be a forced DNF if ($total_time and !Helper::arrayGet($part_data, 'force_dnf')) { $participant->setFinishStatus(Participant::FINISH_NORMAL); } else { $participant->setFinishStatus(Participant::FINISH_DNF); } // Remember vehicle instances by vehicle name $vehicles = array(); // Create vehicle and add to participant $vehicle = null; if (isset($part_data['vehicle'])) { // Init vehicle $vehicle = new Vehicle(); $vehicle->setName($part_data['vehicle']); $participant->setVehicle($vehicle); // Remember vehicle instance $vehicles[$part_data['vehicle']] = $vehicle; // Remember vehicle names for this entire session $vehicle_names[$part_data['vehicle']] = 1; } // Has team if (isset($part_data['team'])) { $participant->setTeam($part_data['team']); } // Has guid if (isset($part_data['guid'])) { $driver->setDriverId($part_data['guid']); } // Collect laps foreach (Helper::arrayGet($part_data, 'laps', array()) as $lap_i => $lap_data) { // Init new lap $lap = new Lap(); // Set participant $lap->setParticipant($participant); // Set first driver of participant as lap driver. AC does // not support swapping $lap->setDriver($participant->getDriver()); // Set lap number $lap->setNumber($lap_i + 1); // Set lap times $lap->setTime($lap_data['time']); // No lap vehicle if (!$lap_data['vehicle']) { // Just use participant vehicle if it is available if ($vehicle) { $lap->setVehicle($vehicle); } } elseif (isset($vehicles[$v = $lap_data['vehicle']])) { // Set vehicle instance $lap->setVehicle($vehicles[$v]); } else { // Init vehicle $vehicle = new Vehicle(); $vehicle->setName($lap_data['vehicle']); $lap->setVehicle($vehicle); // Remember vehicle $vehicles[$lap_data['vehicle']] = $vehicle; } // Add lap to participant $participant->addLap($lap); } // No laps and race result if (!$participant->getLaps() and $session->getType() === Session::TYPE_RACE) { // Did not finish $participant->setFinishStatus(Participant::FINISH_DNF); } // Add participant to collection $participants[] = $participant; } // Is race result if ($session->getType() === Session::TYPE_RACE) { // Sort participants by total time $participants = Helper::sortParticipantsByTotalTime($participants); } else { // Sort by best lap $participants = Helper::sortParticipantsByBestLap($participants); } // Fix participant positions foreach ($participants as $key => $part) { $part->setPosition($key + 1); } // Set participants to session $session->setParticipants($participants); // Fix elapsed seconds for all participant laps foreach ($session->getParticipants() as $participant) { $elapsed_time = 0; foreach ($participant->getLaps() as $lap) { // Set elapsed seconds and increment it $lap->setElapsedSeconds($elapsed_time); $elapsed_time += $lap->getTime(); } } // Is qualify if ($session->getType() === Session::TYPE_QUALIFY) { // Remember last qualify session $last_qualify_session = $session; } else { if ($session->getType() === Session::TYPE_RACE and $last_qualify_session) { // Get pairticpants of last qualify session and store names $last_qualify_session_participants = array(); foreach ($last_qualify_session->getParticipants() as $part) { $last_qualify_session_participants[] = $part->getDriver()->getName(); } // Loop this session participants foreach ($participants as $part) { // Found participant in qualify array if (false !== ($key = array_search($part->getDriver()->getName(), $last_qualify_session_participants))) { $part->setGridPosition($key + 1); } } } } // Fix driver positions for laps $session_lasted_laps = $session->getLastedLaps(); // Loop each lap number, beginning from 2, because we can't // figure out positions for lap 1 in AC // TODO: Duplicate code with RACE07 and AC normal reader for ($i = 2; $i <= $session_lasted_laps; $i++) { // Get laps sorted by elapsed time $laps_sorted = $session->getLapsByLapNumberSortedByTime($i); // Sort laps by elapsed time $laps_sorted = Helper::sortLapsByElapsedTime($laps_sorted); // Loop each lap and fix position data foreach ($laps_sorted as $lap_key => $lap) { // Only fix position if lap has a time, this way users of this // library can easier detect whether it's a dummy lap and // decide how to show them if ($lap->getTime() or $lap->getElapsedSeconds()) { $lap->setPosition($lap_key + 1); } } } // Only one vehicle type in this session if (count($vehicle_names) === 1) { // Find any participant without vehicle and fix missing. // This is an easy last resort fix when parsing was bugged // We assume everybody has this vehicle foreach ($session->getParticipants() as $participant) { if (!$participant->getVehicle()) { // Init vehicle $vehicle = new Vehicle(); $vehicle->setName(key($vehicle_names)); $participant->setVehicle($vehicle); } } } // Add session to collection $sessions[] = $session; } // Return all sessions return $sessions; }