diff options
| author | Linnea Gräf <nea@nea.moe> | 2025-07-31 14:35:25 +0200 |
|---|---|---|
| committer | Linnea Gräf <nea@nea.moe> | 2025-07-31 18:09:40 +0200 |
| commit | 458c641c7473e4857d19bba4b7492b1a406b0f81 (patch) | |
| tree | 7ba3b3a3d84d68a611e07167351914dae529fa71 /src/main/java | |
| parent | 8d655a4008d8fba0ca6f477be0e051924dc67ec6 (diff) | |
| download | Skyblocker-458c641c7473e4857d19bba4b7492b1a406b0f81.tar.gz Skyblocker-458c641c7473e4857d19bba4b7492b1a406b0f81.tar.bz2 Skyblocker-458c641c7473e4857d19bba4b7492b1a406b0f81.zip | |
Add more object models to the api
Diffstat (limited to 'src/main/java')
5 files changed, 304 insertions, 0 deletions
diff --git a/src/main/java/de/hysky/skyblocker/skyblock/profileviewer/model/ApiProfile.java b/src/main/java/de/hysky/skyblocker/skyblock/profileviewer/model/ApiProfile.java index 4864ca52..1d0be925 100644 --- a/src/main/java/de/hysky/skyblocker/skyblock/profileviewer/model/ApiProfile.java +++ b/src/main/java/de/hysky/skyblocker/skyblock/profileviewer/model/ApiProfile.java @@ -13,5 +13,9 @@ public class ApiProfile { public CoopBanking banking = new CoopBanking(); @SerializedName("cute_name") public String cuteName; + public Events events = new Events(); + public PlayerData playerData = new PlayerData(); + public Bestiary bestiary = new Bestiary(); + // TODO: mining_core (which is broken right now) public boolean selected = false; } diff --git a/src/main/java/de/hysky/skyblocker/skyblock/profileviewer/model/Bestiary.java b/src/main/java/de/hysky/skyblocker/skyblock/profileviewer/model/Bestiary.java new file mode 100644 index 00000000..993704cf --- /dev/null +++ b/src/main/java/de/hysky/skyblocker/skyblock/profileviewer/model/Bestiary.java @@ -0,0 +1,46 @@ +package de.hysky.skyblocker.skyblock.profileviewer.model; + +import com.google.gson.annotations.SerializedName; + +import java.util.Map; +import java.util.NavigableMap; +import java.util.TreeMap; + +public class Bestiary { + /** + * Kill counts dived up by level: {@code [mob type]_[level]} + * + * @see PlayerData#kills + */ + public NavigableMap<String, Integer> kills = new TreeMap<>(); + + /** + * Gets a submap of the map with only entries prefixed with the prefix. Assumes that the prefix is always followed by an {@code _} and no non underscore separated values exist. + */ + private static Map<String, Integer> getPrefixMap(NavigableMap<String, Integer> map, String prefix) { + return map.subMap(prefix + '_', prefix + ('_' + 1)); + } + + public Map<String, Integer> getAllKills(String mobKind) { + return getPrefixMap(kills, mobKind); + } + + public Map<String, Integer> getAllDeaths(String mobKind) { + return getPrefixMap(deaths, mobKind); + } + + /** + * Death counts dived up by level: {@code [mob type]_[level]} + */ + public NavigableMap<String, Integer> deaths = new TreeMap<>(); + /** + * There is an old format. This class really deserves to be behind an error boundary for those cases. + */ + public boolean migrated_stats = true; + public Milestone milestone = new Milestone(); + + public static class Milestone { + @SerializedName("last_claimed_milestone") + public int lastClaimedMilestone; + } +} diff --git a/src/main/java/de/hysky/skyblocker/skyblock/profileviewer/model/EasterEvent.java b/src/main/java/de/hysky/skyblocker/skyblock/profileviewer/model/EasterEvent.java new file mode 100644 index 00000000..bb9d003a --- /dev/null +++ b/src/main/java/de/hysky/skyblocker/skyblock/profileviewer/model/EasterEvent.java @@ -0,0 +1,140 @@ +package de.hysky.skyblocker.skyblock.profileviewer.model; + +import com.google.gson.JsonElement; +import com.google.gson.JsonObject; +import com.google.gson.annotations.SerializedName; +import de.hysky.skyblocker.SkyblockerMod; +import it.unimi.dsi.fastutil.objects.Object2IntOpenHashMap; +import org.jetbrains.annotations.Nullable; + +import java.util.List; +import java.util.Map; +import java.util.Objects; + +public class EasterEvent { + + @SerializedName("chocolate") + public long currentChocolate; + @SerializedName("chocolate_since_prestige") + public long chocolateSincePrestige; + @SerializedName("total_chocolate") + public long allTimeChocolate; + @SerializedName("employees") + public Employees employeeLevels = new Employees(); + @SerializedName("last_viewed_chocolate_factory") + public long lastViewedChocolateFactory; + @SerializedName("rabbits") + private JsonObject rawRabbits = new JsonObject(); + public Shop shop = new Shop(); + @SerializedName("rabbit_barn_capacity_level") + public int barnCapacity; + @SerializedName("chocolate_level") + public int chocolateFactoryLevel; + @SerializedName("time_tower") + public TimeTower timeTower = new TimeTower(); + @SerializedName("el_dorado_progress") + public int elDoradoProgress; + @SerializedName("chocolate_multiplier_upgrades") + public int chocolateMultiplierUpgrades; + @SerializedName("rabbit_rarity_upgrades") + public int rabbitRarityUpgrade; + @SerializedName("golden_click_amount") + public int goldenClickAmount; + @SerializedName("golden_click_year") + public int goldenClickYear; + @SerializedName("click_upgrades") + public int clickUpgrades; + @SerializedName("supreme_chocolate_bars") + public int supremeChocolateBars; + @SerializedName("refined_dark_cacao_truffles") + public int refinedDarkCocoaTrufflesConsumer; + @SerializedName("rabbit_hitmen") + public Hitmen hitmen = new Hitmen(); + + public static class Hitmen { + @SerializedName("rabbit_hitmen_slots") + public int unlockedSlots; + @SerializedName("missed_uncollected_eggs") + public int uncollectedEggCount; + /** + * Is this the last collected egg timestamp? + */ + @SerializedName("egg_slot_cooldown_mark") + public long eggSlotCooldownTimestamp; + @SerializedName("egg_slot_cooldown_sum") + public long eggSlotCooldownSum; + } + + public static class TimeTower { + public int charges; + public int level; + @SerializedName("activation_time") + public long activationTime; + @SerializedName("last_charge_time") + public long lastChargeTime; + } + + public static class Shop { + public int year; + public List<String> rabbits = List.of(); + @SerializedName("chocolate_spent") + public long chocolateSpent; + @SerializedName("cocoa_fortune_upgrades") + public int cocoaFortuneUpgrade; + } + + + private transient @Nullable CollectedEggs collectedEggs; + private transient @Nullable Map<String, Integer> rabbitCollectionCount; + + public Map<String, Integer> getRabbitCount() { + if (rabbitCollectionCount == null) { + rabbitCollectionCount = new Object2IntOpenHashMap<>(rawRabbits.size()); + for (Map.Entry<String, JsonElement> entry : rawRabbits.entrySet()) { + if (Objects.equals(entry.getKey(), "collected_eggs")) + continue; + rabbitCollectionCount.put(entry.getKey(), entry.getValue().getAsInt()); + } + } + return rabbitCollectionCount; + } + + public CollectedEggs getLastCollectedEggs() { + if (collectedEggs == null) { + collectedEggs = SkyblockerMod.GSON.fromJson( + rawRabbits.getAsJsonObject("collected_eggs"), + CollectedEggs.class + ); + } + return collectedEggs; + } + + /** + * Last collected egg timestamps, can be used calculate when the next egg is available. + */ + public static class CollectedEggs { + public long breakfast; + public long dinner; + public long lunch; + public long brunch; + public long dejeuner; + public long supper; + } + + public static class Employees { + @SerializedName("rabbit_bro") + public long rabbitBro; + @SerializedName("rabbit_cousin") + public long rabbitCousin; + @SerializedName("rabbit_sis") + public long rabbitSis; + @SerializedName("rabbit_father") + public long rabbitFather; + @SerializedName("rabbit_grandma") + public long rabbitGrandma; + @SerializedName("rabbit_uncle") + public long rabbitUncle; + @SerializedName("rabbit_dog") + public long rabbitDog; + } +} diff --git a/src/main/java/de/hysky/skyblocker/skyblock/profileviewer/model/Events.java b/src/main/java/de/hysky/skyblocker/skyblock/profileviewer/model/Events.java new file mode 100644 index 00000000..2f14f17f --- /dev/null +++ b/src/main/java/de/hysky/skyblocker/skyblock/profileviewer/model/Events.java @@ -0,0 +1,5 @@ +package de.hysky.skyblocker.skyblock.profileviewer.model; + +public class Events { + public EasterEvent easter = new EasterEvent(); +} diff --git a/src/main/java/de/hysky/skyblocker/skyblock/profileviewer/model/PlayerData.java b/src/main/java/de/hysky/skyblocker/skyblock/profileviewer/model/PlayerData.java new file mode 100644 index 00000000..f0c67e3c --- /dev/null +++ b/src/main/java/de/hysky/skyblocker/skyblock/profileviewer/model/PlayerData.java @@ -0,0 +1,109 @@ +package de.hysky.skyblocker.skyblock.profileviewer.model; + +import com.google.gson.annotations.SerializedName; + +import java.util.List; +import java.util.Map; +import java.util.Set; + +public class PlayerData { + @SerializedName("visited_zones") + public List<String> visitedZones = List.of(); + /** + * Seems to be a second timestamp with some sort of offset. + */ + @SerializedName("last_death") + public long lastDeath; + @SerializedName("perks") + public Map<String, Integer> essencePerks = Map.of(); + @SerializedName("active_effects") + public List<Effect> activeEffects = List.of(); + @SerializedName("reaper_peppers_eaten") + public int reaperPeppersEaten; + @SerializedName("death_count") + public int deathCount; + @SerializedName("disabled_potion_effects") + public Set<String> disabledPotionEffects = Set.of(); + /** + * Probably the set of miniature islands that have been spawned. Is this a list of all of them or just the ones that have achievements associated? + */ + @SerializedName("achievement_spawned_island_types") + public Set<String> spawnedIslandTypes = Set.of(); + @SerializedName("visited_modes") + public Set<String> visitedIslandModes = Set.of(); + + /** + * Collection tiers in the format of {@code [collection]_[level]}. Does contain some nonsense levels like {@code -1}. What's up with those? Also those can be derived from adding up {@link ProfileMember#collection} for all players. + */ + @SerializedName("unlocked_coll_tiers") + public Set<String> unlockedCollectionTiers = Set.of(); + + /** + * All minion tiers crafted, in the form of {@code [resource]_[level]} + * + * @see #getMinionTier + * @see #hasCraftedMinionTier + */ + @SerializedName("crafted_generators") + public Set<String> craftedMinions = Set.of(); + @SerializedName("fishing_treasure_caught") + public int fishingTreasuresCaught; + // candy_collected + /** + * Has a {@code total} field and does not distinguish between levels. Not sure if this is updated with new kills after the bestiary data. + * + * @see Bestiary#kills + */ + public Map<String, Float> kills = Map.of(); + /** + * Has a {@code total} field and does not distinguish between levels. Not sure if this is updated with new deaths after the bestiary data. + * + * @see Bestiary#deaths + */ + public Map<String, Float> deaths = Map.of(); + @SerializedName("highest_critical_damage") + public double highestCriticalDamage; + @SerializedName("items_fished") + public ItemsFished itemsFished = new ItemsFished(); + + public static class ItemsFished { + public int total; + public int normal; + public int treasure; + @SerializedName("large_treasure") + public int largeTreasure; + } + + + /** + * @param tier one indexed minion tier + */ + public boolean hasCraftedMinionTier(String minionType, int tier) { + return craftedMinions.contains(String.format("%s_%d", minionType, tier)); + } + + /** + * Gets the highest contiguously unlocked minion tier. It is still possible to craft a higher tier minion by trading with other players. + * + * @return the one indexed highest crafted minion tier contiguously from tier 1. + */ + public int getMinionTier(String resource) { // TODO: are minion crafts shared between players in a profile + int i = 1; + for (; i < 15; i++) { // Let's go for 15 for future proofing! + if (!hasCraftedMinionTier(resource, i)) + break; + } + return i - 1; + } + + public static class Effect { + @SerializedName("effect") + public String effectId; + public int level = 1; + // "modifiers": [] + @SerializedName("ticks_remaining") + public long ticksRemaining; + public boolean infinite; + public int flags; + } +} |
