diff --git a/client/src/main/java/ru/trader/EDLogWatcher.java b/client/src/main/java/ru/trader/EDLogWatcher.java
index a85fcae..9d5d386 100644
--- a/client/src/main/java/ru/trader/EDLogWatcher.java
+++ b/client/src/main/java/ru/trader/EDLogWatcher.java
@@ -4,12 +4,18 @@ import javafx.application.Platform;
import javafx.beans.value.ChangeListener;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
+import ru.trader.core.FACTION;
+import ru.trader.core.GOVERNMENT;
+import ru.trader.core.Place;
+import ru.trader.core.Vendor;
+import ru.trader.edlog.EDJournalReader;
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 ru.trader.edlog.entities.DockedEvent;
+import ru.trader.edlog.entities.FSDJumpEvent;
+import ru.trader.model.*;
+import ru.trader.store.imp.SimpleImporter;
+import ru.trader.store.imp.entities.StarSystemData;
import java.io.File;
import java.io.IOException;
@@ -71,25 +77,34 @@ public class EDLogWatcher {
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);
+ private class EDLogHandler extends EDJournalReader {
+ private final SimpleImporter importer;
- });
+ private EDLogHandler() {
+ importer = new SimpleImporter();
+ }
+
+ @Override
+ protected void docked(DockedEvent dockedEvent) {
+ super.docked(dockedEvent);
+ Vendor vendor = importer.importStation(World.getMarket(), dockedEvent.asImportData());
+ if (vendor != null){
+ StationModel sModel = world.getModeler().get(vendor);
+ Platform.runLater(() -> {
+ profile.setStation(sModel);
+ profile.setDocked(true);
+ });
+ }
+ }
+
+ @Override
+ protected void jump(FSDJumpEvent jumpEvent) {
+ super.jump(jumpEvent);
+ Place place = importer.importSystem(World.getMarket(), jumpEvent.asImportData());
+ if (place != null){
+ SystemModel sModel = world.getModeler().get(place);
+ Platform.runLater(() -> profile.setSystem(sModel));
+ }
}
@Override
diff --git a/core/src/main/java/ru/trader/core/FACTION.java b/core/src/main/java/ru/trader/core/FACTION.java
index 1a2adfc..f3b2c05 100644
--- a/core/src/main/java/ru/trader/core/FACTION.java
+++ b/core/src/main/java/ru/trader/core/FACTION.java
@@ -1,5 +1,5 @@
package ru.trader.core;
public enum FACTION {
- FEDERATION, EMPIRE, ALLIANCE, INDEPENDENT, NONE
+ FEDERATION, EMPIRE, ALLIANCE, INDEPENDENT, NONE, PIRATE
}
diff --git a/core/src/main/java/ru/trader/core/GOVERNMENT.java b/core/src/main/java/ru/trader/core/GOVERNMENT.java
index 22cecaa..f1346ff 100644
--- a/core/src/main/java/ru/trader/core/GOVERNMENT.java
+++ b/core/src/main/java/ru/trader/core/GOVERNMENT.java
@@ -3,5 +3,5 @@ package ru.trader.core;
public enum GOVERNMENT {
ANARCHY, COLONY, COMMUNISM, CONFEDERACY, COOPERATIVE, CORPORATE,
DEMOCRACY, DICTATORSHIP, FEUDAL, IMPERIAL, PATRONAGE, PRISON_COLONY,
- THEOCRACY, NONE
+ THEOCRACY, NONE, ENGINEER, WORKSHOP
}
diff --git a/core/src/main/resources/store/trader.xsd b/core/src/main/resources/store/trader.xsd
index d198a6d..94c614f 100644
--- a/core/src/main/resources/store/trader.xsd
+++ b/core/src/main/resources/store/trader.xsd
@@ -124,6 +124,7 @@
+
@@ -143,6 +144,8 @@
+
+
diff --git a/utils/src/main/java/ru/trader/edlog/EDConverter.java b/utils/src/main/java/ru/trader/edlog/EDConverter.java
new file mode 100644
index 0000000..5cc75aa
--- /dev/null
+++ b/utils/src/main/java/ru/trader/edlog/EDConverter.java
@@ -0,0 +1,144 @@
+package ru.trader.edlog;
+
+import org.jetbrains.annotations.Nullable;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import ru.trader.core.*;
+
+public class EDConverter {
+ private final static Logger LOG = LoggerFactory.getLogger(EDConverter.class);
+
+
+ @Nullable
+ public static STATION_TYPE asStationType(String type){
+ if (type == null) return null;
+ switch (type){
+// case "": return STATION_TYPE.STARPORT;
+ case "Coriolis": return STATION_TYPE.CORIOLIS_STARPORT;
+ case "Bernal": return STATION_TYPE.OCELLUS_STARPORT;
+ case "Orbis": return STATION_TYPE.ORBIS_STARPORT;
+ case "Outpost": return STATION_TYPE.OUTPOST;
+/* case "": return STATION_TYPE.CIVILIAN_OUTPOST;
+ case "": return STATION_TYPE.COMMERCIAL_OUTPOST;
+ case "": return STATION_TYPE.INDUSTRIAL_OUTPOST;
+ case "": return STATION_TYPE.MILITARY_OUTPOST;
+ case "": return STATION_TYPE.MINING_OUTPOST;
+ case "": return STATION_TYPE.SCIENTIFIC_OUTPOST;
+ case "": return STATION_TYPE.UNSANCTIONED_OUTPOST;
+ case "": return STATION_TYPE.PLANETARY_PORT;
+ case "": return STATION_TYPE.PLANETARY_OUTPOST;*/
+
+ }
+ LOG.warn("Unknown station type: {}", type);
+ return null;
+ }
+
+ @Nullable
+ public static GOVERNMENT asGovernment(String government){
+ if (government == null) return null;
+ switch (government){
+ case "$government_Anarchy;": return GOVERNMENT.ANARCHY;
+ case "$government_Colony;": return GOVERNMENT.COLONY;
+ case "$government_Communism;": return GOVERNMENT.COMMUNISM;
+ case "$government_Confederacy;": return GOVERNMENT.CONFEDERACY;
+ case "$government_Cooperative;": return GOVERNMENT.COOPERATIVE;
+ case "$government_Corporate;": return GOVERNMENT.CORPORATE;
+ case "$government_Democracy;": return GOVERNMENT.DEMOCRACY;
+ case "$government_Dictatorship;": return GOVERNMENT.DICTATORSHIP;
+ case "$government_Feudal;": return GOVERNMENT.FEUDAL;
+ case "$government_Imperial;": return GOVERNMENT.IMPERIAL;
+ case "$government_Patronage;": return GOVERNMENT.PATRONAGE;
+ case "$government_PrisonColony;": return GOVERNMENT.PRISON_COLONY;
+ case "$government_Theocracy;": return GOVERNMENT.THEOCRACY;
+ case "$government_engineer;": return GOVERNMENT.ENGINEER;
+ case "$government_Workshop;": return GOVERNMENT.WORKSHOP;
+ case "$government_None;": return GOVERNMENT.NONE;
+ }
+ LOG.warn("Unknown government type: {}", government);
+ return null;
+ }
+
+ @Nullable
+ public static FACTION asAllegiance(String allegiance){
+ if (allegiance == null) return null;
+ switch (allegiance){
+ case "$faction_Federation;": return FACTION.FEDERATION;
+ case "$faction_Empire;": return FACTION.EMPIRE;
+ case "$faction_Alliance;": return FACTION.ALLIANCE;
+ case "$faction_Independent;": return FACTION.INDEPENDENT;
+ case "$faction_Pirate;": return FACTION.PIRATE;
+ case "$faction_none;": return FACTION.NONE;
+ case "Federation": return FACTION.FEDERATION;
+ case "Empire": return FACTION.EMPIRE;
+ case "Alliance": return FACTION.ALLIANCE;
+ case "Independent": return FACTION.INDEPENDENT;
+ case "Pirate": return FACTION.PIRATE;
+ case "": return FACTION.NONE;
+ }
+
+ LOG.warn("Unknown allegiance type: {}", allegiance);
+ return null;
+ }
+
+ @Nullable
+ public static ECONOMIC_TYPE asEconomic(String economic){
+ if (economic == null) return null;
+ switch (economic){
+ case "$economy_Agri;": return ECONOMIC_TYPE.AGRICULTURE;
+ case "$economy_Extraction;": return ECONOMIC_TYPE.EXTRACTION;
+ case "$economy_HighTech;": return ECONOMIC_TYPE.HIGH_TECH;
+ case "$economy_Industrial;": return ECONOMIC_TYPE.INDUSTRIAL;
+ case "$economy_Military;": return ECONOMIC_TYPE.MILITARY;
+ case "$economy_Refinery;": return ECONOMIC_TYPE.REFINERY;
+ case "$economy_Service;": return ECONOMIC_TYPE.SERVICE;
+ case "$economy_Terraforming;": return ECONOMIC_TYPE.TERRAFORMING;
+ case "$economy_Tourism;": return ECONOMIC_TYPE.TOURISM;
+ case "$economy_Colony;": return ECONOMIC_TYPE.COLONY;
+ case "$economy_None;": return ECONOMIC_TYPE.NONE;
+ }
+
+ LOG.warn("Unknown economic type: {}", economic);
+ return null;
+ }
+
+
+ @Nullable
+ public static POWER_STATE asPowerState(String state) {
+ if (state == null) return null;
+ switch (state) {
+ case "Controlled": return POWER_STATE.CONTROL;
+ case "Exploited": return POWER_STATE.EXPLOITED;
+ case "Prepared": return POWER_STATE.EXPANSION;
+ case "": return POWER_STATE.NONE;
+ case "Contested": return POWER_STATE.CONTESTED;
+ case "HomeSystem": return POWER_STATE.HEADQUARTERS;
+ case "InPrepareRadius": return POWER_STATE.BLOCKED;
+ case "Turmoil": return POWER_STATE.TURMOIL;
+ }
+
+ LOG.warn("Unknown power state: {}", state);
+ return null;
+ }
+
+ @Nullable
+ public static POWER asPower(String power) {
+ if (power == null) return null;
+ switch (power) {
+ case "Aisling Duval": return POWER.DUVAL;
+ case "Archon Delaine": return POWER.DELAINE;
+ case "Arissa Lavigny-Duval": return POWER.LAVIGNY_DUVAL;
+ case "Denton Patreus": return POWER.PATREUS;
+ case "Edmund Mahon": return POWER.MAHON;
+ case "Felicia Winters": return POWER.WINTERS;
+ case "Li Yong-Rui": return POWER.YONG_RUI;
+ case "Pranav Antal": return POWER.ANTAL;
+ case "Zachary Hudson": return POWER.HUDSON;
+ case "Zemina Torval": return POWER.TORVAL;
+ case "Yuri Grom": return POWER.GROM;
+ case "": return POWER.NONE;
+ }
+
+ LOG.warn("Unknown power: {}", power);
+ return null;
+ }
+}
diff --git a/utils/src/main/java/ru/trader/edlog/EDJournalReader.java b/utils/src/main/java/ru/trader/edlog/EDJournalReader.java
new file mode 100644
index 0000000..6b1165d
--- /dev/null
+++ b/utils/src/main/java/ru/trader/edlog/EDJournalReader.java
@@ -0,0 +1,63 @@
+package ru.trader.edlog;
+
+import com.fasterxml.jackson.databind.JsonNode;
+import com.fasterxml.jackson.databind.ObjectMapper;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import ru.trader.edlog.entities.DockedEvent;
+import ru.trader.edlog.entities.FSDJumpEvent;
+
+import java.io.IOException;
+
+public class EDJournalReader extends LogReader {
+ private final static Logger LOG = LoggerFactory.getLogger(EDJournalReader.class);
+ private final static String LOG_FILE_PATTERN = ".+Journal\\..+\\.log$";
+ private final static String EVENT_ATTR = "event";
+ private final ObjectMapper mapper;
+
+ public EDJournalReader() {
+ super(LOG_FILE_PATTERN);
+ this.mapper = new ObjectMapper();
+ }
+
+ @Override
+ protected void outLine(String line) {
+ super.outLine(line);
+ try {
+ JsonNode eventNode = mapper.readTree(line);
+ if (!eventNode.has(EVENT_ATTR)){
+ LOG.warn("Attribute {} not found, skip", EVENT_ATTR);
+ return;
+ }
+ String event = eventNode.get(EVENT_ATTR).asText();
+ switch (event){
+ case "Docked": docked(new DockedEvent(eventNode));
+ break;
+ case "FSDJump": jump(new FSDJumpEvent(eventNode));
+ break;
+ case "Undocked": undock();
+ break;
+ }
+
+ } catch (IOException e) {
+ LOG.error("Error on parse journal line: {}", line);
+ LOG.error("",e);
+ }
+
+
+ }
+
+ protected void docked(DockedEvent dockedEvent) {
+ LOG.debug("Docked to station: {} / {}", dockedEvent.getStarSystem(), dockedEvent.getStation());
+ }
+
+ protected void jump(FSDJumpEvent jumpEvent) {
+ LOG.debug("Jump to system {}, coordinates: {}, {}, {}", jumpEvent.getStarSystem(), jumpEvent.getX(), jumpEvent.getY(), jumpEvent.getZ());
+ }
+
+ protected void undock() {
+ LOG.debug("Undocked");
+ }
+
+
+}
diff --git a/utils/src/main/java/ru/trader/edlog/entities/DockedEvent.java b/utils/src/main/java/ru/trader/edlog/entities/DockedEvent.java
new file mode 100644
index 0000000..895bb4f
--- /dev/null
+++ b/utils/src/main/java/ru/trader/edlog/entities/DockedEvent.java
@@ -0,0 +1,115 @@
+package ru.trader.edlog.entities;
+
+import com.fasterxml.jackson.databind.JsonNode;
+import org.jetbrains.annotations.Nullable;
+import ru.trader.core.ECONOMIC_TYPE;
+import ru.trader.core.FACTION;
+import ru.trader.core.GOVERNMENT;
+import ru.trader.core.STATION_TYPE;
+import ru.trader.edlog.EDConverter;
+import ru.trader.store.imp.entities.StarSystemData;
+import ru.trader.store.imp.entities.StarSystemDataBase;
+import ru.trader.store.imp.entities.StationData;
+import ru.trader.store.imp.entities.StationDataBase;
+
+import java.util.Collection;
+import java.util.Collections;
+
+public class DockedEvent{
+ private final JsonNode node;
+
+ public DockedEvent(JsonNode node) {
+ this.node = node;
+ }
+
+ public String getStation(){
+ JsonNode n = node.get("StationName");
+ if (n == null){
+ throw new IllegalArgumentException("Event Docked don't have StationName attribute");
+ }
+ return n.asText();
+ }
+
+ public String getStarSystem(){
+ JsonNode n = node.get("StarSystem");
+ if (n == null){
+ throw new IllegalArgumentException("Event Docked don't have StarSystem attribute");
+ }
+ return n.asText();
+ }
+
+ @Nullable
+ public STATION_TYPE getStationType(){
+ JsonNode n = node.get("StationType");
+ return n != null ? EDConverter.asStationType(n.asText()) : null;
+ }
+
+ @Nullable
+ public GOVERNMENT getGovernment(){
+ JsonNode n = node.get("StationGovernment");
+ return n != null ? EDConverter.asGovernment(n.asText()) : null;
+ }
+
+ @Nullable
+ public FACTION getAllegiance(){
+ JsonNode n = node.get("StationAllegiance");
+ return n != null ? EDConverter.asAllegiance(n.asText()) : null;
+ }
+
+ @Nullable
+ public ECONOMIC_TYPE getEconomic(){
+ JsonNode n = node.get("StationEconomy");
+ return n != null ? EDConverter.asEconomic(n.asText()) : null;
+ }
+
+ public StarSystemData asImportData(){
+ final Collection stationData = Collections.singleton(asStationData());
+ return new StarSystemDataBase() {
+
+ @Override
+ public String getName() {
+ return DockedEvent.this.getStarSystem();
+ }
+
+ @Nullable
+ @Override
+ public Collection getStations() {
+ return stationData;
+ }
+ };
+ }
+
+ private StationData asStationData(){
+ return new StationDataBase(){
+
+ @Override
+ public String getName() {
+ return DockedEvent.this.getStation();
+ }
+
+ @Nullable
+ @Override
+ public STATION_TYPE getType() {
+ return DockedEvent.this.getStationType();
+ }
+
+ @Nullable
+ @Override
+ public FACTION getFaction() {
+ return DockedEvent.this.getAllegiance();
+ }
+
+ @Nullable
+ @Override
+ public GOVERNMENT getGovernment() {
+ return DockedEvent.this.getGovernment();
+ }
+
+ @Nullable
+ @Override
+ public ECONOMIC_TYPE getEconomic() {
+ return DockedEvent.this.getEconomic();
+ }
+ };
+ }
+}
diff --git a/utils/src/main/java/ru/trader/edlog/entities/FSDJumpEvent.java b/utils/src/main/java/ru/trader/edlog/entities/FSDJumpEvent.java
new file mode 100644
index 0000000..f7db450
--- /dev/null
+++ b/utils/src/main/java/ru/trader/edlog/entities/FSDJumpEvent.java
@@ -0,0 +1,133 @@
+package ru.trader.edlog.entities;
+
+import com.fasterxml.jackson.databind.JsonNode;
+import org.jetbrains.annotations.Nullable;
+import ru.trader.core.*;
+import ru.trader.edlog.EDConverter;
+import ru.trader.store.imp.entities.StarSystemData;
+import ru.trader.store.imp.entities.StarSystemDataBase;
+
+public class FSDJumpEvent {
+ private final JsonNode node;
+
+ public FSDJumpEvent(JsonNode node) {
+ this.node = node;
+ }
+
+ public String getStarSystem(){
+ JsonNode n = node.get("StarSystem");
+ if (n == null){
+ throw new IllegalArgumentException("Event FSDJump don't have StarSystem attribute");
+ }
+ return n.asText();
+ }
+
+ public double getX(){
+ JsonNode n = node.get("StarPos");
+ if (n == null || !n.isArray() || n.size() < 3){
+ throw new IllegalArgumentException("Event FSDJump don't have correct StarPos attribute");
+ }
+ return n.get(0).asDouble();
+ }
+
+ public double getY(){
+ JsonNode n = node.get("StarPos");
+ if (n == null || !n.isArray() || n.size() < 3){
+ throw new IllegalArgumentException("Event FSDJump don't have correct StarPos attribute");
+ }
+ return n.get(1).asDouble();
+ }
+
+ public double getZ(){
+ JsonNode n = node.get("StarPos");
+ if (n == null || !n.isArray() || n.size() < 3){
+ throw new IllegalArgumentException("Event FSDJump don't have correct StarPos attribute");
+ }
+ return n.get(2).asDouble();
+ }
+
+
+ @Nullable
+ public GOVERNMENT getGovernment(){
+ JsonNode n = node.get("SystemGovernment");
+ return n != null ? EDConverter.asGovernment(n.asText()) : null;
+ }
+
+ @Nullable
+ public FACTION getAllegiance(){
+ JsonNode n = node.get("SystemAllegiance");
+ return n != null ? EDConverter.asAllegiance(n.asText()) : null;
+ }
+
+ @Nullable
+ public ECONOMIC_TYPE getEconomic(){
+ JsonNode n = node.get("SystemEconomy");
+ return n != null ? EDConverter.asEconomic(n.asText()) : null;
+ }
+
+ @Nullable
+ public POWER getPower(){
+ JsonNode n = node.get("Powers");
+ if (n == null) return null;
+ if (n.isArray()){
+ n = n.get(0);
+ }
+ return n != null ? EDConverter.asPower(n.asText()) : null;
+ }
+
+ @Nullable
+ public POWER_STATE getPowerState(){
+ JsonNode n = node.get("PowerplayState");
+ return n != null ? EDConverter.asPowerState(n.asText()) : null;
+ }
+
+
+ public StarSystemData asImportData(){
+ return new StarSystemDataBase() {
+ @Override
+ public String getName() {
+ return FSDJumpEvent.this.getStarSystem();
+ }
+
+ @Override
+ public double getX() {
+ return FSDJumpEvent.this.getX();
+ }
+
+ @Override
+ public double getY() {
+ return FSDJumpEvent.this.getY();
+ }
+
+ @Override
+ public double getZ() {
+ return FSDJumpEvent.this.getZ();
+ }
+
+ @Nullable
+ @Override
+ public FACTION getFaction() {
+ return FSDJumpEvent.this.getAllegiance();
+ }
+
+ @Nullable
+ @Override
+ public GOVERNMENT getGovernment() {
+ return FSDJumpEvent.this.getGovernment();
+ }
+
+ @Nullable
+ @Override
+ public POWER getPower() {
+ return FSDJumpEvent.this.getPower();
+ }
+
+ @Nullable
+ @Override
+ public POWER_STATE getPowerState() {
+ return FSDJumpEvent.this.getPowerState();
+ }
+ };
+
+ }
+}
diff --git a/utils/src/main/java/ru/trader/store/imp/SimpleImporter.java b/utils/src/main/java/ru/trader/store/imp/SimpleImporter.java
new file mode 100644
index 0000000..c7ccf66
--- /dev/null
+++ b/utils/src/main/java/ru/trader/store/imp/SimpleImporter.java
@@ -0,0 +1,55 @@
+package ru.trader.store.imp;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import ru.trader.core.Market;
+import ru.trader.core.Place;
+import ru.trader.core.Vendor;
+import ru.trader.store.imp.entities.StarSystemData;
+import ru.trader.store.imp.entities.StationData;
+
+import java.io.IOException;
+import java.util.Collection;
+
+public class SimpleImporter extends AbstractImporter {
+ private final static Logger LOG = LoggerFactory.getLogger(SimpleImporter.class);
+
+ @Override
+ protected void before() throws IOException {
+ }
+
+ @Override
+ protected void after() throws IOException {
+ }
+
+ @Override
+ public boolean next() throws IOException {
+ throw new UnsupportedOperationException("Is SimpleImporter, next() unsupported, use importStation or importSystem");
+ }
+
+ @Override
+ public StarSystemData getSystem() {
+ throw new UnsupportedOperationException("Is SimpleImporter, getSystem() unsupported, use importStation or importSystem");
+ }
+
+ public Vendor importStation(Market market, StarSystemData importData){
+ Place system = impSystem(market, importData);
+ if (system != null) {
+ Collection stations = importData.getStations();
+ if (stations == null || stations.isEmpty()){
+ LOG.warn("Station data not found");
+ return null;
+ }
+ StationData stationData = stations.iterator().next();
+ return impStation(system, stationData);
+ } else {
+ LOG.warn("System {} not found", importData.getName());
+ return null;
+ }
+ }
+
+ public Place importSystem(Market market, StarSystemData importData){
+ return impSystem(market, importData);
+ }
+
+}