/* Copyright (c) 2008-2010, developers of the Ascension Log Visualizer * * Permission is hereby granted, free of charge, to any person * obtaining a copy of this software and associated documentation * files (the "Software"), to deal in the Software without * restriction, including without limitation the rights to use, * copy, modify, merge, publish, distribute, sublicense, and/or * sell copies of the Software, and to permit persons to whom * the Software is furnished to do so, subject to the following * conditions: * * The above copyright notice and this permission notice shall be * included in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR * OTHER DEALINGS IN THE SOFTWARE. */ package com.googlecode.logVisualizer.parser.mafiaLogBlockParsers; import java.util.List; import java.util.Locale; import java.util.Scanner; import java.util.regex.Matcher; import java.util.regex.Pattern; import com.googlecode.logVisualizer.logData.LogDataHolder; import com.googlecode.logVisualizer.logData.LogDataHolder.CharacterClass; import com.googlecode.logVisualizer.logData.turn.turnAction.DayChange; import com.googlecode.logVisualizer.logData.turn.turnAction.EquipmentChange; import com.googlecode.logVisualizer.logData.turn.turnAction.FamiliarChange; import com.googlecode.logVisualizer.logData.turn.turnAction.PlayerSnapshot; import com.googlecode.logVisualizer.parser.UsefulPatterns; /** * A parser for the player login snapshot data in mafia logs. * <p> * The snapshot start with this: * <p> * * <pre> * =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= * Player Snapshot * =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= * </pre> * <p> * And ends with this: * <p> * * <pre> * =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= * </pre> */ public final class PlayerSnapshotBlockParser implements LogBlockParser { private static final Pattern PLAYERSTATS_WBUFFED_PATTERN = Pattern .compile("(?:Mus|Mys|Mox)\\: \\d+ \\(\\d+\\).*"); private static final Pattern PLAYERSTATS_WOBUFFED_PATTERN = Pattern .compile("(?:Mus|Mys|Mox)\\: \\d+(?:$|, tnp =.*)"); private static final Pattern NOT_FAMILIAR_NAME_PATTERN = Pattern .compile("Pet: | \\(\\d+ lbs\\)\\s*"); private static final String CLASS_LINE_BEGINNING_STRING = "Class: "; private static final String FAMILIAR_LINE_BEGINNING_STRING = "Pet: "; private static final String ADVENTURES_LINE_BEGINNING_STRING = "Advs: "; private static final String MEAT_LINE_BEGINNING_STRING = "Meat: "; private static final String HAT_BEGINNING_STRING = "Hat: "; private static final String WEAPON_BEGINNING_STRING = "Weapon: "; private static final String OFFHAND_BEGINNING_STRING = "Off-hand: "; private static final String SHIRT_BEGINNING_STRING = "Shirt: "; private static final String PANTS_BEGINNING_STRING = "Pants: "; private static final String ACC1_BEGINNING_STRING = "Acc. 1: "; private static final String ACC2_BEGINNING_STRING = "Acc. 2: "; private static final String ACC3_BEGINNING_STRING = "Acc. 3: "; private static final String FAM_EQUIP_BEGINNING_STRING = "Item: "; private static final String NO_EQUIP_STRING = "(none)"; private static final String DAY_CHANGE_STRING = "Day change occurred"; private final Matcher statsWithBuffed = PlayerSnapshotBlockParser.PLAYERSTATS_WBUFFED_PATTERN .matcher(UsefulPatterns.EMPTY_STRING); private final Matcher statsWithoutBuffed = PlayerSnapshotBlockParser.PLAYERSTATS_WOBUFFED_PATTERN .matcher(UsefulPatterns.EMPTY_STRING); /** * {@inheritDoc} */ @Override public void parseBlock(final List<String> block, final LogDataHolder logData) { String hat = EquipmentChange.NO_EQUIPMENT_STRING; String weapon = EquipmentChange.NO_EQUIPMENT_STRING; String offhand = EquipmentChange.NO_EQUIPMENT_STRING; String shirt = EquipmentChange.NO_EQUIPMENT_STRING; String pants = EquipmentChange.NO_EQUIPMENT_STRING; String acc1 = EquipmentChange.NO_EQUIPMENT_STRING; String acc2 = EquipmentChange.NO_EQUIPMENT_STRING; String acc3 = EquipmentChange.NO_EQUIPMENT_STRING; String famEquip = EquipmentChange.NO_EQUIPMENT_STRING; final int turnNumber = logData.getTurnsSpent().last().getEndTurn(); int mus = -1; int myst = -1; int mox = -1; int adventuresLeft = 0; int meat = 0; for (final String line : block) { if (line.length() > 0) { if (this.statsWithBuffed.reset(line).matches()) { if (mus < 0) { mus = PlayerSnapshotBlockParser.parseStatWBuffed(line); } else if (myst < 0) { myst = PlayerSnapshotBlockParser.parseStatWBuffed(line); } else if (mox < 0) { mox = PlayerSnapshotBlockParser.parseStatWBuffed(line); } } else if (this.statsWithoutBuffed.reset(line).matches()) { if (mus < 0) { mus = PlayerSnapshotBlockParser.parseStatWOBuffed(line); } else if (myst < 0) { myst = PlayerSnapshotBlockParser .parseStatWOBuffed(line); } else if (mox < 0) { mox = PlayerSnapshotBlockParser.parseStatWOBuffed(line); } } else if (line .startsWith(PlayerSnapshotBlockParser.FAMILIAR_LINE_BEGINNING_STRING)) { try (final Scanner s = new Scanner(line)) { s.useDelimiter(PlayerSnapshotBlockParser.NOT_FAMILIAR_NAME_PATTERN); logData.addFamiliarChange(new FamiliarChange(s.next(), turnNumber)); s.close(); } } else if (line .startsWith(PlayerSnapshotBlockParser.ADVENTURES_LINE_BEGINNING_STRING)) { adventuresLeft = Integer.parseInt(line.substring(line .indexOf(UsefulPatterns.COLON) + 2)); } else if (line .startsWith(PlayerSnapshotBlockParser.MEAT_LINE_BEGINNING_STRING) && !line.contains(UsefulPatterns.PERCENTAGE_SIGN)) { meat = Integer.parseInt(line.substring( line.indexOf(UsefulPatterns.COLON) + 2).replace( UsefulPatterns.COMMA, UsefulPatterns.EMPTY_STRING)); } else if (line .startsWith(PlayerSnapshotBlockParser.HAT_BEGINNING_STRING)) { hat = PlayerSnapshotBlockParser.getEquipmentName(line); } else if (line .startsWith(PlayerSnapshotBlockParser.WEAPON_BEGINNING_STRING)) { weapon = PlayerSnapshotBlockParser.getEquipmentName(line); } else if (line .startsWith(PlayerSnapshotBlockParser.OFFHAND_BEGINNING_STRING)) { offhand = PlayerSnapshotBlockParser.getEquipmentName(line); } else if (line .startsWith(PlayerSnapshotBlockParser.SHIRT_BEGINNING_STRING)) { shirt = PlayerSnapshotBlockParser.getEquipmentName(line); } else if (line .startsWith(PlayerSnapshotBlockParser.PANTS_BEGINNING_STRING)) { pants = PlayerSnapshotBlockParser.getEquipmentName(line); } else if (line .startsWith(PlayerSnapshotBlockParser.ACC1_BEGINNING_STRING)) { acc1 = PlayerSnapshotBlockParser.getEquipmentName(line); } else if (line .startsWith(PlayerSnapshotBlockParser.ACC2_BEGINNING_STRING)) { acc2 = PlayerSnapshotBlockParser.getEquipmentName(line); } else if (line .startsWith(PlayerSnapshotBlockParser.ACC3_BEGINNING_STRING)) { acc3 = PlayerSnapshotBlockParser.getEquipmentName(line); } else if (line .startsWith(PlayerSnapshotBlockParser.FAM_EQUIP_BEGINNING_STRING) && !line.contains(UsefulPatterns.PERCENTAGE_SIGN)) { famEquip = PlayerSnapshotBlockParser.getEquipmentName(line); } else if (line .startsWith(PlayerSnapshotBlockParser.DAY_CHANGE_STRING)) { // Get day number of last day change final int dayNumber = logData.getLastDayChange() .getDayNumber(); // Get turn number of last turn spent final int turn = logData.getTurnsSpent().last() .getEndTurn(); // Add day change logData.addDayChange(new DayChange(dayNumber + 1, turn)); } else if (logData.getCharacterClass() == CharacterClass.NOT_DEFINED) { if (line.startsWith(PlayerSnapshotBlockParser.CLASS_LINE_BEGINNING_STRING)) { logData.setCharacterClass(line .substring(PlayerSnapshotBlockParser.CLASS_LINE_BEGINNING_STRING .length())); } } } } // Add the currently worn equipment. logData.addEquipmentChange(new EquipmentChange(turnNumber, hat, weapon, offhand, shirt, pants, acc1, acc2, acc3, famEquip)); // A check to make sure the parsing worked, if it did, add the player // snapshot. if ((mus >= 0) && (myst >= 0) && (mox >= 0)) { logData.addPlayerSnapshot(new PlayerSnapshot(mus, myst, mox, adventuresLeft, meat, turnNumber)); } } private static String getEquipmentName(final String line) { String itemName = line .substring(line.indexOf(UsefulPatterns.COLON) + 2).toLowerCase( Locale.ENGLISH); if (itemName.contains(PlayerSnapshotBlockParser.NO_EQUIP_STRING)) { itemName = EquipmentChange.NO_EQUIPMENT_STRING; } else if (itemName.endsWith(UsefulPatterns.ROUND_BRACKET_CLOSE)) { itemName = itemName .substring(0, itemName .lastIndexOf(UsefulPatterns.ROUND_BRACKET_OPEN) - 1); } return itemName; } private static int parseStatWBuffed(final String line) { return Integer.parseInt(line.substring( line.indexOf(UsefulPatterns.ROUND_BRACKET_OPEN) + 1, line.indexOf(UsefulPatterns.ROUND_BRACKET_CLOSE))); } private static int parseStatWOBuffed(final String line) { final String tmp = line.substring(line .indexOf(UsefulPatterns.WHITE_SPACE) + 1); if (tmp.contains(UsefulPatterns.COMMA)) { return Integer.parseInt(tmp.substring(0, tmp.indexOf(UsefulPatterns.COMMA))); } return Integer.parseInt(tmp); } }