diff options
author | nea <romangraef@gmail.com> | 2022-07-26 16:16:44 +0200 |
---|---|---|
committer | nea <romangraef@gmail.com> | 2022-07-26 16:20:17 +0200 |
commit | 1f3b703bc7b3967bcf918a57988efd14db04eabf (patch) | |
tree | 8adf88d5f942a0f65d7b66bf33d11d611dc04f51 /src/main/java | |
parent | 39769a4aafb1b793c8041bcf0dcf437799717b13 (diff) | |
download | neurepoparsing-1f3b703bc7b3967bcf918a57988efd14db04eabf.tar.gz neurepoparsing-1f3b703bc7b3967bcf918a57988efd14db04eabf.tar.bz2 neurepoparsing-1f3b703bc7b3967bcf918a57988efd14db04eabf.zip |
Recipe parsing
Diffstat (limited to 'src/main/java')
10 files changed, 373 insertions, 0 deletions
diff --git a/src/main/java/io/github/moulberry/repo/NEURecipeCache.java b/src/main/java/io/github/moulberry/repo/NEURecipeCache.java new file mode 100644 index 0000000..50e0481 --- /dev/null +++ b/src/main/java/io/github/moulberry/repo/NEURecipeCache.java @@ -0,0 +1,56 @@ +package io.github.moulberry.repo; + +import io.github.moulberry.repo.data.NEUIngredient; +import io.github.moulberry.repo.data.NEUItem; +import io.github.moulberry.repo.data.NEURecipe; +import lombok.Getter; + +import java.util.HashMap; +import java.util.HashSet; +import java.util.Map; +import java.util.Set; + +public class NEURecipeCache implements IReloadable { + + private NEURecipeCache() { + } + + /** + * Create a recipe cache. + * + * @param repository the repository for which to create a recipe cache + * + * @return an unitialized repository cache, that can be initialized by calling {@link NEURepository#reload()}, or by + * manually {{@link #reload}ing it.} + */ + public static NEURecipeCache forRepo(NEURepository repository) { + NEURecipeCache neuRecipeCache = new NEURecipeCache(); + repository.registerReloadListener(neuRecipeCache); + return neuRecipeCache; + } + + + @Getter + Map<String, Set<NEURecipe>> recipes = new HashMap<>(); + @Getter + Map<String, Set<NEURecipe>> usages = new HashMap<>(); + + + @Override + public void reload(NEURepository repository) throws NEURepositoryException { + Map<String, Set<NEURecipe>> recipes = new HashMap<>(); + Map<String, Set<NEURecipe>> usages = new HashMap<>(); + for (NEUItem item : repository.getItems().getItems().values()) { + for (NEURecipe recipe : item.getRecipes()) { + for (NEUIngredient input : recipe.getAllInputs()) { + usages.computeIfAbsent(input.getItemId(), ignored -> new HashSet<>()).add(recipe); + } + for (NEUIngredient output : recipe.getAllOutputs()) { + recipes.computeIfAbsent(output.getItemId(), ignored -> new HashSet<>()).add(recipe); + } + } + } + this.recipes = recipes; + this.usages = usages; + } +} diff --git a/src/main/java/io/github/moulberry/repo/NEURepository.java b/src/main/java/io/github/moulberry/repo/NEURepository.java index b5f942c..122ef24 100644 --- a/src/main/java/io/github/moulberry/repo/NEURepository.java +++ b/src/main/java/io/github/moulberry/repo/NEURepository.java @@ -23,14 +23,21 @@ public final class NEURepository { final Gson gson = new GsonBuilder() .setPrettyPrinting() + .registerTypeAdapter(new TypeToken<NEUIngredient>() { + }.getType(), new NEUIngredient.Serializer()) .registerTypeAdapter(new TypeToken<Coordinate>() { }.getType(), new Coordinate.CoordinateSerializer()) + .registerTypeAdapter(new TypeToken<NEUMobDropRecipe.Drop>() { + }.getType(), new NEUMobDropRecipe.Drop.Serializer()) + .registerTypeAdapter(new TypeToken<NEUCraftingRecipe>() { + }.getType(), new NEUCraftingRecipe.Serializer()) .registerTypeAdapterFactory( RuntimeTypeAdapterFactory.of(NEURecipe.class, "type") .registerSubtype(NEUForgeRecipe.class, "forge") .registerSubtype(NEUTradeRecipe.class, "trade") .registerSubtype(NEUCraftingRecipe.class, "crafting") .registerSubtype(NEUMobDropRecipe.class, "drops") + .registerSubtype(NEUNpcShopRecipe.class, "npc_shop") .setDefaultTypeTag("crafting") ) .create(); diff --git a/src/main/java/io/github/moulberry/repo/data/NEUCraftingRecipe.java b/src/main/java/io/github/moulberry/repo/data/NEUCraftingRecipe.java index cf025d4..420fad7 100644 --- a/src/main/java/io/github/moulberry/repo/data/NEUCraftingRecipe.java +++ b/src/main/java/io/github/moulberry/repo/data/NEUCraftingRecipe.java @@ -1,4 +1,76 @@ package io.github.moulberry.repo.data; +import com.google.gson.*; +import lombok.Getter; +import org.checkerframework.checker.nullness.qual.Nullable; + +import java.lang.reflect.Type; +import java.util.ArrayList; +import java.util.Collection; +import java.util.Collections; +import java.util.List; + +@Getter public class NEUCraftingRecipe implements NEURecipe { + + NEUIngredient[] inputs; + @Nullable + String extraText; + NEUIngredient output; + int outputCount; + + public static class Serializer implements JsonDeserializer<NEUCraftingRecipe> { + + @Override + public NEUCraftingRecipe deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context) throws JsonParseException { + NEUCraftingRecipe cr = new NEUCraftingRecipe(); + JsonObject recipe = json.getAsJsonObject(); + String[] x = {"1", "2", "3"}; + String[] y = {"A", "B", "C"}; + cr.inputs = new NEUIngredient[9]; + for (int i = 0; i < 9; i++) { + String name = y[i / 3] + x[i % 3]; + if (!recipe.has(name)) continue; + String item = recipe.get(name).getAsString(); + if (item == null || item.isEmpty()) { + cr.inputs[i] = NEUIngredient.SENTINEL_EMPTY; + } else { + cr.inputs[i] = NEUIngredient.fromString(item); + } + } + cr.outputCount = -1; + if (recipe.has("count")) + cr.outputCount = recipe.get("count").getAsInt(); + if (recipe.has("crafttext")) + cr.extraText = recipe.get("crafttext").getAsString(); + if (recipe.has("overrideOutputId")) + cr.output = NEUIngredient.fromString(recipe.get("overrideOutputId").getAsString()); + return cr; + } + } + + @Override + public void fillItemInfo(NEUItem item) { + if (this.extraText == null) + this.extraText = item.crafttext; + if (this.output == null) + this.output = NEUIngredient.fromString(item.skyblockItemId); + if (outputCount > 0) + this.output.amount = outputCount; + } + + @Override + public Collection<NEUIngredient> getAllOutputs() { + return Collections.singletonList(output); + } + + @Override + public Collection<NEUIngredient> getAllInputs() { + List<NEUIngredient> ingredientList = new ArrayList<>(); + for (NEUIngredient ingredient : inputs) { + if (ingredient != null) + ingredientList.add(ingredient); + } + return ingredientList; + } } diff --git a/src/main/java/io/github/moulberry/repo/data/NEUForgeRecipe.java b/src/main/java/io/github/moulberry/repo/data/NEUForgeRecipe.java index 6dbed06..05c2943 100644 --- a/src/main/java/io/github/moulberry/repo/data/NEUForgeRecipe.java +++ b/src/main/java/io/github/moulberry/repo/data/NEUForgeRecipe.java @@ -1,5 +1,42 @@ package io.github.moulberry.repo.data; +import lombok.Getter; + +import java.util.Collection; +import java.util.Collections; +import java.util.List; + public class NEUForgeRecipe implements NEURecipe { + @Getter + List<NEUIngredient> inputs; + int count; + String overrideOutputId; + @Getter + int duration; + @Getter + transient NEUIngredient outputStack; + + + @Override + public void fillItemInfo(NEUItem item) { + if (overrideOutputId == null) { + outputStack = NEUIngredient.fromString(item.skyblockItemId); + } else { + outputStack = NEUIngredient.fromString(overrideOutputId); + } + if (count > 0) { + outputStack.amount = count; + } + } + + @Override + public Collection<NEUIngredient> getAllOutputs() { + return Collections.singletonList(outputStack); + } + + @Override + public Collection<NEUIngredient> getAllInputs() { + return inputs; + } } diff --git a/src/main/java/io/github/moulberry/repo/data/NEUIngredient.java b/src/main/java/io/github/moulberry/repo/data/NEUIngredient.java new file mode 100644 index 0000000..9f7d62c --- /dev/null +++ b/src/main/java/io/github/moulberry/repo/data/NEUIngredient.java @@ -0,0 +1,63 @@ +package io.github.moulberry.repo.data; + +import com.google.gson.*; +import lombok.Getter; + +import java.lang.reflect.Type; + +@Getter +public class NEUIngredient { + String itemId; + int amount; + public static final String NEU_SENTINEL_EMPTY = "NEU_SENTINEL_EMPTY"; + public static final NEUIngredient SENTINEL_EMPTY = new NEUIngredient(); + + static { + SENTINEL_EMPTY.itemId = NEU_SENTINEL_EMPTY; + SENTINEL_EMPTY.amount = 0; + } + + private NEUIngredient() { + } + + public static NEUIngredient fromItem(NEUItem item, int count) { + NEUIngredient ingredient = new NEUIngredient(); + ingredient.amount = count; + ingredient.itemId = item.getSkyblockItemId(); + return ingredient; + } + + public static NEUIngredient fromString(String string) { + String[] parts = string.split(":"); + NEUIngredient ingredient = new NEUIngredient(); + if (parts.length == 2) { + ingredient.amount = Integer.parseInt(parts[1]); + } else if (parts.length == 1) { + ingredient.amount = 1; + } else { + throw new IllegalArgumentException("Could not parse ingredient " + string); + } + ingredient.itemId = parts[0]; + if (NEU_SENTINEL_EMPTY.equals(ingredient.itemId)) + return SENTINEL_EMPTY; + return ingredient; + } + + public static class Serializer implements JsonDeserializer<NEUIngredient> { + + @Override + public NEUIngredient deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context) throws JsonParseException { + + if (!json.isJsonPrimitive()) throw new JsonParseException("Expected string for ingredient, found " + json); + JsonPrimitive p = json.getAsJsonPrimitive(); + if (!p.isString()) throw new JsonParseException("Expected string for ingredient, found " + json); + String asString = json.getAsString(); + return fromString(asString); + } + } + + @Override + public String toString() { + return String.format("NEUIngredient{%s:%d}", itemId, amount); + } +} diff --git a/src/main/java/io/github/moulberry/repo/data/NEUItem.java b/src/main/java/io/github/moulberry/repo/data/NEUItem.java index 61d08aa..94de529 100644 --- a/src/main/java/io/github/moulberry/repo/data/NEUItem.java +++ b/src/main/java/io/github/moulberry/repo/data/NEUItem.java @@ -49,6 +49,9 @@ public class NEUItem { if (singletonRecipe != null) newRecipes.add(singletonRecipe); recipes = newRecipes; + for (NEURecipe recipe : recipes) { + recipe.fillItemInfo(this); + } } } } diff --git a/src/main/java/io/github/moulberry/repo/data/NEUMobDropRecipe.java b/src/main/java/io/github/moulberry/repo/data/NEUMobDropRecipe.java index 6b5dfeb..cf192d4 100644 --- a/src/main/java/io/github/moulberry/repo/data/NEUMobDropRecipe.java +++ b/src/main/java/io/github/moulberry/repo/data/NEUMobDropRecipe.java @@ -1,4 +1,76 @@ package io.github.moulberry.repo.data; +import com.google.gson.*; +import com.google.gson.annotations.SerializedName; +import com.google.gson.reflect.TypeToken; +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.Getter; +import org.checkerframework.checker.nullness.qual.Nullable; + +import java.lang.reflect.Type; +import java.util.ArrayList; +import java.util.Collection; +import java.util.Collections; +import java.util.List; + +@Getter public class NEUMobDropRecipe implements NEURecipe { + @SerializedName("combat_xp") + int combatExperience; + int coins; + @SerializedName("xp") + int enchantingExperience; + String name; + String render; + String panorama; + int level; + List<String> extra; + List<Drop> drops; + transient NEUItem dropsFrom; + + @Data + @AllArgsConstructor + public static class Drop { + NEUIngredient dropItem; + @Nullable + String chance; + List<String> extra; + + public static class Serializer implements JsonDeserializer<Drop> { + + @Override + public Drop deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context) throws JsonParseException { + if (json.isJsonPrimitive()) { + return new Drop(NEUIngredient.fromString(json.getAsString()), null, Collections.emptyList()); + } + JsonObject d = json.getAsJsonObject(); + return new Drop( + NEUIngredient.fromString(d.get("id").getAsString()), + d.has("chance") ? d.get("chance").getAsString() : null, + d.has("extra") ? context.deserialize(d.get("extra"), new TypeToken<List<String>>() { + }.getType()) : Collections.emptyList() + ); + } + } + } + + @Override + public void fillItemInfo(NEUItem item) { + dropsFrom = item; + } + + @Override + public Collection<NEUIngredient> getAllInputs() { + return Collections.singletonList(NEUIngredient.fromItem(dropsFrom, 1)); + } + + @Override + public Collection<NEUIngredient> getAllOutputs() { + List<NEUIngredient> l = new ArrayList<>(); + for (Drop drop : drops) { + l.add(drop.getDropItem()); + } + return l; + } } diff --git a/src/main/java/io/github/moulberry/repo/data/NEUNpcShopRecipe.java b/src/main/java/io/github/moulberry/repo/data/NEUNpcShopRecipe.java new file mode 100644 index 0000000..df8bf73 --- /dev/null +++ b/src/main/java/io/github/moulberry/repo/data/NEUNpcShopRecipe.java @@ -0,0 +1,30 @@ +package io.github.moulberry.repo.data; + +import lombok.Getter; + +import java.util.Collection; +import java.util.Collections; +import java.util.List; + +@Getter +public class NEUNpcShopRecipe implements NEURecipe { + + List<NEUIngredient> cost; + NEUIngredient result; + NEUItem isSoldBy; + + @Override + public void fillItemInfo(NEUItem item) { + isSoldBy = item; + } + + @Override + public Collection<NEUIngredient> getAllInputs() { + return cost; + } + + @Override + public Collection<NEUIngredient> getAllOutputs() { + return Collections.singletonList(result); + } +} diff --git a/src/main/java/io/github/moulberry/repo/data/NEURecipe.java b/src/main/java/io/github/moulberry/repo/data/NEURecipe.java index 4a49f17..28df4b7 100644 --- a/src/main/java/io/github/moulberry/repo/data/NEURecipe.java +++ b/src/main/java/io/github/moulberry/repo/data/NEURecipe.java @@ -1,4 +1,17 @@ package io.github.moulberry.repo.data; +import java.util.Collection; + public interface NEURecipe { + /** + * This is to be called once, after deserialization by the item that contains this recipe. This will be done + * automatically by {@link NEUItem#getRecipes()}. + */ + @Deprecated + default void fillItemInfo(NEUItem item) { + } + + Collection<NEUIngredient> getAllInputs(); + + Collection<NEUIngredient> getAllOutputs(); } diff --git a/src/main/java/io/github/moulberry/repo/data/NEUTradeRecipe.java b/src/main/java/io/github/moulberry/repo/data/NEUTradeRecipe.java index 7fd22f7..e1435d4 100644 --- a/src/main/java/io/github/moulberry/repo/data/NEUTradeRecipe.java +++ b/src/main/java/io/github/moulberry/repo/data/NEUTradeRecipe.java @@ -1,4 +1,24 @@ package io.github.moulberry.repo.data; +import lombok.Getter; + +import java.util.Collection; +import java.util.Collections; + +@Getter public class NEUTradeRecipe implements NEURecipe { + NEUIngredient cost; + int min; + int max; + NEUIngredient result; + + @Override + public Collection<NEUIngredient> getAllInputs() { + return Collections.singletonList(cost); + } + + @Override + public Collection<NEUIngredient> getAllOutputs() { + return Collections.singletonList(result); + } } |