de.tor.tribes.util.parser.SOSParser.java Source code

Java tutorial

Introduction

Here is the source code for de.tor.tribes.util.parser.SOSParser.java

Source

/* 
 * Copyright 2015 Torridity.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package de.tor.tribes.util.parser;

import de.tor.tribes.io.DataHolder;
import de.tor.tribes.io.UnitHolder;
import de.tor.tribes.types.Attack;
import de.tor.tribes.types.SOSRequest;
import de.tor.tribes.types.TargetInformation;
import de.tor.tribes.types.ext.Tribe;
import de.tor.tribes.types.ext.Village;
import de.tor.tribes.util.GenericParserInterface;
import de.tor.tribes.util.ServerSettings;
import java.awt.*;
import java.awt.datatransfer.DataFlavor;
import java.awt.datatransfer.Transferable;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.List;
import java.util.regex.Pattern;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;

/**
 *
 * @author Torridity
 */
public class SOSParser implements GenericParserInterface<SOSRequest> {
    private static Logger logger = LogManager.getLogger("SOSParser");
    /*
     * [b]Verteidiger[/b] Name: [player]Rattenfutter[/player] Stamm: [ally][KdS][/ally] Punkte: 1887516
     *
     * [b]Angegriffenes Dorf[/b] [coord]444|867[/coord] Punkte: 10000 Stufe des Walls: 20
     *
     *
     * [b]Anwesende Truppen[/b] [unit]axe[/unit] 8000 [unit]spy[/unit] 6
     *
     * [b]1. Angriff[/b] Angreifer: [player]Rattenfutter[/player] Stamm: [ally][KdS][/ally] Punkte: 1887516 Herkunft: [coord]444|868[/coord]
     * Ankunftszeit: 24.03.12 18:30:10:935 [b]Angegriffenes Dorf[/b] [coord]443|871[/coord] Punkte: 10014 Stufe des Walls: 20
     *
     *
     * [b]Anwesende Truppen[/b] [unit]axe[/unit] 41 [unit]spy[/unit] 45 [unit]ram[/unit] 8
     *
     * [b]1. Angriff[/b] Angreifer: [player]Rattenfutter[/player] Stamm: [ally][KdS][/ally] Punkte: 1887516 Herkunft: [coord]444|868[/coord]
     * Ankunftszeit: 23.03.12 18:44:00:931
     *
     * [b]2. Angriff[/b] Angreifer: [player]Rattenfutter[/player] Stamm: [ally][KdS][/ally] Punkte: 1887516 Herkunft: [coord]444|867[/coord]
     * Ankunftszeit: 23.03.12 18:44:15:931
     */

    @Override
    public List<SOSRequest> parse(String pData) {
        print("Start parsing SOS request");
        List<SOSRequest> requests = new LinkedList<>();
        try {
            HashMap<Tribe, SOSRequest> parsedData = parseRequests(pData);
            if (parsedData.isEmpty()) {
                print("Check short version");
                parsedData = parseRequestsShort(pData);
            } else {
                print("Got results for long version");
            }
            CollectionUtils.addAll(requests, parsedData.values());
        } catch (Exception ignored) {
        }
        return requests;
    }

