package org.openbakery.racecontrol.plugin.tracker; import java.io.IOException; import java.text.SimpleDateFormat; import java.util.Arrays; import java.util.HashMap; import java.util.List; import org.openbakery.jinsim.Car; import org.openbakery.jinsim.Tiny; import org.openbakery.jinsim.Track; import org.openbakery.jinsim.request.MessageRequest; import org.openbakery.jinsim.response.*; import org.openbakery.jinsim.types.InSimTime; import org.openbakery.racecontrol.JInSimClient; import org.openbakery.racecontrol.RaceControl; import org.openbakery.racecontrol.data.Driver; import org.openbakery.racecontrol.data.Lap; import org.openbakery.racecontrol.event.LapEvent; import org.openbakery.racecontrol.event.LapEventListener; import org.openbakery.racecontrol.gui.Button; import org.openbakery.racecontrol.gui.Panel; import org.openbakery.racecontrol.persistence.PersistenceException; import org.openbakery.racecontrol.persistence.QueryHelper; import org.openbakery.racecontrol.persistence.bean.Profile; import org.openbakery.racecontrol.plugin.Plugin; import org.openbakery.racecontrol.plugin.tracker.data.TrackerSettings; import org.openbakery.racecontrol.plugin.tracker.web.TrackerPage; import org.openbakery.racecontrol.plugin.tracker.web.TrackerSettingsPage; import org.openbakery.racecontrol.service.SettingsService; import org.openbakery.racecontrol.web.bean.MenuItem; import org.openbakery.racecontrol.web.bean.Visibility; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; public class Tracker implements Plugin, LapEventListener { private static Logger log = LoggerFactory.getLogger(Tracker.class); private HashMap<Integer, Panel> trackerPanel; SimpleDateFormat dateFormat = new SimpleDateFormat("m:ss.SSS"); @Autowired private TrackerService trackerService; private RaceControl raceControl; @Autowired private SettingsService settingsService; @Autowired private JInSimClient insimClient; private Lap fastestLap; public Tracker() { trackerPanel = new HashMap<Integer, Panel>(); } @Autowired void setRaceControl(RaceControl raceControl) { this.raceControl = raceControl; raceControl.addLapEventListener(this); } public String getHelp() { return "Provided commands by the '" + getName() + "' plugin are: tracker display the tracker"; } public String getName() { return "Tracker"; } public void packetReceived(InSimResponse response) { if (response instanceof NewPlayerResponse) { NewPlayerResponse newPlayerResponse = (NewPlayerResponse)response; try { showPanel(newPlayerResponse.getConnectionId()); } catch (IOException e) { log.error(e.getMessage(), e); } } else if (response instanceof ConnectionLeaveResponse) { ConnectionLeaveResponse connectionLeaveResponse = (ConnectionLeaveResponse)response; hidePanel(connectionLeaveResponse.getConnectionId()); } else if (response instanceof PitLaneResponse) { Driver driver = raceControl.getRace().getDriverByPlayerId(((PitLaneResponse) response).getPlayerId()); updatePanel(driver.getConnectionId(), null); } } private void hidePanel(Integer connectionId) { log.debug("hidePanel for {}", connectionId); Panel panel = trackerPanel.get(connectionId); if (panel != null) { trackerPanel.remove(connectionId); panel.destroy(); } } private void showPanel(Integer connectionId) throws IOException { // destroy the panel if one exists for this connectionID hidePanel(connectionId); log.debug("showPanel for {}", connectionId); Panel panel = new Panel(135, 4); panel.setColumns(25); panel.add(new Button(connectionId, ""), 0); panel.add(new Button(connectionId, ""), 0); Button infoButton = new Button(connectionId, ""); infoButton.setVisible(false); panel.add(infoButton, 0); updatePanel(connectionId, null); panel.setVisible(true); trackerPanel.put(connectionId, panel); } public void updatePanel(Integer connectionId, Lap currentLap) { log.debug("update panel for {}", connectionId); log.debug("update panel with lap {}", currentLap); Panel panel = trackerPanel.get(connectionId); if (panel == null) { log.debug("Panel not found for connectionId {}, so do nothing", connectionId); return; } Driver driver = raceControl.getRace().getDriver(connectionId); if (driver == null) { log.debug("Driver not found for connectionId {}, so do nothing", connectionId); return; } Lap lap = getFastestLapForDriver(driver); Button numberLapsButton = panel.get(0, 0); //int numberLaps = getNumberLapsOnServerForDriver(driver); int lapsLeft = settingsService.getTrackerSettings().getNumberLaps() - lap.getAttempt(); if (lap.getPosition() > 0) { numberLapsButton.setText("Laps left: " + lapsLeft + " - Pos: " + lap.getPosition()); } else { numberLapsButton.setText("Laps left: " + lapsLeft); } Button lapTimeButton = panel.get(0, 1); lapTimeButton.setText("Fastest Lap: " + InSimTime.toString(lap.getTime())); try { Button infoButton = panel.get(0, 2); if (currentLap != null) { StringBuilder gapString = new StringBuilder(); int i = 0; while(lap.getSplit(i) > 0) { if (i > 0) { gapString.append(" / "); } int gap = fastestLap.getSplit(i) - lap.getSplit(i); gapString.append(InSimTime.toString(gap, true)); i++; } if (lap.isFinished()) { gapString.append(" : "); int gap = fastestLap.getTime() - lap.getTime(); gapString.append(InSimTime.toString(gap, true)); } if (gapString.length() > 0) { infoButton.setText(gapString.toString()); } infoButton.setVisible(gapString.length() > 0); } else { infoButton.setVisible(false); } } catch (IOException ex) { log.error(ex.getMessage(), ex); } } public List<MenuItem> getMenuItems() { return Arrays.asList(new MenuItem("Tracker", TrackerPage.class, -1), new MenuItem("Tracker Settings", TrackerSettingsPage.class, Visibility.AUTHENTICATED, 2)); } @Override public void lapFinished(LapEvent event) { log.debug("lapFinished"); updatePanel(event.getDriver().getConnectionId(), event.getLap()); } private Lap getFastestLapForDriver(Driver driver) { TrackerSettings settings = settingsService.getTrackerSettings(); try { List<Lap>lapList = trackerService.getFastestLap(settings.getTrack(), settings.getCars(), settings.getNumberLaps()); log.debug("lapList {}", lapList); if (lapList.size() > 0) { log.debug("==> set fastest lap: {}", fastestLap); fastestLap = lapList.get(0); } log.debug("==== DRIVER {}", driver); for (Lap lap : lapList) { log.debug("lap.driver {}", lap.getDriver()); if (lap.getDriver().getName().equals(driver.getName())) { log.debug("getFastestLapForDriver found: {}", lap); return lap; } } } catch (PersistenceException e) { log.error(e.getMessage(), e); } return new Lap(); } @Override public void lapSplit(LapEvent event) { log.debug("lapSplit"); updatePanel(event.getDriver().getConnectionId(), event.getLap()); } }