diff --git a/client/src/main/java/ru/trader/EDLogWatcher.java b/client/src/main/java/ru/trader/EDLogWatcher.java new file mode 100644 index 0000000..a85fcae --- /dev/null +++ b/client/src/main/java/ru/trader/EDLogWatcher.java @@ -0,0 +1,117 @@ +package ru.trader; + +import javafx.application.Platform; +import javafx.beans.value.ChangeListener; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import ru.trader.edlog.EDLogReader; +import ru.trader.edlog.LogWatcher; +import ru.trader.model.MarketModel; +import ru.trader.model.ModelFabric; +import ru.trader.model.ProfileModel; +import ru.trader.model.SystemModel; + +import java.io.File; +import java.io.IOException; + +public class EDLogWatcher { + private final static Logger LOG = LoggerFactory.getLogger(EDLogWatcher.class); + + private final ProfileModel profile; + private final MarketModel world; + private final LogWatcher watcher; + private final Settings.EDLogSettings settings; + + + public EDLogWatcher(ProfileModel profile, MarketModel world) { + this.profile = profile; + this.world = world; + this.watcher = new LogWatcher(new EDLogHandler()); + this.settings = Main.SETTINGS.edlog(); + settings.logDirProperty().addListener(dirListener); + settings.activeProperty().addListener(activeListener); + if (settings.activeProperty().get()){ + run(); + } + } + + public boolean isActive(){ + return watcher.isRun(); + } + + public boolean run(){ + LOG.info("Start ED log watcher, log dir {}", settings.logDirProperty().get()); + try { + File dir = new File(settings.logDirProperty().get()); + if (dir.exists()){ + watcher.start(dir.toPath()); + return true; + } + } catch (IOException e) { + LOG.error("Error on start log watcher", e); + } + return false; + } + + public boolean stop(){ + LOG.info("Stop ED log watcher"); + watcher.stop(); + return true; + } + + public void restart(){ + stop(); + run(); + } + + public void shutdown(){ + LOG.debug("Shutdown ED log watcher"); + stop(); + settings.logDirProperty().removeListener(dirListener); + settings.activeProperty().removeListener(activeListener); + } + + private class EDLogHandler extends EDLogReader { + @Override + protected void changeSystem(String name, double x, double y, double z) { + super.changeSystem(name, x, y, z); + Platform.runLater(() -> { + SystemModel sModel = world.get(name); + boolean found = !ModelFabric.isFake(sModel); + if (!found) { + LOG.warn("Not found system {}", name); + sModel = world.add(name, x, y, z); + } else { + if (Double.compare(sModel.getX(), x) != 0 || Double.compare(sModel.getY(), y) != 0 || Double.compare(sModel.getZ(), z) != 0) { + LOG.warn("Wrong coordinates of system {} ({},{},{}), change to ({},{},{})", sModel.getName(), sModel.getX(), sModel.getY(), sModel.getZ(), x, y, z); + sModel.setPosition(x, y, z); + } + } + profile.setSystem(sModel); + + }); + } + + @Override + protected void undock() { + super.undock(); + Platform.runLater(() -> { + profile.setDocked(false); + profile.setStation(ModelFabric.NONE_STATION); + }); + } + } + + private final ChangeListener dirListener = (ov, o, n) -> { + if (isActive()){ + restart(); + } + }; + + private final ChangeListener activeListener = (ov, o, n) -> { + if (n) run(); + else stop(); + + }; + +} diff --git a/client/src/main/java/ru/trader/ServicesManager.java b/client/src/main/java/ru/trader/ServicesManager.java index 6334476..d615187 100644 --- a/client/src/main/java/ru/trader/ServicesManager.java +++ b/client/src/main/java/ru/trader/ServicesManager.java @@ -10,6 +10,7 @@ import java.io.IOException; public class ServicesManager { private final static Logger LOG = LoggerFactory.getLogger(ServicesManager.class); private static EDCE edce; + private static EDLogWatcher logWatcher; public static EDCE getEdce() { return edce; @@ -18,11 +19,13 @@ public class ServicesManager { public static void runAll(){ runEDCE(); runEMDN(); + runLogWatcher(); } public static void stopAll(){ stopEDCE(); stopEMDN(); + stopLogWatcher(); } private static void runEDCE() { @@ -51,4 +54,16 @@ public class ServicesManager { private static void stopEMDN(){ EMDNUpdater.shutdown(); } + + private static void runLogWatcher(){ + logWatcher = new EDLogWatcher(MainController.getProfile(), MainController.getWorld()); + } + + private static void stopLogWatcher(){ + if (logWatcher != null){ + logWatcher.shutdown(); + } + } + + } diff --git a/client/src/main/java/ru/trader/Settings.java b/client/src/main/java/ru/trader/Settings.java index adf664b..175303b 100644 --- a/client/src/main/java/ru/trader/Settings.java +++ b/client/src/main/java/ru/trader/Settings.java @@ -21,23 +21,21 @@ public class Settings { private final File file; private Profile profile; private final EDCESettings edce; + private final EDLogSettings edlog; private final HelperSettings helper; private final JsonStore jsonStore; private MarketFilter filter = new MarketFilter(); public Settings() { - this.file = null; - profile = new Profile(new Ship()); - edce = new EDCESettings(); - helper = new HelperSettings(); - jsonStore = new JsonStore(); + this(null); } public Settings(File file) { this.file = file; profile = new Profile(new Ship()); edce = new EDCESettings(); + edlog = new EDLogSettings(); helper = new HelperSettings(); jsonStore = new JsonStore(); } @@ -53,6 +51,7 @@ public class Settings { } profile = Profile.readFrom(values, market); edce.readFrom(values); + edlog.readFrom(values); helper.readFrom(values); } @@ -60,6 +59,7 @@ public class Settings { try (OutputStream os = new FileOutputStream(file)) { profile.writeTo(values); edce.writeTo(values); + edlog.writeTo(values); helper.writeTo(values); values.store(os, "settings"); jsonStore.saveFilter(filter); @@ -165,6 +165,10 @@ public class Settings { return edce; } + public EDLogSettings edlog(){ + return edlog; + } + public HelperSettings helper(){ return helper; } @@ -231,6 +235,52 @@ public class Settings { } + public final class EDLogSettings { + private final BooleanProperty active; + private final StringProperty logDir; + + public EDLogSettings() { + active = new SimpleBooleanProperty(); + logDir = new SimpleStringProperty(); + } + + public boolean isActive() { + return active.get(); + } + + public BooleanProperty activeProperty() { + return active; + } + + public void setActive(boolean active) { + this.active.set(active); + } + + public String getLogDir() { + return logDir.get(); + } + + public StringProperty logDirProperty() { + return logDir; + } + + public void setLogDir(String logDir) { + this.logDir.set(logDir); + } + + public void readFrom(Properties values){ + setActive(!"0".equals(values.getProperty("edlog.active", "0"))); + setLogDir(values.getProperty("edlog.dir", "%ProgramFiles%/Frontier/Products/elite-dangerous-64/logs")); + } + + public void writeTo(Properties values){ + values.setProperty("edlog.active", isActive() ? "1":"0"); + values.setProperty("edlog.dir", getLogDir()); + } + + } + + public final class HelperSettings { private final IntegerProperty x; private final IntegerProperty y; diff --git a/client/src/main/java/ru/trader/controllers/SettingsController.java b/client/src/main/java/ru/trader/controllers/SettingsController.java index 6744e7d..491ce4f 100644 --- a/client/src/main/java/ru/trader/controllers/SettingsController.java +++ b/client/src/main/java/ru/trader/controllers/SettingsController.java @@ -6,6 +6,8 @@ import javafx.scene.Parent; import javafx.scene.control.*; import javafx.scene.input.KeyCode; import javafx.scene.input.KeyEvent; +import javafx.stage.DirectoryChooser; +import javafx.stage.FileChooser; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import ru.trader.Main; @@ -16,6 +18,7 @@ import ru.trader.view.support.ViewUtils; import javax.swing.*; import java.awt.event.InputEvent; +import java.io.File; public class SettingsController { private final static Logger LOG = LoggerFactory.getLogger(SettingsController.class); @@ -55,6 +58,11 @@ public class SettingsController { @FXML private NumberField edceInterval; + @FXML + private CheckBox edLogActive; + @FXML + private TextField edLogDir; + @FXML private TextField completeKeyText; private KeyStroke completeKey; @@ -106,6 +114,9 @@ public class SettingsController { edceActive.setSelected(Main.SETTINGS.edce().isActive()); edceInterval.setValue(Main.SETTINGS.edce().getInterval()); + edLogActive.setSelected(Main.SETTINGS.edlog().isActive()); + edLogDir.setText(Main.SETTINGS.edlog().getLogDir()); + completeKey = Main.SETTINGS.helper().getCompleteKey(); completeKeyText.setText(ViewUtils.keyToString(completeKey)); } @@ -152,6 +163,14 @@ public class SettingsController { Main.SETTINGS.edce().setActive(edceActive.isSelected()); Main.SETTINGS.edce().setInterval(edceInterval.getValue().intValue()); + if (edLogActive.isSelected()){ + Main.SETTINGS.edlog().setLogDir(edLogDir.getText()); + Main.SETTINGS.edlog().setActive(edLogActive.isSelected()); + } else { + Main.SETTINGS.edlog().setActive(edLogActive.isSelected()); + Main.SETTINGS.edlog().setLogDir(edLogDir.getText()); + } + Main.SETTINGS.helper().setCompleteKey(completeKey); } @@ -163,4 +182,15 @@ public class SettingsController { dlg.showAndWait(); } + @FXML + private void selectLogDir(){ + DirectoryChooser dirChooser = new DirectoryChooser(); + File dir = new File(edLogDir.getText()); + if (!dir.exists()) dir = new File("."); + dirChooser.setInitialDirectory(dir); + File file = dirChooser.showDialog(null); + if (file !=null) { + edLogDir.setText(file.getAbsolutePath()); + } + } } diff --git a/client/src/main/resources/lang/locale_en_US.properties b/client/src/main/resources/lang/locale_en_US.properties index 0945675..63d8611 100644 --- a/client/src/main/resources/lang/locale_en_US.properties +++ b/client/src/main/resources/lang/locale_en_US.properties @@ -200,6 +200,8 @@ settings.search.times.recharge=Recharging FSD time: settings.search.times.orbital=Orbital flight time: settings.hotkeys=Hotkeys settings.hotkeys.complete=Target complete: +settings.edlog.on=Active +settings.edlog.dir=Elite Dangerous logs folder: # sEditor.fxml sEditor.title=Star systems editor diff --git a/client/src/main/resources/lang/locale_ru_RU.properties b/client/src/main/resources/lang/locale_ru_RU.properties index b11bd4d..0b2ffbe 100644 --- a/client/src/main/resources/lang/locale_ru_RU.properties +++ b/client/src/main/resources/lang/locale_ru_RU.properties @@ -199,6 +199,8 @@ settings.search.times.recharge=\u0412\u0440\u0435\u043C\u044F \u043F\u0435\u0440 settings.search.times.orbital=\u0412\u0440\u0435\u043C\u044F \u043E\u0440\u0431\u0438\u0442\u0430\u043B\u044C\u043D\u043E\u0433\u043E \u043F\u043E\u043B\u0435\u0442\u0430: settings.hotkeys=\u0413\u043E\u0440\u044F\u0447\u0438\u0435 \u043A\u043B\u0430\u0432\u0438\u0448\u0438 settings.hotkeys.complete=\u0422\u043E\u0447\u043A\u0430 \u043C\u0430\u0440\u0448\u0440\u0443\u0442\u0430 \u0434\u043E\u0441\u0442\u0438\u0433\u043D\u0443\u0442\u0430: +settings.edlog.on=\u0412\u043A\u043B\u044E\u0447\u0438\u0442\u044C +settings.edlog.dir=\u041F\u0443\u0442\u044C \u043A \u043F\u0430\u043F\u043A\u0435 \u0441 \u043B\u043E\u0433\u0430\u043C\u0438 Elite Dangerous: # sEditor.fxml sEditor.title=\u0420\u0435\u0434\u0430\u043A\u0442\u043E\u0440 \u0437\u0432\u0435\u0437\u0434\u043D\u044B\u0445 \u0441\u0438\u0441\u0442\u0435\u043C diff --git a/client/src/main/resources/view/settings.fxml b/client/src/main/resources/view/settings.fxml index 0dec15f..10bea93 100644 --- a/client/src/main/resources/view/settings.fxml +++ b/client/src/main/resources/view/settings.fxml @@ -1,6 +1,7 @@ + @@ -48,6 +49,15 @@ diff --git a/utils/src/main/java/ru/trader/edlog/EDLogReader.java b/utils/src/main/java/ru/trader/edlog/EDLogReader.java new file mode 100644 index 0000000..e50b500 --- /dev/null +++ b/utils/src/main/java/ru/trader/edlog/EDLogReader.java @@ -0,0 +1,50 @@ +package ru.trader.edlog; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +public class EDLogReader extends LogReader { + private final static Logger LOG = LoggerFactory.getLogger(EDLogReader.class); + private final static String LOG_FILE_PATTERN = ".+NetLog\\.log$"; + private final static Pattern SYSTEM_CHANGE_REGEXP = Pattern.compile("System (.+) pos (-?[\\d\\.]+),(-?[\\d\\.]+),(-?[\\d\\.]+)"); + private final static Pattern UNDOCK_REGEXP = Pattern.compile("undocked"); + + public EDLogReader() { + super(LOG_FILE_PATTERN); + } + + @Override + protected void outLine(String line) { + super.outLine(line); + Matcher matcher = SYSTEM_CHANGE_REGEXP.matcher(line); + if (matcher.find()){ + parseSystem(matcher); + return; + } + matcher = UNDOCK_REGEXP.matcher(line); + if (matcher.find()){ + undock(); + } + } + + private void parseSystem(Matcher matcher) { + String name = matcher.group(1); + double x = Double.valueOf(matcher.group(2)); + double y = Double.valueOf(matcher.group(3)); + double z = Double.valueOf(matcher.group(4)); + changeSystem(name, x, y, z); + } + + protected void changeSystem(String name, double x, double y, double z) { + LOG.debug("System change to {}, coordinates: {},{},{}", name, x, y, z); + } + + protected void undock() { + LOG.debug("Undocked"); + } + + +}