    private HashMap<Tribe, SOSRequest> parseRequests(String pData) {
        String[] lines = pData.split("\n");
        HashMap<Tribe, SOSRequest> requests = new HashMap<>();
        SOSRequest currentRequest = null;
        boolean waitForTarget = false;
        boolean waitForTroops = false;
        Village source = null;
        Village target = null;

        SimpleDateFormat dateFormat;
        boolean useMillis = ServerSettings.getSingleton().isMillisArrival();
        if (!useMillis) {
            dateFormat = new SimpleDateFormat(getVariable("sos.date.format"));
        } else {
            dateFormat = new SimpleDateFormat(getVariable("sos.date.format.ms"));
        }

        for (String line : lines) {
            if (line.contains(getVariable("sos.defender"))) {
                //start new support request
                if (currentRequest != null && currentRequest.getDefender() != null) {
                    requests.put(currentRequest.getDefender(), currentRequest);
                }

                currentRequest = new SOSRequest();
                //  System.out.println("Create new reuqest");
            } else if (line.contains(getVariable("sos.name"))) {
                //defender name
                String defender = line.replaceAll(getVariable("sos.name"), "").replaceAll("\\[player\\]", "")
                        .replaceAll("\\[\\/player\\]", "").trim();
                // System.out.println("Defender: " + defender);
                Tribe defTribe = DataHolder.getSingleton().getTribeByName(defender);
                if (requests.get(defTribe) != null) {
                    currentRequest = requests.get(defTribe);
                } else {
                    currentRequest.setDefender(defTribe);
                    requests.put(defTribe, currentRequest);
                }
            } else if (line.contains(getVariable("sos.destination"))) {
                //new target village
                waitForTarget = true;
                //  System.out.println("Wait for target");
            } else if (line.contains(getVariable("sos.source"))) {
                Village sourceVillage = VillageParser.parseSingleLine(line);
                if (sourceVillage != null) {
                    //set target
                    source = sourceVillage;
                    //System.out.println("source: " + source);
                }
            } else if (line.contains(getVariable("sos.arrive.time"))) {
                //arrive time
                try {
                    String arrive = line.replaceAll(getVariable("sos.arrive.time"), "").trim();
                    Date arriveDate = dateFormat.parse(arrive);
                    // System.out.println("Got arrive");
                    if (!useMillis) {//add current millis to be able to compare times
                        arriveDate = new Date(
                                arriveDate.getTime() + Calendar.getInstance().get(Calendar.MILLISECOND));
                    }
                    currentRequest.getTargetInformation(target).addAttack(source, arriveDate);
                } catch (Exception e) {
                    //  System.out.println("NO ARRIVE!!");
                }
            } else if (line.contains(getVariable("sos.wall.level"))) {
                try {
                    int wallLevel = Integer.parseInt(line.replaceAll(getVariable("sos.wall.level"), "").trim());
                    currentRequest.getTargetInformation(target).setWallLevel(wallLevel);
                } catch (Exception ignored) {
                }
            } else if (line.contains(getVariable("sos.troops.in.village"))) {
                // System.out.println("WAIT FOR TROOPS");
                waitForTroops = true;
            } else {
                if (waitForTarget) {
                    Village targetVillage = VillageParser.parseSingleLine(line);
                    if (targetVillage != null) {
                        //set target
                        target = targetVillage;
                        currentRequest.addTarget(target);
                        // System.out.println("Got target " + target);
                        waitForTarget = false;
                    }
                } else if (waitForTroops) {
                    //System.out.println("WAIT TROOPS " + line);
                    try {
                        String plainUnit = line.replaceAll("\\[unit\\]", "").replaceAll("\\[\\/unit\\]", "").trim();
                        //System.out.println("UNIT: " + plainUnit);
                        if (plainUnit.trim().length() != 0) {
                            //skip empty line

                            String[] unitAmount = plainUnit.split(" ");
                            UnitHolder u = DataHolder.getSingleton().getUnitByPlainName(unitAmount[0]);

                            //System.out.println("UNIT : " + u);
                            Integer amount = Integer.parseInt(unitAmount[1]);
                            // System.out.println("AM " + amount);
                            currentRequest.getTargetInformation(target).addTroopInformation(u, amount);
                        }
                    } catch (Exception e) {
                        waitForTroops = false;
                    }
                }
            }
        }

        return requests;
    }

