Archived
0

implement parsing Maddavo price file

This commit is contained in:
iMoHax
2015-02-28 17:54:28 +03:00
parent 0888b5a4a9
commit fc573c0184
4 changed files with 1442 additions and 0 deletions

View File

@@ -0,0 +1,100 @@
package ru.trader.maddavo;
import java.util.HashMap;
import java.util.Map;
public class ItemConverter {
private final static Map<String, String> IDS = new HashMap<>(85, 0.9f);
static {
IDS.put("Explosives", "explosives");
IDS.put("Hydrogen Fuel", "hydrogenfuel");
IDS.put("Mineral Oil", "mineraloil");
IDS.put("Pesticides", "pesticides");
IDS.put("Clothing", "clothing");
IDS.put("Consumer Technology", "consumertechnology");
IDS.put("Domestic Appliances", "domesticappliances");
IDS.put("Algae", "algae");
IDS.put("Animal Meat", "animalmeat");
IDS.put("Coffee", "coffee");
IDS.put("Energy Drinks", "energydrinks");
IDS.put("Fish", "fish");
IDS.put("Food Cartridges", "foodcartridges");
IDS.put("Fruit And Vegetables", "fruitandvegetables");
IDS.put("Grain", "grain");
IDS.put("Synthetic Meat", "syntheticmeat");
IDS.put("Tea", "tea");
IDS.put("Polymers", "polymers");
IDS.put("Semiconductors", "semiconductors");
IDS.put("Superconductors", "superconductors");
IDS.put("Legal Drugs", "group.drugs");
IDS.put("Beer", "beer");
IDS.put("Liquor", "liquor");
IDS.put("Narcotics", "basicnarcotics");
IDS.put("Tobacco", "tobacco");
IDS.put("Wine", "wine");
IDS.put("Atmospheric Processors", "atmosphericprocessors");
IDS.put("Crop Harvesters", "cropharvesters");
IDS.put("Marine Equipment", "marinesupplies");
IDS.put("Microbial Furnaces", "microbialfurnaces");
IDS.put("Mineral Extractors", "mineralextractors");
IDS.put("Power Generators", "powergenerators");
IDS.put("Water Purifiers", "waterpurifiers");
IDS.put("Agri-Medicines", "agriculturalmedicines");
IDS.put("Basic Medicines", "basicmedicines");
IDS.put("Combat Stabilisers", "combatstabilisers");
IDS.put("Performance Enhancers", "performanceenhancers");
IDS.put("Progenitor Cells", "progenitorcells");
IDS.put("Aluminium", "aluminium");
IDS.put("Beryllium", "beryllium");
IDS.put("Copper", "copper");
IDS.put("Cobalt", "cobalt");
IDS.put("Gallium", "gallium");
IDS.put("Gold", "gold");
IDS.put("Indium", "indium");
IDS.put("Lithium", "lithium");
IDS.put("Palladium", "palladium");
IDS.put("Platinum", "platinum");
IDS.put("Tantalum", "tantalum");
IDS.put("Titanium", "titanium");
IDS.put("Silver", "silver");
IDS.put("Uranium", "uranium");
IDS.put("Minerals", "group.minerals");
IDS.put("Bauxite", "bauxite");
IDS.put("Bertrandite", "bertrandite");
IDS.put("Coltan", "coltan");
IDS.put("Gallite", "gallite");
IDS.put("Indite", "indite");
IDS.put("Lepidolite", "lepidolite");
IDS.put("Rutile", "rutile");
IDS.put("Uraninite", "uraninite");
IDS.put("Imperial Slaves", "imperialslaves");
IDS.put("Slaves", "slaves");
IDS.put("Advanced Catalysers", "advancedcatalysers");
IDS.put("Animal Monitors", "animalmonitors");
IDS.put("Aquaponic Systems", "aquaponicsystems");
IDS.put("Auto-Fabricatos", "autofabricators");
IDS.put("Bioreducing Lichen", "bioreducinglichen");
IDS.put("Computer Components", "computercomponents");
IDS.put("H.E. Suits", "hazardousenvironmentsuits");
IDS.put("Resonating Separators", "resonatingseparators");
IDS.put("Robotics", "robotics");
IDS.put("Land Enrichment Systems", "landenrichmentsystems");
IDS.put("Leather", "leather");
IDS.put("Natural Fabrics", "naturalfabrics");
IDS.put("Synthetic Fabrics", "syntheticfabrics");
IDS.put("Biowaste", "biowaste");
IDS.put("Chemical Waste", "chemicalwaste");
IDS.put("Scrap", "scrap");
IDS.put("Battle Weapons", "battleweapons");
IDS.put("Non-Lethal Weapons", "nonlethalweapons");
IDS.put("Personal Weapons", "personalweapons");
IDS.put("Reactive Armour", "reactivearmour");
}
public static String getItemId(String name){
String id = IDS.get(name);
return id != null ? id : name;
}
}

View File

