/* * Copyright (C) 2015 thirdy * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; either version 2 * of the License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ package io.jexiletools.es.modsmapping; import java.io.IOException; import java.io.InputStreamReader; import java.util.Arrays; import java.util.List; import java.util.Map; import java.util.Map.Entry; import java.util.Optional; import java.util.stream.Collectors; import org.apache.commons.lang3.StringUtils; import com.google.common.io.CharStreams; import com.google.gson.Gson; import io.jexiletools.es.model.ItemType; /** * @author thirdy * */ public final class ModsMapping { private static ModsMapping instance = new ModsMapping(); private List<ModMapping> modMappings; public static ModsMapping getInstance() { return instance; } @SuppressWarnings("unchecked") private ModsMapping() { Gson gson = new Gson(); Map<String, Object> m = null; try(InputStreamReader isr = new InputStreamReader(ModsMapping.class.getResourceAsStream("/mods.json")) {}) { String s = CharStreams.toString(isr); s = s.replace("\\", "\\\\"); m = gson.fromJson(s, Map.class); } catch (IOException e) { throw new RuntimeException(e); } m = (Map<String, Object>) m.get("poe"); m = (Map<String, Object>) m.get("mappings"); m = (Map<String, Object>) m.get("item"); modMappings = m.entrySet().stream().map(e -> toMapping(e)) .collect(Collectors.toList()); // the json mod mapping represents ranged mods as two, one for min and one for max // we only want one of the two, so let's clean // Remove DOUBLE_MAX mods modMappings = modMappings.stream().filter(mm -> mm.type != Type.DOUBLE_MAX).collect(Collectors.toList()); // Change DOUBLE_MIN mods to DOUBLE_MIN_MAX modMappings.stream().filter(mm -> mm.type == Type.DOUBLE_MIN).forEach(mm -> mm.type = Type.DOUBLE_MIN_MAX); // also add pseudo mods modMappings.add(new ModMapping("modsPseudo.eleResistSumChaos", "modsPseudo.eleResistSumChaos", "+#% to Lightning Chaos", Type.DOUBLE, ModType.PSEUDO, null)); modMappings.add(new ModMapping("modsPseudo.eleResistSumCold", "modsPseudo.eleResistSumCold", "+#% to Cold Resistance", Type.DOUBLE, ModType.PSEUDO, null)); modMappings.add(new ModMapping("modsPseudo.eleResistSumFire", "modsPseudo.eleResistSumFire", "+#% to Fire Resistance", Type.DOUBLE, ModType.PSEUDO, null)); modMappings.add(new ModMapping("modsPseudo.eleResistSumLightning", "modsPseudo.eleResistSumLightning", "+#% to Lightning Resistance", Type.DOUBLE, ModType.PSEUDO, null)); modMappings.add(new ModMapping("modsPseudo.eleResistTotal", "modsPseudo.eleResistTotal", "+#% total Elemental Resistance", Type.DOUBLE, ModType.PSEUDO, null)); modMappings.add(new ModMapping("modsPseudo.flatAttributesTotal", "modsPseudo.flatAttributesTotal", "+# to all Attributes", Type.DOUBLE, ModType.PSEUDO, null)); modMappings.add(new ModMapping("modsPseudo.flatSumDex", "modsPseudo.flatSumDex", "+# to Dexterity", Type.DOUBLE, ModType.PSEUDO, null)); modMappings.add(new ModMapping("modsPseudo.flatSumInt", "modsPseudo.flatSumInt", "+# to Intelligence", Type.DOUBLE, ModType.PSEUDO, null)); modMappings.add(new ModMapping("modsPseudo.flatSumStr", "modsPseudo.flatSumStr", "+# to Strength", Type.DOUBLE, ModType.PSEUDO, null)); modMappings.add(new ModMapping("modsPseudo.maxLife", "modsPseudo.maxLife", "+# to Maximum Life", Type.DOUBLE, ModType.PSEUDO, null)); } public List<ModMapping> getModMappings() { return modMappings; } @SuppressWarnings("unchecked") private ModMapping toMapping(Entry<String, Object> e) { ModMapping mapping = new ModMapping(); Map<String, Object> itemMap = (Map<String, Object>) e.getValue(); Map<String, Object> mappingMap = (Map<String, Object>) itemMap.get("mapping"); // Note that key is equal to fullName mapping.key = e.getKey(); mapping.fullName = (String) itemMap.get("full_name"); mapping.mapping = mappingMap.keySet().iterator().next(); String typeStr = (String) ((Map) mappingMap.get(mapping.mapping)).get("type"); mapping.type = Type.valueOf(typeStr.toUpperCase()); mapping.parse(); return mapping; } public enum Type { DOUBLE, BOOLEAN, DOUBLE_MIN, DOUBLE_MAX, DOUBLE_MIN_MAX; } public enum ModType { PSEUDO, IMPLICIT, EXPLICIT, CRAFTED, COSMETIC; public static Optional<ModType> fromModType(String modType) { return Arrays.asList(values()) .stream() .filter(e -> e.toString().equalsIgnoreCase(modType)) .findFirst(); } } public static class ModMapping { String key; String fullName; String mapping; Type type; ModType modType; String itemType; public ModMapping() { } void parse() { // mods.Boots.explicit.Adds #-# Cold Damage to Spells.min String[] tokens = key.split("\\."); if(tokens.length < 4 || tokens.length > 5) throw new IllegalStateException("Mod key is not 4 or 5 tokens. Indexer mapping has changed?"); itemType = tokens[1]; modType = ModType.valueOf(tokens[2].toUpperCase()); if (tokens.length == 5) { type = tokens[4].equalsIgnoreCase("min") ? Type.DOUBLE_MIN : Type.DOUBLE_MAX; mapping = tokens[3]; } } @Override public String toString() { return mapping; } public String getKey() { return key; } public String getMapping() { return mapping; } public Type getType() { return type; } public ModType getModType() { return modType; } public String getItemType() { return itemType; } public ModMapping(String key, String fullName, String mapping, Type type, ModType modType, String itemType) { this.key = key; this.fullName = fullName; this.mapping = mapping; this.type = type; this.modType = modType; this.itemType = itemType; } } // public static void main(String[] args) { // List<ModMapping> mms = ModsMapping.getInstance().getModMappings(); // mms.forEach(mm -> { // System.out.println(String.format("%s\t%s\t%s\t%s\t%s\t%s", // mm.itemType, mm.modType, mm.type, mm.mapping, mm.fullName, mm.key)); // }); // } public List<ModMapping> listByModType(ModType modType) { return getModMappings() .stream() .filter(m -> m.modType == modType) .sorted((m1, m2) -> m1.toString().compareTo(m2.toString())) .collect(Collectors.toList()); } }