/** * */ 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.TreeMap; import logbook.constants.AppConstants; import logbook.data.context.GlobalContext; import logbook.dto.ItemInfoDto; import logbook.dto.ShipBaseDto; import logbook.dto.ShipDto; import logbook.dto.ShipInfoDto; import logbook.gui.ApplicationMain; import au.com.bytecode.opencsv.CSVReader; import au.com.bytecode.opencsv.CSVWriter; /** * 七四式互換ShipParameterRecord * ただし航海日誌拡張版が取得&記録できるデータは敵艦、ドロップ艦の初期装備のみ * * @author Nekopanda */ public class ShipParameterRecord { /** ロガー */ private static final LoggerHolder LOG = new LoggerHolder(ShipParameterRecord.class); private static Map<Integer, ShipParameterRecord> SHIP = new TreeMap<Integer, ShipParameterRecord>(); /** 変更があったか */ private static boolean modified = false; // 始めてアクセスがあった時に読み込む public static final boolean INIT_COMPLETE; static { try { load(); } catch (IOException e) { LOG.get().warn("艦パラメータファイル読み込みに失敗しました", e); } INIT_COMPLETE = true; } public static class UpdateShipParameter { private int maxShipId = -1; public void sortieStart() { this.maxShipId = 0; for (ShipDto ship : GlobalContext.getShipMap().values()) { if (this.maxShipId < ship.getId()) { this.maxShipId = ship.getId(); } } } public void sortieEnd() { if (this.maxShipId != -1) { for (ShipDto ship : GlobalContext.getShipMap().values()) { if (this.maxShipId < ship.getId()) { // 新しい艦娘 ShipParameterRecord.update(ship); } } } this.maxShipId = -1; } public void battleStart() { for (ShipBaseDto ship : GlobalContext.getLastBattleDto().getEnemy()) { ShipParameterRecord.update(ship); } } } private final int shipId; private final String shipName; private final int[] ASW; private final int[] Evasion; private final int[] LOS; private int[] defaultSlot; private String albumMessage; private int[] maxeq; private Integer seiku; private static int[] readIntegerArray(String[] data, int offset, int length) { int[] ret = new int[length]; for (int i = 0; i < length; ++i) { if (data[offset + i].equals("null")) { return null; } ret[i] = Integer.parseInt(data[offset + i]); } return ret; } private static void addToString(List<String> data, int[] intarray) { for (int n : intarray) { data.add(String.valueOf(n)); } } public ShipParameterRecord(String[] data) { this.shipId = Integer.parseInt(data[0]); this.shipName = data[1]; this.ASW = readIntegerArray(data, 2, 3); this.Evasion = readIntegerArray(data, 5, 3); this.LOS = readIntegerArray(data, 8, 3); this.defaultSlot = readIntegerArray(data, 11, 5); this.albumMessage = data[16]; if (data.length > 17) { this.maxeq = readIntegerArray(data, 17, 5); this.seiku = (data[22].equals("null") ? null : Integer.parseInt(data[22])); } } public ShipParameterRecord(int shipId, String shipName) { this.shipId = shipId; this.shipName = shipName; this.ASW = new int[] { 0, 9999, 9999 }; this.Evasion = new int[] { 0, 9999, 9999 }; this.LOS = new int[] { 0, 9999, 9999 }; } /** 装備を更新 */ public static void update(ShipBaseDto ship) { ShipParameterRecord record = SHIP.get(ship.getShipId()); if (record == null) { record = new ShipParameterRecord(ship.getShipId(), ship.getFullName()); } int[] itemId = ship.getItemId(); if (ship.isFriend()) { // 艦娘の場合は個別IDになっているので変換 List<ItemInfoDto> items = ship.getItem(); itemId = new int[itemId.length]; for (int i = 0; i < itemId.length; ++i) { itemId[i] = ((i < items.size()) && (items.get(i) != null)) ? items.get(i).getId() : -1; } } if (Arrays.equals(record.defaultSlot, itemId) == false) { record.defaultSlot = itemId; SHIP.put(ship.getShipId(), record); modified = true; ApplicationMain.main.printMessage(ship.getFullName() + "の装備データを更新"); } } public static void update(ShipInfoDto ship, Integer seiku) { ShipParameterRecord record = SHIP.get(ship.getShipId()); if (record == null) { record = new ShipParameterRecord(ship.getShipId(), ship.getFullName()); } boolean updated = false; int[] maxeq = ship.getMaxeq(); if ((maxeq != null) && (Arrays.equals(record.maxeq, maxeq) == false)) { record.maxeq = maxeq; updated = true; ApplicationMain.main.printMessage(ship.getFullName() + "のスロット数データを更新"); } if ((seiku != null) && (seiku.equals(record.seiku) == false)) { record.seiku = seiku; updated = true; ApplicationMain.main.printMessage(ship.getFullName() + "の制空値データを更新"); } if (updated) { SHIP.put(ship.getShipId(), record); modified = true; } } public static ShipParameterRecord get(int id) { return SHIP.get(id); } private static String[] getHeader() { return new String[] { "艦船ID", "艦船名", "対潜初期下限", "対潜初期上限", "対潜最大", "回避初期下限", "回避初期上限", "回避最大", "索敵初期下限", "索敵初期上限", "索敵最大", "装備1", "装備2", "装備3", "装備4", "装備5", "図鑑説明", "スロット1", "スロット2", "スロット3", "スロット4", "スロット5", "制空値" }; } public static void store() throws IOException { // 変更があったときだけ書き込む if (modified) { try (CSVWriter writer = new CSVWriter(new OutputStreamWriter(new BufferedOutputStream( new FileOutputStream(AppConstants.SHIP_PARAMETER_FILE)), AppConstants.CHARSET), CSVWriter.DEFAULT_SEPARATOR, CSVWriter.NO_QUOTE_CHARACTER)) { List<String> flatten = new ArrayList<String>(); writer.writeNext(getHeader()); for (Entry<Integer, ShipParameterRecord> e : SHIP.entrySet()) { ShipParameterRecord data = e.getValue(); flatten.add(String.valueOf(data.shipId)); flatten.add(data.shipName); addToString(flatten, data.ASW); addToString(flatten, data.Evasion); addToString(flatten, data.LOS); if (data.defaultSlot != null) { addToString(flatten, data.defaultSlot); } else { flatten.addAll(Arrays.asList(new String[] { "null", "null", "null", "null", "null" })); } flatten.add(data.albumMessage); if (data.maxeq != null) { addToString(flatten, data.maxeq); } else { flatten.addAll(Arrays.asList(new String[] { "null", "null", "null", "null", "null" })); } flatten.add(data.seiku != null ? String.valueOf(data.seiku) : "null"); writer.writeNext(flatten.toArray(new String[0])); flatten.clear(); } } ApplicationMain.sysPrint("艦パラメータファイル更新"); modified = false; } } public static void load() throws IOException { if (AppConstants.SHIP_PARAMETER_FILE.exists()) { CSVReader reader = new CSVReader(new InputStreamReader( new FileInputStream(AppConstants.SHIP_PARAMETER_FILE), AppConstants.CHARSET)); int line = 0; for (String[] entry : reader.readAll()) { if (line++ == 0) continue; // ヘッダーを飛ばす if (entry.length >= 17) { ShipParameterRecord record = new ShipParameterRecord(entry); if (SHIP.containsKey(record.shipId)) { modified = true; } SHIP.put(record.shipId, record); } } reader.close(); } } /** * @return shipId */ public int getShipId() { return this.shipId; } /** * @return defaultSlot */ public int[] getDefaultSlot() { return this.defaultSlot; } /** * @return maxeq */ public int[] getMaxeq() { return this.maxeq; } }