diff options
author | nea <romangraef@gmail.com> | 2022-07-12 02:40:32 +0200 |
---|---|---|
committer | nea <romangraef@gmail.com> | 2022-07-12 02:40:32 +0200 |
commit | f38206401e76303f04c7d82f24cbd1fa034d354f (patch) | |
tree | aa58289977b7b1bd804b3d59f5b543083edb1a7f /src/main/java/io/github/moulberry/repo | |
download | neurepoparsing-f38206401e76303f04c7d82f24cbd1fa034d354f.tar.gz neurepoparsing-f38206401e76303f04c7d82f24cbd1fa034d354f.tar.bz2 neurepoparsing-f38206401e76303f04c7d82f24cbd1fa034d354f.zip |
Initial commit
Diffstat (limited to 'src/main/java/io/github/moulberry/repo')
16 files changed, 595 insertions, 0 deletions
diff --git a/src/main/java/io/github/moulberry/repo/IReloadable.java b/src/main/java/io/github/moulberry/repo/IReloadable.java new file mode 100644 index 0000000..99590d8 --- /dev/null +++ b/src/main/java/io/github/moulberry/repo/IReloadable.java @@ -0,0 +1,5 @@ +package io.github.moulberry.repo; + +public interface IReloadable { + void reload(NEURepository repository) throws NEURepositoryException; +} diff --git a/src/main/java/io/github/moulberry/repo/NEUConstants.java b/src/main/java/io/github/moulberry/repo/NEUConstants.java new file mode 100644 index 0000000..eb37341 --- /dev/null +++ b/src/main/java/io/github/moulberry/repo/NEUConstants.java @@ -0,0 +1,40 @@ +package io.github.moulberry.repo; + +import com.google.gson.JsonElement; +import com.google.gson.JsonObject; +import com.google.gson.reflect.TypeToken; +import io.github.moulberry.repo.constants.Parents; +import io.github.moulberry.repo.constants.Bonuses; +import io.github.moulberry.repo.constants.Enchants; +import io.github.moulberry.repo.constants.EssenceCosts; +import io.github.moulberry.repo.constants.FairySouls; +import lombok.Getter; + +import java.util.List; +import java.util.Map; + +public class NEUConstants implements IReloadable { + @Getter + Bonuses bonuses; + @Getter + Parents parents; + @Getter + Enchants enchants; + @Getter + EssenceCosts essenceCost; + @Getter + FairySouls fairySouls; + + public void reload(NEURepository repository) throws NEURepositoryException { + bonuses = repository.requireFile("constants/bonuses.json").json(Bonuses.class); + parents = new Parents(repository.requireFile("constants/parents.json") + .json(new TypeToken<Map<String, List<String>>>() { + })); + enchants = repository.requireFile("constants/enchants.json").json(Enchants.class); + essenceCost = new EssenceCosts(repository.requireFile("constants/essencecosts.json").json(JsonObject.class)); + fairySouls = new FairySouls(repository.gson, repository.requireFile("constants/fairy_souls.json").json(new TypeToken<Map<String, JsonElement>>() { + })); + } + + +} diff --git a/src/main/java/io/github/moulberry/repo/NEUItems.java b/src/main/java/io/github/moulberry/repo/NEUItems.java new file mode 100644 index 0000000..650e67d --- /dev/null +++ b/src/main/java/io/github/moulberry/repo/NEUItems.java @@ -0,0 +1,35 @@ +package io.github.moulberry.repo; + +import io.github.moulberry.repo.data.NEUItem; +import io.github.moulberry.repo.util.StreamIt; +import lombok.Getter; +import org.checkerframework.checker.nullness.qual.Nullable; + +import java.util.HashMap; +import java.util.Locale; +import java.util.Map; +import java.util.stream.Stream; + +public class NEUItems implements IReloadable { + + @Getter + Map<String, NEUItem> items; + + @Override + public void reload(NEURepository repository) throws NEURepositoryException { + items = new HashMap<>(); + try (Stream<NEURepoFile> itemSources = repository.tree("items") + .filter(NEURepoFile::isFile) + .filter(it -> it.getFsPath().getFileName().toString().toLowerCase(Locale.ROOT).endsWith(".json"))) { + for (NEURepoFile rf : new StreamIt<>(itemSources)) { + NEUItem item = rf.json(NEUItem.class); + items.put(item.getSkyblockItemId(), item); + } + } + } + + @Nullable + public NEUItem getItemBySkyblockId(String itemId) { + return items.get(itemId.toUpperCase(Locale.ROOT)); + } +} diff --git a/src/main/java/io/github/moulberry/repo/NEURepoFile.java b/src/main/java/io/github/moulberry/repo/NEURepoFile.java new file mode 100644 index 0000000..df25d43 --- /dev/null +++ b/src/main/java/io/github/moulberry/repo/NEURepoFile.java @@ -0,0 +1,60 @@ +package io.github.moulberry.repo; + + +import com.google.gson.JsonSyntaxException; +import com.google.gson.reflect.TypeToken; +import lombok.AccessLevel; +import lombok.AllArgsConstructor; +import lombok.Getter; + +import java.io.IOException; +import java.io.InputStream; +import java.nio.charset.StandardCharsets; +import java.nio.file.Files; +import java.nio.file.LinkOption; +import java.nio.file.Path; + +@AllArgsConstructor(access = AccessLevel.PACKAGE) +public class NEURepoFile { + + public String getPath() { + return repository.baseFolder.relativize(fsPath).toString(); + } + + @Getter + private NEURepository repository; + @Getter + private Path fsPath; + + public <T> T json(TypeToken<T> type) throws NEURepositoryException { + try { + return repository.gson.fromJson(Files.newBufferedReader(fsPath, StandardCharsets.UTF_8), type.getType()); + } catch (IOException | SecurityException e) { + throw new NEURepositoryException(getPath(), "Could not read file", e); + } catch (JsonSyntaxException e) { + throw new NEURepositoryException(getPath(), "Invalid Json Syntax", e); + } + } + + public <T> T json(Class<T> $class) throws NEURepositoryException { + try { + return repository.gson.fromJson(Files.newBufferedReader(fsPath, StandardCharsets.UTF_8), $class); + } catch (IOException | SecurityException e) { + throw new NEURepositoryException(getPath(), "Could not read file", e); + } catch (JsonSyntaxException e) { + throw new NEURepositoryException(getPath(), "Invalid Json Syntax", e); + } + } + + public InputStream stream() throws NEURepositoryException { + try { + return Files.newInputStream(fsPath); + } catch (IOException | SecurityException e) { + throw new NEURepositoryException(getPath(), "Could not read file", e); + } + } + + public boolean isFile() { + return Files.isRegularFile(fsPath); + } +} diff --git a/src/main/java/io/github/moulberry/repo/NEURepository.java b/src/main/java/io/github/moulberry/repo/NEURepository.java new file mode 100644 index 0000000..d1d49f4 --- /dev/null +++ b/src/main/java/io/github/moulberry/repo/NEURepository.java @@ -0,0 +1,97 @@ +package io.github.moulberry.repo; + +import com.google.gson.Gson; +import com.google.gson.GsonBuilder; +import com.google.gson.reflect.TypeToken; +import io.github.moulberry.repo.data.Coordinate; +import lombok.Getter; +import lombok.NonNull; +import org.checkerframework.checker.nullness.qual.Nullable; + +import java.io.IOException; +import java.nio.file.Files; +import java.nio.file.Path; +import java.util.ArrayList; +import java.util.List; +import java.util.stream.Stream; + + +public final class NEURepository { + + final Gson gson = new GsonBuilder() + .setPrettyPrinting() + .registerTypeAdapter(new TypeToken<Coordinate>() { + }.getType(), new Coordinate.CoordinateSerializer()) + .create(); + @Getter + final Path baseFolder; + @Getter + final NEUConstants constants; + @Getter + final List<IReloadable> reloadables = new ArrayList<>(); + @Getter + final NEUItems items; + + public static NEURepository of(@NonNull Path baseFolder) { + return new NEURepository(baseFolder); + } + + + private NEURepository(@NonNull Path baseFolder) { + this.baseFolder = baseFolder; + this.constants = new NEUConstants(); + this.items = new NEUItems(); + registerReloadListener(this.constants); + registerReloadListener(this.items); + } + + public void registerReloadListener(IReloadable reloadable) { + reloadables.add(reloadable); + } + + public void reload() throws NEURepositoryException { + List<NEURepositoryException> storedExceptions = new ArrayList<>(); + for (IReloadable reloadable : reloadables) { + try { + reloadable.reload(this); + } catch (NEURepositoryException e) { + storedExceptions.add(e); + } + } + for (int i = 1; i < storedExceptions.size(); i++) { + storedExceptions.get(0).addSuppressed(storedExceptions.get(i)); + } + if (storedExceptions.size() > 0) { + throw storedExceptions.get(0); + } + } + + + public NEURepoFile requireFile(@NonNull String path) throws NEURepositoryException { + NEURepoFile file = file(path); + if (file == null) throw new NEURepositoryException(path, "this file is required", null); + return file; + } + + @Nullable + public NEURepoFile file(@NonNull String path) { + Path fsPath = baseFolder.resolve(path); + if (!Files.isReadable(fsPath)) + return null; + return new NEURepoFile(this, fsPath); + } + + /** + * @return a stream of {@link NEURepoFile}s below this path. This stream needs to be closed + */ + public Stream<NEURepoFile> tree(@NonNull String path) throws NEURepositoryException { + Path fsPath = baseFolder.resolve(path); + if (!Files.isDirectory(fsPath)) + return Stream.empty(); + try { + return Files.walk(fsPath).map(it -> new NEURepoFile(this, it)); + } catch (IOException e) { + throw new NEURepositoryException(path, "could not walk directory", e); + } + } +} diff --git a/src/main/java/io/github/moulberry/repo/NEURepositoryException.java b/src/main/java/io/github/moulberry/repo/NEURepositoryException.java new file mode 100644 index 0000000..3ae1faf --- /dev/null +++ b/src/main/java/io/github/moulberry/repo/NEURepositoryException.java @@ -0,0 +1,8 @@ +package io.github.moulberry.repo; + +public class NEURepositoryException extends Exception { + public NEURepositoryException(String path, String message, Throwable cause) { + super("NEU Repository | Failure loading " + path + ": " + message, cause); + } + +} diff --git a/src/main/java/io/github/moulberry/repo/NEURepositoryVersion.java b/src/main/java/io/github/moulberry/repo/NEURepositoryVersion.java new file mode 100644 index 0000000..c3996b8 --- /dev/null +++ b/src/main/java/io/github/moulberry/repo/NEURepositoryVersion.java @@ -0,0 +1,25 @@ +package io.github.moulberry.repo; + +import java.io.IOException; +import java.io.InputStream; +import java.util.Properties; + +public class NEURepositoryVersion { + + public static Properties VERSION_PROPERTIES = new Properties(); + + static { + InputStream resourceAsStream = NEURepositoryVersion.class.getClassLoader().getResourceAsStream("neurepoparser.properties"); + try { + VERSION_PROPERTIES.load(resourceAsStream); + } catch (IOException | NullPointerException e) { + new RuntimeException("NEURepositoryVersion could not load neurepoparser.properties.", e).printStackTrace(); + } + } + + public static String REPOSITORY_PARSER_VERSION = VERSION_PROPERTIES.getProperty("neurepository.parser.version", "unknown"); + public static int REPOSITORY_SCHEMA_VERSION_MINOR = Integer.parseInt(VERSION_PROPERTIES.getProperty("neurepository.schema.minor", "-1")); + public static int REPOSITORY_SCHEMA_VERSION_MAJOR = Integer.parseInt(VERSION_PROPERTIES.getProperty("neurepository.schema.major", "-1")); + + +} diff --git a/src/main/java/io/github/moulberry/repo/constants/Bonuses.java b/src/main/java/io/github/moulberry/repo/constants/Bonuses.java new file mode 100644 index 0000000..782ffec --- /dev/null +++ b/src/main/java/io/github/moulberry/repo/constants/Bonuses.java @@ -0,0 +1,51 @@ +package io.github.moulberry.repo.constants; + +import com.google.gson.annotations.SerializedName; +import io.github.moulberry.repo.data.Rarity; +import lombok.Getter; + +import java.util.Comparator; +import java.util.HashMap; +import java.util.Map; + +public class Bonuses { + + @Getter + @SerializedName("pet_rewards") + Map<Integer, Map<String, Float>> petRewards; + @Getter + @SerializedName("pet_value") + Map<Rarity, Integer> petValue; + @Getter + @SerializedName("bonus_stats") + Map<String, Map<Integer, Map<String, Float>>> bonusStats; + + public int getPetValue(Rarity rarity) { + return petValue.getOrDefault(rarity, 0); + } + + public Map<String, Float> getPetRewards(int score) { + return petRewards.entrySet().stream() + .sorted(Comparator.comparingInt(Map.Entry::getKey)) + .filter(it -> it.getKey() <= score) + .map(Map.Entry::getValue) + .reduce(new HashMap<>(), (a, b) -> { + a.putAll(b); + return a; + }); + } + + public Map<String, Float> getAccumulativeLevelingRewards(String name, int level) { + Map<Integer, Map<String, Float>> rewardTiers = bonusStats.getOrDefault(name, new HashMap<>()); + Map<String, Float> rewards = new HashMap<>(); + Map<String, Float> currentBonuses = new HashMap<>(); + for (int i = 0; i <= level; i++) { + currentBonuses = rewardTiers.getOrDefault(i, currentBonuses); + for (Map.Entry<String, Float> reward : currentBonuses.entrySet()) { + rewards.put(reward.getKey(), rewards.getOrDefault(reward.getKey(), 0F) + reward.getValue()); + } + } + return rewards; + } + +} diff --git a/src/main/java/io/github/moulberry/repo/constants/Enchants.java b/src/main/java/io/github/moulberry/repo/constants/Enchants.java new file mode 100644 index 0000000..84e5761 --- /dev/null +++ b/src/main/java/io/github/moulberry/repo/constants/Enchants.java @@ -0,0 +1,38 @@ +package io.github.moulberry.repo.constants; + +import com.google.gson.annotations.SerializedName; +import lombok.Getter; + +import java.util.ArrayList; +import java.util.List; +import java.util.Map; + +public class Enchants { + + @Getter + @SerializedName("enchants") + Map<String, List<String>> availableEnchants; + + @Getter + @SerializedName("enchant_pools") + List<List<String>> enchantPools; + + @Getter + @SerializedName("enchants_xp_cost") + Map<String, List<Integer>> enchantExperienceCost; + + public List<String> getAvailableEnchants(String tooltype) { + return availableEnchants.get(tooltype); + } + + public List<String> getConflictingEnchants(String enchant) { + List<String> conflicts = new ArrayList<>(); + for (List<String> enchantPool : enchantPools) { + if (enchantPool.contains(enchant)) { + conflicts.addAll(enchantPool); + conflicts.remove(enchant); + } + } + return conflicts; + } +} diff --git a/src/main/java/io/github/moulberry/repo/constants/EssenceCosts.java b/src/main/java/io/github/moulberry/repo/constants/EssenceCosts.java new file mode 100644 index 0000000..2280b13 --- /dev/null +++ b/src/main/java/io/github/moulberry/repo/constants/EssenceCosts.java @@ -0,0 +1,75 @@ +package io.github.moulberry.repo.constants; + +import com.google.gson.JsonArray; +import com.google.gson.JsonElement; +import com.google.gson.JsonObject; +import io.github.moulberry.repo.NEURepositoryException; +import lombok.Data; +import lombok.Getter; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +public class EssenceCosts { + + @Data + public static class EssenceCost { + private EssenceCost() { + } + + @Getter + String type; + + @Getter + Map<Integer, Integer> essenceCosts; + + /** + * WARNING: The inner list of strings is NOT item ids or ingredients, instead it *currently* is item + * descriptions (as intended to be user facing strings). + */ + @Getter + Map<Integer, List<String>> itemCosts; + } + + @Getter + Map<String, EssenceCost> costs; + + public EssenceCosts(JsonObject json) throws NEURepositoryException { + costs = new HashMap<>(); + + try { + for (Map.Entry<String, JsonElement> costs : json.entrySet()) { + EssenceCost essenceCost = new EssenceCost(); + JsonElement value = costs.getValue(); + JsonObject object = value.getAsJsonObject(); + essenceCost.type = object.get("type").getAsString(); + essenceCost.essenceCosts = new HashMap<>(); + int i = 1; + while (true) { + JsonElement costThing = object.get(i + ""); + if (costThing == null) break; + int cost = costThing.getAsInt(); + essenceCost.essenceCosts.put(i, cost); + i++; + } + essenceCost.itemCosts = new HashMap<>(); + if (object.has("items")) { + JsonObject items = object.getAsJsonObject("items"); + for (Map.Entry<String, JsonElement> itemCost : items.entrySet()) { + JsonArray itemCostList = itemCost.getValue().getAsJsonArray(); + List<String> itemCostListTrans = new ArrayList<>(); + for (JsonElement jsonElement : itemCostList) { + itemCostListTrans.add(jsonElement.getAsString()); + } + essenceCost.itemCosts.put(Integer.parseInt(itemCost.getKey()), itemCostListTrans); + } + } + this.costs.put(costs.getKey(), essenceCost); + } + } catch (ClassCastException | NumberFormatException e) { + throw new NEURepositoryException("constants/essencecosts.json", "Invalid JSON Syntax", e); + } + } +} diff --git a/src/main/java/io/github/moulberry/repo/constants/FairySouls.java b/src/main/java/io/github/moulberry/repo/constants/FairySouls.java new file mode 100644 index 0000000..ca6426d --- /dev/null +++ b/src/main/java/io/github/moulberry/repo/constants/FairySouls.java @@ -0,0 +1,31 @@ +package io.github.moulberry.repo.constants; + +import com.google.gson.Gson; +import com.google.gson.JsonElement; +import com.google.gson.reflect.TypeToken; +import io.github.moulberry.repo.data.Coordinate; +import lombok.Getter; + +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +public class FairySouls { + @Getter + int maxSouls; + @Getter + Map<String, List<Coordinate>> soulLocations = new HashMap<>(); + + public FairySouls(Gson gson, Map<String, JsonElement> json) { + for (Map.Entry<String, JsonElement> things : json.entrySet()) { + if (things.getValue().isJsonArray()) { + soulLocations.put( + things.getKey(), + gson.fromJson(things.getValue(), + new TypeToken<List<Coordinate>>() { + }.getType())); + } + } + maxSouls = json.get("Max Souls").getAsInt(); + } +} diff --git a/src/main/java/io/github/moulberry/repo/constants/Parents.java b/src/main/java/io/github/moulberry/repo/constants/Parents.java new file mode 100644 index 0000000..cd1d770 --- /dev/null +++ b/src/main/java/io/github/moulberry/repo/constants/Parents.java @@ -0,0 +1,33 @@ +package io.github.moulberry.repo.constants; + +import lombok.Getter; + +import java.util.*; + +public class Parents { + @Getter + Map<String, List<String>> parents; + + Map<String, String> reverseParents = new HashMap<>(); + + public Parents(Map<String, List<String>> parents) { + this.parents = parents; + for (Map.Entry<String, List<String>> parentings : parents.entrySet()) { + String parent = parentings.getKey(); + for (String child : parentings.getValue()) { + reverseParents.put(child, parent); + } + } + } + + public List<String> getChildren(String itemId) { + return parents.getOrDefault(itemId, new ArrayList<>()); + } + + public Optional<String> getParent(String itemId) { + return reverseParents.containsKey(itemId) + ? Optional.of(reverseParents.get(itemId)) + : Optional.empty(); + } + +} diff --git a/src/main/java/io/github/moulberry/repo/data/Coordinate.java b/src/main/java/io/github/moulberry/repo/data/Coordinate.java new file mode 100644 index 0000000..ffd2ee4 --- /dev/null +++ b/src/main/java/io/github/moulberry/repo/data/Coordinate.java @@ -0,0 +1,31 @@ +package io.github.moulberry.repo.data; + +import com.google.gson.JsonDeserializationContext; +import com.google.gson.JsonDeserializer; +import com.google.gson.JsonElement; +import com.google.gson.JsonParseException; +import lombok.AllArgsConstructor; +import lombok.Data; + +import java.lang.reflect.Type; + +@Data +@AllArgsConstructor +public class Coordinate { + int x, y, z; + + public static class CoordinateSerializer implements JsonDeserializer<Coordinate> { + @Override + public Coordinate deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context) throws JsonParseException { + String asString = json.getAsString(); + String[] split = asString.split(","); + if (split.length != 3) + throw new JsonParseException("Coordinate must be a string consisting of 3 numbers seperated by , but is `" + asString + "`"); + return new Coordinate( + Integer.parseInt(split[0]), + Integer.parseInt(split[1]), + Integer.parseInt(split[2]) + ); + } + } +} diff --git a/src/main/java/io/github/moulberry/repo/data/NEUItem.java b/src/main/java/io/github/moulberry/repo/data/NEUItem.java new file mode 100644 index 0000000..7503544 --- /dev/null +++ b/src/main/java/io/github/moulberry/repo/data/NEUItem.java @@ -0,0 +1,25 @@ +package io.github.moulberry.repo.data; + +import com.google.gson.annotations.SerializedName; +import lombok.Getter; + +import java.util.List; + +@Getter +public class NEUItem { + @SerializedName("itemid") + String minecraftItemId; + @SerializedName("displayname") + String displayName; + String nbttag; + int damage; + List<String> lore; + @SerializedName("internalname") + String skyblockItemId; + String crafttext; + String clickcommand; + String modver; + String infoType; + List<String> info; + +} diff --git a/src/main/java/io/github/moulberry/repo/data/Rarity.java b/src/main/java/io/github/moulberry/repo/data/Rarity.java new file mode 100644 index 0000000..0dfb365 --- /dev/null +++ b/src/main/java/io/github/moulberry/repo/data/Rarity.java @@ -0,0 +1,17 @@ +package io.github.moulberry.repo.data; + +public enum Rarity { + + COMMON, + UNCOMMON, + RARE, + EPIC, + LEGENDARY, + MYTHIC, + DIVINE, + SUPREME, + SPECIAL, + VERY_SPECIAL, + UNKNOWN + +} diff --git a/src/main/java/io/github/moulberry/repo/util/StreamIt.java b/src/main/java/io/github/moulberry/repo/util/StreamIt.java new file mode 100644 index 0000000..14b6e54 --- /dev/null +++ b/src/main/java/io/github/moulberry/repo/util/StreamIt.java @@ -0,0 +1,24 @@ +package io.github.moulberry.repo.util; + +import java.util.Iterator; +import java.util.Spliterator; +import java.util.stream.Stream; + +public class StreamIt<T> implements Iterable<T> { + Stream<T> s; + + public StreamIt(Stream<T> t) { + s = t; + } + + + @Override + public Iterator<T> iterator() { + return s.iterator(); + } + + @Override + public Spliterator<T> spliterator() { + return s.spliterator(); + } +} |