@@ -0,0 +1,177 @@
package ru.trader.maddavo;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import ru.trader.core.*;
import java.io.IOException;
import java.util.HashMap;
import java.util.Map;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
public class OffersHandler implements ParseHandler {
private final static Logger LOG = LoggerFactory.getLogger(OffersHandler.class);
private final Market market;
private final boolean withRemove;
private Vendor station;
private final Map<Item, OfferData> sellUpdates = new HashMap<>(100, 0.9f);
private final Map<Item, OfferData> buyUpdates = new HashMap<>(100, 0.9f);
protected OffersHandler(Market market, boolean withRemove) {
this.market = market;
this.withRemove = withRemove;
}
@Override
public void parse(String str) throws IOException {
if (str.isEmpty()) {
if (station != null){
updateStation();
}
return;
}
if (str.startsWith("#")) return;
if (str.startsWith("@")){
if (station != null){
updateStation();
}
parseStation(str);
} else {
if (station == null){
LOG.trace("Station not exists, skip");
return;
}
parseLine(str);
}
}
private void updateStation() {
LOG.trace("Update offers of station {}", station);
station.getAllBuyOffers().forEach(this::updateOffer);
station.getAllSellOffers().forEach(this::updateOffer);
buyUpdates.entrySet().forEach( entry -> addOffer(entry, OFFER_TYPE.BUY));
sellUpdates.entrySet().forEach( entry -> addOffer(entry, OFFER_TYPE.SELL));
buyUpdates.clear();
sellUpdates.clear();
station = null;
}
private void updateOffer(Offer offer) {
Map<Item, OfferData> offerDatas = offer.getType() == OFFER_TYPE.SELL ? sellUpdates : buyUpdates;
OfferData data = offerDatas.get(offer.getItem());
if (data != null){
if (data.price != offer.getPrice()) offer.setPrice(data.price);
if (data.count != null && data.count != offer.getCount()) offer.setCount(data.count);
data.isnew = false;
} else {
if (withRemove && offer.getItem().getGroup().isMarket()){
station.remove(offer);
}
}
}
private void addOffer(Map.Entry<Item,OfferData> entry, OFFER_TYPE type){
OfferData offer = entry.getValue();
if (offer.isnew){
station.addOffer(type, entry.getKey(), offer.price, offer.count != null ? offer.count : 0);
}
}
private void parseStation(String str) {
StringBuilder sb = new StringBuilder(20);
String system = "";
String name;
LOG.trace("Parse system line: {}", str);
for (int i = 1; i < str.length(); i++) {
char c = str.charAt(i);
if (c == '#') break;
if (c == ' '){
//trim
if (sb.length() == 0 || i == str.length()-1) continue;
char next = str.charAt(i+1);
if (next == ' ' || next == '/') continue;
}
if (c == '/'){
system = sb.toString();
sb = new StringBuilder(20);
} else {
sb.append(c);
}
}
name = sb.toString();
LOG.trace("system: {}, station: {}", system, name);
Place sys = market.get(system);
if (sys != null){
station = sys.get(name);
if (station == null){
LOG.warn("Station {} not found", name);
}
} else {
LOG.warn("System {} not found", system);
}
}
private final static String NAME_REGEXP = "(.+\\S)";
private final static String BUY_SELL_REGEXP = "([\\d]+|[\\?-])";
private final static String SUPPLY_DEMAND_REGEXP = "([\\d]+|[\\?-])([LMH\\?])?";
private final static String DATE_REGEXP = "(\\d+(?:[- :]+\\d+)+)";
private final static Pattern PRICE_REGEXP = Pattern.compile("\\s+" + NAME_REGEXP + "\\s+" + BUY_SELL_REGEXP + "\\s+" + BUY_SELL_REGEXP + "\\s+"+ SUPPLY_DEMAND_REGEXP + "\\s+"+ SUPPLY_DEMAND_REGEXP + "\\s+"+ DATE_REGEXP +"\\s*(:?#.+)?");
private void parseLine(String str){
Matcher matcher = PRICE_REGEXP.matcher(str);
if (matcher.find()){
String name = matcher.group(1);
Double buy = getDoubleValue(matcher.group(2));
Double sell = getDoubleValue(matcher.group(3));
Long demand = getLongValue(matcher.group(4));
Long supply = getLongValue(matcher.group(6));
Item item = market.getItem(ItemConverter.getItemId(name));
if (item != null){
if (buy != null && buy > 0){
buyUpdates.put(item, new OfferData(buy, demand));
}
if (sell != null && sell > 0){
sellUpdates.put(item, new OfferData(sell, supply));
}
} else {
LOG.warn("Item {} not found", name);
}
} else {
LOG.trace("Line is not prices: {}", str);
}
}
private Double getDoubleValue(String string){
if ("?".equals(string)) return null;
if ("-".equals(string)) return 0.0;
return Double.valueOf(string);
}
private Long getLongValue(String string){
if ("?".equals(string)) return null;
if ("-".equals(string)) return 0L;
return Long.valueOf(string);
}
private class OfferData {
private Double price;
private Long count;
private boolean isnew;
private OfferData(Double price, Long count) {
this.price = price;
this.count = count;
isnew = true;
}
}
}