    /**
     * [b]Dorf:[/b] [coord]454|943[/coord] [b]Wallstufe:[/b] 20 [b]Verteidiger:[/b] 18314 13982 0 18659 353 0 0 4825 0 17 0 0
     *
     * LKAV?, 20 Checkpoint (465|883) , K84 [coord]465|883[/coord] --> Ankunftszeit: 24.08.11 23:38:53:674 [player]Frank R.[/player] Ramm,
     * 31 dieBrder 02 (460|888) , K84 [coord]460|888[/coord] --> Ankunftszeit: 25.08.11 17:14:33:064 [player]Frank R.[/player]
     *
     * [b]Dorf:[/b] [coord]453|943[/coord] [b]Wallstufe:[/b] 20 [b]Verteidiger:[/b] 14998 13360 5929 14998 100 2809 260 3000 300 40 0 0
     *
     * Ramm, 22 Checkpoint (452|898) , K84 [coord]452|898[/coord] --> Ankunftszeit: 25.08.11 12:01:23:952 [player]Frank R.[/player]
     *
     * [b]Dorf:[/b] [coord]452|944[/coord] [b]Wallstufe:[/b] 20 [b]Verteidiger:[/b] 18581 13354 0 18581 410 0 0 4994 0 19 0 0
     *
     * Ramm, 42 The White Knigth 04 (448|894) , K84 [coord]448|894[/coord] --> Ankunftszeit: 25.08.11 14:46:51:846 [player]Frank R.[/player]
     *
     * ================================================ Dorf: Just4Testing (454|943) K55 Wallstufe: 20 Verteidiger: 18314 13982 0 18659 353
     * 0 0 4825 0 17 0 0
     *
     * LKAV?, 20 Checkpoint (465|883) , K84 Just4Testing (465|883) K55 --> Ankunftszeit: 24.08.11 23:38:53:674 Frank R. Ramm, 31 dieBrder
     * 02 (460|888) , K84 Just4Testing (460|888) K55 --> Ankunftszeit: 25.08.11 17:14:33:064 Frank R.
     *
     * Dorf: Just4Testing (453|943) K55 Wallstufe: 20 Verteidiger: 14998 13360 5929 14998 100 2809 260 3000 300 40 0 0
     *
     * Ramm, 22 Checkpoint (452|898) , K84 Just4Testing (452|898) K55 --> Ankunftszeit: 25.08.11 12:01:23:952 Torridity
     *
     * Dorf: Just4Testing (452|944) K55 Wallstufe: 20 Verteidiger: 18581 13354 0 18581 410 0 0 4994 0 19 0 0
     *
     * Ramm, 42 The White Knigth 04 (448|894) , K84 Just4Testing (448|894) K55 --> Ankunftszeit: 25.08.11 14:46:51:846 Torridity
     *
     */
    private HashMap<Tribe, SOSRequest> parseRequestsShort(String pData) {
        String[] lines = pData.split("\n");
        HashMap<Tribe, SOSRequest> requests = new HashMap<>();
        Village destination = null;
        SOSRequest request = null;
        SimpleDateFormat dateFormat = null;

        boolean useMillis = ServerSettings.getSingleton().isMillisArrival();
        if (!useMillis) {
            dateFormat = new SimpleDateFormat(getVariable("sos.date.format"));
        } else {
            dateFormat = new SimpleDateFormat(getVariable("sos.date.format.ms"));
        }

        for (String line : lines) {
            // System.out.println("L " + line);
            String usedLine = line.trim();
            if (usedLine.contains(getVariable("sos.short.village"))) {
                print("Village line '" + usedLine + "'");
                if (request != null && destination != null) {
                    print("Store last request");
                    requests.put(destination.getTribe(), request);
                }

                destination = VillageParser.parseSingleLine(usedLine);
                //check if there is a village in the line
                if (destination != null) {
                    print("Destination: " + destination);
                    //check for existing request
                    request = requests.get(destination.getTribe());

                    if (request == null) {
                        print("New request");
                        //create new request
                        request = new SOSRequest(destination.getTribe());
                        requests.put(destination.getTribe(), request);
                    }
                    print("Adding target " + destination);
                    request.addTarget(destination);
                }
            }

            if (destination != null) {
                print("Check destination in '" + usedLine + "'");
                if (usedLine.contains(getVariable("sos.short.wall.level"))) {
                    print("Check wall in line '" + usedLine + "'");
                    String wallSplit[] = usedLine.split(" ");
                    if (wallSplit != null && wallSplit.length >= 2) {
                        print("Check for valid wall");
                        try {
                            Integer wall = Integer.parseInt(wallSplit[wallSplit.length - 1]);
                            print("Wall: " + wall);
                            request.getTargetInformation(destination).setWallLevel(wall);
                        } catch (Exception e) {
                            print("Failed to get Wall " + e.getMessage());
                        }
                    } else {
                        print("Invalid wall entry '" + Arrays.toString(wallSplit) + "'");
                    }
                } else if (usedLine.contains(getVariable("sos.short.defender"))) {
                    print("Get units from line '" + usedLine + "'");
                    int[] units = parseUnits(usedLine);
                    if (units.length != 0) {
                        print("Valid units, add to destination");
                        int cnt = 0;
                        for (UnitHolder unit : DataHolder.getSingleton().getUnits()) {
                            request.getTargetInformation(destination).addTroopInformation(unit, units[cnt]);
                            cnt++;
                        }
                    }
                } else if (usedLine.contains("-->")) {
                    //got attack?
                    print("Check attack in line '" + usedLine + "'");
                    String[] attackSplit = usedLine.split(getVariable("sos.short.movement"));
                    if (attackSplit != null && attackSplit.length >= 2) {
                        print("Try to get attacker in split '" + attackSplit[0]);
                        Village source = VillageParser.parseSingleLine(attackSplit[0]);
                        if (source != null) {
                            print("Got source");
                            Date arrive = null;
                            UnitHolder unit = null;
                            boolean fake = false;
                            unit = guessUnit(attackSplit[0].replaceAll(Pattern.quote(source.getName()), ""));
                            fake = markedAsFake(attackSplit[0].replaceAll(Pattern.quote(source.getName()), ""));

                            try {
                                String[] arriveSplit = attackSplit[1].trim().split(" ");
                                if (arriveSplit != null && arriveSplit.length >= 4) {
                                    print("Try to check arrive time");
                                    String arriveValue = arriveSplit[1] + " " + arriveSplit[2];
                                    // System.out.println("AV " + arriveValue);
                                    arrive = dateFormat.parse(arriveValue);
                                    // System.out.println("HAVE AR ");
                                    if (!useMillis) {//add current millis to be able to compare times
                                        //    System.out.println("ADD CM");
                                        arrive = new Date(arrive.getTime()
                                                + Calendar.getInstance().get(Calendar.MILLISECOND));
                                    }
                                } else {
                                    print("Invalid arrive '" + attackSplit[1]);
                                }
                            } catch (Exception e) {
                                print("Failed to parse date (" + e.getMessage() + ")");
                                // e.printStackTrace();
                            }
                            if (arrive != null) {
                                try {
                                    //  System.out.println("T " + dateFormat.format(arrive));
                                    if (unit != null && unit.getPlainName().equals("ag")) {
                                        request.getTargetInformation(destination).addAttack(source, arrive, unit,
                                                false, true);
                                    } else if (fake) {
                                        request.getTargetInformation(destination).addAttack(source, arrive, unit,
                                                true, false);
                                    } else {
                                        request.getTargetInformation(destination).addAttack(source, arrive, unit);
                                    }
                                } catch (Throwable t) {
                                    logger.info(
                                            "Failed to add attack with unit. Using old target information format");
                                    //old target information format!?
                                    request.getTargetInformation(destination).addAttack(source, arrive);
                                }
                            }
                        }
                    } else {
                        print("Invalid split");
                    }
                }
            }
        }

        if (request != null && destination != null) {
            print("Store last request");
            requests.put(destination.getTribe(), request);
        }
        return requests;
    }

