package io.github.moulberry.notenoughupdates.profileviewer; import com.google.gson.*; import io.github.moulberry.notenoughupdates.util.Utils; import net.minecraft.nbt.*; import net.minecraft.util.EnumChatFormatting; import org.apache.commons.lang3.StringUtils; import java.io.ByteArrayInputStream; import java.io.IOException; import java.util.Base64; import java.util.HashMap; import java.util.HashSet; import java.util.Map; import java.util.regex.Matcher; import java.util.regex.Pattern; public class PlayerStats { public static final String HEALTH = "health"; public static final String DEFENCE = "defence"; public static final String STRENGTH = "strength"; public static final String SPEED = "speed"; public static final String CRIT_CHANCE = "crit_chance"; public static final String CRIT_DAMAGE = "crit_damage"; public static final String BONUS_ATTACK_SPEED = "bonus_attack_speed"; public static final String INTELLIGENCE = "intelligence"; public static final String SEA_CREATURE_CHANCE = "sea_creature_chance"; public static final String MAGIC_FIND = "magic_find"; public static final String PET_LUCK = "pet_luck"; public static final String[] defaultStatNames = new String[]{"health","defence","strength","speed","crit_chance", "crit_damage","bonus_attack_speed","intelligence","sea_creature_chance","magic_find","pet_luck"}; public static final String[] defaultStatNamesPretty = new String[]{EnumChatFormatting.RED+"\u2764 Health",EnumChatFormatting.GREEN+"\u2748 Defence", EnumChatFormatting.RED+"\u2741 Strength",EnumChatFormatting.WHITE+"\u2726 Speed",EnumChatFormatting.BLUE+"\u2623 Crit Chance", EnumChatFormatting.BLUE+"\u2620 Crit Damage",EnumChatFormatting.YELLOW+"\u2694 Attack Speed",EnumChatFormatting.AQUA+"\u270e Intelligence", EnumChatFormatting.DARK_AQUA+"\u03b1 SC Chance",EnumChatFormatting.AQUA+"\u272f Magic Find",EnumChatFormatting.LIGHT_PURPLE+"\u2663 Pet Luck"}; public static class Stats { JsonObject statsJson = new JsonObject(); /*public float health; public float defence; public float strength; public float speed; public float crit_chance; public float crit_damage; public float bonus_attack_speed; public float intelligence; public float sea_creature_chance; public float magic_find; public float pet_luck;*/ public Stats(Stats... statses) { for(Stats stats : statses) { add(stats); } } /*@Override public String toString() { return String.format("{health=%s,defence=%s,strength=%s,speed=%s,crit_chance=%s,crit_damage=%s," + "bonus_attack_speed=%s,intelligence=%s,sea_creature_chance=%s,magic_find=%s,pet_luck=%s}", stats.get("health"), defence, strength, speed, crit_chance, crit_damage, bonus_attack_speed, intelligence, sea_creature_chance, magic_find, pet_luck); }*/ public float get(String statName) { if(statsJson.has(statName)) { return statsJson.get(statName).getAsFloat(); } else { return 0; } } public Stats add(Stats stats) { for(Map.Entry statEntry : stats.statsJson.entrySet()) { if(statEntry.getValue().isJsonPrimitive() && ((JsonPrimitive)statEntry.getValue()).isNumber()) { if(!statsJson.has(statEntry.getKey())) { statsJson.add(statEntry.getKey(), statEntry.getValue()); } else { JsonPrimitive e = statsJson.get(statEntry.getKey()).getAsJsonPrimitive(); float statNum = e.getAsFloat() + statEntry.getValue().getAsFloat(); statsJson.add(statEntry.getKey(), new JsonPrimitive(statNum)); } } } return this; } public void scaleAll(float scale) { for(Map.Entry statEntry : statsJson.entrySet()) { statsJson.add(statEntry.getKey(), new JsonPrimitive(statEntry.getValue().getAsFloat()*scale)); } } public void addStat(String statName, float amount) { if(!statsJson.has(statName)) { statsJson.add(statName, new JsonPrimitive(amount)); } else { JsonPrimitive e = statsJson.get(statName).getAsJsonPrimitive(); statsJson.add(statName, new JsonPrimitive(e.getAsFloat() + amount)); } } } public static Stats getBaseStats() { JsonObject misc = Utils.getConstant("misc"); if(misc == null) return null; Stats stats = new Stats(); for(String statName : defaultStatNames) { stats.addStat(statName, Utils.getElementAsFloat(Utils.getElement(misc, "base_stats."+statName), 0)); } return stats; } private static Stats getFairyBonus(int fairyExchanges) { Stats bonus = new Stats(); bonus.addStat(SPEED, fairyExchanges/10); for(int i=0; i entry : skillInfo.entrySet()) { if(entry.getKey().startsWith("level_")) { String skill = entry.getKey().substring("level_".length()); JsonObject skillStatMap = Utils.getElement(bonuses, "bonus_stats."+skill).getAsJsonObject(); Stats currentBonus = new Stats(); for(int i=1; i<=entry.getValue().getAsFloat(); i++) { if(skillStatMap.has(""+i)) { currentBonus = new Stats(); for(Map.Entry entry2 : skillStatMap.get(""+i).getAsJsonObject().entrySet()) { currentBonus.addStat(entry2.getKey(), entry2.getValue().getAsFloat()); } } skillBonus.add(currentBonus); } } } return skillBonus; } private static Stats getPetBonus(JsonObject profile) { JsonObject bonuses = Utils.getConstant("bonuses"); if(bonuses == null) return null; JsonElement petsElement = Utils.getElement(profile, "pets"); if(petsElement == null) return new Stats(); JsonArray pets = petsElement.getAsJsonArray(); HashMap highestRarityMap = new HashMap<>(); for(int i=0; i entry : petRewards.get(""+i).getAsJsonObject().entrySet()) { petBonus.addStat(entry.getKey(), entry.getValue().getAsFloat()); } } } return petBonus; } private static float harpBonus(JsonObject profile) { String talk_to_melody = Utils.getElementAsString(Utils.getElement(profile, "objectives.talk_to_melody.status"), "INCOMPLETE"); if(talk_to_melody.equalsIgnoreCase("COMPLETE")) { return 26; } else { return 0; } } public static Stats getPassiveBonuses(JsonObject skillInfo, JsonObject profile) { Stats passiveBonuses = new Stats(); Stats fairyBonus = getFairyBonus((int)Utils.getElementAsFloat(Utils.getElement(profile, "fairy_exchanges"), 0)); Stats skillBonus = getSkillBonus(skillInfo); Stats petBonus = getPetBonus(profile); if(fairyBonus == null || skillBonus == null || petBonus == null) return null; passiveBonuses.add(fairyBonus); passiveBonuses.add(skillBonus); passiveBonuses.addStat(INTELLIGENCE, harpBonus(profile)); passiveBonuses.add(petBonus); return passiveBonuses; } private static String getFullset(JsonArray armor, int ignore) { String fullset = null; for(int i=0; i=0; i--) { String line = lore.get(i).getAsString(); for(String rarity : rarityArr) { for(int j=0; j STAT_PATTERN_MAP = new HashMap<>(); static { STAT_PATTERN_MAP.put("health", HEALTH_PATTERN); STAT_PATTERN_MAP.put("defence", DEFENCE_PATTERN); STAT_PATTERN_MAP.put("strength", STRENGTH_PATTERN); STAT_PATTERN_MAP.put("speed", SPEED_PATTERN); STAT_PATTERN_MAP.put("crit_chance", CC_PATTERN); STAT_PATTERN_MAP.put("crit_damage", CD_PATTERN); STAT_PATTERN_MAP.put("bonus_attack_speed", ATKSPEED_PATTERN); STAT_PATTERN_MAP.put("intelligence", INTELLIGENCE_PATTERN); STAT_PATTERN_MAP.put("sea_creature_chance", SCC_PATTERN); } private static Stats getStatForItem(String internalname, JsonObject item, JsonArray lore) { Stats stats = new Stats(); for(int i=0; i entry : STAT_PATTERN_MAP.entrySet()) { Matcher matcher = entry.getValue().matcher(Utils.cleanColour(line)); if(matcher.find()) { int bonus = Integer.parseInt(matcher.group(1)); //System.out.println(entry.getKey() + ":" + bonus); stats.addStat(entry.getKey(), bonus); } } } if(internalname.equals("DAY_CRYSTAL") || internalname.equals("NIGHT_CRYSTAL")) { stats.addStat(STRENGTH, 2.5f); stats.addStat(DEFENCE, 2.5f); System.out.println("added day"); } if(internalname.equals("NEW_YEAR_CAKE_BAG") && item.has("item_contents")) { JsonArray bytesArr = item.get("item_contents").getAsJsonArray(); byte[] bytes = new byte[bytesArr.size()]; for(int i=0; i cakes = new HashSet<>(); for(int j=0; j 0) { NBTTagCompound nbt = items.getCompoundTagAt(j).getCompoundTag("tag"); if(nbt != null && nbt.hasKey("ExtraAttributes", 10)) { NBTTagCompound ea = nbt.getCompoundTag("ExtraAttributes"); if (ea.hasKey("new_years_cake")) { cakes.add(ea.getInteger("new_years_cake")); } } } } stats.addStat(HEALTH, cakes.size()); } catch(IOException e) { e.printStackTrace(); return stats; } } return stats; } private static Stats getItemBonuses(boolean talismanOnly, JsonArray... inventories) { JsonObject misc = Utils.getConstant("misc"); if(misc == null) return null; JsonElement talisman_upgrades_element = misc.get("talisman_upgrades"); if(talisman_upgrades_element == null) return null; JsonObject talisman_upgrades = talisman_upgrades_element.getAsJsonObject(); HashMap itemBonuses = new HashMap<>(); for(JsonArray inventory : inventories) { for(int i=0; i= 0) { Stats itemBonus = getStatForItem(internalname, item, item.get("lore").getAsJsonArray()); itemBonuses.put(internalname, itemBonus); for(Map.Entry talisman_upgrades_item : talisman_upgrades.entrySet()) { JsonArray upgrades = talisman_upgrades_item.getValue().getAsJsonArray(); for(int j=0; j0 JsonArray armor = Utils.getElement(inventoryInfo, "inv_armor").getAsJsonArray(); String fullset = getFullset(armor, 3); if(fullset != null) { switch(fullset) { case "CHEAP_TUXEDO_": stats.statsJson.add(HEALTH, new JsonPrimitive(Math.min(75, stats.get(HEALTH)))); case "FANCY_TUXEDO_": stats.statsJson.add(HEALTH, new JsonPrimitive(Math.min(150, stats.get(HEALTH)))); case "ELEGANT_TUXEDO_": stats.statsJson.add(HEALTH, new JsonPrimitive(Math.min(250, stats.get(HEALTH)))); } } for(Map.Entry statEntry : stats.statsJson.entrySet()) { stats.statsJson.add(statEntry.getKey(), new JsonPrimitive(Math.max(0, statEntry.getValue().getAsFloat()))); } } public static Stats getStats(JsonObject skillInfo, JsonObject inventoryInfo, JsonObject collectionInfo, JsonObject profile) { if(skillInfo == null || inventoryInfo == null || collectionInfo == null || profile == null) return null; JsonArray armor = Utils.getElement(inventoryInfo, "inv_armor").getAsJsonArray(); JsonArray inventory = Utils.getElement(inventoryInfo, "inv_contents").getAsJsonArray(); JsonArray talisman_bag = Utils.getElement(inventoryInfo, "talisman_bag").getAsJsonArray(); Stats passiveBonuses = getPassiveBonuses(skillInfo, profile); System.out.println("passive:"+new Stats(passiveBonuses, getBaseStats())); Stats armorBonuses = getItemBonuses(false, armor); Stats talismanBonuses = getItemBonuses(true, inventory, talisman_bag); if(passiveBonuses == null) System.out.println("passive null"); if(armorBonuses == null) System.out.println("armorBonuses null"); if(talismanBonuses == null) System.out.println("talismanBonuses null"); if(passiveBonuses == null || armorBonuses == null || talismanBonuses == null) return null; Stats stats = getBaseStats().add(passiveBonuses).add(armorBonuses).add(talismanBonuses); stats.add(getSetBonuses(stats, inventoryInfo, collectionInfo, skillInfo, profile)); stats.scaleAll(getStatMult(inventoryInfo)); applyLimits(stats, inventoryInfo); return stats; } }