/** * */ package logbook.internal; import java.io.BufferedOutputStream; import java.io.FileInputStream; import java.io.FileOutputStream; import java.io.IOException; import java.io.InputStreamReader; import java.io.OutputStreamWriter; import java.util.ArrayList; import java.util.Arrays; import java.util.List; import java.util.Map; import java.util.Map.Entry; import java.util.Set; import java.util.TreeMap; import logbook.constants.AppConstants; import logbook.dto.BattleExDto; import logbook.dto.ShipInfoDto; import logbook.gui.ApplicationMain; import org.apache.commons.lang3.StringUtils; import au.com.bytecode.opencsv.CSVReader; import au.com.bytecode.opencsv.CSVWriter; import com.dyuproject.protostuff.Tag; /** * @author Nekopanda * */ public class EnemyData { /** ロガー */ private static final LoggerHolder LOG = new LoggerHolder(EnemyData.class); private static Map<Integer, EnemyData> ENEMY = new TreeMap<Integer, EnemyData>(); /** 変更があったか */ private static boolean modified = false; // 始めてアクセスがあった時に読み込む public static final boolean INIT_COMPLETE; static { try { load(); } catch (IOException e) { LOG.get().warn("e_idと敵艦隊の対応ファイル読み込みに失敗しました", e); } INIT_COMPLETE = true; } @Tag(1) private final int enemyId; @Tag(2) private final String enemyName; //@Tag(3) //private final String[] enemyShips; @Tag(4) private final String formation; @Tag(5) private final int[] enemyShipsId; @Override public boolean equals(Object o) { if (o instanceof EnemyData) { EnemyData e = (EnemyData) o; if ((e.enemyId == this.enemyId) && e.enemyName.equals(this.enemyName) && Arrays.equals(e.enemyShipsId, this.enemyShipsId) && e.formation.equals(this.formation)) { return true; } } return false; } public EnemyData(int enemyId, String enemyName, int[] enemyShipsId, String formation) { this.enemyId = enemyId; this.enemyName = enemyName; this.enemyShipsId = enemyShipsId; this.formation = formation; } /** * 敵編成を設定します */ public static void set(int id, EnemyData item) { EnemyData old = ENEMY.get(id); if ((old != null) && old.equals(item)) { // 更新する必要なし return; } ENEMY.put(id, item); modified = true; } /** * 敵編成を取得します * * @param id エネミーID * @return 敵編成 */ public static EnemyData get(int id) { return ENEMY.get(id); } /** * IDの一覧を取得します * * @return IDの一覧 */ public static Set<Integer> keySet() { return ENEMY.keySet(); } private static String[] getHeader() { return new String[] { "敵編成ID", "敵艦隊名", "陣形", "敵1番艦", "敵2番艦", "敵3番艦", "敵4番艦", "敵5番艦", "敵6番艦" }; } public static void store() throws IOException { // 変更があったときだけ書き込む if (modified) { try (CSVWriter writer = new CSVWriter(new OutputStreamWriter(new BufferedOutputStream( new FileOutputStream(AppConstants.ENEMY_DATA_FILE)), AppConstants.CHARSET), CSVWriter.DEFAULT_SEPARATOR, CSVWriter.NO_QUOTE_CHARACTER)) { List<String> flatten = new ArrayList<String>(); writer.writeNext(getHeader()); for (Entry<Integer, EnemyData> e : ENEMY.entrySet()) { EnemyData data = e.getValue(); flatten.add(String.valueOf(data.getEnemyId())); flatten.add(data.getEnemyName()); flatten.add(String.valueOf(BattleExDto.fromFormation(data.getFormation()))); for (int s : data.getEnemyShipsId()) { flatten.add(String.valueOf(s)); } writer.writeNext(flatten.toArray(new String[flatten.size()])); flatten.clear(); } } ApplicationMain.sysPrint("Enemyファイル更新"); modified = false; } } private static void readOldfile() { if (AppConstants.ENEMY_DATA_OLD_FILE.exists()) { try { Map<Integer, EnemyData> TMP = new TreeMap<Integer, EnemyData>(); Map<String, ShipInfoDto> nameMap = Ship.getEnemyNameMap(); try (CSVReader reader = new CSVReader(new InputStreamReader( new FileInputStream(AppConstants.ENEMY_DATA_OLD_FILE), AppConstants.CHARSET))) { for (String[] entry : reader.readAll()) { if (entry.length >= 8) { int id = Integer.parseInt(entry[0]); int[] enemyShipsId = new int[6]; for (int i = 0; i < 6; ++i) { String shipdata = entry[i + 1]; int shipId = -1; if (!StringUtils.isEmpty(shipdata)) { ShipInfoDto shipinfo = nameMap.get(shipdata); if (shipinfo != null) { shipId = shipinfo.getShipId(); } } enemyShipsId[i] = shipId; } String name = (entry.length >= 9) ? entry[8] : ""; TMP.put(id, new EnemyData(id, name, enemyShipsId, entry[7])); } } } for (EnemyData data : TMP.values()) { if (!ENEMY.containsKey(data.enemyId)) { ENEMY.put(data.enemyId, data); modified = true; } } } catch (IOException e) { LOG.get().warn("旧敵データファイル読み込み失敗", e); } } } public static void load() throws IOException { if (AppConstants.ENEMY_DATA_FILE.exists()) { try (CSVReader reader = new CSVReader(new InputStreamReader( new FileInputStream(AppConstants.ENEMY_DATA_FILE), AppConstants.CHARSET))) { int line = 0; for (String[] entry : reader.readAll()) { if (line++ == 0) continue; // ヘッダーを飛ばす if (entry.length >= 9) { int id = Integer.parseInt(entry[0]); String name = entry[1]; String formation = BattleExDto.toFormation(Integer.parseInt(entry[2])); int[] enemyShipsId = new int[6]; for (int i = 0; i < 6; ++i) { enemyShipsId[i] = Integer.parseInt(entry[i + 3]); } if (ENEMY.containsKey(id)) { modified = true; } ENEMY.put(id, new EnemyData(id, name, enemyShipsId, formation)); } } } } readOldfile(); } /** * @return enemyId */ public int getEnemyId() { return this.enemyId; } public String getEnemyName() { return this.enemyName; } /** * @return enemyShips */ public int[] getEnemyShipsId() { return this.enemyShipsId; } public String[] getEnemyShips() { String[] names = new String[6]; for (int i = 0; i < 6; ++i) { String name = ""; ShipInfoDto shipinfo = Ship.get(this.enemyShipsId[i]); if (shipinfo != null) { name = shipinfo.getFullName(); } names[i] = name; } return names; } /** * @return formation */ public String getFormation() { return this.formation; } }