    private UnitHolder guessUnit(String pString) {
        if (pString.toLowerCase().startsWith("ram")) {
            return DataHolder.getSingleton().getUnitByPlainName("ram");
        } else if (pString.toLowerCase().startsWith("ag")) {
            return DataHolder.getSingleton().getUnitByPlainName("ag");
        } else if (pString.toLowerCase().startsWith("kata") || pString.toLowerCase().startsWith("cata")) {
            return DataHolder.getSingleton().getUnitByPlainName("catapult");
        } else if (pString.toLowerCase().startsWith("lkav")) {
            return DataHolder.getSingleton().getUnitByPlainName("light");
        } else if (pString.toLowerCase().startsWith("axt")) {
            return DataHolder.getSingleton().getUnitByPlainName("axe");
        } else if (pString.toLowerCase().startsWith("sph") || pString.toLowerCase().startsWith("spy")) {
            return DataHolder.getSingleton().getUnitByPlainName("spy");
        } else if (pString.toLowerCase().startsWith("axt")) {
            return DataHolder.getSingleton().getUnitByPlainName("axe");
        } else if (pString.toLowerCase().startsWith("lkav")) {
            return DataHolder.getSingleton().getUnitByPlainName("light");
        } else if (pString.toLowerCase().startsWith("speer")) {
            return DataHolder.getSingleton().getUnitByPlainName("spear");
        } else if (pString.toLowerCase().startsWith("schwert")) {
            return DataHolder.getSingleton().getUnitByPlainName("sword");
        } else if (pString.toLowerCase().startsWith("skav")) {
            return DataHolder.getSingleton().getUnitByPlainName("heavy");
        }

        return null;
    }

