io.jexiletools.es.modsmapping.ModsMapping.java Source code

Java tutorial

Introduction

Here is the source code for io.jexiletools.es.modsmapping.ModsMapping.java

Source

/*
 * 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());
    }
}