From 9d0509f15672c524451083de58ce38d7a05e5822 Mon Sep 17 00:00:00 2001 From: iMoHax Date: Wed, 30 Aug 2017 15:23:36 +0300 Subject: [PATCH] add journal import --- .../src/main/java/ru/trader/EDLogWatcher.java | 59 ++++--- .../src/main/java/ru/trader/core/FACTION.java | 2 +- .../main/java/ru/trader/core/GOVERNMENT.java | 2 +- core/src/main/resources/store/trader.xsd | 3 + .../java/ru/trader/edlog/EDConverter.java | 144 ++++++++++++++++++ .../java/ru/trader/edlog/EDJournalReader.java | 63 ++++++++ .../ru/trader/edlog/entities/DockedEvent.java | 115 ++++++++++++++ .../trader/edlog/entities/FSDJumpEvent.java | 133 ++++++++++++++++ .../ru/trader/store/imp/SimpleImporter.java | 55 +++++++ 9 files changed, 552 insertions(+), 24 deletions(-) create mode 100644 utils/src/main/java/ru/trader/edlog/EDConverter.java create mode 100644 utils/src/main/java/ru/trader/edlog/EDJournalReader.java create mode 100644 utils/src/main/java/ru/trader/edlog/entities/DockedEvent.java create mode 100644 utils/src/main/java/ru/trader/edlog/entities/FSDJumpEvent.java create mode 100644 utils/src/main/java/ru/trader/store/imp/SimpleImporter.java 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); + } + +}