    private boolean markedAsFake(String pString) {
        return pString.toLowerCase().startsWith("fake");
    }

    private int[] parseUnits(String pLine) {
        String line = pLine.replaceAll(getVariable("troops.own"), "").replaceAll(getVariable("troops.commands"), "")
                .replaceAll(getVariable("troops"), "");
        StringTokenizer t = new StringTokenizer(line, " \t");
        int uCount = DataHolder.getSingleton().getUnits().size();
        int[] units = new int[uCount];
        int cnt = 0;
        while (t.hasMoreTokens()) {
            try {
                units[cnt] = Integer.parseInt(t.nextToken());
                cnt++;
            } catch (Exception e) {
                //token with no troops
            }
        }
        if (cnt < uCount) {
            return new int[] {};
        }
        return units;
    }

    private void print(String pText) {
        logger.debug(pText);

        /*
         * if (debug) { System.out.println(pText); }
         */
    }

    public HashMap<Tribe, SOSRequest> attacksToSOSRequests(List<Attack> pAttacks) {
        HashMap<Tribe, SOSRequest> requests = new HashMap<>();

        for (Attack attack : pAttacks) {
            Tribe defender = attack.getTarget().getTribe();
            SOSRequest requestForDefender = requests.get(defender);
            if (requestForDefender == null) {
                requestForDefender = new SOSRequest(defender);
                requests.put(defender, requestForDefender);
            }
            requestForDefender.addTarget(attack.getTarget());
            TargetInformation targetInfo = requestForDefender.getTargetInformation(attack.getTarget());
            targetInfo.addAttack(attack.getSource(), attack.getArriveTime());
        }
        return requests;
    }

    private String getVariable(String pProperty) {
        return ParserVariableManager.getSingleton().getProperty(pProperty);
    }

    public static void main(String[] args) throws Exception {

        try {
            Transferable t = Toolkit.getDefaultToolkit().getSystemClipboard().getContents(null);
            String data = (String) t.getTransferData(DataFlavor.stringFlavor);
            new SOSParser().parse(data);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}