From 1f353f844fead0b9c11bce7696e612ab2b199c84 Mon Sep 17 00:00:00 2001 From: AriDev <75741608+ArikSquad@users.noreply.github.com> Date: Sat, 20 Dec 2025 16:56:42 +0200 Subject: [PATCH 001/113] feat: partial fishing hook --- configuration/skyblock/items/vanillaItems.yml | 1 + .../skyblockgeneric/entity/FishingHook.java | 211 +++++ .../item/ItemConfigParser.java | 892 +++++++++--------- .../item/components/FishingRodComponent.java | 33 + 4 files changed, 692 insertions(+), 445 deletions(-) create mode 100644 type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/entity/FishingHook.java create mode 100644 type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/item/components/FishingRodComponent.java diff --git a/configuration/skyblock/items/vanillaItems.yml b/configuration/skyblock/items/vanillaItems.yml index 5df04acb6..0da9213bc 100644 --- a/configuration/skyblock/items/vanillaItems.yml +++ b/configuration/skyblock/items/vanillaItems.yml @@ -183,6 +183,7 @@ items: material: FISHING_ROD rarity: COMMON components: + - id: FISHING_ROD - id: DEFAULT_CRAFTABLE recipes: - type: SHAPED diff --git a/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/entity/FishingHook.java b/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/entity/FishingHook.java new file mode 100644 index 000000000..1fb323cc3 --- /dev/null +++ b/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/entity/FishingHook.java @@ -0,0 +1,211 @@ +package net.swofty.type.skyblockgeneric.entity; + +import lombok.Getter; +import net.kyori.adventure.key.Key; +import net.kyori.adventure.sound.Sound; +import net.minestom.server.coordinate.Pos; +import net.minestom.server.entity.Entity; +import net.minestom.server.entity.EntityType; +import net.minestom.server.entity.Player; +import net.minestom.server.entity.metadata.other.FishingHookMeta; +import net.minestom.server.event.entity.EntityTickEvent; +import net.minestom.server.instance.Instance; +import net.minestom.server.instance.block.Block; +import net.minestom.server.item.Material; +import net.minestom.server.network.packet.server.play.ParticlePacket; +import net.minestom.server.particle.Particle; +import net.minestom.server.sound.SoundEvent; +import net.minestom.server.timer.Scheduler; +import org.jetbrains.annotations.NotNull; + +import java.util.ArrayList; +import java.util.List; + +public class FishingHook { + + public static final List activeHooks = new ArrayList<>(); + private static final double INITIAL_SPEED_MULTIPLIER = 10.0; + private static final double BOB_SPEED = 0.1; + private static final double BOB_AMOUNT = 0.09; + private static final double SURFACE_OFFSET = -0.02; + private static final double MAX_PULL_DOWN = 0.3; + private static final double PULL_DOWN_RECOVERY_SPEED = 0.016666666666666666; + private static final double CONTROLLER_DRAG = 0.2; + private static final double WATER_CHECK_OFFSET = -0.2; + private final Player owner; + private final Entity hook; + private final Entity controller; + @Getter + private boolean isRemoved = false; + private double bobTick = 0; + private double pullDownOffset = 0; + private Double stableWaterY = null; + + public FishingHook(Player owner) { + this.owner = owner; + + this.hook = new Entity(EntityType.FISHING_BOBBER); + this.hook.editEntityMeta(FishingHookMeta.class, meta -> { + meta.setOwnerEntity(owner); + }); + + this.controller = new Entity(EntityType.TEXT_DISPLAY); + this.controller.setNoGravity(true); + + this.controller.eventNode().addListener(EntityTickEvent.class, + event -> tick(event.getEntity())); + } + + public static FishingHook getFishingHookForOwner(@NotNull Player owner) { + for (FishingHook fishingHook : activeHooks) { + if (fishingHook.owner.getUuid().equals(owner.getUuid())) { + return fishingHook; + } + } + return null; + } + + private static boolean isNotWater(@NotNull Block block) { + return !block.isLiquid() || !block.name().contains("water"); + } + + public void spawn(Instance instance) { + Pos spawnPos = owner.getPosition().add(0, owner.getEyeHeight(), 0); + spawn(instance, spawnPos); + } + + public void spawn(Instance instance, Pos pos) { + activeHooks.add(this); + this.controller.setInstance(instance, pos); + this.hook.setInstance(instance, pos); + this.controller.addPassenger(hook); + this.controller.setVelocity(owner.getPosition().direction().mul(INITIAL_SPEED_MULTIPLIER)); + owner.playSound( + Sound.sound() + .type(Key.key("entity.fishing_bobber.throw")) + .source(Sound.Source.NEUTRAL) + .volume(0.5f) + .pitch((float) 1 / 3) // the pitch is 1/3-0.5 + .build() + ); + } + + private boolean shouldKeepExisting() { + // Checks if the user is still in the same instance as the hook + Instance instance = controller.getInstance(); + if (instance == null) return false; + if (owner.getInstance() != instance) return false; + // Checks if the owner is still holding a fishing rod + return owner.getItemInMainHand().material() == Material.FISHING_ROD; + } + + private void tick(@NotNull Entity controller) { + Instance instance = controller.getInstance(); + if (instance == null) return; + if (!shouldKeepExisting()) { + remove(); + return; + } + + Pos pos = controller.getPosition(); + if (notInWater()) { + stableWaterY = null; + controller.setNoGravity(false); // Re-enable gravity to fall/stop + return; + } + + // Hook is in water + controller.setNoGravity(true); + Block blockBelow = instance.getBlock(pos.add(0, WATER_CHECK_OFFSET, 0)); + + if (stableWaterY == null) { + // First time hitting water, establish stable surface Y + stableWaterY = getWaterSurface(blockBelow, (int) Math.floor(pos.y() + WATER_CHECK_OFFSET)) + SURFACE_OFFSET; + bobTick = 0; + pullDownOffset = 0; + // show particles + instance.playSound(Sound.sound() + .type(SoundEvent.ENTITY_FISHING_BOBBER_SPLASH) + .source(Sound.Source.PLAYER) + .volume(0.25f) + .pitch(0.8f) // 0.6-1.4 in vanilla + .build() + ); + instance.sendGroupedPacket(new ParticlePacket( + Particle.SPLASH, + controller.getPosition(), + new Pos(0.1, 0.001, 0.1), + 0, 5 + )); + } + + bobTick += BOB_SPEED; + double yBob = Math.sin(bobTick) * BOB_AMOUNT; + + pullDownOffset = Math.max(pullDownOffset - PULL_DOWN_RECOVERY_SPEED, 0); + Pos targetPos = new Pos(pos.x(), stableWaterY + yBob - pullDownOffset, pos.z()); + + controller.teleport(targetPos); + controller.setVelocity(controller.getVelocity().mul(CONTROLLER_DRAG)); + } + + + public boolean notInWater() { + Instance instance = controller.getInstance(); + Pos pos = controller.getPosition(); + // Check the block at the entity's precise location + Block currentBlock = instance.getBlock(pos); + + // Check the block slightly below the entity's location + Block blockBelow = instance.getBlock(pos.add(0, WATER_CHECK_OFFSET, 0)); + + // The hook is considered "in water" if either its current block OR + // the block directly below it is water. + return isNotWater(currentBlock) && isNotWater(blockBelow); + } + + public void showBiteAnimation() { + Instance instance = controller.getInstance(); + if (instance == null) return; + + instance.playSound(Sound.sound() + .type(SoundEvent.ENTITY_FISHING_BOBBER_SPLASH) + .source(Sound.Source.PLAYER) + .build() + ); + instance.sendGroupedPacket(new ParticlePacket( + Particle.SPLASH, + controller.getPosition(), + new Pos(0.1, 0.001, 0.1), + 0, 20 + )); + + pullDownOffset = Math.min(pullDownOffset + 0.15, MAX_PULL_DOWN); + bobTick += Math.PI / 6; + } + + public void remove() { + activeHooks.remove(this); + if (this.isRemoved) return; + this.isRemoved = true; + hook.remove(); + controller.remove(); + } + + private double getWaterSurface(Block block, int blockY) { + if (!block.isLiquid()) return blockY + 1.0; + + String levelStr = block.getProperty("level"); + int level = (levelStr == null) ? 0 : Integer.parseInt(levelStr); + + return blockY + ((level == 0) ? 1.0 : (8 - level) / 8.0); + } + + public Scheduler getScheduler() { + return hook.scheduler(); + } + + public Instance getInstance() { + return controller.getInstance(); + } +} \ No newline at end of file diff --git a/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/item/ItemConfigParser.java b/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/item/ItemConfigParser.java index 73b2b7d17..1644bee55 100644 --- a/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/item/ItemConfigParser.java +++ b/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/item/ItemConfigParser.java @@ -27,449 +27,451 @@ import java.util.Map; public class ItemConfigParser { - public static ConfigurableSkyBlockItem parseItem(Map config) { - String id = (String) config.get("id"); - // Clean up the ID - id = id.replaceAll("[^a-zA-Z0-9_]", ""); - - Material material = Material.values().stream().filter(loopedMaterial -> { - return loopedMaterial.key().value().equalsIgnoreCase((String) config.get("material")); - }).findFirst().orElse(Material.AIR); - - List lore = (List) config.get("lore"); - Map statistics = new HashMap<>(); - - if (config.containsKey("default_statistics")) { - // Convert all the objects to doubles, noting they may be integers - for (Map.Entry entry : ((Map) config.get("default_statistics")).entrySet()) { - statistics.put(entry.getKey(), Double.parseDouble(entry.getValue().toString())); - } - } - - ConfigurableSkyBlockItem item = new ConfigurableSkyBlockItem(id, material, lore, statistics); - - List> components = (List>) config.get("components"); - if (components == null) components = new ArrayList<>(); - for (Map componentConfig : components) { - String componentId = (String) componentConfig.get("id"); - SkyBlockItemComponent component = parseComponent(id, componentId, componentConfig); - if (component != null) { - // Mark all components from YAML as explicit - item.addComponent(component, true); - } - } - - item.register(); - return item; - } - - private static @Nullable SkyBlockItemComponent parseComponent(String itemId, String id, Map config) { - return switch (id.toUpperCase()) { - case "ABILITY" -> { - List abilities = (List) config.get("abilities"); - yield new AbilityComponent(abilities); - } - case "TALISMAN", "ACCESSORY" -> new AccessoryComponent(); - case "ANVIL_COMBINABLE" -> { - String handlerId = (String) config.get("handler_id"); - yield new AnvilCombinableComponent(handlerId); - } - case "ARMOR" -> new ArmorComponent(); - case "ARROW" -> new ArrowComponent(); - case "AUCTION_CATEGORY" -> { - String category = (String) config.get("category"); - yield new AuctionCategoryComponent(category); - } - case "AXE" -> new AxeComponent(); - case "BACKPACK" -> { - int rows = (int) config.get("rows"); - String skullTexture = (String) config.get("skull-texture"); - yield new BackpackComponent(rows, skullTexture); - } - case "BOW" -> { - String handlerId = (String) config.get("handler_id"); - boolean shouldBeArrow = (boolean) config.getOrDefault("should-be-arrow", true); - yield new BowComponent(handlerId, shouldBeArrow); - } - case "CONSTANT_STATISTICS" -> new ConstantStatisticsComponent(); - case "DEFAULT_CRAFTABLE" -> { - List> recipes = (List>) config.get("recipes"); - boolean defaultCraftable = true; - if (config.containsKey("default-craftable")) { - defaultCraftable = (boolean) config.get("default-craftable"); - } - CraftableComponent component = new CraftableComponent(recipes); - component.setDefaultCraftable(defaultCraftable); - yield component; - } - case "CUSTOM_DISPLAY_NAME" -> new CustomDisplayNameComponent((item) -> config.get("display_name").toString()); - case "DECORATION_HEAD" -> { - String texture = (String) config.get("texture"); - yield new DecorationHeadComponent(texture); - } - case "DEFAULT_SOULBOUND" -> { - boolean coopAllowed = (boolean) config.get("coop_allowed"); - yield new DefaultSoulboundComponent(coopAllowed); - } - case "DISABLE_ANIMATION" -> { - List animations = (List) config.get("disabled_animations"); - yield new DisableAnimationComponent(animations); - } - case "DRILL" -> new DrillComponent(); - case "ENCHANTABLE" -> { - List groups = (List) config.getOrDefault("enchant_groups", List.of()); - boolean showLores = (boolean) config.getOrDefault("show_lores", true); - yield new EnchantableComponent( - groups.stream().map(EnchantItemGroups::valueOf).toList(), - showLores - ); - } - case "ENCHANTED" -> { - if (config.containsKey("recipe_type") && config.containsKey("item_id")) { - SkyBlockRecipe.RecipeType type = SkyBlockRecipe.RecipeType.valueOf((String) config.get("recipe_type")); - String baseMaterial = (String) config.get("item_id"); - yield new EnchantedComponent(type, itemId, baseMaterial); - } - yield new EnchantedComponent(); - } - case "EXTRA_RARITY" -> { - String display = (String) config.get("display"); - yield new ExtraRarityComponent(display); - } - case "DUNGEON_ITEM" -> new ExtraRarityComponent("DUNGEON ITEM"); - case "EXTRA_UNDER_NAME" -> { - if (config.containsKey("displays")) { - List displays = (List) config.get("displays"); - yield new ExtraUnderNameComponent(displays); - } else { - String display = (String) config.get("display"); - yield new ExtraUnderNameComponent(display); - } - } - case "GEMSTONE" -> { - List gemstones = (List) config.get("gemstones"); - yield new GemstoneComponent(gemstones); - } - case "GEMSTONE_IMPL" -> { - GemRarity rarity = GemRarity.valueOf((String) config.get("rarity")); - Gemstone gemstone = Gemstone.valueOf((String) config.get("gemstone")); - String texture = (String) config.get("skull_texture"); - yield new GemstoneImplComponent(rarity, gemstone, texture); - } - case "HOT_POTATO" -> { - String type = (String) config.get("potato_type"); - - if (config.containsKey("appliable_items")) { - var appliableItems = (List) config.get("appliable_items"); - HashMap appliable = new HashMap<>(); - - for (var item : appliableItems) { - var split = item.split(":"); - - if (split.length != 2) - continue; - - appliable.put(ItemType.valueOf(split[0]), Integer.parseInt(split[1])); - } - - yield new HotPotatoableComponent(PotatoType.valueOf(type), appliable); - } - - yield new HotPotatoableComponent(PotatoType.valueOf(type)); - } - case "INTERACTABLE" -> { - String handlerId = (String) config.get("handler_id"); - try { - yield new InteractableComponent(handlerId); - } catch (Exception e) { - Logger.error("Failed to parse InteractableComponent for " + handlerId); - yield null; - } - } - case "KAT" -> { - int reducedDays = (int) config.get("reduced_days"); - yield new KatComponent(reducedDays); - } - case "LEATHER_COLOR" -> { - String r = (String) config.get("r"); - String g = (String) config.get("g"); - String b = (String) config.get("b"); - - Color color = new Color(Integer.parseInt(r), Integer.parseInt(g), Integer.parseInt(b)); - yield new LeatherColorComponent(color); - } - case "MINION" -> { - String minionType = (String) config.get("minion_type"); - String baseItem = (String) config.get("base_item"); - boolean isByDefaultCraftable = (boolean) config.get("default_craftable"); - - List ingredients = (List) config.get("ingredients"); - List ingredientsMap = new ArrayList<>(); - - for (String ingredient : ingredients) { - String[] ingredientParts = ingredient.split(":"); - ingredientsMap.add(new MinionIngredient( - ItemType.valueOf(ingredientParts[0]), - Integer.parseInt(ingredientParts[1]) - )); - } - - yield new MinionComponent(minionType,baseItem, isByDefaultCraftable, ingredientsMap); - } - case "MINION_FUEL" -> { - double percentage = (double) config.get("fuel_percentage"); - long lastTime = (int) config.get("last_time_ms"); - yield new MinionFuelComponent(percentage, lastTime); - } - case "MINION_SHIPPING" -> { - double percentage = (double) config.get("percentage"); - yield new MinionShippingComponent(percentage); - } - case "MINION_SKIN" -> { - String skinName = (String) config.get("name"); - Map helmetConfig = (Map) config.get("helmet"); - Map chestplateConfig = (Map) config.get("chestplate"); - Map leggingsConfig = (Map) config.get("leggings"); - Map bootsConfig = (Map) config.get("boots"); - - MinionSkinComponent.MinionArmorPiece helmet = helmetConfig != null ? MinionSkinComponent.MinionArmorPiece.fromConfig(helmetConfig) : - new MinionSkinComponent.MinionArmorPiece(Material.AIR, null, null); - MinionSkinComponent.MinionArmorPiece chestplate = chestplateConfig != null ? MinionSkinComponent.MinionArmorPiece.fromConfig(chestplateConfig) : - new MinionSkinComponent.MinionArmorPiece(Material.AIR, null, null); - MinionSkinComponent.MinionArmorPiece leggings = leggingsConfig != null ? MinionSkinComponent.MinionArmorPiece.fromConfig(leggingsConfig) : - new MinionSkinComponent.MinionArmorPiece(Material.AIR, null, null); - MinionSkinComponent.MinionArmorPiece boots = bootsConfig != null ? MinionSkinComponent.MinionArmorPiece.fromConfig(bootsConfig) : - new MinionSkinComponent.MinionArmorPiece(Material.AIR, null, null); - - yield new MinionSkinComponent(skinName, helmet, chestplate, leggings, boots); - } - case "MINION_UPGRADE" -> { - double speedIncrease = (double) config.get("speed_increase"); - yield new MinionUpgradeComponent(speedIncrease); - } - case "MUSEUM" -> { - String category = (String) config.get("museum_category"); - yield new MuseumComponent(category); - } - case "NOT_FINISHED_YET" -> new NotFinishedYetComponent(); - case "LORE_UPDATE" -> { - boolean isAbsolute = (boolean) config.getOrDefault("is_absolute", false); - yield new LoreUpdateComponent(config.get("handler_id").toString(), isAbsolute); - } - case "PET_ITEM" -> new PetItemComponent(); - case "PICKAXE" -> new PickaxeComponent(); - case "PLACEABLE" -> { - String blockType = (String) config.get("block_type"); - yield new PlaceableComponent(blockType); - } - case "PLACE_EVENT" -> { - String handlerId = (String) config.get("handler_id"); - yield new PlaceEventComponent(handlerId); - } - case "POWER_STONE" -> new PowerStoneComponent(); - case "QUIVER_DISPLAY" -> { - boolean shouldBeArrow = (boolean) config.get("should_be_arrow"); - yield new QuiverDisplayComponent(shouldBeArrow); - } - case "REFORGABLE" -> { - String type = (String) config.get("reforge_type"); - yield new ReforgableComponent(ReforgeType.valueOf(type)); - } - case "RIGHT_CLICK_RECIPE" -> { - String recipeItem = (String) config.get("recipe_item"); - yield new RightClickRecipeComponent(recipeItem); - } - case "RUNEABLE" -> { - String applicableTo = (String) config.get("applicable_to"); - yield new RuneableComponent(RuneableComponent.RuneApplicableTo.valueOf(applicableTo)); - } - case "CUSTOM_DROP" -> { - List> rulesConfig = (List>) config.get("rules"); - List rules = new ArrayList<>(); - - for (Map ruleConfig : rulesConfig) { - // Parse conditions - Map conditionsConfig = (Map) ruleConfig.get("conditions"); - CustomDropComponent.DropConditions conditions = CustomDropComponent.parseDropConditions(conditionsConfig); - - // Parse drops - List> dropsConfig = (List>) ruleConfig.get("drops"); - List drops = new ArrayList<>(); - - for (Map dropConfig : dropsConfig) { - String itemName = (String) dropConfig.get("item"); - ItemType itemType = ItemType.valueOf(itemName); - double chance = ((Number) dropConfig.get("chance")).doubleValue(); - String amount = dropConfig.get("amount").toString(); - - drops.add(new CustomDropComponent.Drop(itemType, chance, amount)); - } - - rules.add(new CustomDropComponent.DropRule(conditions, drops)); - } - - yield new CustomDropComponent(rules); - } - case "RUNE" -> { - int level = (int) config.get("required_level"); - String color = (String) config.get("color"); - String applicableTo = (String) config.get("applicable_to"); - String texture = (String) config.get("skull_texture"); - yield new RuneComponent(level, color, applicableTo, texture); - } - case "SACK" -> { - List items = (List) config.get("valid_items"); - int capacity = (int) config.get("max_capacity"); - yield new SackComponent(items, capacity); - } - case "SELLABLE" -> { - Object value = config.get("value"); - if (value instanceof Double) { - yield new SellableComponent((double) value); - } else if (value instanceof Integer) { - yield new SellableComponent((int) value); - } - yield new SellableComponent(1); - } - case "SERVER_ORB" -> { - String handlerId = (String) config.get("handler_id"); - List blockStrings = ((List) config.getOrDefault("valid_blocks", List.of())).stream().map( - String::toLowerCase - ).toList(); - List materials = Material.values().stream() - .filter(material -> blockStrings.contains(material.key().value().toLowerCase())) - .toList(); - - yield new ServerOrbComponent(handlerId, materials); - } - case "SHORT_BOW" -> { - String handlerId = (String) config.get("handler_id"); - float cooldown = (float) config.get("cooldown"); - boolean shouldBeArrow = (boolean) config.getOrDefault("should-be-arrow", true); - yield new ShortBowComponent(cooldown, handlerId, shouldBeArrow); - } - case "SHOVEL" -> new ShovelComponent(); - case "SKILLABLE_MINE" -> { - String category = (String) config.get("category"); - double value = (double) config.get("mining_value"); - yield new SkillableMineComponent(category, value); - } - case "SKULL_HEAD" -> new SkullHeadComponent((item) -> config.get("texture").toString()); - case "STANDARD_ITEM" -> { - String type = (String) config.get("standard_item_type"); - yield new StandardItemComponent(type); - } - case "CUSTOM_STATISTICS" -> { - String handlerId = (String) config.get("handler_id"); - yield new CustomStatisticsComponent(handlerId); - } - case "TIERED_TALISMAN" -> { - ItemType baseTier = ItemType.valueOf((String) config.get("base_tier")); - int tier = (int) config.get("tier"); - yield new TieredTalismanComponent(baseTier, tier); - } - case "TRACKED_UNIQUE" -> new TrackedUniqueComponent(); - case "TRAVEL_SCROLL" -> { - String scrollType = (String) config.get("scroll_type"); - yield new TravelScrollComponent(scrollType); - } - case "PET" -> { - String petName = (String) config.get("pet_name"); - - // Parse george price - Map georgePriceMap = (Map) config.get("george_price"); - RarityValue georgePrice = new RarityValue<>( - georgePriceMap.get("common"), - georgePriceMap.get("uncommon"), - georgePriceMap.get("rare"), - georgePriceMap.get("epic"), - georgePriceMap.get("legendary"), - georgePriceMap.get("rest") - ); - - // Parse kat upgrades if present - RarityValue katUpgrades = null; - if (config.containsKey("kat_upgrades")) { - Map> katUpgradeMap = (Map>) config.get("kat_upgrades"); - katUpgrades = new RarityValue<>( - parseKatUpgrade(katUpgradeMap.get("common")), - parseKatUpgrade(katUpgradeMap.get("uncommon")), - parseKatUpgrade(katUpgradeMap.get("rare")), - parseKatUpgrade(katUpgradeMap.get("epic")), - parseKatUpgrade(katUpgradeMap.get("legendary")), - parseKatUpgrade(katUpgradeMap.get("rest")) - ); - } - - // Parse base statistics - Map baseStatsMap = (Map) config.get("base_statistics"); - ItemStatistics.Builder baseBuilder = ItemStatistics.builder(); - baseStatsMap.forEach((stat, value) -> - baseBuilder.withBase(ItemStatistic.valueOf(stat.toUpperCase()), value) - ); - ItemStatistics baseStatistics = baseBuilder.build(); - - // Parse per level statistics - Map perLevelStatsMap = (Map) config.get("per_level_statistics"); - Map perLevelStatistics = new HashMap<>(); - for (Map.Entry entry : perLevelStatsMap.entrySet()) { - String rarity = entry.getKey(); - ItemStatistics.Builder rarityBuilder = ItemStatistics.builder(); - try { - Map rarityStatsMap = (Map) entry.getValue(); - rarityBuilder = ItemStatistics.builder(); - for (Map.Entry e : rarityStatsMap.entrySet()) { - String stat = e.getKey(); - Double value = e.getValue(); - rarityBuilder.withBase(ItemStatistic.valueOf(stat.toUpperCase()), value); - } - } catch (ClassCastException e) { - // Per level statistics is a map with an Integer, so we need to convert it to a double - Map rarityStatsMap = (Map) entry.getValue(); - rarityBuilder = ItemStatistics.builder(); - for (Map.Entry mapEntry : rarityStatsMap.entrySet()) { - String stat = mapEntry.getKey(); - Integer value = mapEntry.getValue(); - rarityBuilder.withBase(ItemStatistic.valueOf(stat.toUpperCase()), Double.valueOf(value)); - } - } - perLevelStatistics.put(Rarity.valueOf(rarity.toUpperCase()), rarityBuilder.build()); - } - - // Parse other fields - Particle particleId = Particle.fromId((Integer) config.get("particle")); - String skillCategory = (String) config.get("skill_category"); - String skullTexture = (String) config.get("skull_texture"); - String handlerId = (String) config.get("handler_id"); - - yield new PetComponent( - petName, - georgePrice, - katUpgrades, - baseStatistics, - perLevelStatistics, - particleId, - skillCategory, - skullTexture, - handlerId - ); - } - default -> throw new IllegalArgumentException("Unknown component type: " + id); - }; - } - - private static KatUpgrade parseKatUpgrade(Map config) { - if (config == null) return null; - - Long time = ((Number) config.get("time")).longValue(); - Integer coins = (Integer) config.get("coins"); - - if (config.containsKey("item")) { - String item = (String) config.get("item"); - Integer amount = (Integer) config.get("amount"); - return KatUpgrade.WithItem(time, coins, ItemType.valueOf(item), amount); - } - - return KatUpgrade.OnlyCoins(time, coins); - } + public static ConfigurableSkyBlockItem parseItem(Map config) { + String id = (String) config.get("id"); + // Clean up the ID + id = id.replaceAll("[^a-zA-Z0-9_]", ""); + + Material material = Material.values().stream().filter(loopedMaterial -> { + return loopedMaterial.key().value().equalsIgnoreCase((String) config.get("material")); + }).findFirst().orElse(Material.AIR); + + List lore = (List) config.get("lore"); + Map statistics = new HashMap<>(); + + if (config.containsKey("default_statistics")) { + // Convert all the objects to doubles, noting they may be integers + for (Map.Entry entry : ((Map) config.get("default_statistics")).entrySet()) { + statistics.put(entry.getKey(), Double.parseDouble(entry.getValue().toString())); + } + } + + ConfigurableSkyBlockItem item = new ConfigurableSkyBlockItem(id, material, lore, statistics); + + List> components = (List>) config.get("components"); + if (components == null) components = new ArrayList<>(); + for (Map componentConfig : components) { + String componentId = (String) componentConfig.get("id"); + SkyBlockItemComponent component = parseComponent(id, componentId, componentConfig); + if (component != null) { + // Mark all components from YAML as explicit + item.addComponent(component, true); + } + } + + item.register(); + return item; + } + + private static @Nullable SkyBlockItemComponent parseComponent(String itemId, String id, Map config) { + return switch (id.toUpperCase()) { + case "ABILITY" -> { + List abilities = (List) config.get("abilities"); + yield new AbilityComponent(abilities); + } + case "TALISMAN", "ACCESSORY" -> new AccessoryComponent(); + case "ANVIL_COMBINABLE" -> { + String handlerId = (String) config.get("handler_id"); + yield new AnvilCombinableComponent(handlerId); + } + case "ARMOR" -> new ArmorComponent(); + case "ARROW" -> new ArrowComponent(); + case "AUCTION_CATEGORY" -> { + String category = (String) config.get("category"); + yield new AuctionCategoryComponent(category); + } + case "AXE" -> new AxeComponent(); + case "BACKPACK" -> { + int rows = (int) config.get("rows"); + String skullTexture = (String) config.get("skull-texture"); + yield new BackpackComponent(rows, skullTexture); + } + case "BOW" -> { + String handlerId = (String) config.get("handler_id"); + boolean shouldBeArrow = (boolean) config.getOrDefault("should-be-arrow", true); + yield new BowComponent(handlerId, shouldBeArrow); + } + case "CONSTANT_STATISTICS" -> new ConstantStatisticsComponent(); + case "DEFAULT_CRAFTABLE" -> { + List> recipes = (List>) config.get("recipes"); + boolean defaultCraftable = true; + if (config.containsKey("default-craftable")) { + defaultCraftable = (boolean) config.get("default-craftable"); + } + CraftableComponent component = new CraftableComponent(recipes); + component.setDefaultCraftable(defaultCraftable); + yield component; + } + case "CUSTOM_DISPLAY_NAME" -> + new CustomDisplayNameComponent((item) -> config.get("display_name").toString()); + case "DECORATION_HEAD" -> { + String texture = (String) config.get("texture"); + yield new DecorationHeadComponent(texture); + } + case "DEFAULT_SOULBOUND" -> { + boolean coopAllowed = (boolean) config.get("coop_allowed"); + yield new DefaultSoulboundComponent(coopAllowed); + } + case "DISABLE_ANIMATION" -> { + List animations = (List) config.get("disabled_animations"); + yield new DisableAnimationComponent(animations); + } + case "DRILL" -> new DrillComponent(); + case "ENCHANTABLE" -> { + List groups = (List) config.getOrDefault("enchant_groups", List.of()); + boolean showLores = (boolean) config.getOrDefault("show_lores", true); + yield new EnchantableComponent( + groups.stream().map(EnchantItemGroups::valueOf).toList(), + showLores + ); + } + case "FISHING_ROD" -> new FishingRodComponent(); + case "ENCHANTED" -> { + if (config.containsKey("recipe_type") && config.containsKey("item_id")) { + SkyBlockRecipe.RecipeType type = SkyBlockRecipe.RecipeType.valueOf((String) config.get("recipe_type")); + String baseMaterial = (String) config.get("item_id"); + yield new EnchantedComponent(type, itemId, baseMaterial); + } + yield new EnchantedComponent(); + } + case "EXTRA_RARITY" -> { + String display = (String) config.get("display"); + yield new ExtraRarityComponent(display); + } + case "DUNGEON_ITEM" -> new ExtraRarityComponent("DUNGEON ITEM"); + case "EXTRA_UNDER_NAME" -> { + if (config.containsKey("displays")) { + List displays = (List) config.get("displays"); + yield new ExtraUnderNameComponent(displays); + } else { + String display = (String) config.get("display"); + yield new ExtraUnderNameComponent(display); + } + } + case "GEMSTONE" -> { + List gemstones = (List) config.get("gemstones"); + yield new GemstoneComponent(gemstones); + } + case "GEMSTONE_IMPL" -> { + GemRarity rarity = GemRarity.valueOf((String) config.get("rarity")); + Gemstone gemstone = Gemstone.valueOf((String) config.get("gemstone")); + String texture = (String) config.get("skull_texture"); + yield new GemstoneImplComponent(rarity, gemstone, texture); + } + case "HOT_POTATO" -> { + String type = (String) config.get("potato_type"); + + if (config.containsKey("appliable_items")) { + var appliableItems = (List) config.get("appliable_items"); + HashMap appliable = new HashMap<>(); + + for (var item : appliableItems) { + var split = item.split(":"); + + if (split.length != 2) + continue; + + appliable.put(ItemType.valueOf(split[0]), Integer.parseInt(split[1])); + } + + yield new HotPotatoableComponent(PotatoType.valueOf(type), appliable); + } + + yield new HotPotatoableComponent(PotatoType.valueOf(type)); + } + case "INTERACTABLE" -> { + String handlerId = (String) config.get("handler_id"); + try { + yield new InteractableComponent(handlerId); + } catch (Exception e) { + Logger.error("Failed to parse InteractableComponent for " + handlerId); + yield null; + } + } + case "KAT" -> { + int reducedDays = (int) config.get("reduced_days"); + yield new KatComponent(reducedDays); + } + case "LEATHER_COLOR" -> { + String r = (String) config.get("r"); + String g = (String) config.get("g"); + String b = (String) config.get("b"); + + Color color = new Color(Integer.parseInt(r), Integer.parseInt(g), Integer.parseInt(b)); + yield new LeatherColorComponent(color); + } + case "MINION" -> { + String minionType = (String) config.get("minion_type"); + String baseItem = (String) config.get("base_item"); + boolean isByDefaultCraftable = (boolean) config.get("default_craftable"); + + List ingredients = (List) config.get("ingredients"); + List ingredientsMap = new ArrayList<>(); + + for (String ingredient : ingredients) { + String[] ingredientParts = ingredient.split(":"); + ingredientsMap.add(new MinionIngredient( + ItemType.valueOf(ingredientParts[0]), + Integer.parseInt(ingredientParts[1]) + )); + } + + yield new MinionComponent(minionType, baseItem, isByDefaultCraftable, ingredientsMap); + } + case "MINION_FUEL" -> { + double percentage = (double) config.get("fuel_percentage"); + long lastTime = (int) config.get("last_time_ms"); + yield new MinionFuelComponent(percentage, lastTime); + } + case "MINION_SHIPPING" -> { + double percentage = (double) config.get("percentage"); + yield new MinionShippingComponent(percentage); + } + case "MINION_SKIN" -> { + String skinName = (String) config.get("name"); + Map helmetConfig = (Map) config.get("helmet"); + Map chestplateConfig = (Map) config.get("chestplate"); + Map leggingsConfig = (Map) config.get("leggings"); + Map bootsConfig = (Map) config.get("boots"); + + MinionSkinComponent.MinionArmorPiece helmet = helmetConfig != null ? MinionSkinComponent.MinionArmorPiece.fromConfig(helmetConfig) : + new MinionSkinComponent.MinionArmorPiece(Material.AIR, null, null); + MinionSkinComponent.MinionArmorPiece chestplate = chestplateConfig != null ? MinionSkinComponent.MinionArmorPiece.fromConfig(chestplateConfig) : + new MinionSkinComponent.MinionArmorPiece(Material.AIR, null, null); + MinionSkinComponent.MinionArmorPiece leggings = leggingsConfig != null ? MinionSkinComponent.MinionArmorPiece.fromConfig(leggingsConfig) : + new MinionSkinComponent.MinionArmorPiece(Material.AIR, null, null); + MinionSkinComponent.MinionArmorPiece boots = bootsConfig != null ? MinionSkinComponent.MinionArmorPiece.fromConfig(bootsConfig) : + new MinionSkinComponent.MinionArmorPiece(Material.AIR, null, null); + + yield new MinionSkinComponent(skinName, helmet, chestplate, leggings, boots); + } + case "MINION_UPGRADE" -> { + double speedIncrease = (double) config.get("speed_increase"); + yield new MinionUpgradeComponent(speedIncrease); + } + case "MUSEUM" -> { + String category = (String) config.get("museum_category"); + yield new MuseumComponent(category); + } + case "NOT_FINISHED_YET" -> new NotFinishedYetComponent(); + case "LORE_UPDATE" -> { + boolean isAbsolute = (boolean) config.getOrDefault("is_absolute", false); + yield new LoreUpdateComponent(config.get("handler_id").toString(), isAbsolute); + } + case "PET_ITEM" -> new PetItemComponent(); + case "PICKAXE" -> new PickaxeComponent(); + case "PLACEABLE" -> { + String blockType = (String) config.get("block_type"); + yield new PlaceableComponent(blockType); + } + case "PLACE_EVENT" -> { + String handlerId = (String) config.get("handler_id"); + yield new PlaceEventComponent(handlerId); + } + case "POWER_STONE" -> new PowerStoneComponent(); + case "QUIVER_DISPLAY" -> { + boolean shouldBeArrow = (boolean) config.get("should_be_arrow"); + yield new QuiverDisplayComponent(shouldBeArrow); + } + case "REFORGABLE" -> { + String type = (String) config.get("reforge_type"); + yield new ReforgableComponent(ReforgeType.valueOf(type)); + } + case "RIGHT_CLICK_RECIPE" -> { + String recipeItem = (String) config.get("recipe_item"); + yield new RightClickRecipeComponent(recipeItem); + } + case "RUNEABLE" -> { + String applicableTo = (String) config.get("applicable_to"); + yield new RuneableComponent(RuneableComponent.RuneApplicableTo.valueOf(applicableTo)); + } + case "CUSTOM_DROP" -> { + List> rulesConfig = (List>) config.get("rules"); + List rules = new ArrayList<>(); + + for (Map ruleConfig : rulesConfig) { + // Parse conditions + Map conditionsConfig = (Map) ruleConfig.get("conditions"); + CustomDropComponent.DropConditions conditions = CustomDropComponent.parseDropConditions(conditionsConfig); + + // Parse drops + List> dropsConfig = (List>) ruleConfig.get("drops"); + List drops = new ArrayList<>(); + + for (Map dropConfig : dropsConfig) { + String itemName = (String) dropConfig.get("item"); + ItemType itemType = ItemType.valueOf(itemName); + double chance = ((Number) dropConfig.get("chance")).doubleValue(); + String amount = dropConfig.get("amount").toString(); + + drops.add(new CustomDropComponent.Drop(itemType, chance, amount)); + } + + rules.add(new CustomDropComponent.DropRule(conditions, drops)); + } + + yield new CustomDropComponent(rules); + } + case "RUNE" -> { + int level = (int) config.get("required_level"); + String color = (String) config.get("color"); + String applicableTo = (String) config.get("applicable_to"); + String texture = (String) config.get("skull_texture"); + yield new RuneComponent(level, color, applicableTo, texture); + } + case "SACK" -> { + List items = (List) config.get("valid_items"); + int capacity = (int) config.get("max_capacity"); + yield new SackComponent(items, capacity); + } + case "SELLABLE" -> { + Object value = config.get("value"); + if (value instanceof Double) { + yield new SellableComponent((double) value); + } else if (value instanceof Integer) { + yield new SellableComponent((int) value); + } + yield new SellableComponent(1); + } + case "SERVER_ORB" -> { + String handlerId = (String) config.get("handler_id"); + List blockStrings = ((List) config.getOrDefault("valid_blocks", List.of())).stream().map( + String::toLowerCase + ).toList(); + List materials = Material.values().stream() + .filter(material -> blockStrings.contains(material.key().value().toLowerCase())) + .toList(); + + yield new ServerOrbComponent(handlerId, materials); + } + case "SHORT_BOW" -> { + String handlerId = (String) config.get("handler_id"); + float cooldown = (float) config.get("cooldown"); + boolean shouldBeArrow = (boolean) config.getOrDefault("should-be-arrow", true); + yield new ShortBowComponent(cooldown, handlerId, shouldBeArrow); + } + case "SHOVEL" -> new ShovelComponent(); + case "SKILLABLE_MINE" -> { + String category = (String) config.get("category"); + double value = (double) config.get("mining_value"); + yield new SkillableMineComponent(category, value); + } + case "SKULL_HEAD" -> new SkullHeadComponent((item) -> config.get("texture").toString()); + case "STANDARD_ITEM" -> { + String type = (String) config.get("standard_item_type"); + yield new StandardItemComponent(type); + } + case "CUSTOM_STATISTICS" -> { + String handlerId = (String) config.get("handler_id"); + yield new CustomStatisticsComponent(handlerId); + } + case "TIERED_TALISMAN" -> { + ItemType baseTier = ItemType.valueOf((String) config.get("base_tier")); + int tier = (int) config.get("tier"); + yield new TieredTalismanComponent(baseTier, tier); + } + case "TRACKED_UNIQUE" -> new TrackedUniqueComponent(); + case "TRAVEL_SCROLL" -> { + String scrollType = (String) config.get("scroll_type"); + yield new TravelScrollComponent(scrollType); + } + case "PET" -> { + String petName = (String) config.get("pet_name"); + + // Parse george price + Map georgePriceMap = (Map) config.get("george_price"); + RarityValue georgePrice = new RarityValue<>( + georgePriceMap.get("common"), + georgePriceMap.get("uncommon"), + georgePriceMap.get("rare"), + georgePriceMap.get("epic"), + georgePriceMap.get("legendary"), + georgePriceMap.get("rest") + ); + + // Parse kat upgrades if present + RarityValue katUpgrades = null; + if (config.containsKey("kat_upgrades")) { + Map> katUpgradeMap = (Map>) config.get("kat_upgrades"); + katUpgrades = new RarityValue<>( + parseKatUpgrade(katUpgradeMap.get("common")), + parseKatUpgrade(katUpgradeMap.get("uncommon")), + parseKatUpgrade(katUpgradeMap.get("rare")), + parseKatUpgrade(katUpgradeMap.get("epic")), + parseKatUpgrade(katUpgradeMap.get("legendary")), + parseKatUpgrade(katUpgradeMap.get("rest")) + ); + } + + // Parse base statistics + Map baseStatsMap = (Map) config.get("base_statistics"); + ItemStatistics.Builder baseBuilder = ItemStatistics.builder(); + baseStatsMap.forEach((stat, value) -> + baseBuilder.withBase(ItemStatistic.valueOf(stat.toUpperCase()), value) + ); + ItemStatistics baseStatistics = baseBuilder.build(); + + // Parse per level statistics + Map perLevelStatsMap = (Map) config.get("per_level_statistics"); + Map perLevelStatistics = new HashMap<>(); + for (Map.Entry entry : perLevelStatsMap.entrySet()) { + String rarity = entry.getKey(); + ItemStatistics.Builder rarityBuilder = ItemStatistics.builder(); + try { + Map rarityStatsMap = (Map) entry.getValue(); + rarityBuilder = ItemStatistics.builder(); + for (Map.Entry e : rarityStatsMap.entrySet()) { + String stat = e.getKey(); + Double value = e.getValue(); + rarityBuilder.withBase(ItemStatistic.valueOf(stat.toUpperCase()), value); + } + } catch (ClassCastException e) { + // Per level statistics is a map with an Integer, so we need to convert it to a double + Map rarityStatsMap = (Map) entry.getValue(); + rarityBuilder = ItemStatistics.builder(); + for (Map.Entry mapEntry : rarityStatsMap.entrySet()) { + String stat = mapEntry.getKey(); + Integer value = mapEntry.getValue(); + rarityBuilder.withBase(ItemStatistic.valueOf(stat.toUpperCase()), Double.valueOf(value)); + } + } + perLevelStatistics.put(Rarity.valueOf(rarity.toUpperCase()), rarityBuilder.build()); + } + + // Parse other fields + Particle particleId = Particle.fromId((Integer) config.get("particle")); + String skillCategory = (String) config.get("skill_category"); + String skullTexture = (String) config.get("skull_texture"); + String handlerId = (String) config.get("handler_id"); + + yield new PetComponent( + petName, + georgePrice, + katUpgrades, + baseStatistics, + perLevelStatistics, + particleId, + skillCategory, + skullTexture, + handlerId + ); + } + default -> throw new IllegalArgumentException("Unknown component type: " + id); + }; + } + + private static KatUpgrade parseKatUpgrade(Map config) { + if (config == null) return null; + + Long time = ((Number) config.get("time")).longValue(); + Integer coins = (Integer) config.get("coins"); + + if (config.containsKey("item")) { + String item = (String) config.get("item"); + Integer amount = (Integer) config.get("amount"); + return KatUpgrade.WithItem(time, coins, ItemType.valueOf(item), amount); + } + + return KatUpgrade.OnlyCoins(time, coins); + } } \ No newline at end of file diff --git a/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/item/components/FishingRodComponent.java b/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/item/components/FishingRodComponent.java new file mode 100644 index 000000000..0493b516a --- /dev/null +++ b/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/item/components/FishingRodComponent.java @@ -0,0 +1,33 @@ +package net.swofty.type.skyblockgeneric.item.components; + +import net.kyori.adventure.key.Key; +import net.kyori.adventure.sound.Sound; +import net.swofty.type.skyblockgeneric.entity.FishingHook; +import net.swofty.type.skyblockgeneric.item.SkyBlockItemComponent; + +public class FishingRodComponent extends SkyBlockItemComponent { + + public FishingRodComponent() { + addInheritedComponent(new InteractableComponent( + null, + (player, item) -> { + FishingHook hook = FishingHook.getFishingHookForOwner(player); + if (hook != null) { + hook.remove(); + player.playSound( + Sound.sound() + .type(Key.key("entity.fishing_bobber.retrieve")) + .source(Sound.Source.NEUTRAL) + .volume(1f) + .pitch(0.8f) // the pitch is 0.8-1.2 + .build() + ); + } else { + new FishingHook(player).spawn(player.getInstance()); + } + }, + null + )); + } + +} From 0de4b09d02911a34c70f2a130a02b39535ce312e Mon Sep 17 00:00:00 2001 From: ArikSquad <75741608+ArikSquad@users.noreply.github.com> Date: Tue, 23 Dec 2025 13:57:22 +0200 Subject: [PATCH 002/113] feat: unfinished fishing quests --- .../data/datapoints/DatapointToggles.java | 2 + .../swofty/type/hub/gui/GUIGFishingShip.java | 133 ++++++++++++++++++ .../swofty/type/hub/npcs/NPCCaptainBaha.java | 77 ++++++++++ .../type/hub/npcs/NPCFishermanGerald.java | 82 +++++++++++ .../net/swofty/type/hub/npcs/NPCGavin.java | 77 ++++++++++ .../skyblockgeneric/entity/FishingHook.java | 3 +- .../item/components/FishingRodComponent.java | 3 +- 7 files changed, 375 insertions(+), 2 deletions(-) create mode 100644 type.hub/src/main/java/net/swofty/type/hub/gui/GUIGFishingShip.java create mode 100644 type.hub/src/main/java/net/swofty/type/hub/npcs/NPCCaptainBaha.java create mode 100644 type.hub/src/main/java/net/swofty/type/hub/npcs/NPCFishermanGerald.java create mode 100644 type.hub/src/main/java/net/swofty/type/hub/npcs/NPCGavin.java diff --git a/type.generic/src/main/java/net/swofty/type/generic/data/datapoints/DatapointToggles.java b/type.generic/src/main/java/net/swofty/type/generic/data/datapoints/DatapointToggles.java index 86d7e7324..df8c8c565 100644 --- a/type.generic/src/main/java/net/swofty/type/generic/data/datapoints/DatapointToggles.java +++ b/type.generic/src/main/java/net/swofty/type/generic/data/datapoints/DatapointToggles.java @@ -75,6 +75,8 @@ public enum ToggleType { HAS_SPOKEN_TO_LIFT_OPERATOR(false), HAS_SPOKEN_TO_LAZY_MINER(false), HAS_SPOKEN_TO_BAKER(false), + HAS_SPOKEN_TO_GAVIN(false), + HAS_SPOKEN_TO_FISHERMAN_GERALD(false), HAS_SPOKEN_TO_RUSTY(false), HAS_SPOKEN_TO_RUSTY_ABOUT_PICKAXE(false), HAS_SPOKEN_TO_CURATOR(false), diff --git a/type.hub/src/main/java/net/swofty/type/hub/gui/GUIGFishingShip.java b/type.hub/src/main/java/net/swofty/type/hub/gui/GUIGFishingShip.java new file mode 100644 index 000000000..5886b6a03 --- /dev/null +++ b/type.hub/src/main/java/net/swofty/type/hub/gui/GUIGFishingShip.java @@ -0,0 +1,133 @@ +package net.swofty.type.hub.gui; + +import net.minestom.server.event.inventory.InventoryPreClickEvent; +import net.minestom.server.inventory.InventoryType; +import net.minestom.server.item.ItemStack; +import net.minestom.server.item.Material; +import net.swofty.type.generic.gui.inventory.HypixelInventoryGUI; +import net.swofty.type.generic.gui.inventory.ItemStackCreator; +import net.swofty.type.generic.gui.inventory.item.GUIClickableItem; +import net.swofty.type.generic.gui.inventory.item.GUIItem; +import net.swofty.type.generic.user.HypixelPlayer; + +// TOOD: Fishing ship name can be changed. And the parts can be changed +public class GUIGFishingShip extends HypixelInventoryGUI { + + public GUIGFishingShip() { + super("{Fishing Ship}", InventoryType.CHEST_5_ROW); + } + + @Override + public void onOpen(InventoryGUIOpenEvent e) { + fill(FILLER_ITEM); + set(new GUIItem(4) { + @Override + public ItemStack.Builder getItem(HypixelPlayer player) { + return ItemStackCreator.getStack( + "§6{Fishing Ship}", + Material.OAK_BOAT, + 1, + "§7Your §6Ship §7will help you travel to", + "§7different §9fishing islands §7in SkyBlock.", + "", + "§7For now, it can only get you to the", + "§2Backwater Bayou§7.", + "", + "§7Helm: §fCracked Ship Helm", + "§7Engine: §fRusty Ship Engine", + "§7Hull: §fRusty Ship Hull" + ); + } + }); + set(new GUIItem(21) { + @Override + public ItemStack.Builder getItem(HypixelPlayer player) { + return ItemStackCreator.getStackHead( + "§fCracked Ship Helm", + "d8d4a54d1fcf47b2efc99ba4cc772250aee5c2f26ed1a19052213e0f3323ca1d", + 1, + "§7A cracked ship helm, incapable of", + "§7changing its heading which appears", + "§7due east.", + "", + "§6§lUPGRADE TO §8➜ §9Bronze Ship Helm", + "§7Crafted from §aBronze Bowls§7, which", + "§7are rarely dropped by §cDumpster", + "§cDivers §7in the §2Backwater Bayou§7.", + "", + "§eClick a Ship Part in your inventory to", + "§eupgrade this part!" + ); + } + }); + // TODO: this is "missing" by default, need to implement that state + set(new GUIItem(22) { + @Override + public ItemStack.Builder getItem(HypixelPlayer player) { + return ItemStackCreator.getStackHead( + "§fRusty Ship Engine", + "53e84793917c890f7f8a2c4078a29e8ba939790498727af9342c2b6f6ac43c9c", + 1, + "§7Rusted by the waters, but it seems to", + "§7be able to run...for now.", + "", + "§6§lUPGRADE TO §8➜ §9Bronze Ship Engine", + "§7Purchased from §2Junker Joel §7in the", + "§2Backwater Bayou§7.", + "", + "§eClick a Ship Part in your inventory to", + "§eupgrade this part!" + ); + } + }); + set(new GUIItem(23) { + @Override + public ItemStack.Builder getItem(HypixelPlayer player) { + return ItemStackCreator.getStackHead( + "§fRusty Ship Hull", + "f42d53ca6e7d80a99a699c2036dcf6e233394feb9f46fb2ff9d9a819690894a9", + 1, + "§7A hull rusted and dilapidated beyond", + "§7repair. It's a miracle the ship", + "§7remains afloat.", + "", + "§6§lUPGRADE TO §8➜ §9Bronze Ship Hull", + "§7Crafted from §aTorn Cloth§7, which is", + "§7rarely dropped by §cBanshees §7in the", + "§2Backwater Bayou§7.", + "", + "§eClick a Ship Part in your inventory to", + "§eupgrade this part!" + ); + } + }); + set(new GUIItem(44) { + @Override + public ItemStack.Builder getItem(HypixelPlayer player) { + return ItemStackCreator.getStack( + "§aRename Ship", + Material.NAME_TAG, + 1, + "§7You may be going on long voyages", + "§7with your §6Ship§7, best to give it a name!", + "", + "§7Current Name: §6Zephyr", + "", + "§eClick to rename!" + ); + } + }); + set(GUIClickableItem.getCloseItem(40)); + updateItemStacks(getInventory(), getPlayer()); + } + + @Override + public boolean allowHotkeying() { + return false; + } + + @Override + public void onBottomClick(InventoryPreClickEvent e) { + e.setCancelled(true); + } +} diff --git a/type.hub/src/main/java/net/swofty/type/hub/npcs/NPCCaptainBaha.java b/type.hub/src/main/java/net/swofty/type/hub/npcs/NPCCaptainBaha.java new file mode 100644 index 000000000..985de6655 --- /dev/null +++ b/type.hub/src/main/java/net/swofty/type/hub/npcs/NPCCaptainBaha.java @@ -0,0 +1,77 @@ +package net.swofty.type.hub.npcs; + +import net.minestom.server.coordinate.Pos; +import net.swofty.type.generic.data.datapoints.DatapointToggles; +import net.swofty.type.generic.entity.npc.HypixelNPC; +import net.swofty.type.generic.entity.npc.configuration.HumanConfiguration; +import net.swofty.type.generic.user.HypixelPlayer; + +import java.util.stream.Stream; + +public class NPCCaptainBaha extends HypixelNPC { + + public NPCCaptainBaha() { + super(new HumanConfiguration() { + @Override + public String[] holograms(HypixelPlayer player) { + return new String[]{"§6Captain Baha", "§e§lCLICK"}; + } + + @Override + public String signature(HypixelPlayer player) { + return "A9Wh529RWV2HEMvVnPzQEPfvT7p8m2GU8IB5FowBVYRash8GUSC6OvO88v5eBXAsCJvAauOnCFkp0DrxNTHUTS6E8rcGpo5ieHTr+QYglXIlA8S+rgA5eGODgI3LEtOZucHJ6H64a23Bu41lNMpN2c+LzQbisqC9WBnfVBxYo6qrzgh5JBGsRDIg2h3UKmTnNgJPuhN2cwRDDlHG8/k+xES5ZqyEFvdjGn6O5HHL6xyMkCukjZN0E8s03NkpkKxZXEm1M/Eg8EWtwGqZIa3DHNmxchYok4mDPMst8iRy4pGRlJN+VBCmGLIV7pq4QZlGzuXWplrX/PAOb+B36Rg67SHvmIk23tpnu+7uvB3rw9NedWY1+xLp8W4gPKpynOobSCbKiJ6bX0mCQfURVh2svFT5nG/VnKCL0TE8CUiTxOuxJR8QWwWRI4BMRMJQfQxy0mofvPnR5g1XUnHzvGWr4m44dmooqyCgB4W9iysADAEgc9CVtizjroopAJLXCtfsxwIuioHaZsBKQU1NpvpH55bPqf//RI9FyJJwOXTgX7fbF49z0eAgjnRAyF9VE9VYI2hFZwa3BIFnvdGxlZhE63QPB+nmKQMT0WzTz15lm77lxvvpQsurkm2gKr6FlL9+SokbTUuQmisyzS84s2EocpRscgc9JF1Dv/NjK7T+3GU="; + } + + @Override + public String texture(HypixelPlayer player) { + return "ewogICJ0aW1lc3RhbXAiIDogMTc0MDQxOTU1NzI0NiwKICAicHJvZmlsZUlkIiA6ICIzY2I3YTA3YWY3ZjM0ZWZiYTlkNGI4ODQ3NDM4Mzc0ZSIsCiAgInByb2ZpbGVOYW1lIiA6ICJBUkJVWklLMTIwMTMiLAogICJzaWduYXR1cmVSZXF1aXJlZCIgOiB0cnVlLAogICJ0ZXh0dXJlcyIgOiB7CiAgICAiU0tJTiIgOiB7CiAgICAgICJ1cmwiIDogImh0dHA6Ly90ZXh0dXJlcy5taW5lY3JhZnQubmV0L3RleHR1cmUvMzcxYzQ0YWQ0MDdjMDIxNzM3YWQ3ODkwN2I1MDY4ZDdiY2MwYzY1OGIyYTJmYmFiZjAxNzA2NTYzYmQ5NDQ3ZCIKICAgIH0KICB9Cn0="; + } + + @Override + public Pos position(HypixelPlayer player) { + return new Pos(179.500, 69.000, 55.500, 105, 0); + } + + @Override + public boolean looking() { + return true; + } + }); + } + + @Override + public void onClick(NPCInteractEvent event) { + HypixelPlayer player = event.player(); + if (isInDialogue(player)) return; + + if(!player.getToggles().get(DatapointToggles.Toggles.ToggleType.HAS_SPOKEN_TO_GAVIN)) { + setDialogue(player, "first-interaction").thenRun(() -> { + player.getToggles().set(DatapointToggles.Toggles.ToggleType.HAS_SPOKEN_TO_GAVIN, true); + }); + return; + } + + setDialogue(player, "idle-" + (int)(Math.random() * 2 + 1)); + // TODO: new GUIFishingShip().open(player); + } + + @Override + protected DialogueSet[] dialogues(HypixelPlayer player) { + return Stream.of( + DialogueSet.builder() + .key("first-interaction").lines(new String[]{ + "I was about to set sail, but this §6Ship §fis missing its §cengine§f!", + "Maybe §3Fisherman §fGerald knows where it is?", + }).build(), + DialogueSet.builder() + .key("rust-ship-engine").lines(new String[]{ + "Ahoy, is that the §cRusty Ship Engine§f?" + }).build(), + DialogueSet.builder() + .key("dialogue-yes").lines(new String[]{ + "Excellent! I'm the captain of this §6Ship§f, which means I oversee everything from repairs to navigation.", + "Apply that §cRusty Ship Engine §fin the §6Engine §fslot by clicking the engine in your inventory!" + }).build() + ).toArray(DialogueSet[]::new); + } +} diff --git a/type.hub/src/main/java/net/swofty/type/hub/npcs/NPCFishermanGerald.java b/type.hub/src/main/java/net/swofty/type/hub/npcs/NPCFishermanGerald.java new file mode 100644 index 000000000..c6f8fcd62 --- /dev/null +++ b/type.hub/src/main/java/net/swofty/type/hub/npcs/NPCFishermanGerald.java @@ -0,0 +1,82 @@ +package net.swofty.type.hub.npcs; + +import net.minestom.server.coordinate.Pos; +import net.swofty.type.generic.data.datapoints.DatapointToggles; +import net.swofty.type.generic.entity.npc.HypixelNPC; +import net.swofty.type.generic.entity.npc.configuration.HumanConfiguration; +import net.swofty.type.generic.user.HypixelPlayer; +import net.swofty.type.skyblockgeneric.skill.SkillCategories; +import net.swofty.type.skyblockgeneric.user.SkyBlockPlayer; + +import java.util.stream.Stream; + +public class NPCFishermanGerald extends HypixelNPC { + + public NPCFishermanGerald() { + super(new HumanConfiguration() { + @Override + public String[] holograms(HypixelPlayer player) { + return new String[]{"§3Fisherman Gerald", "§e§lCLICK"}; + } + + @Override + public String signature(HypixelPlayer player) { + return "oJ24ajDV0/I3NFdHBh7D71v+jboQFJlaFxxu47bWeSmUXhLl6z1Vk9aksUE8qqTNs9EVUWFpSjAe7i/w57nkh4AAH+GvplyzZANEhHf9SJhBdwjCpIDVJZ453hs9xMYbyvp4KiZkia+jbLKrQfQOFOa9aWt1mmhhOneNgzx4it5Bo1qzDoPvbgFu5uL7rbyzdOl9ZW5wEobb2Ns4TbqPdT+NjZurw7rkpRpdLhAbHZoD2NEw0BX3VHTvtlY8zh14//YV7Vo5+xUUWGTrt0UjudIxDdJI8R9ZiWgCgl9N1ElzokFh/h0aHg0vL0QSG1Y5bHY5ea+E2+3tLDiEvQO7Soh/VV1/yySjmkt/JbUiEFmCv6vkjm4bgbAZAm42GxlvkAyFpZoFZijmCaw8ObJivZlwJNUjY4D0PBEm4rnVSVFjjWBGaGXyFG2/KtUL8nYZE81ABqrL3xSHFeEUIBePNsBq84eI88aNGYCjU9Ct4bfAhbdZMWM84PzBqAa5jH6NNqb/5aV2jmEp0OcoF80W+pcaR/uNPOo9Gjy5HkUYMpLJ775SqC//m/Rrh7RypdNcVUIanmUqP+hP7oz1SI3L6glv4+CGlGprr67QHP9d9PcZzVgF1YHOfOKW4muqJNjgpKYFZRiz4yWmOdURKomqUuz4tyKDxu0drx5eHfQ+3mw="; + } + + @Override + public String texture(HypixelPlayer player) { + return "eyJ0aW1lc3RhbXAiOjE1NTk1NzQ0MjU3OTEsInByb2ZpbGVJZCI6ImZkNjBmMzZmNTg2MTRmMTJiM2NkNDdjMmQ4NTUyOTlhIiwicHJvZmlsZU5hbWUiOiJSZWFkIiwic2lnbmF0dXJlUmVxdWlyZWQiOnRydWUsInRleHR1cmVzIjp7IlNLSU4iOnsidXJsIjoiaHR0cDovL3RleHR1cmVzLm1pbmVjcmFmdC5uZXQvdGV4dHVyZS9hNjc1ZjA3MWVmYjBjZjI3YmYxNjA4MWUzZjgyZjliNWY4YWU4OGVjYTllZTk1MjNiNjIxNmU2MTdmNmY0NWM5In19fQ=="; + } + + @Override + public Pos position(HypixelPlayer player) { + return new Pos(153.500, 68.500, 55.500, -60, 0); + } + + @Override + public boolean looking() { + return true; + } + }); + } + + @Override + public void onClick(NPCInteractEvent event) { + SkyBlockPlayer player = (SkyBlockPlayer) event.player(); + if (isInDialogue(player)) return; + + boolean belowFive = player.getSkills().getCurrentLevel(SkillCategories.FISHING) < 5; + if (belowFive) { + setDialogue(player, "below-fishing-5"); + return; + } + + if(!player.getToggles().get(DatapointToggles.Toggles.ToggleType.HAS_SPOKEN_TO_FISHERMAN_GERALD)) { + setDialogue(player, "first-interaction").thenRun(() -> { + player.getToggles().set(DatapointToggles.Toggles.ToggleType.HAS_SPOKEN_TO_FISHERMAN_GERALD, true); + }); + return; + } + + // TODO: finish this quest + } + + @Override + protected DialogueSet[] dialogues(HypixelPlayer player) { + return Stream.of( + DialogueSet.builder() + .key("below-fishing-5").lines(new String[]{ + "Hmm, you're not quite ready yet.", + "Go talk to the §eFish Merchant §fin the §bFishing Outpost§f, get geared up, and get fishin'!", + "Come back once you've reached §aFishing Skill V §fand I'll tell you how you can get to a §anew island§f!", + }).build(), + DialogueSet.builder() + .key("first-interaction").lines(new String[]{ + "Keep the noise down, kid!", + "If you want to learn about §aFishing§f, go talk to my wife, Fisherwoman Enid.", + "She's fishing a bit §bupstream§f. Once she's shown you the ropes, come back and talk to me!", + }).build() + ).toArray(DialogueSet[]::new); + } +} diff --git a/type.hub/src/main/java/net/swofty/type/hub/npcs/NPCGavin.java b/type.hub/src/main/java/net/swofty/type/hub/npcs/NPCGavin.java new file mode 100644 index 000000000..019f86891 --- /dev/null +++ b/type.hub/src/main/java/net/swofty/type/hub/npcs/NPCGavin.java @@ -0,0 +1,77 @@ +package net.swofty.type.hub.npcs; + +import net.minestom.server.coordinate.Pos; +import net.swofty.type.generic.data.datapoints.DatapointToggles; +import net.swofty.type.generic.entity.npc.HypixelNPC; +import net.swofty.type.generic.entity.npc.configuration.HumanConfiguration; +import net.swofty.type.generic.user.HypixelPlayer; + +import java.util.stream.Stream; + +public class NPCGavin extends HypixelNPC { + + public NPCGavin() { + super(new HumanConfiguration() { + @Override + public String[] holograms(HypixelPlayer player) { + return new String[]{"§bGavin", "§e§lCLICK"}; + } + + @Override + public String signature(HypixelPlayer player) { + return "qwNSHj1b7UwXoeP6/Vs/1EGb0pyfO+DGOVUQ9DJ7DY0ZPn6VwQv1Ej1W39wANDGJI1p8eQKRqMLKH0Xj4WkSwnMnj0e7DZU2VROO9xi3th5IhJg/7SzpMt2vMvYUN3u6HI1EzhYHuLL1oHF1eGK/5lZZp6xvb2X4ZuOvX8oASvrgQFPcxR2WMn4nwS4bKRp5CDFGg+fCHCMuHHQAjZpJAHqbfxD2DWXq7CbuyOQJlIybhGDY30syWVKH1aZsp5Nmm8fOeSysqyZL+F49zBbxPUBaX/gmxsBR8cRyU37gBzT39aTeybFsZrQSOz3raFX7H4pRC8xf9dKQzTYxCvi14ljjp8q+IH1AWYSZJSZkxA6k03gxVH6Oxbs8XjHWxYQIu4uPhTV3LRShkSRz1WTLYHqu+I/fhmAsAN7YJQHYNFJGkLSBVYRCkSPCQ3efj7TDX455KlojZ23waaqEvH0d9gUMEScRc3Qpq1Tf3X63CNvd5BBO6apiN9Vfq3TZ3YKdhGLQLXBsu3QewCH2qcf6jbU37in6FltyncRsrd84pFsl2ryquOYhwj2slnVNIyhG7zAguRM9p7zvZOPYlgSplcMgW8sQ3Isv25PBGZ+B6Qhwdl4yYpUnc/n7EyxMuthGyID/nhwTBq4f51L3+RNDYnFz9ED26E3IcW/dQdgxPNA="; + } + + @Override + public String texture(HypixelPlayer player) { + return "ewogICJ0aW1lc3RhbXAiIDogMTc0MDA3MTUzNTE3NCwKICAicHJvZmlsZUlkIiA6ICI1ODc5MjNlNDkxMzM0ZDMzYWE4ZjQ3ZWJkZTljOTc3MiIsCiAgInByb2ZpbGVOYW1lIiA6ICJFbGV2ZW5mb3VyMTAiLAogICJzaWduYXR1cmVSZXF1aXJlZCIgOiB0cnVlLAogICJ0ZXh0dXJlcyIgOiB7CiAgICAiU0tJTiIgOiB7CiAgICAgICJ1cmwiIDogImh0dHA6Ly90ZXh0dXJlcy5taW5lY3JhZnQubmV0L3RleHR1cmUvZDZlMzc1NmQ4Y2ZhYzU0MDU1YmNkNTUyNWQyYTNhYmVmZTZjZWY3NzkyNGY4YTk5ODQ2YmVhMmZlZmY3NjExNCIKICAgIH0KICB9Cn0="; + } + + @Override + public Pos position(HypixelPlayer player) { + return new Pos(161.500, 69.900, 43.500, 203, 17); + } + + @Override + public boolean looking() { + return true; + } + }); + } + + @Override + public void onClick(NPCInteractEvent event) { + HypixelPlayer player = event.player(); + if (isInDialogue(player)) return; + + if(!player.getToggles().get(DatapointToggles.Toggles.ToggleType.HAS_SPOKEN_TO_GAVIN)) { + setDialogue(player, "first-interaction").thenRun(() -> { + player.getToggles().set(DatapointToggles.Toggles.ToggleType.HAS_SPOKEN_TO_GAVIN, true); + }); + return; + } + + setDialogue(player, "idle-" + (int)(Math.random() * 2 + 1)); + } + + @Override + protected DialogueSet[] dialogues(HypixelPlayer player) { + return Stream.of( + DialogueSet.builder() + .key("first-interaction").lines(new String[]{ + "At the end of each year I bake cakes for everyone in town to celebrate the year.", + "I made one especially for you, here you go.", + "I've recently added a §dNew Year Cake Bag §fto my inventory. Sadly, it's not free! Click me again to open my shop!", + }).build(), + DialogueSet.builder() + .key("idle-1").lines(new String[]{ + "You can open your §aSea Creature Guide §fthrough your §aFishing Skill §fmenu, or with §d/scg§f!" + }).build(), + DialogueSet.builder() + .key("idle-2").lines(new String[]{ + "I'd rather be out there fishing for §6Treasure§f.", + "But mum insists I finish my studies first." + }).build() + ).toArray(DialogueSet[]::new); + } +} diff --git a/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/entity/FishingHook.java b/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/entity/FishingHook.java index 1fb323cc3..93033b42f 100644 --- a/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/entity/FishingHook.java +++ b/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/entity/FishingHook.java @@ -80,12 +80,13 @@ public void spawn(Instance instance, Pos pos) { this.hook.setInstance(instance, pos); this.controller.addPassenger(hook); this.controller.setVelocity(owner.getPosition().direction().mul(INITIAL_SPEED_MULTIPLIER)); + float pitch = (float) 1/3 + (float) (Math.random() * (0.5 - 1.0 / 3.0)); owner.playSound( Sound.sound() .type(Key.key("entity.fishing_bobber.throw")) .source(Sound.Source.NEUTRAL) .volume(0.5f) - .pitch((float) 1 / 3) // the pitch is 1/3-0.5 + .pitch(pitch) .build() ); } diff --git a/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/item/components/FishingRodComponent.java b/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/item/components/FishingRodComponent.java index 0493b516a..2cbed8e14 100644 --- a/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/item/components/FishingRodComponent.java +++ b/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/item/components/FishingRodComponent.java @@ -14,12 +14,13 @@ public FishingRodComponent() { FishingHook hook = FishingHook.getFishingHookForOwner(player); if (hook != null) { hook.remove(); + float pitch = 0.8f + (float) (Math.random() * 0.4f); player.playSound( Sound.sound() .type(Key.key("entity.fishing_bobber.retrieve")) .source(Sound.Source.NEUTRAL) .volume(1f) - .pitch(0.8f) // the pitch is 0.8-1.2 + .pitch(pitch) .build() ); } else { From 04bdea1263f91e10add48dbde1f51de061aa32da Mon Sep 17 00:00:00 2001 From: ArikSquad <75741608+ArikSquad@users.noreply.github.com> Date: Sun, 28 Dec 2025 19:26:12 +0200 Subject: [PATCH 003/113] fix: import after merge --- .../src/main/java/net/swofty/type/hub/npcs/NPCCaptainBaha.java | 1 + .../main/java/net/swofty/type/hub/npcs/NPCFishermanGerald.java | 1 + type.hub/src/main/java/net/swofty/type/hub/npcs/NPCGavin.java | 1 + 3 files changed, 3 insertions(+) diff --git a/type.hub/src/main/java/net/swofty/type/hub/npcs/NPCCaptainBaha.java b/type.hub/src/main/java/net/swofty/type/hub/npcs/NPCCaptainBaha.java index 985de6655..e41346ea4 100644 --- a/type.hub/src/main/java/net/swofty/type/hub/npcs/NPCCaptainBaha.java +++ b/type.hub/src/main/java/net/swofty/type/hub/npcs/NPCCaptainBaha.java @@ -4,6 +4,7 @@ import net.swofty.type.generic.data.datapoints.DatapointToggles; import net.swofty.type.generic.entity.npc.HypixelNPC; import net.swofty.type.generic.entity.npc.configuration.HumanConfiguration; +import net.swofty.type.generic.event.custom.NPCInteractEvent; import net.swofty.type.generic.user.HypixelPlayer; import java.util.stream.Stream; diff --git a/type.hub/src/main/java/net/swofty/type/hub/npcs/NPCFishermanGerald.java b/type.hub/src/main/java/net/swofty/type/hub/npcs/NPCFishermanGerald.java index c6f8fcd62..399d73784 100644 --- a/type.hub/src/main/java/net/swofty/type/hub/npcs/NPCFishermanGerald.java +++ b/type.hub/src/main/java/net/swofty/type/hub/npcs/NPCFishermanGerald.java @@ -4,6 +4,7 @@ import net.swofty.type.generic.data.datapoints.DatapointToggles; import net.swofty.type.generic.entity.npc.HypixelNPC; import net.swofty.type.generic.entity.npc.configuration.HumanConfiguration; +import net.swofty.type.generic.event.custom.NPCInteractEvent; import net.swofty.type.generic.user.HypixelPlayer; import net.swofty.type.skyblockgeneric.skill.SkillCategories; import net.swofty.type.skyblockgeneric.user.SkyBlockPlayer; diff --git a/type.hub/src/main/java/net/swofty/type/hub/npcs/NPCGavin.java b/type.hub/src/main/java/net/swofty/type/hub/npcs/NPCGavin.java index 019f86891..8195ba1fd 100644 --- a/type.hub/src/main/java/net/swofty/type/hub/npcs/NPCGavin.java +++ b/type.hub/src/main/java/net/swofty/type/hub/npcs/NPCGavin.java @@ -4,6 +4,7 @@ import net.swofty.type.generic.data.datapoints.DatapointToggles; import net.swofty.type.generic.entity.npc.HypixelNPC; import net.swofty.type.generic.entity.npc.configuration.HumanConfiguration; +import net.swofty.type.generic.event.custom.NPCInteractEvent; import net.swofty.type.generic.user.HypixelPlayer; import java.util.stream.Stream; From 52785c845cc1fc3fe7213f9b08ce30007afcf319 Mon Sep 17 00:00:00 2001 From: ArikSquad <75741608+ArikSquad@users.noreply.github.com> Date: Tue, 30 Dec 2025 01:17:08 +0200 Subject: [PATCH 004/113] feat: add HypixelPlayer method signature to overriden HypixelNPC#looking methods --- .../src/main/java/net/swofty/type/hub/npcs/NPCCaptainBaha.java | 2 +- .../main/java/net/swofty/type/hub/npcs/NPCFishermanGerald.java | 2 +- type.hub/src/main/java/net/swofty/type/hub/npcs/NPCGavin.java | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/type.hub/src/main/java/net/swofty/type/hub/npcs/NPCCaptainBaha.java b/type.hub/src/main/java/net/swofty/type/hub/npcs/NPCCaptainBaha.java index e41346ea4..4bf4cd26c 100644 --- a/type.hub/src/main/java/net/swofty/type/hub/npcs/NPCCaptainBaha.java +++ b/type.hub/src/main/java/net/swofty/type/hub/npcs/NPCCaptainBaha.java @@ -34,7 +34,7 @@ public Pos position(HypixelPlayer player) { } @Override - public boolean looking() { + public boolean looking(HypixelPlayer player) { return true; } }); diff --git a/type.hub/src/main/java/net/swofty/type/hub/npcs/NPCFishermanGerald.java b/type.hub/src/main/java/net/swofty/type/hub/npcs/NPCFishermanGerald.java index 399d73784..0c919476b 100644 --- a/type.hub/src/main/java/net/swofty/type/hub/npcs/NPCFishermanGerald.java +++ b/type.hub/src/main/java/net/swofty/type/hub/npcs/NPCFishermanGerald.java @@ -36,7 +36,7 @@ public Pos position(HypixelPlayer player) { } @Override - public boolean looking() { + public boolean looking(HypixelPlayer player) { return true; } }); diff --git a/type.hub/src/main/java/net/swofty/type/hub/npcs/NPCGavin.java b/type.hub/src/main/java/net/swofty/type/hub/npcs/NPCGavin.java index 8195ba1fd..0ef94e224 100644 --- a/type.hub/src/main/java/net/swofty/type/hub/npcs/NPCGavin.java +++ b/type.hub/src/main/java/net/swofty/type/hub/npcs/NPCGavin.java @@ -34,7 +34,7 @@ public Pos position(HypixelPlayer player) { } @Override - public boolean looking() { + public boolean looking(HypixelPlayer player) { return true; } }); From a24c1cefe0603c3014a9f5986e29bd36c561ec8c Mon Sep 17 00:00:00 2001 From: ArikSquad <75741608+ArikSquad@users.noreply.github.com> Date: Tue, 30 Dec 2025 01:22:11 +0200 Subject: [PATCH 005/113] refactor: remove extra 0s on positions --- .../src/main/java/net/swofty/type/hub/npcs/NPCCaptainBaha.java | 2 +- .../main/java/net/swofty/type/hub/npcs/NPCFishermanGerald.java | 2 +- type.hub/src/main/java/net/swofty/type/hub/npcs/NPCGavin.java | 2 +- .../missions/thepark/birchpark/MissionGiveCharlieBirchLogs.java | 2 +- .../missions/thepark/birchpark/MissionTalkToCharlie.java | 2 +- .../missions/thepark/birchpark/MissionTalkToCharlieAgain.java | 2 +- .../thepark/darkthicket/MissionGiveRyanDarkOakLogs.java | 2 +- .../missions/thepark/darkthicket/MissionSneakUpOnRyan.java | 2 +- .../mission/missions/thepark/darkthicket/MissionTalkToRyan.java | 2 +- .../mission/missions/thepark/jungle/MissionTalkToMolbert.java | 2 +- .../mission/missions/thepark/savanna/MissionCheckOnMelody.java | 2 +- .../missions/thepark/savanna/MissionGiveMelodyAcaciaLogs.java | 2 +- .../mission/missions/thepark/spruce/MissionFindKelly.java | 2 +- .../missions/thepark/spruce/MissionGiveKellySpruceLogs.java | 2 +- 14 files changed, 14 insertions(+), 14 deletions(-) diff --git a/type.hub/src/main/java/net/swofty/type/hub/npcs/NPCCaptainBaha.java b/type.hub/src/main/java/net/swofty/type/hub/npcs/NPCCaptainBaha.java index 4bf4cd26c..d5ade58e1 100644 --- a/type.hub/src/main/java/net/swofty/type/hub/npcs/NPCCaptainBaha.java +++ b/type.hub/src/main/java/net/swofty/type/hub/npcs/NPCCaptainBaha.java @@ -30,7 +30,7 @@ public String texture(HypixelPlayer player) { @Override public Pos position(HypixelPlayer player) { - return new Pos(179.500, 69.000, 55.500, 105, 0); + return new Pos(179.5, 69, 55.5, 105, 0); } @Override diff --git a/type.hub/src/main/java/net/swofty/type/hub/npcs/NPCFishermanGerald.java b/type.hub/src/main/java/net/swofty/type/hub/npcs/NPCFishermanGerald.java index 0c919476b..a0cb82351 100644 --- a/type.hub/src/main/java/net/swofty/type/hub/npcs/NPCFishermanGerald.java +++ b/type.hub/src/main/java/net/swofty/type/hub/npcs/NPCFishermanGerald.java @@ -32,7 +32,7 @@ public String texture(HypixelPlayer player) { @Override public Pos position(HypixelPlayer player) { - return new Pos(153.500, 68.500, 55.500, -60, 0); + return new Pos(153.5, 68.5, 55.5, -60, 0); } @Override diff --git a/type.hub/src/main/java/net/swofty/type/hub/npcs/NPCGavin.java b/type.hub/src/main/java/net/swofty/type/hub/npcs/NPCGavin.java index 0ef94e224..49e07821c 100644 --- a/type.hub/src/main/java/net/swofty/type/hub/npcs/NPCGavin.java +++ b/type.hub/src/main/java/net/swofty/type/hub/npcs/NPCGavin.java @@ -30,7 +30,7 @@ public String texture(HypixelPlayer player) { @Override public Pos position(HypixelPlayer player) { - return new Pos(161.500, 69.900, 43.500, 203, 17); + return new Pos(161.5, 69.900, 43.5, 203, 17); } @Override diff --git a/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/mission/missions/thepark/birchpark/MissionGiveCharlieBirchLogs.java b/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/mission/missions/thepark/birchpark/MissionGiveCharlieBirchLogs.java index d796dc2ba..70a517d61 100644 --- a/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/mission/missions/thepark/birchpark/MissionGiveCharlieBirchLogs.java +++ b/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/mission/missions/thepark/birchpark/MissionGiveCharlieBirchLogs.java @@ -44,6 +44,6 @@ public Set getValidRegions() { @Override public Pos getLocation() { - return new Pos(-277.5, 80, -17.500); + return new Pos(-277.5, 80, -17.5); } } diff --git a/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/mission/missions/thepark/birchpark/MissionTalkToCharlie.java b/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/mission/missions/thepark/birchpark/MissionTalkToCharlie.java index ef062d1f5..a0e35b5b0 100644 --- a/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/mission/missions/thepark/birchpark/MissionTalkToCharlie.java +++ b/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/mission/missions/thepark/birchpark/MissionTalkToCharlie.java @@ -40,6 +40,6 @@ public Set getValidRegions() { @Override public Pos getLocation() { - return new Pos(-277.5, 80, -17.500); + return new Pos(-277.5, 80, -17.5); } } diff --git a/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/mission/missions/thepark/birchpark/MissionTalkToCharlieAgain.java b/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/mission/missions/thepark/birchpark/MissionTalkToCharlieAgain.java index f8c7ba560..fac3eb988 100644 --- a/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/mission/missions/thepark/birchpark/MissionTalkToCharlieAgain.java +++ b/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/mission/missions/thepark/birchpark/MissionTalkToCharlieAgain.java @@ -45,6 +45,6 @@ public Set getValidRegions() { @Override public Pos getLocation() { - return new Pos(-277.5, 80, -17.500); + return new Pos(-277.5, 80, -17.5); } } diff --git a/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/mission/missions/thepark/darkthicket/MissionGiveRyanDarkOakLogs.java b/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/mission/missions/thepark/darkthicket/MissionGiveRyanDarkOakLogs.java index 42ec99156..4b7c983fd 100644 --- a/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/mission/missions/thepark/darkthicket/MissionGiveRyanDarkOakLogs.java +++ b/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/mission/missions/thepark/darkthicket/MissionGiveRyanDarkOakLogs.java @@ -22,7 +22,7 @@ public class MissionGiveRyanDarkOakLogs extends SkyBlockMission implements Locat @Override public Pos getLocation() { - return new Pos(-364.5, 102.5, -90.500); + return new Pos(-364.5, 102.5, -90.5); } @Override diff --git a/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/mission/missions/thepark/darkthicket/MissionSneakUpOnRyan.java b/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/mission/missions/thepark/darkthicket/MissionSneakUpOnRyan.java index d4971f034..6acbbb650 100644 --- a/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/mission/missions/thepark/darkthicket/MissionSneakUpOnRyan.java +++ b/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/mission/missions/thepark/darkthicket/MissionSneakUpOnRyan.java @@ -14,7 +14,7 @@ public class MissionSneakUpOnRyan extends SkyBlockMission implements LocationAss @Override public Pos getLocation() { - return new Pos(-364.5, 102.5, -90.500); + return new Pos(-364.5, 102.5, -90.5); } @Override diff --git a/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/mission/missions/thepark/darkthicket/MissionTalkToRyan.java b/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/mission/missions/thepark/darkthicket/MissionTalkToRyan.java index 8f6f02b65..62136e8d3 100644 --- a/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/mission/missions/thepark/darkthicket/MissionTalkToRyan.java +++ b/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/mission/missions/thepark/darkthicket/MissionTalkToRyan.java @@ -14,7 +14,7 @@ public class MissionTalkToRyan extends SkyBlockMission implements LocationAssoci @Override public Pos getLocation() { - return new Pos(-364.5, 102.5, -90.500); + return new Pos(-364.5, 102.5, -90.5); } @Override diff --git a/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/mission/missions/thepark/jungle/MissionTalkToMolbert.java b/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/mission/missions/thepark/jungle/MissionTalkToMolbert.java index f29d22c30..60bf01d1c 100644 --- a/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/mission/missions/thepark/jungle/MissionTalkToMolbert.java +++ b/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/mission/missions/thepark/jungle/MissionTalkToMolbert.java @@ -14,7 +14,7 @@ public class MissionTalkToMolbert extends SkyBlockMission implements LocationAss @Override public Pos getLocation() { - return new Pos(-447.5, 120, -63.500); + return new Pos(-447.5, 120, -63.5); } @Override diff --git a/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/mission/missions/thepark/savanna/MissionCheckOnMelody.java b/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/mission/missions/thepark/savanna/MissionCheckOnMelody.java index 4ab4fbc35..b14c2813f 100644 --- a/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/mission/missions/thepark/savanna/MissionCheckOnMelody.java +++ b/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/mission/missions/thepark/savanna/MissionCheckOnMelody.java @@ -40,6 +40,6 @@ public Set getValidRegions() { @Override public Pos getLocation() { - return new Pos(-411.5, 109, 71.500); + return new Pos(-411.5, 109, 71.5); } } diff --git a/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/mission/missions/thepark/savanna/MissionGiveMelodyAcaciaLogs.java b/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/mission/missions/thepark/savanna/MissionGiveMelodyAcaciaLogs.java index 2072491f5..3efc71140 100644 --- a/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/mission/missions/thepark/savanna/MissionGiveMelodyAcaciaLogs.java +++ b/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/mission/missions/thepark/savanna/MissionGiveMelodyAcaciaLogs.java @@ -21,7 +21,7 @@ public class MissionGiveMelodyAcaciaLogs extends SkyBlockMission implements Loca @Override public Pos getLocation() { - return new Pos(-411.5, 109, 71.500); + return new Pos(-411.5, 109, 71.5); } @Override diff --git a/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/mission/missions/thepark/spruce/MissionFindKelly.java b/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/mission/missions/thepark/spruce/MissionFindKelly.java index de04e80a7..5cc574129 100644 --- a/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/mission/missions/thepark/spruce/MissionFindKelly.java +++ b/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/mission/missions/thepark/spruce/MissionFindKelly.java @@ -14,7 +14,7 @@ public class MissionFindKelly extends SkyBlockMission implements LocationAssocia @Override public Pos getLocation() { - return new Pos(-350.5, 94, 33.500); + return new Pos(-350.5, 94, 33.5); } @Override diff --git a/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/mission/missions/thepark/spruce/MissionGiveKellySpruceLogs.java b/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/mission/missions/thepark/spruce/MissionGiveKellySpruceLogs.java index 471cd78cc..f5e79f5dd 100644 --- a/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/mission/missions/thepark/spruce/MissionGiveKellySpruceLogs.java +++ b/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/mission/missions/thepark/spruce/MissionGiveKellySpruceLogs.java @@ -15,7 +15,7 @@ public class MissionGiveKellySpruceLogs extends SkyBlockMission implements Locat @Override public Pos getLocation() { - return new Pos(-350.5, 94, 33.500); + return new Pos(-350.5, 94, 33.5); } @Override From eb262b2483511c4a5ed82cc4af0387f4e5add0e6 Mon Sep 17 00:00:00 2001 From: ArikSquad <75741608+ArikSquad@users.noreply.github.com> Date: Mon, 16 Mar 2026 23:35:45 +0200 Subject: [PATCH 006/113] feat: slop --- build.gradle.kts | 12 +- .../commons/skyblock/item/ItemType.java | 124 +++ .../ItemAttributeFishingExpertiseKills.java | 27 + .../attributes/ItemAttributeFishingHook.java | 27 + .../attributes/ItemAttributeFishingLine.java | 27 + .../ItemAttributeFishingSinker.java | 27 + .../skyblock/statistics/ItemStatistic.java | 3 + configuration/skyblock/fishing/hotspots.yml | 5 + configuration/skyblock/fishing/tables.yml | 206 +++++ .../skyblock/fishing/trophy_fish.yml | 13 + .../skyblock/items/fishing/fishingContent.yml | 735 ++++++++++++++++++ .../TypeBackwaterBayouLoader.java | 4 +- .../gui/GUIFishingRodParts.java | 100 +++ .../type/backwaterbayou/gui/GUIHook.java | 48 ++ .../backwaterbayou/gui/GUIJunkerJoel.java | 461 +++++++++++ .../type/backwaterbayou/gui/GUILine.java | 48 ++ .../backwaterbayou/gui/GUIRodPartGuide.java | 64 ++ .../type/backwaterbayou/gui/GUISinker.java | 48 ++ .../backwaterbayou/npcs/NPCCaptainBaha.java | 75 ++ .../type/backwaterbayou/npcs/NPCHattie.java | 69 ++ .../backwaterbayou/npcs/NPCJunkerJoel.java | 64 ++ .../type/backwaterbayou/npcs/NPCRoddy.java | 74 ++ .../crimsonisle/TypeCrimsonIsleLoader.java | 4 +- .../data/datapoints/DatapointToggles.java | 6 + .../gui/{ => fishing}/GUIGFishingShip.java | 2 +- .../type/hub/gui/fishing/GUINavigator.java | 57 ++ .../swofty/type/hub/npcs/NPCCaptainBaha.java | 51 +- .../type/hub/npcs/NPCFishermanGerald.java | 59 +- .../type/hub/npcs/NPCFisherwomanEnid.java | 64 ++ .../SkyBlockGenericLoader.java | 2 + .../data/SkyBlockDataHandler.java | 23 +- .../data/datapoints/DatapointShipState.java | 97 +++ .../data/datapoints/DatapointTrophyFish.java | 124 +++ .../enchantment/EnchantmentType.java | 15 + .../enchantment/impl/EnchantmentAngler.java | 58 ++ .../enchantment/impl/EnchantmentBlessing.java | 51 ++ .../enchantment/impl/EnchantmentCaster.java | 51 ++ .../enchantment/impl/EnchantmentCharm.java | 34 + .../impl/EnchantmentCorruption.java | 50 ++ .../impl/EnchantmentExpertise.java | 52 ++ .../enchantment/impl/EnchantmentFlash.java | 57 ++ .../enchantment/impl/EnchantmentFrail.java | 52 ++ .../impl/EnchantmentLuckOfTheSea.java | 59 ++ .../enchantment/impl/EnchantmentLure.java | 58 ++ .../enchantment/impl/EnchantmentMagnet.java | 51 ++ .../enchantment/impl/EnchantmentPiscary.java | 59 ++ .../impl/EnchantmentQuickBite.java | 50 ++ .../impl/EnchantmentSpikedHook.java | 52 ++ .../enchantment/impl/EnchantmentTabasco.java | 53 ++ .../skyblockgeneric/entity/FishingHook.java | 162 +++- .../fishing/BaitDefinition.java | 22 + .../fishing/FishingBaitService.java | 54 ++ .../fishing/FishingCatchKind.java | 10 + .../fishing/FishingCatchResolver.java | 10 + .../fishing/FishingCatchResult.java | 15 + .../fishing/FishingContext.java | 21 + .../fishing/FishingHotspotService.java | 69 ++ .../fishing/FishingItemBootstrap.java | 25 + .../fishing/FishingItemCatalog.java | 160 ++++ .../fishing/FishingLootResolver.java | 259 ++++++ .../fishing/FishingMedium.java | 30 + .../fishing/FishingRegistry.java | 438 +++++++++++ .../fishing/FishingRodDefinition.java | 23 + .../fishing/FishingRodLoreBuilder.java | 222 ++++++ .../fishing/FishingRodPartService.java | 62 ++ .../fishing/FishingService.java | 158 ++++ .../fishing/FishingSession.java | 29 + .../fishing/FishingShipService.java | 30 + .../fishing/FishingTableDefinition.java | 19 + .../fishing/HotspotDefinition.java | 20 + .../fishing/RodPartDefinition.java | 30 + .../fishing/SeaCreatureDefinition.java | 14 + .../fishing/ShipPartDefinition.java | 19 + .../fishing/TrophyFishDefinition.java | 25 + .../fishing/FishingGuideStackFactory.java | 151 ++++ .../fishing/GUI13SeaCreatureGuide.java | 645 +++++++++++++++ .../fishing/GUI23SeaCreatureGuide.java | 574 ++++++++++++++ .../fishing/GUI33SeaCreatureGuide.java | 272 +++++++ .../gui/inventories/fishing/GUIBaitGuide.java | 42 + .../GUIFishingSkillExampleRemoveThis.java | 450 +++++++++++ .../item/ItemAttributeHandler.java | 48 +- .../item/ItemConfigParser.java | 73 ++ .../skyblockgeneric/item/SkyBlockItem.java | 28 + .../item/components/FishingBaitComponent.java | 46 ++ .../item/components/FishingRodComponent.java | 11 +- .../FishingRodMetadataComponent.java | 52 ++ .../components/FishingRodPartComponent.java | 53 ++ .../components/FishingShipPartComponent.java | 22 + .../skyblockgeneric/region/RegionType.java | 11 + .../skyblockgeneric/user/SkyBlockPlayer.java | 23 +- 90 files changed, 7933 insertions(+), 46 deletions(-) create mode 100644 commons/src/main/java/net/swofty/commons/skyblock/item/attribute/attributes/ItemAttributeFishingExpertiseKills.java create mode 100644 commons/src/main/java/net/swofty/commons/skyblock/item/attribute/attributes/ItemAttributeFishingHook.java create mode 100644 commons/src/main/java/net/swofty/commons/skyblock/item/attribute/attributes/ItemAttributeFishingLine.java create mode 100644 commons/src/main/java/net/swofty/commons/skyblock/item/attribute/attributes/ItemAttributeFishingSinker.java create mode 100644 configuration/skyblock/fishing/hotspots.yml create mode 100644 configuration/skyblock/fishing/tables.yml create mode 100644 configuration/skyblock/fishing/trophy_fish.yml create mode 100644 configuration/skyblock/items/fishing/fishingContent.yml create mode 100644 type.backwaterbayou/src/main/java/net/swofty/type/backwaterbayou/gui/GUIFishingRodParts.java create mode 100644 type.backwaterbayou/src/main/java/net/swofty/type/backwaterbayou/gui/GUIHook.java create mode 100644 type.backwaterbayou/src/main/java/net/swofty/type/backwaterbayou/gui/GUIJunkerJoel.java create mode 100644 type.backwaterbayou/src/main/java/net/swofty/type/backwaterbayou/gui/GUILine.java create mode 100644 type.backwaterbayou/src/main/java/net/swofty/type/backwaterbayou/gui/GUIRodPartGuide.java create mode 100644 type.backwaterbayou/src/main/java/net/swofty/type/backwaterbayou/gui/GUISinker.java create mode 100644 type.backwaterbayou/src/main/java/net/swofty/type/backwaterbayou/npcs/NPCCaptainBaha.java create mode 100644 type.backwaterbayou/src/main/java/net/swofty/type/backwaterbayou/npcs/NPCHattie.java create mode 100644 type.backwaterbayou/src/main/java/net/swofty/type/backwaterbayou/npcs/NPCJunkerJoel.java create mode 100644 type.backwaterbayou/src/main/java/net/swofty/type/backwaterbayou/npcs/NPCRoddy.java rename type.hub/src/main/java/net/swofty/type/hub/gui/{ => fishing}/GUIGFishingShip.java (99%) create mode 100644 type.hub/src/main/java/net/swofty/type/hub/gui/fishing/GUINavigator.java create mode 100644 type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/data/datapoints/DatapointShipState.java create mode 100644 type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/data/datapoints/DatapointTrophyFish.java create mode 100644 type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/enchantment/impl/EnchantmentAngler.java create mode 100644 type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/enchantment/impl/EnchantmentBlessing.java create mode 100644 type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/enchantment/impl/EnchantmentCaster.java create mode 100644 type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/enchantment/impl/EnchantmentCharm.java create mode 100644 type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/enchantment/impl/EnchantmentCorruption.java create mode 100644 type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/enchantment/impl/EnchantmentExpertise.java create mode 100644 type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/enchantment/impl/EnchantmentFlash.java create mode 100644 type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/enchantment/impl/EnchantmentFrail.java create mode 100644 type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/enchantment/impl/EnchantmentLuckOfTheSea.java create mode 100644 type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/enchantment/impl/EnchantmentLure.java create mode 100644 type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/enchantment/impl/EnchantmentMagnet.java create mode 100644 type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/enchantment/impl/EnchantmentPiscary.java create mode 100644 type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/enchantment/impl/EnchantmentQuickBite.java create mode 100644 type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/enchantment/impl/EnchantmentSpikedHook.java create mode 100644 type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/enchantment/impl/EnchantmentTabasco.java create mode 100644 type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/fishing/BaitDefinition.java create mode 100644 type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/fishing/FishingBaitService.java create mode 100644 type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/fishing/FishingCatchKind.java create mode 100644 type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/fishing/FishingCatchResolver.java create mode 100644 type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/fishing/FishingCatchResult.java create mode 100644 type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/fishing/FishingContext.java create mode 100644 type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/fishing/FishingHotspotService.java create mode 100644 type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/fishing/FishingItemBootstrap.java create mode 100644 type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/fishing/FishingItemCatalog.java create mode 100644 type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/fishing/FishingLootResolver.java create mode 100644 type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/fishing/FishingMedium.java create mode 100644 type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/fishing/FishingRegistry.java create mode 100644 type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/fishing/FishingRodDefinition.java create mode 100644 type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/fishing/FishingRodLoreBuilder.java create mode 100644 type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/fishing/FishingRodPartService.java create mode 100644 type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/fishing/FishingService.java create mode 100644 type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/fishing/FishingSession.java create mode 100644 type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/fishing/FishingShipService.java create mode 100644 type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/fishing/FishingTableDefinition.java create mode 100644 type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/fishing/HotspotDefinition.java create mode 100644 type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/fishing/RodPartDefinition.java create mode 100644 type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/fishing/SeaCreatureDefinition.java create mode 100644 type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/fishing/ShipPartDefinition.java create mode 100644 type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/fishing/TrophyFishDefinition.java create mode 100644 type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/gui/inventories/fishing/FishingGuideStackFactory.java create mode 100644 type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/gui/inventories/fishing/GUI13SeaCreatureGuide.java create mode 100644 type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/gui/inventories/fishing/GUI23SeaCreatureGuide.java create mode 100644 type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/gui/inventories/fishing/GUI33SeaCreatureGuide.java create mode 100644 type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/gui/inventories/fishing/GUIBaitGuide.java create mode 100644 type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/gui/inventories/fishing/GUIFishingSkillExampleRemoveThis.java create mode 100644 type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/item/components/FishingBaitComponent.java create mode 100644 type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/item/components/FishingRodMetadataComponent.java create mode 100644 type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/item/components/FishingRodPartComponent.java create mode 100644 type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/item/components/FishingShipPartComponent.java diff --git a/build.gradle.kts b/build.gradle.kts index f80468c61..b840da473 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -1,7 +1,3 @@ -import org.gradle.api.artifacts.VersionCatalog -import org.gradle.api.artifacts.VersionCatalogsExtension -import org.gradle.kotlin.dsl.getByType - plugins { base java @@ -14,6 +10,14 @@ version = "1.0" val libsCatalog: VersionCatalog = extensions.getByType().named("libs") +repositories { + mavenCentral() + mavenLocal() + maven("https://repo.viaversion.com") + maven("https://jitpack.io") + maven("https://repo.lucko.me/") +} + subprojects { apply(plugin = "java") apply(plugin = "java-library") diff --git a/commons/src/generated/java/net/swofty/commons/skyblock/item/ItemType.java b/commons/src/generated/java/net/swofty/commons/skyblock/item/ItemType.java index ec8113c04..0021effb6 100644 --- a/commons/src/generated/java/net/swofty/commons/skyblock/item/ItemType.java +++ b/commons/src/generated/java/net/swofty/commons/skyblock/item/ItemType.java @@ -1,6 +1,8 @@ // AUTO-GENERATED FILE. DO NOT EDIT. package net.swofty.commons.skyblock.item; +import java.lang.Exception; +import java.lang.String; import net.minestom.server.item.Material; import net.swofty.commons.StringUtility; import org.jetbrains.annotations.Nullable; @@ -136,6 +138,8 @@ public enum ItemType { ATTACK_SPEED_ENRICHMENT(Material.PLAYER_HEAD, Rarity.COMMON), + AUGER_ROD(Material.FISHING_ROD, Rarity.LEGENDARY), + AUTOPET_RULES_2_PACK(Material.PLAYER_HEAD, Rarity.SPECIAL), AUTO_RECOMBOBULATOR(Material.PLAYER_HEAD, Rarity.COMMON), @@ -316,6 +320,8 @@ public enum ItemType { BLAZE_ROD_DISTILLATE(Material.PLAYER_HEAD, Rarity.RARE), + BLESSED_BAIT(Material.PLAYER_HEAD, Rarity.UNCOMMON), + BLOCK_DATA_TOOL(Material.DEBUG_STICK, Rarity.ADMIN), BLOCK_ZAPPER(Material.FLINT, Rarity.COMMON), @@ -402,6 +408,12 @@ public enum ItemType { BRONZE_BOWL(Material.PLAYER_HEAD, Rarity.UNCOMMON), + BRONZE_SHIP_ENGINE(Material.PLAYER_HEAD, Rarity.RARE), + + BRONZE_SHIP_HELM(Material.PLAYER_HEAD, Rarity.RARE), + + BRONZE_SHIP_HULL(Material.PLAYER_HEAD, Rarity.RARE), + BROWN_BANNER(Material.BROWN_BANNER, Rarity.COMMON), BROWN_BED(Material.BROWN_BED, Rarity.COMMON), @@ -518,6 +530,8 @@ public enum ItemType { CARROT(Material.CARROT, Rarity.COMMON), + CARROT_BAIT(Material.PLAYER_HEAD, Rarity.COMMON), + CARROT_CRYSTAL(Material.PLAYER_HEAD, Rarity.COMMON), CARROT_MINION(Material.PLAYER_HEAD, Rarity.COMMON), @@ -550,8 +564,12 @@ public enum ItemType { CHAINMAIL_LEGGINGS(Material.CHAINMAIL_LEGGINGS, Rarity.COMMON), + CHALLENGE_ROD(Material.FISHING_ROD, Rarity.UNCOMMON), + CHAMPION(Material.ENCHANTED_BOOK, Rarity.COMMON), + CHAMP_ROD(Material.FISHING_ROD, Rarity.RARE), + CHARCOAL(Material.CHARCOAL, Rarity.COMMON), CHARLIE_TROUSERS(Material.LEATHER_LEGGINGS, Rarity.COMMON), @@ -620,6 +638,10 @@ public enum ItemType { CHUM(Material.PLAYER_HEAD, Rarity.UNCOMMON), + CHUM_ROD(Material.FISHING_ROD, Rarity.RARE), + + CHUM_SINKER(Material.PLAYER_HEAD, Rarity.RARE), + CLAY_BALL(Material.CLAY_BALL, Rarity.COMMON), CLAY_MINION(Material.PLAYER_HEAD, Rarity.COMMON), @@ -654,6 +676,8 @@ public enum ItemType { COMBAT_EXP_BOOST(Material.IRON_SWORD, Rarity.COMMON), + COMMON_HOOK(Material.PLAYER_HEAD, Rarity.RARE), + COMPACT(Material.ENCHANTED_BOOK, Rarity.COMMON), COMPACTED_MOONFLOWER(Material.BLUE_ORCHID, Rarity.COMMON), @@ -678,6 +702,8 @@ public enum ItemType { CORNFLOWER(Material.CORNFLOWER, Rarity.COMMON), + CORRUPTED_BAIT(Material.PLAYER_HEAD, Rarity.COMMON), + COW_MINION(Material.PLAYER_HEAD, Rarity.COMMON), CRACKED_PIGGY_BANK(Material.PLAYER_HEAD, Rarity.UNCOMMON), @@ -770,6 +796,8 @@ public enum ItemType { DANDELION(Material.DANDELION, Rarity.COMMON), + DARK_BAIT(Material.PLAYER_HEAD, Rarity.COMMON), + DARK_OAK_BOAT(Material.DARK_OAK_BOAT, Rarity.COMMON), DARK_OAK_BUTTON(Material.DARK_OAK_BUTTON, Rarity.COMMON), @@ -910,6 +938,8 @@ public enum ItemType { DIRT(Material.DIRT, Rarity.COMMON), + DIRT_ROD(Material.FISHING_ROD, Rarity.UNCOMMON), + DISPENSER(Material.DISPENSER, Rarity.COMMON), DITTO_BLOB(Material.PLAYER_HEAD, Rarity.COMMON), @@ -1294,6 +1324,8 @@ public enum ItemType { FANCY_TUXEDO_LEGGINGS(Material.LEATHER_LEGGINGS, Rarity.COMMON), + FARMER_ROD(Material.FISHING_ROD, Rarity.UNCOMMON), + FARMING_EXP_BOOST_COMMON(Material.IRON_HOE, Rarity.COMMON), FARMING_EXP_BOOST_RARE(Material.IRON_HOE, Rarity.COMMON), @@ -1324,6 +1356,8 @@ public enum ItemType { FEROCITY_ENRICHMENT(Material.PLAYER_HEAD, Rarity.COMMON), + FESTIVE_SINKER(Material.PLAYER_HEAD, Rarity.RARE), + FIERY_KUUDRA_CORE(Material.PLAYER_HEAD, Rarity.EPIC), FIGSTONE(Material.PLAYER_HEAD, Rarity.COMMON), @@ -1366,6 +1400,8 @@ public enum ItemType { FISHING_ROD(Material.FISHING_ROD, Rarity.COMMON), + FISH_BAIT(Material.PLAYER_HEAD, Rarity.COMMON), + FLAMES(Material.BLAZE_POWDER, Rarity.COMMON), FLAWED_AMBER_GEM(Material.PLAYER_HEAD, Rarity.UNCOMMON), @@ -1446,6 +1482,8 @@ public enum ItemType { FRIED_FROZEN_CHICKEN(Material.PLAYER_HEAD, Rarity.EPIC), + FROZEN_BAIT(Material.PLAYER_HEAD, Rarity.RARE), + FROZEN_CHICKEN(Material.PLAYER_HEAD, Rarity.RARE), FTX_3070(Material.PLAYER_HEAD, Rarity.COMMON), @@ -1472,6 +1510,8 @@ public enum ItemType { GHAST_TEAR(Material.GHAST_TEAR, Rarity.UNCOMMON), + GIANT_FISHING_ROD(Material.FISHING_ROD, Rarity.LEGENDARY), + GILL_MEMBRANE(Material.PLAYER_HEAD, Rarity.COMMON), GLACIAL_ARTIFACT(Material.PLAYER_HEAD, Rarity.RARE), @@ -1510,12 +1550,16 @@ public enum ItemType { GLOWSTONE_MINION(Material.PLAYER_HEAD, Rarity.COMMON), + GLOWY_CHUM_BAIT(Material.PLAYER_HEAD, Rarity.UNCOMMON), + GOBLIN_EGG(Material.EGG, Rarity.COMMON), GOD_POTION(Material.PLAYER_HEAD, Rarity.COMMON), GOLDEN_AXE(Material.GOLDEN_AXE, Rarity.COMMON), + GOLDEN_BAIT(Material.PLAYER_HEAD, Rarity.UNCOMMON), + GOLDEN_BOOTS(Material.GOLDEN_BOOTS, Rarity.COMMON), GOLDEN_CARROT(Material.GOLDEN_CARROT, Rarity.COMMON), @@ -1670,6 +1714,8 @@ public enum ItemType { HELIX(Material.PLAYER_HEAD, Rarity.COMMON), + HELLFIRE_ROD(Material.FISHING_ROD, Rarity.LEGENDARY), + HIGH_CLASS_ARCHFIEND_DICE(Material.PLAYER_HEAD, Rarity.LEGENDARY), HOLOGRAM(Material.PLAYER_HEAD, Rarity.COMMON), @@ -1686,6 +1732,14 @@ public enum ItemType { HORSEMAN_CANDLE(Material.PLAYER_HEAD, Rarity.RARE), + HOTSPOT_BAIT(Material.PLAYER_HEAD, Rarity.RARE), + + HOTSPOT_HOOK(Material.PLAYER_HEAD, Rarity.RARE), + + HOTSPOT_SINKER(Material.PLAYER_HEAD, Rarity.RARE), + + HOT_BAIT(Material.PLAYER_HEAD, Rarity.UNCOMMON), + HOT_POTATO_BOOK(Material.BOOK, Rarity.EPIC), HUB_CASTLE_TRAVEL_SCROLL(Material.PAPER, Rarity.UNCOMMON), @@ -1710,12 +1764,20 @@ public enum ItemType { ICE(Material.ICE, Rarity.COMMON), + ICE_BAIT(Material.PLAYER_HEAD, Rarity.UNCOMMON), + ICE_MINION(Material.PLAYER_HEAD, Rarity.COMMON), + ICE_ROD(Material.FISHING_ROD, Rarity.RARE), + + ICY_SINKER(Material.PLAYER_HEAD, Rarity.RARE), + INFERNAL_KUUDRA_CORE(Material.PLAYER_HEAD, Rarity.LEGENDARY), INFERNO_FUEL_BLOCK(Material.PLAYER_HEAD, Rarity.COMMON), + INFERNO_ROD(Material.FISHING_ROD, Rarity.EPIC), + INFINI_TORCH(Material.TORCH, Rarity.EPIC), INK_SAC(Material.INK_SAC, Rarity.COMMON), @@ -1830,6 +1892,8 @@ public enum ItemType { JUNK_RING(Material.PLAYER_HEAD, Rarity.UNCOMMON), + JUNK_SINKER(Material.PLAYER_HEAD, Rarity.RARE), + JUNK_TALISMAN(Material.PLAYER_HEAD, Rarity.COMMON), KAT_BOUQUET(Material.ROSE_BUSH, Rarity.COMMON), @@ -1912,10 +1976,14 @@ public enum ItemType { LEATHER_LEGGINGS(Material.LEATHER_LEGGINGS, Rarity.COMMON), + LEGEND_ROD(Material.FISHING_ROD, Rarity.EPIC), + LEVER(Material.LEVER, Rarity.COMMON), LIGHTER_BLUE_ABICASE(Material.PLAYER_HEAD, Rarity.COMMON), + LIGHT_BAIT(Material.PLAYER_HEAD, Rarity.COMMON), + LIGHT_BLUE_BANNER(Material.LIGHT_BLUE_BANNER, Rarity.COMMON), LIGHT_BLUE_BED(Material.LIGHT_BLUE_BED, Rarity.COMMON), @@ -2032,6 +2100,8 @@ public enum ItemType { MAGMA_CUBE_MINION(Material.PLAYER_HEAD, Rarity.COMMON), + MAGMA_ROD(Material.FISHING_ROD, Rarity.RARE), + MANA_DISINTEGRATOR(Material.PLAYER_HEAD, Rarity.RARE), MANGCORE(Material.PLAYER_HEAD, Rarity.COMMON), @@ -2160,6 +2230,8 @@ public enum ItemType { MINION_STORAGE_EXPANDER(Material.PLAYER_HEAD, Rarity.COMMON), + MINNOW_BAIT(Material.PLAYER_HEAD, Rarity.COMMON), + MINOS_RELIC(Material.PLAYER_HEAD, Rarity.EPIC), MITHRIL(Material.PRISMARINE_CRYSTALS, Rarity.COMMON), @@ -2432,6 +2504,10 @@ public enum ItemType { PET_LUCK_POTION_1(Material.POTION, Rarity.COMMON), + PHANTOM_HOOK(Material.PLAYER_HEAD, Rarity.RARE), + + PHANTOM_ROD(Material.FISHING_ROD, Rarity.LEGENDARY), + PICKONIMBUS_2000(Material.DIAMOND_PICKAXE, Rarity.COMMON), PIGGY_BANK(Material.PLAYER_HEAD, Rarity.UNCOMMON), @@ -2502,6 +2578,8 @@ public enum ItemType { POLISHED_PUMPKIN(Material.PLAYER_HEAD, Rarity.COMMON), + POLISHED_TOPAZ_ROD(Material.FISHING_ROD, Rarity.RARE), + POOCH_SWORD(Material.GOLDEN_SWORD, Rarity.LEGENDARY), POPPY(Material.POPPY, Rarity.COMMON), @@ -2548,8 +2626,12 @@ public enum ItemType { PRISMARINE_CRYSTALS(Material.PRISMARINE_CRYSTALS, Rarity.COMMON), + PRISMARINE_ROD(Material.FISHING_ROD, Rarity.COMMON), + PRISMARINE_SHARD(Material.PRISMARINE_SHARD, Rarity.COMMON), + PRISMARINE_SINKER(Material.PLAYER_HEAD, Rarity.RARE), + PROMISING_AXE(Material.IRON_AXE, Rarity.COMMON), PROMISING_PICKAXE(Material.IRON_PICKAXE, Rarity.UNCOMMON), @@ -2766,6 +2848,8 @@ public enum ItemType { ROBOTRON_REFLECTOR(Material.PLAYER_HEAD, Rarity.COMMON), + ROD_OF_THE_SEA(Material.FISHING_ROD, Rarity.LEGENDARY), + ROGUE_SWORD(Material.GOLDEN_SWORD, Rarity.COMMON), ROOKIE_AXE(Material.STONE_AXE, Rarity.COMMON), @@ -2824,6 +2908,8 @@ public enum ItemType { RUSTY_COIN(Material.PLAYER_HEAD, Rarity.UNCOMMON), + RUSTY_SHIP_ENGINE(Material.PLAYER_HEAD, Rarity.SPECIAL), + SAND(Material.SAND, Rarity.COMMON), SANDBOX_ITEM(Material.BLAZE_POWDER, Rarity.COMMON), @@ -2880,6 +2966,8 @@ public enum ItemType { SHARD_OF_THE_SHREDDED(Material.PLAYER_HEAD, Rarity.COMMON), + SHARK_BAIT(Material.PLAYER_HEAD, Rarity.UNCOMMON), + SHARK_FIN(Material.PRISMARINE_SHARD, Rarity.RARE), SHARPENED_CLAWS(Material.PRISMARINE_SHARD, Rarity.COMMON), @@ -2892,6 +2980,8 @@ public enum ItemType { SHORT_GRASS(Material.SHORT_GRASS, Rarity.COMMON), + SHREDDED_LINE(Material.PLAYER_HEAD, Rarity.RARE), + SILVER_FANG(Material.IRON_SWORD, Rarity.UNCOMMON), SILVER_MAGMAFISH(Material.PLAYER_HEAD, Rarity.COMMON), @@ -3026,6 +3116,10 @@ public enum ItemType { SOUL_STRING(Material.STRING, Rarity.COMMON), + SPEEDSTER_ROD(Material.FISHING_ROD, Rarity.UNCOMMON), + + SPEEDY_LINE(Material.PLAYER_HEAD, Rarity.RARE), + SPEED_ARTIFACT(Material.PLAYER_HEAD, Rarity.COMMON), SPEED_ENRICHMENT(Material.PLAYER_HEAD, Rarity.COMMON), @@ -3056,8 +3150,16 @@ public enum ItemType { SPIDER_TALISMAN(Material.PLAYER_HEAD, Rarity.COMMON), + SPIKED_BAIT(Material.PLAYER_HEAD, Rarity.COMMON), + SPONGE(Material.SPONGE, Rarity.COMMON), + SPONGE_ROD(Material.FISHING_ROD, Rarity.COMMON), + + SPONGE_SINKER(Material.PLAYER_HEAD, Rarity.RARE), + + SPOOKY_BAIT(Material.PLAYER_HEAD, Rarity.COMMON), + SPOOKY_SHARD(Material.PLAYER_HEAD, Rarity.RARE), SPRUCE_BOAT(Material.SPRUCE_BOAT, Rarity.COMMON), @@ -3120,10 +3222,14 @@ public enum ItemType { STARLYN_PRIZE(Material.PLAYER_HEAD, Rarity.COMMON), + STARTER_LAVA_ROD(Material.FISHING_ROD, Rarity.UNCOMMON), + STICK(Material.STICK, Rarity.COMMON), STICKY_PISTON(Material.STICKY_PISTON, Rarity.COMMON), + STINGY_SINKER(Material.PLAYER_HEAD, Rarity.RARE), + STONE(Material.STONE, Rarity.COMMON), STONE_AXE(Material.STONE_AXE, Rarity.COMMON), @@ -3260,6 +3366,8 @@ public enum ItemType { TESSELLATED_ENDER_PEARL(Material.PLAYER_HEAD, Rarity.LEGENDARY), + THE_SHREDDER(Material.FISHING_ROD, Rarity.LEGENDARY), + TIGER_SHARK_TOOTH(Material.GHAST_TEAR, Rarity.EPIC), TIGHTLY_TIED_HAY_BALE(Material.PLAYER_HEAD, Rarity.COMMON), @@ -3274,6 +3382,8 @@ public enum ItemType { TITANIUM_TALISMAN(Material.PLAYER_HEAD, Rarity.UNCOMMON), + TITAN_LINE(Material.PLAYER_HEAD, Rarity.RARE), + TNT(Material.TNT, Rarity.COMMON), TNT_MINECART(Material.TNT_MINECART, Rarity.COMMON), @@ -3290,6 +3400,10 @@ public enum ItemType { TREASURE_ARTIFACT(Material.PLAYER_HEAD, Rarity.COMMON), + TREASURE_BAIT(Material.PLAYER_HEAD, Rarity.RARE), + + TREASURE_HOOK(Material.PLAYER_HEAD, Rarity.RARE), + TREASURE_RING(Material.PLAYER_HEAD, Rarity.COMMON), TREASURE_TALISMAN(Material.PLAYER_HEAD, Rarity.COMMON), @@ -3380,6 +3494,8 @@ public enum ItemType { WET_WATER(Material.PLAYER_HEAD, Rarity.COMMON), + WHALE_BAIT(Material.PLAYER_HEAD, Rarity.RARE), + WHEAT(Material.WHEAT, Rarity.COMMON), WHEAT_CRYSTAL(Material.PLAYER_HEAD, Rarity.COMMON), @@ -3418,6 +3534,8 @@ public enum ItemType { WILSON_ENGINEERING_PLANS(Material.PAPER, Rarity.LEGENDARY), + WINTER_ROD(Material.FISHING_ROD, Rarity.RARE), + WISHING_COMPASS(Material.PLAYER_HEAD, Rarity.COMMON), WITHER_ARTIFACT(Material.PLAYER_HEAD, Rarity.EPIC), @@ -3438,6 +3556,8 @@ public enum ItemType { WOODEN_AXE(Material.WOODEN_AXE, Rarity.COMMON), + WOODEN_BAIT(Material.PLAYER_HEAD, Rarity.UNCOMMON), + WOODEN_HOE(Material.WOODEN_HOE, Rarity.COMMON), WOODEN_PICKAXE(Material.WOODEN_PICKAXE, Rarity.COMMON), @@ -3446,6 +3566,8 @@ public enum ItemType { WOODEN_SWORD(Material.WOODEN_SWORD, Rarity.COMMON), + WORM_BAIT(Material.PLAYER_HEAD, Rarity.UNCOMMON), + WORM_MEMBRANE(Material.ROTTEN_FLESH, Rarity.COMMON), YELLOW_BANNER(Material.YELLOW_BANNER, Rarity.COMMON), @@ -3470,6 +3592,8 @@ public enum ItemType { YELLOW_WOOL(Material.YELLOW_WOOL, Rarity.COMMON), + YETI_ROD(Material.FISHING_ROD, Rarity.EPIC), + ZOMBIE_ARTIFACT(Material.PLAYER_HEAD, Rarity.COMMON), ZOMBIE_BRAIN_MIXIN(Material.PLAYER_HEAD, Rarity.COMMON), diff --git a/commons/src/main/java/net/swofty/commons/skyblock/item/attribute/attributes/ItemAttributeFishingExpertiseKills.java b/commons/src/main/java/net/swofty/commons/skyblock/item/attribute/attributes/ItemAttributeFishingExpertiseKills.java new file mode 100644 index 000000000..1eb86bfcb --- /dev/null +++ b/commons/src/main/java/net/swofty/commons/skyblock/item/attribute/attributes/ItemAttributeFishingExpertiseKills.java @@ -0,0 +1,27 @@ +package net.swofty.commons.skyblock.item.attribute.attributes; + +import net.swofty.commons.skyblock.item.attribute.ItemAttribute; +import net.swofty.commons.skyblock.statistics.ItemStatistics; +import org.jetbrains.annotations.Nullable; + +public class ItemAttributeFishingExpertiseKills extends ItemAttribute { + @Override + public String getKey() { + return "fishing_expertise_kills"; + } + + @Override + public Long getDefaultValue(@Nullable ItemStatistics defaultStatistics) { + return 0L; + } + + @Override + public Long loadFromString(String string) { + return Long.parseLong(string); + } + + @Override + public String saveIntoString() { + return String.valueOf(getValue()); + } +} diff --git a/commons/src/main/java/net/swofty/commons/skyblock/item/attribute/attributes/ItemAttributeFishingHook.java b/commons/src/main/java/net/swofty/commons/skyblock/item/attribute/attributes/ItemAttributeFishingHook.java new file mode 100644 index 000000000..704b574c7 --- /dev/null +++ b/commons/src/main/java/net/swofty/commons/skyblock/item/attribute/attributes/ItemAttributeFishingHook.java @@ -0,0 +1,27 @@ +package net.swofty.commons.skyblock.item.attribute.attributes; + +import net.swofty.commons.skyblock.item.attribute.ItemAttribute; +import net.swofty.commons.skyblock.statistics.ItemStatistics; +import org.jetbrains.annotations.Nullable; + +public class ItemAttributeFishingHook extends ItemAttribute { + @Override + public String getKey() { + return "fishing_hook"; + } + + @Override + public String getDefaultValue(@Nullable ItemStatistics defaultStatistics) { + return "none"; + } + + @Override + public String loadFromString(String string) { + return string == null || string.isBlank() ? "none" : string; + } + + @Override + public String saveIntoString() { + return getValue() == null || getValue().isBlank() ? "none" : getValue(); + } +} diff --git a/commons/src/main/java/net/swofty/commons/skyblock/item/attribute/attributes/ItemAttributeFishingLine.java b/commons/src/main/java/net/swofty/commons/skyblock/item/attribute/attributes/ItemAttributeFishingLine.java new file mode 100644 index 000000000..bf6ca37ba --- /dev/null +++ b/commons/src/main/java/net/swofty/commons/skyblock/item/attribute/attributes/ItemAttributeFishingLine.java @@ -0,0 +1,27 @@ +package net.swofty.commons.skyblock.item.attribute.attributes; + +import net.swofty.commons.skyblock.item.attribute.ItemAttribute; +import net.swofty.commons.skyblock.statistics.ItemStatistics; +import org.jetbrains.annotations.Nullable; + +public class ItemAttributeFishingLine extends ItemAttribute { + @Override + public String getKey() { + return "fishing_line"; + } + + @Override + public String getDefaultValue(@Nullable ItemStatistics defaultStatistics) { + return "none"; + } + + @Override + public String loadFromString(String string) { + return string == null || string.isBlank() ? "none" : string; + } + + @Override + public String saveIntoString() { + return getValue() == null || getValue().isBlank() ? "none" : getValue(); + } +} diff --git a/commons/src/main/java/net/swofty/commons/skyblock/item/attribute/attributes/ItemAttributeFishingSinker.java b/commons/src/main/java/net/swofty/commons/skyblock/item/attribute/attributes/ItemAttributeFishingSinker.java new file mode 100644 index 000000000..daa12ee81 --- /dev/null +++ b/commons/src/main/java/net/swofty/commons/skyblock/item/attribute/attributes/ItemAttributeFishingSinker.java @@ -0,0 +1,27 @@ +package net.swofty.commons.skyblock.item.attribute.attributes; + +import net.swofty.commons.skyblock.item.attribute.ItemAttribute; +import net.swofty.commons.skyblock.statistics.ItemStatistics; +import org.jetbrains.annotations.Nullable; + +public class ItemAttributeFishingSinker extends ItemAttribute { + @Override + public String getKey() { + return "fishing_sinker"; + } + + @Override + public String getDefaultValue(@Nullable ItemStatistics defaultStatistics) { + return "none"; + } + + @Override + public String loadFromString(String string) { + return string == null || string.isBlank() ? "none" : string; + } + + @Override + public String saveIntoString() { + return getValue() == null || getValue().isBlank() ? "none" : getValue(); + } +} diff --git a/commons/src/main/java/net/swofty/commons/skyblock/statistics/ItemStatistic.java b/commons/src/main/java/net/swofty/commons/skyblock/statistics/ItemStatistic.java index 2c9e75300..bf2f12a24 100644 --- a/commons/src/main/java/net/swofty/commons/skyblock/statistics/ItemStatistic.java +++ b/commons/src/main/java/net/swofty/commons/skyblock/statistics/ItemStatistic.java @@ -80,6 +80,9 @@ public enum ItemStatistic { PET_LUCK("Pet Luck", "§a", "§d", false, "♣"), SEA_CREATURE_CHANCE("Sea Creature Chance", "§c", "§9", true, "α", 2D, 1D), FISHING_SPEED("Fishing Speed", "§a", "§b", false, "☂"), + TREASURE_CHANCE("Treasure Chance", "§a", "§6", true, "⛃"), + TROPHY_FISH_CHANCE("Trophy Fish Chance", "§a", "§6", true, "♔"), + DOUBLE_HOOK_CHANCE("Double Hook Chance", "§a", "§3", true, "⚓"), BONUS_PEST_CHANCE("Bonus Pest Chance", "§a", "§2", true, "ൠ"), HEAT_RESISTANCE("Heat Resistance","§a","§c",false,"♨"), COLD_RESISTANCE("Cold Resistance", "§a", "§b", false, "❄"), diff --git a/configuration/skyblock/fishing/hotspots.yml b/configuration/skyblock/fishing/hotspots.yml new file mode 100644 index 000000000..0168a99cc --- /dev/null +++ b/configuration/skyblock/fishing/hotspots.yml @@ -0,0 +1,5 @@ +hotspots: + - x: 100 + y: 50 + z: 100 + serverType: BACKWATER_BAYOU diff --git a/configuration/skyblock/fishing/tables.yml b/configuration/skyblock/fishing/tables.yml new file mode 100644 index 000000000..a429e3b80 --- /dev/null +++ b/configuration/skyblock/fishing/tables.yml @@ -0,0 +1,206 @@ +tables: + - id: DEFAULT_WATER + regions: [ ] + mediums: + - WATER + items: + - itemId: RAW_FISH + chance: 36 + amount: 1 + skillXp: 5 + - itemId: RAW_SALMON + chance: 22 + amount: 1 + skillXp: 6 + - itemId: PUFFERFISH + chance: 10 + amount: 1 + skillXp: 7 + - itemId: INK_SAC + chance: 8 + amount: 1 + skillXp: 5 + - itemId: LILY_PAD + chance: 8 + amount: 1 + skillXp: 5 + - itemId: CLAY_BALL + chance: 6 + amount: 1 + skillXp: 5 + - itemId: PRISMARINE_CRYSTALS + chance: 4 + amount: 1 + skillXp: 6 + - itemId: PRISMARINE_SHARD + chance: 3 + amount: 1 + skillXp: 6 + - itemId: TROPICAL_FISH + chance: 2 + amount: 1 + skillXp: 8 + - itemId: SPONGE + chance: 1 + amount: 1 + skillXp: 10 + treasures: + - itemId: PRISMARINE_CRYSTALS + chance: 50 + amount: 2 + skillXp: 10 + - itemId: PRISMARINE_SHARD + chance: 35 + amount: 2 + skillXp: 10 + - itemId: SPONGE + chance: 15 + amount: 1 + skillXp: 12 + junk: [ ] + seaCreatures: + - seaCreatureId: SQUID + chance: 6 + - seaCreatureId: SEA_WALKER + chance: 4 + - seaCreatureId: NIGHT_SQUID + chance: 2 + - id: DEFAULT_LAVA + regions: [ ] + mediums: + - LAVA + items: + - itemId: MAGMAFISH + chance: 100 + amount: 1 + skillXp: 10 + treasures: + - itemId: MAGMAFISH + chance: 100 + amount: 2 + skillXp: 15 + junk: [ ] + seaCreatures: + - seaCreatureId: LAVA_BLAZE + chance: 5 + - id: BAYOU_WATERS + regions: + - BACKWATER_BAYOU + mediums: + - WATER + items: + - itemId: RAW_FISH + chance: 30 + amount: 1 + skillXp: 5 + - itemId: RAW_SALMON + chance: 20 + amount: 1 + skillXp: 6 + - itemId: PUFFERFISH + chance: 10 + amount: 1 + skillXp: 7 + - itemId: INK_SAC + chance: 8 + amount: 1 + skillXp: 5 + - itemId: LILY_PAD + chance: 8 + amount: 1 + skillXp: 5 + - itemId: CLAY_BALL + chance: 8 + amount: 1 + skillXp: 5 + - itemId: PRISMARINE_CRYSTALS + chance: 5 + amount: 1 + skillXp: 6 + - itemId: PRISMARINE_SHARD + chance: 4 + amount: 1 + skillXp: 6 + - itemId: TROPICAL_FISH + chance: 5 + amount: 1 + skillXp: 8 + - itemId: SPONGE + chance: 2 + amount: 1 + skillXp: 10 + treasures: + - itemId: PRISMARINE_CRYSTALS + chance: 40 + amount: 2 + skillXp: 10 + - itemId: PRISMARINE_SHARD + chance: 30 + amount: 2 + skillXp: 10 + - itemId: SPONGE + chance: 20 + amount: 1 + skillXp: 12 + - itemId: CLAY_BALL + chance: 10 + amount: 4 + skillXp: 8 + junk: + - itemId: RUSTY_COIN + chance: 50 + amount: 1 + skillXp: 2 + - itemId: BUSTED_BELT_BUCKLE + chance: 30 + amount: 1 + skillXp: 2 + - itemId: OLD_LEATHER_BOOT + chance: 20 + amount: 1 + skillXp: 2 + seaCreatures: + - seaCreatureId: ALLIGATOR + chance: 5 + - seaCreatureId: BANSHEE + chance: 3 + - seaCreatureId: BAYOU_SLUDGE + chance: 3 + - seaCreatureId: DUMPSTER_DIVER + chance: 2 + - seaCreatureId: TITANOBOA + chance: 1 + - seaCreatureId: TRASH_GOBBLER + chance: 1 + - id: CRIMSON_ISLE_LAVA + regions: + - CRIMSON_ISLE + - BLAZING_VOLCANO + mediums: + - LAVA + items: + - itemId: MAGMAFISH + chance: 100 + amount: 1 + skillXp: 10 + treasures: + - itemId: MAGMAFISH + chance: 75 + amount: 2 + skillXp: 15 + - itemId: SULPHUR + chance: 25 + amount: 2 + skillXp: 15 + junk: [ ] + seaCreatures: + - seaCreatureId: LAVA_BLAZE + chance: 3 + - seaCreatureId: FRIED_CHICKEN + chance: 2 + - seaCreatureId: FIREPROOF_WITCH + chance: 2 + - seaCreatureId: FIERY_SCUTTLER + chance: 1 + - seaCreatureId: RAGNAROK + chance: 1 diff --git a/configuration/skyblock/fishing/trophy_fish.yml b/configuration/skyblock/fishing/trophy_fish.yml new file mode 100644 index 000000000..229f74b3d --- /dev/null +++ b/configuration/skyblock/fishing/trophy_fish.yml @@ -0,0 +1,13 @@ +trophyFish: + - id: MAGMAFISH + displayName: Magmafish + catchChance: 18 + regions: [ ] + requiredFishingLevel: 0 + minimumCastTimeMs: 0 + requiresStarterRodWithoutEnchantments: false + specialGoldenFish: false + bronzeItemId: MAGMAFISH + silverItemId: SILVER_MAGMAFISH + goldItemId: GOLD_MAGMAFISH + diamondItemId: DIAMOND_MAGMAFISH diff --git a/configuration/skyblock/items/fishing/fishingContent.yml b/configuration/skyblock/items/fishing/fishingContent.yml new file mode 100644 index 000000000..2d93a58d0 --- /dev/null +++ b/configuration/skyblock/items/fishing/fishingContent.yml @@ -0,0 +1,735 @@ +items: + - id: CHALLENGE_ROD + material: FISHING_ROD + rarity: UNCOMMON + default_statistics: + DAMAGE: 75 + STRENGTH: 75 + FISHING_SPEED: 40 + SEA_CREATURE_CHANCE: 7 + TREASURE_CHANCE: 2.5 + components: + - id: FISHING_ROD_METADATA + display_name: Challenging Rod + medium: WATER + required_fishing_level: 10 + rod_parts_enabled: true + enchantments: + ANGLER: 5 + CASTER: 5 + FRAIL: 5 + IMPALING: 3 + LOOTING: 3 + LUCK_OF_THE_SEA: 5 + LURE: 5 + MAGNET: 5 + PISCARY: 5 + SPIKED_HOOK: 5 + - id: CHAMP_ROD + material: FISHING_ROD + rarity: RARE + default_statistics: + DAMAGE: 100 + STRENGTH: 100 + FISHING_SPEED: 55 + SEA_CREATURE_CHANCE: 10 + TREASURE_CHANCE: 3.0 + components: + - id: FISHING_ROD_METADATA + display_name: Rod of Champions + medium: WATER + required_fishing_level: 15 + rod_parts_enabled: true + enchantments: + ANGLER: 6 + CASTER: 5 + CHARM: 3 + FRAIL: 6 + IMPALING: 4 + LOOTING: 4 + LUCK_OF_THE_SEA: 6 + LURE: 6 + MAGNET: 5 + PISCARY: 5 + SPIKED_HOOK: 6 + - id: LEGEND_ROD + material: FISHING_ROD + rarity: EPIC + default_statistics: + DAMAGE: 125 + STRENGTH: 125 + FISHING_SPEED: 70 + SEA_CREATURE_CHANCE: 14 + TREASURE_CHANCE: 3.5 + components: + - id: FISHING_ROD_METADATA + display_name: Rod of Legends + medium: WATER + required_fishing_level: 20 + rod_parts_enabled: true + enchantments: + ANGLER: 6 + CASTER: 6 + CHARM: 4 + FRAIL: 7 + IMPALING: 5 + LOOTING: 4 + LUCK_OF_THE_SEA: 7 + LURE: 6 + MAGNET: 6 + PISCARY: 6 + SPIKED_HOOK: 7 + - id: ROD_OF_THE_SEA + material: FISHING_ROD + rarity: LEGENDARY + default_statistics: + DAMAGE: 150 + STRENGTH: 150 + FISHING_SPEED: 95 + SEA_CREATURE_CHANCE: 20 + TREASURE_CHANCE: 3.5 + components: + - id: FISHING_ROD_METADATA + display_name: Rod of the Sea + medium: WATER + required_fishing_level: 24 + rod_parts_enabled: true + enchantments: + FLASH: 5 + ANGLER: 6 + BLESSING: 6 + CASTER: 6 + CHARM: 6 + CORRUPTION: 5 + EXPERTISE: 10 + FRAIL: 7 + IMPALING: 5 + LOOTING: 4 + LUCK_OF_THE_SEA: 7 + LURE: 6 + MAGNET: 6 + PISCARY: 7 + QUICK_BITE: 5 + SPIKED_HOOK: 7 + TABASCO: 3 + - id: GIANT_FISHING_ROD + material: FISHING_ROD + rarity: LEGENDARY + default_statistics: + DAMAGE: 20 + STRENGTH: 10 + FISHING_SPEED: 20 + DOUBLE_HOOK_CHANCE: 10 + components: + - id: FISHING_ROD_METADATA + display_name: Giant Fishing Rod + medium: WATER + rod_parts_enabled: true + - id: DIRT_ROD + material: FISHING_ROD + rarity: UNCOMMON + default_statistics: + FISHING_SPEED: 20 + components: + - id: FISHING_ROD_METADATA + display_name: Dirt Rod + medium: WATER + rod_parts_enabled: false + - id: STARTER_LAVA_ROD + material: FISHING_ROD + rarity: UNCOMMON + default_statistics: + DAMAGE: 50 + STRENGTH: 50 + FISHING_SPEED: 10 + TROPHY_FISH_CHANCE: 5 + components: + - id: FISHING_ROD_METADATA + display_name: Starter Lava Rod + subtitle: Lava Rod + medium: LAVA + required_fishing_level: 10 + rod_parts_enabled: true + - id: POLISHED_TOPAZ_ROD + material: FISHING_ROD + rarity: RARE + default_statistics: + DAMAGE: 80 + STRENGTH: 80 + FISHING_SPEED: 30 + TROPHY_FISH_CHANCE: 8 + components: + - id: FISHING_ROD_METADATA + display_name: Topaz Rod + subtitle: Lava Rod + medium: LAVA + required_fishing_level: 14 + rod_parts_enabled: true + - id: MAGMA_ROD + material: FISHING_ROD + rarity: RARE + default_statistics: + DAMAGE: 110 + STRENGTH: 110 + FISHING_SPEED: 50 + TROPHY_FISH_CHANCE: 12 + components: + - id: FISHING_ROD_METADATA + display_name: Magma Rod + subtitle: Lava Rod + medium: LAVA + required_fishing_level: 18 + rod_parts_enabled: true + - id: INFERNO_ROD + material: FISHING_ROD + rarity: EPIC + default_statistics: + DAMAGE: 140 + STRENGTH: 140 + FISHING_SPEED: 70 + TROPHY_FISH_CHANCE: 16 + components: + - id: FISHING_ROD_METADATA + display_name: Inferno Rod + subtitle: Lava Rod + medium: LAVA + required_fishing_level: 22 + rod_parts_enabled: true + - id: HELLFIRE_ROD + material: FISHING_ROD + rarity: LEGENDARY + default_statistics: + DAMAGE: 175 + STRENGTH: 175 + FISHING_SPEED: 95 + TROPHY_FISH_CHANCE: 22 + components: + - id: FISHING_ROD_METADATA + display_name: Hellfire Rod + subtitle: Lava Rod + medium: LAVA + required_fishing_level: 26 + rod_parts_enabled: true + - id: CHUM_ROD + material: FISHING_ROD + rarity: RARE + default_statistics: + DAMAGE: 20 + STRENGTH: 10 + FISHING_SPEED: 30 + components: + - id: FISHING_ROD_METADATA + display_name: Chum Rod + medium: WATER + required_fishing_level: 4 + rod_parts_enabled: false + legacy_conversion_target: CHALLENGE_ROD + legacy_conversion_part: CHUM_SINKER + - id: PRISMARINE_ROD + material: FISHING_ROD + rarity: COMMON + default_statistics: + DAMAGE: 10 + FISHING_SPEED: 10 + components: + - id: FISHING_ROD_METADATA + display_name: Prismarine Rod + medium: WATER + rod_parts_enabled: false + legacy_conversion_target: CHALLENGE_ROD + legacy_conversion_part: PRISMARINE_SINKER + - id: SPONGE_ROD + material: FISHING_ROD + rarity: COMMON + default_statistics: + DAMAGE: 10 + FISHING_SPEED: 10 + components: + - id: FISHING_ROD_METADATA + display_name: Sponge Rod + medium: WATER + rod_parts_enabled: false + legacy_conversion_target: CHALLENGE_ROD + legacy_conversion_part: SPONGE_SINKER + - id: SPEEDSTER_ROD + material: FISHING_ROD + rarity: UNCOMMON + default_statistics: + DAMAGE: 30 + STRENGTH: 15 + FISHING_SPEED: 45 + components: + - id: FISHING_ROD_METADATA + display_name: Speedster Rod + medium: WATER + required_fishing_level: 6 + rod_parts_enabled: false + legacy_conversion_target: CHALLENGE_ROD + legacy_conversion_part: SPEEDY_LINE + - id: FARMER_ROD + material: FISHING_ROD + rarity: UNCOMMON + default_statistics: + DAMAGE: 50 + STRENGTH: 20 + FISHING_SPEED: 60 + components: + - id: FISHING_ROD_METADATA + display_name: Farmer's Rod + medium: WATER + required_fishing_level: 8 + rod_parts_enabled: false + legacy_conversion_target: CHALLENGE_ROD + - id: ICE_ROD + material: FISHING_ROD + rarity: RARE + default_statistics: + DAMAGE: 30 + FISHING_SPEED: 15 + components: + - id: FISHING_ROD_METADATA + display_name: Ice Rod + medium: WATER + rod_parts_enabled: false + legacy_conversion_target: CHALLENGE_ROD + legacy_conversion_part: ICY_SINKER + - id: WINTER_ROD + material: FISHING_ROD + rarity: RARE + default_statistics: + DAMAGE: 50 + STRENGTH: 50 + FISHING_SPEED: 75 + components: + - id: FISHING_ROD_METADATA + display_name: Winter Rod + medium: WATER + required_fishing_level: 10 + rod_parts_enabled: false + legacy_conversion_target: CHALLENGE_ROD + legacy_conversion_part: FESTIVE_SINKER + - id: YETI_ROD + material: FISHING_ROD + rarity: EPIC + default_statistics: + DAMAGE: 150 + STRENGTH: 130 + FISHING_SPEED: 75 + components: + - id: FISHING_ROD_METADATA + display_name: Yeti Rod + medium: WATER + required_fishing_level: 25 + rod_parts_enabled: false + legacy_conversion_target: CHALLENGE_ROD + legacy_conversion_part: ICY_SINKER + - id: THE_SHREDDER + material: FISHING_ROD + rarity: LEGENDARY + default_statistics: + DAMAGE: 120 + STRENGTH: 15 + FEROCITY: 50 + FISHING_SPEED: 115 + components: + - id: FISHING_ROD_METADATA + display_name: Shredder + medium: WATER + required_fishing_level: 20 + rod_parts_enabled: false + legacy_conversion_target: CHALLENGE_ROD + legacy_conversion_part: SHREDDED_LINE + - id: PHANTOM_ROD + material: FISHING_ROD + rarity: LEGENDARY + default_statistics: + DAMAGE: 200 + STRENGTH: 125 + FISHING_SPEED: 100 + components: + - id: FISHING_ROD_METADATA + display_name: Phantom Rod + medium: WATER + required_fishing_level: 21 + rod_parts_enabled: false + legacy_conversion_target: CHALLENGE_ROD + legacy_conversion_part: PHANTOM_HOOK + - id: AUGER_ROD + material: FISHING_ROD + rarity: LEGENDARY + default_statistics: + DAMAGE: 135 + STRENGTH: 90 + FISHING_SPEED: 110 + components: + - id: FISHING_ROD_METADATA + display_name: Auger Rod + medium: WATER + required_fishing_level: 25 + rod_parts_enabled: false + legacy_conversion_target: ROD_OF_THE_SEA + legacy_conversion_part: ICY_SINKER + - id: COMMON_HOOK + material: PLAYER_HEAD + rarity: RARE + components: + - id: FISHING_ROD_PART + display_name: Common Hook + category: HOOK + required_fishing_level: 5 + tag_bonuses: + COMMON: 25 + texture: d235388f091b7fd13397151fca580fdf9a41c2a0a297f887838710f629aa3fd6 + - id: HOTSPOT_HOOK + material: PLAYER_HEAD + rarity: RARE + components: + - id: FISHING_ROD_PART + display_name: Hotspot Hook + category: HOOK + required_fishing_level: 20 + tag_bonuses: + HOTSPOT: 100 + texture: 17415df9f4c8cdabdacd442da80826188e46a3d166f56fd1509bba26faac76dd + - id: PHANTOM_HOOK + material: PLAYER_HEAD + rarity: RARE + components: + - id: FISHING_ROD_PART + display_name: Phantom Hook + category: HOOK + required_fishing_level: 21 + tag_bonuses: + SPOOKY: 100 + texture: c95eff1654366d5245238ddbfb65a7a7128468a9ce343861fe239e87c14c3f6d + - id: TREASURE_HOOK + material: PLAYER_HEAD + rarity: RARE + components: + - id: FISHING_ROD_PART + display_name: Treasure Hook + category: HOOK + required_fishing_level: 25 + treasure_only: true + texture: 9809753cbab0380c7a1c18925faf9b51e44caadd1e5748542b0f23835f4ef64e + - id: SPEEDY_LINE + material: PLAYER_HEAD + rarity: RARE + default_statistics: + FISHING_SPEED: 10 + components: + - id: FISHING_ROD_PART + display_name: Speedy Line + category: LINE + required_fishing_level: 5 + texture: 5cbac3c84e21e65ec88007604c4eba1da391e185544b90252fc16ca695c59b4b + - id: SHREDDED_LINE + material: PLAYER_HEAD + rarity: RARE + default_statistics: + DAMAGE: 250 + FEROCITY: 50 + components: + - id: FISHING_ROD_PART + display_name: Shredded Line + category: LINE + required_fishing_level: 20 + texture: f5424291868be6ae16512641666c5286a740f936e42f96e34987fb6f43d16e6e + - id: TITAN_LINE + material: PLAYER_HEAD + rarity: RARE + default_statistics: + DOUBLE_HOOK_CHANCE: 2 + components: + - id: FISHING_ROD_PART + display_name: Titan Line + category: LINE + required_fishing_level: 35 + texture: 9a850a4f721bc150bb72b067e5074c8251058a6b9111691da315b393467c1aa9 + - id: JUNK_SINKER + material: PLAYER_HEAD + rarity: RARE + components: + - id: FISHING_ROD_PART + display_name: Junk Sinker + category: SINKER + required_fishing_level: 5 + bayou_treasure_to_junk: true + texture: d24892a3142d2e130e5feb88b805b83de905489d2ccd1d031b9d7a2922b96500 + - id: PRISMARINE_SINKER + material: PLAYER_HEAD + rarity: RARE + components: + - id: FISHING_ROD_PART + display_name: Prismarine Sinker + category: SINKER + required_fishing_level: 5 + materialized_item_id: PRISMARINE_SHARD + texture: b9d2d0fe4c93fbc21309e93d985df37e1133d2ece58d2f96b6be5cffba53c181 + - id: SPONGE_SINKER + material: PLAYER_HEAD + rarity: RARE + components: + - id: FISHING_ROD_PART + display_name: Sponge Sinker + category: SINKER + required_fishing_level: 5 + materialized_item_id: SPONGE + texture: 8b24369807fcf3bd852e6da87ddeca9d38a04f32c78599f4c5823b9522278259 + - id: CHUM_SINKER + material: PLAYER_HEAD + rarity: RARE + components: + - id: FISHING_ROD_PART + display_name: Chum Sinker + category: SINKER + required_fishing_level: 5 + materialized_item_id: CHUM + texture: d02b855b4acc508086248ff468aaaaba0c0d8deaa2adc0321ed0809e416736ef + - id: FESTIVE_SINKER + material: PLAYER_HEAD + rarity: RARE + components: + - id: FISHING_ROD_PART + display_name: Festive Sinker + category: SINKER + required_fishing_level: 5 + materialized_chance: 0.05 + texture: 6f5840e5b76a2ed0de1c2280ae8be0edd90d83e5f8408af9f1e92f2db92e0383 + - id: ICY_SINKER + material: PLAYER_HEAD + rarity: RARE + components: + - id: FISHING_ROD_PART + display_name: Icy Sinker + category: SINKER + required_fishing_level: 5 + tag_bonuses: + WINTER: 200 + materialized_item_id: ICE + texture: 41dfb1861aa0dd49f7bd8a4ecb14fbda35055fbe9b06b4d7be5cdde0fc7cc60e + - id: STINGY_SINKER + material: PLAYER_HEAD + rarity: RARE + components: + - id: FISHING_ROD_PART + display_name: Stingy Sinker + category: SINKER + required_fishing_level: 5 + bait_preservation_chance: 10.0 + texture: e886d5cac32bd32fc07938908c552b7b27965d92065b3157dfc7ef849281ee9d + - id: HOTSPOT_SINKER + material: PLAYER_HEAD + rarity: RARE + components: + - id: FISHING_ROD_PART + display_name: Hotspot Sinker + category: SINKER + required_fishing_level: 20 + hotspot_buff_multiplier: 2.0 + texture: 88891d33b55dd1572814527b9c027ec724909c26281a197d0309fbfa925cbce4 + - id: MINNOW_BAIT + material: PLAYER_HEAD + rarity: COMMON + default_statistics: + FISHING_SPEED: 25 + components: + - id: FISHING_BAIT + display_name: Minnow Bait + texture: b8e749ba141c054bb0c125320b17677bdcb3a7e9807a57527c0877b94548a2e + - id: FISH_BAIT + material: PLAYER_HEAD + rarity: COMMON + default_statistics: + FISHING_SPEED: 45 + components: + - id: FISHING_BAIT + display_name: Fish Bait + texture: 49e8dc9fdc9f00e1d17666a4787d34cca7cc6dc030f0dc686195546f81c6f22 + - id: LIGHT_BAIT + material: PLAYER_HEAD + rarity: COMMON + components: + - id: FISHING_BAIT + display_name: Light Bait + texture: e3bcc16f402342b4acd29aecac72d1d5a116e0abb478bb4960e734fd70686ba + - id: DARK_BAIT + material: PLAYER_HEAD + rarity: COMMON + components: + - id: FISHING_BAIT + display_name: Dark Bait + texture: 7281618a5c8239078fd43fef8eae14ea00665f635bd56d4451cccd5d0fa11821 + - id: SPIKED_BAIT + material: PLAYER_HEAD + rarity: COMMON + default_statistics: + SEA_CREATURE_CHANCE: 6 + components: + - id: FISHING_BAIT + display_name: Spiked Bait + texture: e42c436c6580fad217323b9f045daa23a9f88219ac26506637669eff20901f74 + - id: SPOOKY_BAIT + material: PLAYER_HEAD + rarity: COMMON + default_statistics: + FISHING_SPEED: 25 + components: + - id: FISHING_BAIT + display_name: Spooky Bait + tag_bonuses: + SPOOKY: 15 + texture: 977eab558e6a90f7cedd72c2416c891f47d71eb4e7bdcc299a6335286f5cba98 + - id: CARROT_BAIT + material: PLAYER_HEAD + rarity: COMMON + components: + - id: FISHING_BAIT + display_name: Carrot Bait + texture: 4d3a6bd98ac1833c664c4909ff8d2dc62ce887bdcf3cc5b3848651ae5af6b + - id: CORRUPTED_BAIT + material: PLAYER_HEAD + rarity: COMMON + components: + - id: FISHING_BAIT + display_name: Corrupted Bait + texture: 4bbcddd45cd347865bceab3e3dc5d382723463963f85ecce81cdd61b53db14e4 + - id: BLESSED_BAIT + material: PLAYER_HEAD + rarity: UNCOMMON + components: + - id: FISHING_BAIT + display_name: Blessed Bait + treasure_quality_bonus: 50 + texture: c2b910b5897cdb86b21ebfcba544afa470ae6d228bee3494427c9c7e8f33502b + - id: ICE_BAIT + material: PLAYER_HEAD + rarity: UNCOMMON + components: + - id: FISHING_BAIT + display_name: Ice Bait + tag_bonuses: + WINTER: 20 + texture: 609e161bdc325c71572a548a79bb15481c924d63e4fb821379d5dd6c8929f39f + - id: SHARK_BAIT + material: PLAYER_HEAD + rarity: UNCOMMON + components: + - id: FISHING_BAIT + display_name: Shark Bait + tag_bonuses: + SHARK: 20 + texture: edff904124efe486b3a54261dbb8072b0a4e11615ad8d7394d814e0e8c8ef9eb + - id: GLOWY_CHUM_BAIT + material: PLAYER_HEAD + rarity: UNCOMMON + default_statistics: + FISHING_SPEED: 25 + SEA_CREATURE_CHANCE: 3 + components: + - id: FISHING_BAIT + display_name: Glowy Chum Bait + texture: dfdc1eed684dd805eae96d132e3da53d64267d7361388d5e2c67f5969871e71d + - id: HOT_BAIT + material: PLAYER_HEAD + rarity: UNCOMMON + default_statistics: + FISHING_SPEED: 15 + components: + - id: FISHING_BAIT + display_name: Hot Bait + trophy_fish_chance_bonus: 5 + texture: 213c6899d97109c6cacbbcdd01e8900abaf46432f197595baa15ad137d5fb9ba + - id: WORM_BAIT + material: PLAYER_HEAD + rarity: UNCOMMON + default_statistics: + FISHING_SPEED: 60 + components: + - id: FISHING_BAIT + display_name: Worm Bait + texture: df03ad96092f3f789902436709cdf69de6b727c121b3c2daef9ffa1ccaed186c + - id: FROZEN_BAIT + material: PLAYER_HEAD + rarity: RARE + components: + - id: FISHING_BAIT + display_name: Frozen Bait + tag_bonuses: + WINTER: 35 + texture: 38dc68a97cefe92c8cdaa7cb1a7a4de8f16c161da736edf54f79b74beecd6513 + - id: GOLDEN_BAIT + material: PLAYER_HEAD + rarity: UNCOMMON + components: + - id: FISHING_BAIT + display_name: Golden Bait + treasure_chance_bonus: 4 + texture: 72e2908dbb112dcd0b367df43fafcc41a56d9cf803e90a367834b4911f84f391 + - id: TREASURE_BAIT + material: PLAYER_HEAD + rarity: RARE + default_statistics: + FISHING_SPEED: 10 + components: + - id: FISHING_BAIT + display_name: Treasure Bait + treasure_chance_bonus: 2 + texture: c1695c80854447b5db5a0ee6d57ef0a7d91d815bd7e6318c516a39d12fe0639e + - id: WOODEN_BAIT + material: PLAYER_HEAD + rarity: UNCOMMON + components: + - id: FISHING_BAIT + display_name: Wooden Bait + texture: 5b236a39e51a39dff9bced39333a73413984bc74db37c1318bfc4a4459f035d2 + - id: HOTSPOT_BAIT + material: PLAYER_HEAD + rarity: RARE + components: + - id: FISHING_BAIT + display_name: Hotspot Bait + tag_bonuses: + HOTSPOT: 50 + texture: de9b17db5c4cadef737e2fefb42a0123c32cbeaa1ca8932579eb2f05018612cd + - id: WHALE_BAIT + material: PLAYER_HEAD + rarity: RARE + default_statistics: + FISHING_SPEED: 30 + components: + - id: FISHING_BAIT + display_name: Whale Bait + texture: 5b4fb49ae77cfcf0b8f62df9c69cc96b27096ad2737d6d0aa450b50664fb2303 + - id: RUSTY_SHIP_ENGINE + material: PLAYER_HEAD + rarity: SPECIAL + components: + - id: FISHING_SHIP_PART + display_name: Rusty Ship Engine + slot: ENGINE + texture: 53e84793917c890f7f8a2c4078a29e8ba939790498727af9342c2b6f6ac43c9c + - id: BRONZE_SHIP_ENGINE + material: PLAYER_HEAD + rarity: RARE + components: + - id: FISHING_SHIP_PART + display_name: Bronze Ship Engine + slot: ENGINE + texture: 9172c1e729e0ca00193ab5d43e893fabedf5a80fc647258176e8502432885925 + - id: BRONZE_SHIP_HELM + material: PLAYER_HEAD + rarity: RARE + components: + - id: FISHING_SHIP_PART + display_name: Bronze Ship Helm + slot: HELM + texture: 646c5393c3c57742c992c56a7b7a8b98d267538de947c1096fe76341431008f2 + - id: BRONZE_SHIP_HULL + material: PLAYER_HEAD + rarity: RARE + components: + - id: FISHING_SHIP_PART + display_name: Bronze Ship Hull + slot: HULL + texture: a4a7254f1ad8448097d83ddfc790c9f02bc889acbd304b414cee5a13ceadc1e diff --git a/type.backwaterbayou/src/main/java/net/swofty/type/backwaterbayou/TypeBackwaterBayouLoader.java b/type.backwaterbayou/src/main/java/net/swofty/type/backwaterbayou/TypeBackwaterBayouLoader.java index d4905f1ff..092c5d4ad 100644 --- a/type.backwaterbayou/src/main/java/net/swofty/type/backwaterbayou/TypeBackwaterBayouLoader.java +++ b/type.backwaterbayou/src/main/java/net/swofty/type/backwaterbayou/TypeBackwaterBayouLoader.java @@ -42,9 +42,7 @@ public void afterInitialize(MinecraftServer server) { @Override public LoaderValues getLoaderValues() { return new LoaderValues( - (type) -> switch (type) { - default -> new Pos(-12.5, 74, -10.5, -55, 0); - }, // Spawn position + (type) -> new Pos(-12.5, 74, -10.5, -55, 0), // Spawn position true // Announce death messages ); } diff --git a/type.backwaterbayou/src/main/java/net/swofty/type/backwaterbayou/gui/GUIFishingRodParts.java b/type.backwaterbayou/src/main/java/net/swofty/type/backwaterbayou/gui/GUIFishingRodParts.java new file mode 100644 index 000000000..135a02aa8 --- /dev/null +++ b/type.backwaterbayou/src/main/java/net/swofty/type/backwaterbayou/gui/GUIFishingRodParts.java @@ -0,0 +1,100 @@ +package net.swofty.type.backwaterbayou.gui; + +import net.minestom.server.inventory.InventoryType; +import net.minestom.server.item.ItemStack; +import net.minestom.server.item.Material; +import net.swofty.commons.skyblock.item.ItemType; +import net.swofty.type.generic.gui.inventory.ItemStackCreator; +import net.swofty.type.generic.gui.v2.Components; +import net.swofty.type.generic.gui.v2.DefaultState; +import net.swofty.type.generic.gui.v2.StatelessView; +import net.swofty.type.generic.gui.v2.ViewConfiguration; +import net.swofty.type.generic.gui.v2.ViewLayout; +import net.swofty.type.generic.gui.v2.ViewSession; +import net.swofty.type.generic.gui.v2.context.ViewContext; +import net.swofty.type.skyblockgeneric.fishing.FishingItemCatalog; +import net.swofty.type.skyblockgeneric.fishing.FishingRodDefinition; +import net.swofty.type.skyblockgeneric.item.SkyBlockItem; +import net.swofty.type.skyblockgeneric.user.SkyBlockPlayer; + +public class GUIFishingRodParts extends StatelessView { + + @Override + public ViewConfiguration configuration() { + return new ViewConfiguration<>("Fishing Rod Parts", InventoryType.CHEST_6_ROW); + } + + @Override + public void onClose(DefaultState state, ViewContext ctx, ViewSession.CloseReason reason) { + ItemStack rodItem = ctx.inventory().getItemStack(21); + if (!rodItem.isAir()) { + SkyBlockPlayer player = (SkyBlockPlayer) ctx.player(); + player.addAndUpdateItem(new SkyBlockItem(rodItem)); + ctx.inventory().setItemStack(21, ItemStack.AIR); + } + } + + @Override + public void layout(ViewLayout layout, DefaultState state, ViewContext ctx) { + Components.close(layout, 49); + + layout.editable(21, (_, _) -> ItemStackCreator.createNamedItemStack( + Material.FISHING_ROD, + "§7Place your §aFishing Rod §7here!" + ), (_, oldItem, newItem, _) -> { + if (newItem.isAir()) return; + SkyBlockItem rod = new SkyBlockItem(newItem); + ItemType type = rod.getAttributeHandler().getPotentialType(); + FishingRodDefinition def = type == null ? null : FishingItemCatalog.getRod(type.name()); + if (def == null || !def.rodPartsEnabled()) { + SkyBlockPlayer player = (SkyBlockPlayer) ctx.player(); + player.sendMessage("§cThat fishing rod does not support rod parts."); + ctx.inventory().setItemStack(21, oldItem); + if (!newItem.isAir()) { + player.addAndUpdateItem(new SkyBlockItem(newItem)); + } + } + }); + + layout.slot(22, ItemStackCreator.getStack( + "§9ථ Hook", + Material.LIGHT_BLUE_STAINED_GLASS_PANE, + 1, + "§7Place a §aFishing Rod §7in the slot to the", + "§7left to view and modify its §9Hook§7!", + "", + "§eClick to browse Hooks!" + ), (_, viewCtx) -> viewCtx.push(new GUIHook())); + + layout.slot(23, ItemStackCreator.getStack( + "§9ꨃ Line", + Material.LIGHT_BLUE_STAINED_GLASS_PANE, + 1, + "§7Place a §aFishing Rod §7in the slot to the", + "§7left to view and modify its §9Line§7!", + "", + "§eClick to browse Lines!" + ), (_, viewCtx) -> viewCtx.push(new GUILine())); + + layout.slot(24, ItemStackCreator.getStack( + "§9࿉ Sinker", + Material.LIGHT_BLUE_STAINED_GLASS_PANE, + 1, + "§7Place a §aFishing Rod §7in the slot to the", + "§7left to view and modify its §9Sinker§7!", + "", + "§eClick to browse Sinkers!" + ), (_, viewCtx) -> viewCtx.push(new GUISinker())); + + layout.slot(50, ItemStackCreator.getStack( + "§9Rod Part Guide", + Material.BOOK, + 1, + "§7View all of the §9Rod Parts §7that can be", + "§7applied to §aFishing Rods§7! Can also be", + "§7accessed with §a/rodparts§7!", + "", + "§eClick to view!" + ), (_, viewCtx) -> viewCtx.push(new GUIRodPartGuide())); + } +} diff --git a/type.backwaterbayou/src/main/java/net/swofty/type/backwaterbayou/gui/GUIHook.java b/type.backwaterbayou/src/main/java/net/swofty/type/backwaterbayou/gui/GUIHook.java new file mode 100644 index 000000000..5dfd61149 --- /dev/null +++ b/type.backwaterbayou/src/main/java/net/swofty/type/backwaterbayou/gui/GUIHook.java @@ -0,0 +1,48 @@ +package net.swofty.type.backwaterbayou.gui; + +import net.minestom.server.inventory.InventoryType; +import net.minestom.server.item.Material; +import net.swofty.type.generic.gui.inventory.ItemStackCreator; +import net.swofty.type.generic.gui.v2.Components; +import net.swofty.type.generic.gui.v2.DefaultState; +import net.swofty.type.generic.gui.v2.StatelessView; +import net.swofty.type.generic.gui.v2.ViewConfiguration; +import net.swofty.type.generic.gui.v2.ViewLayout; +import net.swofty.type.generic.gui.v2.context.ViewContext; +import net.swofty.type.skyblockgeneric.fishing.FishingItemCatalog; +import net.swofty.type.skyblockgeneric.fishing.RodPartDefinition; +import net.swofty.type.skyblockgeneric.gui.inventories.fishing.FishingGuideStackFactory; + +public class GUIHook extends StatelessView { + private static final int[] PART_SLOTS = {10, 11, 12, 13, 14, 15, 16}; + + @Override + public ViewConfiguration configuration() { + return new ViewConfiguration<>("Hook", InventoryType.CHEST_6_ROW); + } + + @Override + public void layout(ViewLayout layout, DefaultState state, ViewContext ctx) { + Components.close(layout, 49); + layout.slot(4, ItemStackCreator.getStackHead( + "§9ථ Hooks", + "9809753cbab0380c7a1c18925faf9b51e44caadd1e5748542b0f23835f4ef64e", + 1, + "§9Hooks §7change what your rod is better at catching." + )); + + int index = 0; + for (RodPartDefinition part : FishingItemCatalog.getRodParts()) { + if (part.category() != RodPartDefinition.PartCategory.HOOK || index >= PART_SLOTS.length) { + continue; + } + layout.slot(PART_SLOTS[index++], FishingGuideStackFactory.buildRodPartStack(part)); + } + layout.slot(48, ItemStackCreator.getStack( + "§aGo Back", + Material.ARROW, + 1, + "§7To Rod Part Guide" + ), (_, viewCtx) -> viewCtx.pop()); + } +} diff --git a/type.backwaterbayou/src/main/java/net/swofty/type/backwaterbayou/gui/GUIJunkerJoel.java b/type.backwaterbayou/src/main/java/net/swofty/type/backwaterbayou/gui/GUIJunkerJoel.java new file mode 100644 index 000000000..35ee873cb --- /dev/null +++ b/type.backwaterbayou/src/main/java/net/swofty/type/backwaterbayou/gui/GUIJunkerJoel.java @@ -0,0 +1,461 @@ +package net.swofty.type.backwaterbayou.gui; + +import net.minestom.server.inventory.InventoryType; +import net.minestom.server.item.Material; +import net.swofty.type.generic.gui.inventory.ItemStackCreator; +import net.swofty.type.generic.gui.v2.DefaultState; +import net.swofty.type.generic.gui.v2.StatelessView; +import net.swofty.type.generic.gui.v2.ViewConfiguration; +import net.swofty.type.generic.gui.v2.ViewLayout; +import net.swofty.type.generic.gui.v2.context.ViewContext; + +// TODO: use ShopView +public class GUIJunkerJoel extends StatelessView { + + @Override + public ViewConfiguration configuration() { + return new ViewConfiguration<>("Junker Joel", InventoryType.CHEST_6_ROW); + } + + @Override + public void layout(ViewLayout layout, DefaultState state, ViewContext ctx) { + layout.slot(10, ItemStackCreator.getStackHead( + "§9Junk Sinker", + "d24892a3142d2e130e5feb88b805b83de905489d2ccd1d031b9d7a2922b96500", + 1, + "§7Grants §6+10⛃ Treasure Chance §7while", + "§7in the §2Backwater Bayou §7but replaces", + "§7all §6Treasure §7catches with §2Junk§7!", + "", + "§7Talk to §2Roddy §7in the §2Backwater", + "§2Bayou §7to apply this §9Sinker §7to a", + "§7Fishing Rod.", + "", + "§9§lRARE ROD PART", + "", + "§7Cost", + "§610,000 Coins", + "", + "§eClick to trade!" + )); + layout.slot(11, ItemStackCreator.getStackHead( + "§9Treasure Bait §8x16", + "c1695c80854447b5db5a0ee6d57ef0a7d91d815bd7e6318c516a39d12fe0639e", + 16, + "§8Fishing Bait", + "§8Consumes on Cast", + "", + "§7Grants §b+10☂ Fishing Speed§7 and §6+2⛃", + "§6Treasure Chance§7.", + "", + "§9§lRARE BAIT", + "", + "§7Cost", + "§aRusty Coin", + "", + "§eClick to trade!", + "§eRight-click for more trading options!" + )); + layout.slot(12, ItemStackCreator.getStack( + "§aChallenging Rod", + Material.FISHING_ROD, + 1, + "§7Damage: §c+75", + "§7Strength: §c+75", + "§7Fishing Speed: §b+35", + "§7Sea Creature Chance: §3+2%", + "", + "§9ථ Hook §8§lNONE", + "§9ꨃ Line §8§lNONE", + "§9࿉ Sinker §8§lNONE", + "", + "§7Talk to §2Roddy §7in the §2Backwater", + "§2Bayou §7to apply parts to this rod.", + "", + "§8This item can be reforged!", + "§a§lUNCOMMON FISHING ROD", + "", + "§7Cost", + "§fFishing Rod", + "§aRusty Coin §8x16", + "", + "§eClick to trade!" + )); + layout.slot(13, ItemStackCreator.getStackHead( + "§aBackwater Helmet", + "f6f6c3ebab908a184d49a0f8c85edd3ed48a65d69213bc0367db67a7a1c0c3a7", + 1, + "§7Health: §c+30", + "§7Defense: §a+15", + "§7Sea Creature Chance: §3+1%", + "§7Treasure Chance: §6+0.1%", + "", + "§8Tiered Bonus: Swamp Soldier (0/8)", + "§7Increases damage dealt to §3Sea", + "§3Creatures §7by §a5%§7.", + "", + "§8This item can be reforged!", + "§a§lUNCOMMON HELMET", + "", + "§7Cost", + "§fAngler Helmet", + "§aRusty Coin §8x4", + "", + "§eClick to trade!" + )); + layout.slot(14, ItemStackCreator.getStack( + "§aBackwater Chestplate", + Material.LEATHER_CHESTPLATE, + 1, + "§7Health: §c+50", + "§7Defense: §a+25", + "§7Sea Creature Chance: §3+1%", + "§7Treasure Chance: §6+0.1%", + "", + "§8Tiered Bonus: Swamp Soldier (0/8)", + "§7Increases damage dealt to §3Sea", + "§3Creatures §7by §a5%§7.", + "", + "§8This item can be reforged!", + "§a§lUNCOMMON CHESTPLATE", + "", + "§7Cost", + "§fAngler Chestplate", + "§aRusty Coin §8x4", + "", + "§eClick to trade!" + )); + layout.slot(15, ItemStackCreator.getStack( + "§aBackwater Leggings", + Material.LEATHER_LEGGINGS, + 1, + "§7Health: §c+40", + "§7Defense: §a+20", + "§7Sea Creature Chance: §3+1%", + "§7Treasure Chance: §6+0.1%", + "", + "§8Tiered Bonus: Swamp Soldier (0/8)", + "§7Increases damage dealt to §3Sea", + "§3Creatures §7by §a5%§7.", + "", + "§8This item can be reforged!", + "§a§lUNCOMMON LEGGINGS", + "", + "§7Cost", + "§fAngler Leggings", + "§aRusty Coin §8x4", + "", + "§eClick to trade!" + )); + layout.slot(16, ItemStackCreator.getStack( + "§aBackwater Boots", + Material.LEATHER_BOOTS, + 1, + "§7Health: §c+20", + "§7Defense: §a+10", + "§7Sea Creature Chance: §3+1%", + "§7Treasure Chance: §6+0.1%", + "", + "§8Tiered Bonus: Swamp Soldier (0/8)", + "§7Increases damage dealt to §3Sea", + "§3Creatures §7by §a5%§7.", + "", + "§8This item can be reforged!", + "§a§lUNCOMMON BOOTS", + "", + "§7Cost", + "§fAngler Boots", + "§aRusty Coin §8x4", + "", + "§eClick to trade!" + )); + layout.slot(19, ItemStackCreator.getStackHead( + "§fJunk Talisman", + "d24c6d00c53b51685a6be7453d236228f9837f1c1e27a9175813983ca49c792f", + 1, + "§7Grants §6+2.5⛃ Treasure Chance §7while", + "§7on the §2Backwater Bayou§7.", + "", + "§8§oOne man's trash is another man's", + "§8§otreasure.", + "", + "§8Works while in Accessory Bag!", + "§f§lCOMMON ACCESSORY", + "", + "§7Cost", + "§aRusty Coin §8x32", + "", + "§eClick to trade!" + )); + layout.slot(20, ItemStackCreator.getStackHead( + "§aJunk Ring", + "4c920d3593ed4936defc894b88c43a2bb0b50c3a1e9a6dd8e859cb27bd3cabd", + 1, + "§7Grants §6+5⛃ Treasure Chance §7while", + "§7on the §2Backwater Bayou§7.", + "", + "§8§oOne man's trash is another man's", + "§8§otreasure.", + "", + "§8Works while in Accessory Bag!", + "§a§lUNCOMMON ACCESSORY", + "", + "§7Cost", + "§fJunk Talisman", + "§9Busted Belt Buckle §8x4", + "", + "§eClick to trade!" + )); + layout.slot(21, ItemStackCreator.getStackHead( + "§9Junk Artifact", + "9727812f708dee1826bceecdadb9c7719e3d0f385a3b2515d00b5f665d8ba83e", + 1, + "§7Grants §6+7.5⛃ Treasure Chance §7while", + "§7on the §2Backwater Bayou§7.", + "", + "§8§oOne man's trash is another man's", + "§8§otreasure.", + "", + "§8Works while in Accessory Bag!", + "§9§lRARE ACCESSORY", + "", + "§7Cost", + "§aJunk Ring", + "§5Old Leather Boot", + "", + "§eClick to trade!" + )); + layout.slot(22, ItemStackCreator.getStackHead( + "§aBackwater Necklace", + "ab6f8eea74ca22c2ab64592bab2699df39c3e7c1db7d2c9fc687be0dc8c7f1ed", + 1, + "§7Fishing Speed: §b+2", + "§7Sea Creature Chance: §3+1%", + "§7Treasure Chance: §6+0.1%", + "", + "§8Tiered Bonus: Swamp Soldier (0/8)", + "§7Increases damage dealt to §3Sea", + "§3Creatures §7by §a5%§7.", + "", + "§8This item can be reforged!", + "§a§lUNCOMMON NECKLACE", + "", + "§7Cost", + "§fAngler Necklace", + "§aRusty Coin §8x4", + "", + "§eClick to trade!" + )); + layout.slot(23, ItemStackCreator.getStackHead( + "§aBackwater Cloak", + "f2adeecbf20b58fd4cad8aaa3b4653d7165e07aa167be48a321b096d56a9fe35", + 1, + "§7Fishing Speed: §b+2", + "§7Sea Creature Chance: §3+1%", + "§7Treasure Chance: §6+0.1%", + "", + "§8Tiered Bonus: Swamp Soldier (0/8)", + "§7Increases damage dealt to §3Sea", + "§3Creatures §7by §a5%§7.", + "", + "§8This item can be reforged!", + "§a§lUNCOMMON CLOAK", + "", + "§7Cost", + "§fAngler Cloak", + "§aRusty Coin §8x4", + "", + "§eClick to trade!" + )); + layout.slot(24, ItemStackCreator.getStackHead( + "§aBackwater Belt", + "3c150be849a39208a38a83c5605e79aef93a12b37072b931693990192cb77a19", + 1, + "§7Fishing Speed: §b+2", + "§7Sea Creature Chance: §3+1%", + "§7Treasure Chance: §6+0.1%", + "", + "§8Tiered Bonus: Swamp Soldier (0/8)", + "§7Increases damage dealt to §3Sea", + "§3Creatures §7by §a5%§7.", + "", + "§8This item can be reforged!", + "§a§lUNCOMMON BELT", + "", + "§7Cost", + "§fAngler Belt", + "§aRusty Coin §8x4", + "", + "§eClick to trade!" + )); + layout.slot(25, ItemStackCreator.getStackHead( + "§aBackwater Gloves", + "9a6c887b86b2a59fdea5052413eab74d434c07f52231ce7ac33af5b395beded0", + 1, + "§7Fishing Speed: §b+2", + "§7Sea Creature Chance: §3+1%", + "§7Treasure Chance: §6+0.1%", + "", + "§8Tiered Bonus: Swamp Soldier (0/8)", + "§7Increases damage dealt to §3Sea", + "§3Creatures §7by §a5%§7.", + "", + "§8This item can be reforged!", + "§a§lUNCOMMON GLOVES", + "", + "§7Cost", + "§fAngler Bracelet", + "§aRusty Coin §8x4", + "", + "§eClick to trade!" + )); + layout.slot(28, ItemStackCreator.getStackHead( + "§7[Lvl 100] §fHermit Crab", + "26629dfa3fdfef04054024e0156d5e19da5401b1911f59b4bd3982685fe54c2c", + 1, + "§8Fishing Pet", + "", + "§7Defense: §a+20", + "§7Fishing Speed: §b+20", + "§7Sea Creature Chance: §3+2%", + "", + "§6Comfort Zone", + "§7Grants §b+20☂ Fishing Speed §7for §a30s", + "§7upon catching §6Treasure§7.", + "", + "§cThis is a preview of Lvl 100.", + "§cNew pets are lowest level!", + "", + "§7Cost", + "§aRusty Coin §8x32", + "", + "§eClick to trade!" + )); + layout.slot(29, ItemStackCreator.getStackHead( + "§9Stingy Sinker", + "e886d5cac32bd32fc07938908c552b7b27965d92065b3157dfc7ef849281ee9d", + 1, + "§7Grants a §a10% §7chance to not consume", + "§7Bait.", + "", + "§7Talk to §2Roddy §7in the §2Backwater", + "§2Bayou §7to apply this §9Sinker §7to a", + "§7Fishing Rod.", + "", + "§9§lRARE ROD PART", + "", + "§7Cost", + "§aRusty Coin §8x64", + "", + "§eClick to trade!" + )); + layout.slot(30, ItemStackCreator.getStackHead( + "§9Speedy Line", + "5cbac3c84e21e65ec88007604c4eba1da391e185544b90252fc16ca695c59b4b", + 1, + "§7Grants §b+10☂ Fishing Speed§7.", + "", + "§7Talk to §2Roddy §7in the §2Backwater", + "§2Bayou §7to apply this §9Line §7to a Fishing", + "§7Rod.", + "", + "§9§lRARE ROD PART", + "", + "§7Cost", + "§9Busted Belt Buckle §8x8", + "", + "§eClick to trade!" + )); + layout.slot(31, ItemStackCreator.getStackHead( + "§9Bronze Ship Engine", + "9172c1e729e0ca00193ab5d43e893fabedf5a80fc647258176e8502432885925", + 1, + "§8Ship Part", + "", + "§7Bring this item to §6Captain Baha§7.", + "", + "§7Grants §3+0.5☯ Fishing Wisdom §7when", + "§7attached to your §6Ship§7.", + "", + "§8§l* Soulbound §l*", + "§9§lRARE", + "", + "§7Cost", + "§aRusty Coin §8x64", + "§9Busted Belt Buckle §8x8", + "", + "§eClick to trade!" + )); + layout.slot(32, ItemStackCreator.getStackHead( + "§6Gold Bottle Cap", + "269698fd92fb14827af97e54a3f28f5e2685d7e94bd128c0c27f259df996717c", + 1, + "§8Combinable in Anvil", + "", + "§7When applied to a fishing rod,", + "§7increases its §9Luck of the Sea §7level", + "§7by §a1§7!", + "§8Can be applied once.", + "§8Requires Luck of the Sea VI!", + "", + "§8§oOne man's trash is, indeed, another", + "§8§oman's treasure.", + "", + "§6§lLEGENDARY", + "", + "§7Cost", + "§aRusty Coin §8x512", + "§9Busted Belt Buckle §8x64", + "§5Old Leather Boot §8x8", + "", + "§eClick to trade!" + )); + layout.slot(33, ItemStackCreator.getStackHead( + "§9Treasure Hook", + "9809753cbab0380c7a1c18925faf9b51e44caadd1e5748542b0f23835f4ef64e", + 1, + "§7Only allows you to catch items and", + "§6Treasure§7.", + "", + "§7Talk to §2Roddy §7in the §2Backwater", + "§2Bayou §7to apply this §9Hook §7to a Fishing", + "§7Rod.", + "", + "§4❣ §cRequires §aFishing Skill 25§c.", + "§9§lRARE ROD PART", + "", + "§7Cost", + "§6Bayou Water Orb", + "§5Old Leather Boot §8x4", + "§9Busted Belt Buckle §8x32", + "§aRusty Coin §8x256", + "", + "§cNot unlocked!" + )); + layout.slot(34, ItemStackCreator.getStack( + "§9Travel Scroll to the Bayou", + Material.MAP, + 1, + "§7Consume this item to add its", + "§7destination to your Fast Travel", + "§7options.", + "", + "§7Island: §aBackwater Bayou", + "§7Teleport: §eSpawn", + "", + "§9§lRARE TRAVEL SCROLL", + "", + "§7Cost", + "§9Busted Belt Buckle §8x8", + "", + "§eClick to trade!" + )); + layout.slot(49, ItemStackCreator.getStack( + "§aSell Item", + Material.HOPPER, + 1, + "§7Click items in your inventory to sell", + "§7them to this Shop!" + )); + } +} diff --git a/type.backwaterbayou/src/main/java/net/swofty/type/backwaterbayou/gui/GUILine.java b/type.backwaterbayou/src/main/java/net/swofty/type/backwaterbayou/gui/GUILine.java new file mode 100644 index 000000000..0572d1b34 --- /dev/null +++ b/type.backwaterbayou/src/main/java/net/swofty/type/backwaterbayou/gui/GUILine.java @@ -0,0 +1,48 @@ +package net.swofty.type.backwaterbayou.gui; + +import net.minestom.server.inventory.InventoryType; +import net.minestom.server.item.Material; +import net.swofty.type.generic.gui.inventory.ItemStackCreator; +import net.swofty.type.generic.gui.v2.Components; +import net.swofty.type.generic.gui.v2.DefaultState; +import net.swofty.type.generic.gui.v2.StatelessView; +import net.swofty.type.generic.gui.v2.ViewConfiguration; +import net.swofty.type.generic.gui.v2.ViewLayout; +import net.swofty.type.generic.gui.v2.context.ViewContext; +import net.swofty.type.skyblockgeneric.fishing.FishingItemCatalog; +import net.swofty.type.skyblockgeneric.fishing.RodPartDefinition; +import net.swofty.type.skyblockgeneric.gui.inventories.fishing.FishingGuideStackFactory; + +public class GUILine extends StatelessView { + private static final int[] PART_SLOTS = {10, 11, 12, 13, 14, 15, 16}; + + @Override + public ViewConfiguration configuration() { + return new ViewConfiguration<>("Line", InventoryType.CHEST_6_ROW); + } + + @Override + public void layout(ViewLayout layout, DefaultState state, ViewContext ctx) { + Components.close(layout, 49); + layout.slot(4, ItemStackCreator.getStackHead( + "§9ꨃ Lines", + "9a850a4f721bc150bb72b067e5074c8251058a6b9111691da315b393467c1aa9", + 1, + "§9Lines §7grant stat bonuses to your rod everywhere." + )); + + int index = 0; + for (RodPartDefinition part : FishingItemCatalog.getRodParts()) { + if (part.category() != RodPartDefinition.PartCategory.LINE || index >= PART_SLOTS.length) { + continue; + } + layout.slot(PART_SLOTS[index++], FishingGuideStackFactory.buildRodPartStack(part)); + } + layout.slot(48, ItemStackCreator.getStack( + "§aGo Back", + Material.ARROW, + 1, + "§7To Rod Part Guide" + ), (_, viewCtx) -> viewCtx.pop()); + } +} diff --git a/type.backwaterbayou/src/main/java/net/swofty/type/backwaterbayou/gui/GUIRodPartGuide.java b/type.backwaterbayou/src/main/java/net/swofty/type/backwaterbayou/gui/GUIRodPartGuide.java new file mode 100644 index 000000000..a1b29cff4 --- /dev/null +++ b/type.backwaterbayou/src/main/java/net/swofty/type/backwaterbayou/gui/GUIRodPartGuide.java @@ -0,0 +1,64 @@ +package net.swofty.type.backwaterbayou.gui; + +import net.minestom.server.inventory.InventoryType; +import net.minestom.server.item.Material; +import net.swofty.type.generic.gui.inventory.ItemStackCreator; +import net.swofty.type.generic.gui.v2.Components; +import net.swofty.type.generic.gui.v2.DefaultState; +import net.swofty.type.generic.gui.v2.StatelessView; +import net.swofty.type.generic.gui.v2.ViewConfiguration; +import net.swofty.type.generic.gui.v2.ViewLayout; +import net.swofty.type.generic.gui.v2.context.ViewContext; + +public class GUIRodPartGuide extends StatelessView { + @Override + public ViewConfiguration configuration() { + return new ViewConfiguration<>("Rod Part Guide", InventoryType.CHEST_6_ROW); + } + + @Override + public void layout(ViewLayout layout, DefaultState state, ViewContext ctx) { + Components.close(layout, 49); + + layout.slot(4, ItemStackCreator.getStack( + "§9Rod Part Guide", + Material.BOOK, + 1, + "§7View all §9Rod Parts §7that can be applied", + "§7to your upgraded fishing rods." + )); + layout.slot(20, ItemStackCreator.getStackHead( + "§9ථ Hooks", + "9809753cbab0380c7a1c18925faf9b51e44caadd1e5748542b0f23835f4ef64e", + 1, + "§9Hooks §7make you more likely to catch", + "§7certain things.", + "", + "§eClick to view!" + ), (_, viewCtx) -> viewCtx.push(new GUIHook())); + layout.slot(22, ItemStackCreator.getStackHead( + "§9ꨃ Lines", + "9a850a4f721bc150bb72b067e5074c8251058a6b9111691da315b393467c1aa9", + 1, + "§9Lines §7grant you stat bonuses", + "§7everywhere.", + "", + "§eClick to view!" + ), (_, viewCtx) -> viewCtx.push(new GUILine())); + layout.slot(24, ItemStackCreator.getStackHead( + "§9࿉ Sinkers", + "d24892a3142d2e130e5feb88b805b83de905489d2ccd1d031b9d7a2922b96500", + 1, + "§9Sinkers §7add special fishing effects", + "§7to your rod.", + "", + "§eClick to view!" + ), (_, viewCtx) -> viewCtx.push(new GUISinker())); + layout.slot(48, ItemStackCreator.getStack( + "§aGo Back", + Material.ARROW, + 1, + "§7To Fishing Rod Parts" + ), (_, viewCtx) -> viewCtx.pop()); + } +} diff --git a/type.backwaterbayou/src/main/java/net/swofty/type/backwaterbayou/gui/GUISinker.java b/type.backwaterbayou/src/main/java/net/swofty/type/backwaterbayou/gui/GUISinker.java new file mode 100644 index 000000000..cbe71b12f --- /dev/null +++ b/type.backwaterbayou/src/main/java/net/swofty/type/backwaterbayou/gui/GUISinker.java @@ -0,0 +1,48 @@ +package net.swofty.type.backwaterbayou.gui; + +import net.minestom.server.inventory.InventoryType; +import net.minestom.server.item.Material; +import net.swofty.type.generic.gui.inventory.ItemStackCreator; +import net.swofty.type.generic.gui.v2.Components; +import net.swofty.type.generic.gui.v2.DefaultState; +import net.swofty.type.generic.gui.v2.StatelessView; +import net.swofty.type.generic.gui.v2.ViewConfiguration; +import net.swofty.type.generic.gui.v2.ViewLayout; +import net.swofty.type.generic.gui.v2.context.ViewContext; +import net.swofty.type.skyblockgeneric.fishing.FishingItemCatalog; +import net.swofty.type.skyblockgeneric.fishing.RodPartDefinition; +import net.swofty.type.skyblockgeneric.gui.inventories.fishing.FishingGuideStackFactory; + +public class GUISinker extends StatelessView { + private static final int[] PART_SLOTS = {10, 11, 12, 13, 14, 15, 16, 19, 20}; + + @Override + public ViewConfiguration configuration() { + return new ViewConfiguration<>("Sinker", InventoryType.CHEST_6_ROW); + } + + @Override + public void layout(ViewLayout layout, DefaultState state, ViewContext ctx) { + Components.close(layout, 49); + layout.slot(4, ItemStackCreator.getStackHead( + "§9࿉ Sinkers", + "d24892a3142d2e130e5feb88b805b83de905489d2ccd1d031b9d7a2922b96500", + 1, + "§9Sinkers §7add special fishing effects to your rod." + )); + + int index = 0; + for (RodPartDefinition part : FishingItemCatalog.getRodParts()) { + if (part.category() != RodPartDefinition.PartCategory.SINKER || index >= PART_SLOTS.length) { + continue; + } + layout.slot(PART_SLOTS[index++], FishingGuideStackFactory.buildRodPartStack(part)); + } + layout.slot(48, ItemStackCreator.getStack( + "§aGo Back", + Material.ARROW, + 1, + "§7To Rod Part Guide" + ), (_, viewCtx) -> viewCtx.pop()); + } +} diff --git a/type.backwaterbayou/src/main/java/net/swofty/type/backwaterbayou/npcs/NPCCaptainBaha.java b/type.backwaterbayou/src/main/java/net/swofty/type/backwaterbayou/npcs/NPCCaptainBaha.java new file mode 100644 index 000000000..8e232ac42 --- /dev/null +++ b/type.backwaterbayou/src/main/java/net/swofty/type/backwaterbayou/npcs/NPCCaptainBaha.java @@ -0,0 +1,75 @@ +package net.swofty.type.backwaterbayou.npcs; + +import net.minestom.server.coordinate.Pos; +import net.swofty.type.generic.data.datapoints.DatapointToggles; +import net.swofty.type.generic.entity.npc.HypixelNPC; +import net.swofty.type.generic.entity.npc.configuration.HumanConfiguration; +import net.swofty.type.generic.event.custom.NPCInteractEvent; +import net.swofty.type.generic.user.HypixelPlayer; +import net.swofty.type.skyblockgeneric.user.SkyBlockPlayer; + +import java.util.stream.Stream; + +public class NPCCaptainBaha extends HypixelNPC { + + public NPCCaptainBaha() { + super(new HumanConfiguration() { + @Override + public String[] holograms(HypixelPlayer player) { + return new String[]{"§6Captain Baha", "§e§lCLICK"}; + } + + @Override + public String signature(HypixelPlayer player) { + return "A9Wh529RWV2HEMvVnPzQEPfvT7p8m2GU8IB5FowBVYRash8GUSC6OvO88v5eBXAsCJvAauOnCFkp0DrxNTHUTS6E8rcGpo5ieHTr+QYglXIlA8S+rgA5eGODgI3LEtOZucHJ6H64a23Bu41lNMpN2c+LzQbisqC9WBnfVBxYo6qrzgh5JBGsRDIg2h3UKmTnNgJPuhN2cwRDDlHG8/k+xES5ZqyEFvdjGn6O5HHL6xyMkCukjZN0E8s03NkpkKxZXEm1M/Eg8EWtwGqZIa3DHNmxchYok4mDPMst8iRy4pGRlJN+VBCmGLIV7pq4QZlGzuXWplrX/PAOb+B36Rg67SHvmIk23tpnu+7uvB3rw9NedWY1+xLp8W4gPKpynOobSCbKiJ6bX0mCQfURVh2svFT5nG/VnKCL0TE8CUiTxOuxJR8QWwWRI4BMRMJQfQxy0mofvPnR5g1XUnHzvGWr4m44dmooqyCgB4W9iysADAEgc9CVtizjroopAJLXCtfsxwIuioHaZsBKQU1NpvpH55bPqf//RI9FyJJwOXTgX7fbF49z0eAgjnRAyF9VE9VYI2hFZwa3BIFnvdGxlZhE63QPB+nmKQMT0WzTz15lm77lxvvpQsurkm2gKr6FlL9+SokbTUuQmisyzS84s2EocpRscgc9JF1Dv/NjK7T+3GU="; + } + + @Override + public String texture(HypixelPlayer player) { + return "ewogICJ0aW1lc3RhbXAiIDogMTc0MDQxOTU1NzI0NiwKICAicHJvZmlsZUlkIiA6ICIzY2I3YTA3YWY3ZjM0ZWZiYTlkNGI4ODQ3NDM4Mzc0ZSIsCiAgInByb2ZpbGVOYW1lIiA6ICJBUkJVWklLMTIwMTMiLAogICJzaWduYXR1cmVSZXF1aXJlZCIgOiB0cnVlLAogICJ0ZXh0dXJlcyIgOiB7CiAgICAiU0tJTiIgOiB7CiAgICAgICJ1cmwiIDogImh0dHA6Ly90ZXh0dXJlcy5taW5lY3JhZnQubmV0L3RleHR1cmUvMzcxYzQ0YWQ0MDdjMDIxNzM3YWQ3ODkwN2I1MDY4ZDdiY2MwYzY1OGIyYTJmYmFiZjAxNzA2NTYzYmQ5NDQ3ZCIKICAgIH0KICB9Cn0="; + } + + @Override + public Pos position(HypixelPlayer player) { + return new Pos(-22.5, 75, -8.5, -115, 0); + } + + @Override + public boolean looking(HypixelPlayer player) { + return true; + } + }); + } + + @Override + public void onClick(NPCInteractEvent event) { + SkyBlockPlayer player = (SkyBlockPlayer) event.player(); + if (isInDialogue(player)) { + return; + } + + if (!player.getToggles().get(DatapointToggles.Toggles.ToggleType.HAS_VISITED_BACKWATER_BAYOU)) { + setDialogue(player, "arrived").thenRun(() -> + player.getToggles().set(DatapointToggles.Toggles.ToggleType.HAS_VISITED_BACKWATER_BAYOU, true)); + return; + } + + setDialogue(player, "idle"); + } + + @Override + protected DialogueSet[] dialogues(HypixelPlayer player) { + return Stream.of( + DialogueSet.builder() + .key("arrived").lines(new String[]{ + "Land ho! We have arrived at the §2Backwater Bayou§f!", + "You go on and explore! Come back to the §6Ship §fand set sail when you're done!" + }).build(), + DialogueSet.builder() + .key("idle").lines(new String[]{ + "The §6Ship Navigator §fis yours whenever you're ready to head back.", + "Don't keep the marsh waiting too long, though." + }).build() + ).toArray(DialogueSet[]::new); + } +} diff --git a/type.backwaterbayou/src/main/java/net/swofty/type/backwaterbayou/npcs/NPCHattie.java b/type.backwaterbayou/src/main/java/net/swofty/type/backwaterbayou/npcs/NPCHattie.java new file mode 100644 index 000000000..10b6e5f33 --- /dev/null +++ b/type.backwaterbayou/src/main/java/net/swofty/type/backwaterbayou/npcs/NPCHattie.java @@ -0,0 +1,69 @@ +package net.swofty.type.backwaterbayou.npcs; + +import net.minestom.server.coordinate.Pos; +import net.swofty.type.generic.entity.npc.HypixelNPC; +import net.swofty.type.generic.entity.npc.configuration.HumanConfiguration; +import net.swofty.type.generic.event.custom.NPCInteractEvent; +import net.swofty.type.generic.user.HypixelPlayer; + +import java.util.stream.Stream; + +public class NPCHattie extends HypixelNPC { + + public NPCHattie() { + super(new HumanConfiguration() { + @Override + public String[] holograms(HypixelPlayer player) { + return new String[]{"§dHattie", "§e§lCLICK"}; + } + + @Override + public String signature(HypixelPlayer player) { + return "vQ5zgSiec5YR9aUfRwR+dZH29487jWT9Pr7PfdIx9pCuK07orJTg5/h8LQBsLFFiNNxQDnENw7/JeaRUP9JxZcxT/OjVLGnlR/P5fn+AET6tSok86mYS81JMDuFPFR2qhoEPBEmOnT0JDmMW4MCCVZtjBz5ENvHvVelZ3eDqy5KROz2u1qwjVBL6QToyT1pLravS8Y/juJDkmFEr4HW76cErnsXU73TOcJ8VeN0oV8KMeKyayLnFK6zZ0OMHZmBEDyQJ59tfoNo12jkdyEZ2rIo/Ix2inZ/VB4QYA+sODyFbTb+YGWSOBU50fkGngwLXsCsc51xm3nGNm3+fVvO5Y6MoVKsUk9G7pddppFdw0G/dOLuoyMTtcWVbuYPqvVhd+b47h5z3zG5767FmZbm2QwlR1VqKC6KqyZFSR5T8p6RdZxz5to+d6RGs1reK5tCGyyPwyVc0TW1hTXQ523uiMYmPKbRWUssjd2uypIAFSiytjVWRl9LI2K5QrRazyv4t8e4JIoDczELdgM8y2qxHrbb4rdMbkSS2/KQnYWDBZoR4xprZR0j4rOxbXVjwQ/lZsHhYV7SPbtun2sHyNd/nD+XvydM7V7Zjci1Zt48AvHpkHGn+4J/eTLpBHe4C4aKdDCnnfdwb1F3DPWyQKs5nsc/LSvTacfwYZwW7SQ6f+U0="; + } + + @Override + public String texture(HypixelPlayer player) { + return "ewogICJ0aW1lc3RhbXAiIDogMTczOTk4ODE2OTQyNCwKICAicHJvZmlsZUlkIiA6ICI0YWY1YmQ3NTdmZDE0MWEwOTczYmUxNTFkZWRjNmM5ZiIsCiAgInByb2ZpbGVOYW1lIiA6ICJjcmFzaGludG95b3VybW9tIiwKICAic2lnbmF0dXJlUmVxdWlyZWQiIDogdHJ1ZSwKICAidGV4dHVyZXMiIDogewogICAgIlNLSU4iIDogewogICAgICAidXJsIiA6ICJodHRwOi8vdGV4dHVyZXMubWluZWNyYWZ0Lm5ldC90ZXh0dXJlL2E4NzQxZTFiZTdjY2VlN2E3YjY2ZDE5YWMwZjZmNDM2ZmFlNjhkNGFkZjNlNzVkMjBmNTk1MjIxYzIyOTMwMSIsCiAgICAgICJtZXRhZGF0YSIgOiB7CiAgICAgICAgIm1vZGVsIiA6ICJzbGltIgogICAgICB9CiAgICB9CiAgfQp9"; + } + + @Override + public Pos position(HypixelPlayer player) { + return new Pos(17.5, 71, 14.5, -135, 20); + } + + @Override + public boolean looking(HypixelPlayer player) { + return true; + } + }); + } + + @Override + public void onClick(NPCInteractEvent event) { + HypixelPlayer player = event.player(); + if (isInDialogue(player)) { + return; + } + + setDialogue(player, "hotspots-" + (1 + (int) (Math.random() * 2))); + } + + @Override + protected DialogueSet[] dialogues(HypixelPlayer player) { + return Stream.of( + DialogueSet.builder() + .key("hotspots-1").lines(new String[]{ + "Hotspots are temporary rings that appear above the water or lava.", + "Fish inside one and you'll get a bonus while your bobber stays in it.", + "The Bayou, Hub, Spider's Den, and Crimson Isle all have them. Keep your eyes open!" + }).build(), + DialogueSet.builder() + .key("hotspots-2").lines(new String[]{ + "Hotspots can boost your §bFishing Speed§f, §3Sea Creature Chance§f, §6Treasure Chance§f, or even §5Trophy Fish Chance§f.", + "Some creatures only show up when you're fishing inside one.", + "If the water starts glowing, don't waste the opportunity." + }).build() + ).toArray(DialogueSet[]::new); + } +} diff --git a/type.backwaterbayou/src/main/java/net/swofty/type/backwaterbayou/npcs/NPCJunkerJoel.java b/type.backwaterbayou/src/main/java/net/swofty/type/backwaterbayou/npcs/NPCJunkerJoel.java new file mode 100644 index 000000000..d66c9ac7d --- /dev/null +++ b/type.backwaterbayou/src/main/java/net/swofty/type/backwaterbayou/npcs/NPCJunkerJoel.java @@ -0,0 +1,64 @@ +package net.swofty.type.backwaterbayou.npcs; + +import net.minestom.server.coordinate.Pos; +import net.swofty.type.backwaterbayou.gui.GUIJunkerJoel; +import net.swofty.type.generic.entity.npc.HypixelNPC; +import net.swofty.type.generic.entity.npc.configuration.HumanConfiguration; +import net.swofty.type.generic.event.custom.NPCInteractEvent; +import net.swofty.type.generic.user.HypixelPlayer; + +import java.util.stream.Stream; + +public class NPCJunkerJoel extends HypixelNPC { + + public NPCJunkerJoel() { + super(new HumanConfiguration() { + @Override + public String[] holograms(HypixelPlayer player) { + return new String[]{"§2Junker Joel", "§e§lCLICK"}; + } + + @Override + public String signature(HypixelPlayer player) { + return "cuTJRxZ5c0tPjwo+PK4Wuzp8Gymj87qIm+p9QQHLfgQWj75RkXAigGjcbWcIpBol4eP9xQ1KpZwuCfoIToRc9Y1HMMNAzdm459KJfSkhiHWMXggJBbW8CFvdKVIhQHMVKBCA0cgVDQE/ozNScwS63TXSSIE7iyHMAbFxoOw6hZMd9oQuaujnFt2lYda0yLmOSq1CKR+xUbLOsDqOPtQRaKw7hdYL99QzX8rMu7CAdPJkbnvb8ki/r/hkzqj0HikoBM02XZycdArMHq9MQPT6M7XKgRur/1AfMkaIFMTTGDVcIMQiWBY10I7UGui/hWm2jnIBjJrI/bvN5VRBeTxeoSaFSxQfZ1YJpLfuGjBY4XitD1W7UL11Z6BTI63VVIdW6L7vYm/4pRek/AAEfwa/cmEQelM44pvj3Yk/9/RWoZ0J+Sb/v6VX96apDmHk30pRDSx0gWrBXf9DGW56VFtiklR2edZI7OgGtfNcu83S2fmVZoxYO5zCEejbNj9tI7W2eY8Qmoqwo7J6OlfJWc3Ng/ucHBqlVR/T3sxnsyOE24BjvqPM349eyas079dzGc8PlYyvMj6RXtjX/Jz9clFdAXw94zENzvUltPNxcJgj9Xt41/9L7oEcEn9okM5kCqzfJXIAvZQmiZSv3rxYNg6TEoCY1r+eVRwRJMDTgefOpcs="; + } + + @Override + public String texture(HypixelPlayer player) { + return "ewogICJ0aW1lc3RhbXAiIDogMTc0MDE1NjgzNjkxNCwKICAicHJvZmlsZUlkIiA6ICI2NDU4Mjc0MjEyNDg0MDY0YTRkMDBlNDdjZWM4ZjcyZSIsCiAgInByb2ZpbGVOYW1lIiA6ICJUaDNtMXMiLAogICJzaWduYXR1cmVSZXF1aXJlZCIgOiB0cnVlLAogICJ0ZXh0dXJlcyIgOiB7CiAgICAiU0tJTiIgOiB7CiAgICAgICJ1cmwiIDogImh0dHA6Ly90ZXh0dXJlcy5taW5lY3JhZnQubmV0L3RleHR1cmUvYWE0NTAzZTdmMTYxOTg1ZDAyNzMxYTMwNjczNWFlOTRlNDA3Yzc5MGY1ZWI0N2I2MzExOTA3N2RkODgzNDc2YiIKICAgIH0KICB9Cn0="; + } + + @Override + public Pos position(HypixelPlayer player) { + return new Pos(6.5, 72, 4.5, 135, 0); + } + + @Override + public boolean looking(HypixelPlayer player) { + return true; + } + }); + } + + @Override + public void onClick(NPCInteractEvent event) { + HypixelPlayer player = event.player(); + if (isInDialogue(player)) { + return; + } + + setDialogue(player, "intro").thenRun(() -> player.openView(new GUIJunkerJoel())); + } + + @Override + protected DialogueSet[] dialogues(HypixelPlayer player) { + return Stream.of( + DialogueSet.builder() + .key("intro").lines(new String[]{ + "People dump all sorts of junk in these waters, and I make sure none of it goes to waste.", + "Bring me your scraps and I'll trade you something useful.", + "If you're planning to fish up a mountain of junk, you'll want a §9Junk Sinker§f." + }).build() + ).toArray(DialogueSet[]::new); + } +} diff --git a/type.backwaterbayou/src/main/java/net/swofty/type/backwaterbayou/npcs/NPCRoddy.java b/type.backwaterbayou/src/main/java/net/swofty/type/backwaterbayou/npcs/NPCRoddy.java new file mode 100644 index 000000000..3c26b83b3 --- /dev/null +++ b/type.backwaterbayou/src/main/java/net/swofty/type/backwaterbayou/npcs/NPCRoddy.java @@ -0,0 +1,74 @@ +package net.swofty.type.backwaterbayou.npcs; + +import net.minestom.server.coordinate.Pos; +import net.swofty.type.backwaterbayou.gui.GUIFishingRodParts; +import net.swofty.type.generic.data.datapoints.DatapointToggles; +import net.swofty.type.generic.entity.npc.HypixelNPC; +import net.swofty.type.generic.entity.npc.configuration.HumanConfiguration; +import net.swofty.type.generic.event.custom.NPCInteractEvent; +import net.swofty.type.generic.user.HypixelPlayer; +import net.swofty.type.skyblockgeneric.user.SkyBlockPlayer; + +import java.util.stream.Stream; + +public class NPCRoddy extends HypixelNPC { + + public NPCRoddy() { + super(new HumanConfiguration() { + @Override + public String[] holograms(HypixelPlayer player) { + return new String[]{"§6§lROD MECHANIC", "§2Roddy", "§e§lCLICK"}; + } + + @Override + public String signature(HypixelPlayer player) { + return "m9YzKGb9O5Hs5mLECUJS6JmzLBDBQy9J768PK8lwNBEmF5a9J8Xdy93EWCAtCGCAFMar9CWRmyqt9Ees7u/3PHNtUVg9EkmvG27cPEIMUB2lqVir0U62pfNcR+5JkjjqaleDLhcOBgXdN9iVHJUcZq2tTY3t1eVX5OKI8K9SVjGvxgGMKxFmR1758eqwh9Krvb7AXI1/zRaRdFRsdXs2SgrvI/HcD4GN4vrjl6ZteOprTY4vB9oHZZSBLffkL28psxckC6JwvpiEahEtHKo1lS43qMpKtqKX9qwSs8WZ8/9A+/dXwB6g0+b1C/JSFWkyETFfFs1dUSdVsThkqGstRmt6c6Ko4xdvS61WQYLS4pbEbPN4kk0WapdqrWrrqNvjjcBUd94mnqNgvA0N+qPVOD/QkLGLvZDfXC5Iyv2BlpdeQHosTgn9ZPDjotESMwWrGwhm/uLLxNc2Z/rAGke5zTjz4v1JDSha7uyXT1yZ3oCckUqhbGFzmx5YOQoT/PbWr/mONQbYWTJ5GnSeWIIEs616Icwn+Rlw0qF+3EPUeR7QRO1bt5aqpmCUcZvrYoMyS1pvLDjS66MyuK5mEsQDEY5Uufux4iB3J0rrSGSgoC/XP1s6kGlz+jFRbDT9VPv/m72msPS35uAB6nCnI3o6uXKr0GrUGX9BiHB68Us0Pfs="; + } + + @Override + public String texture(HypixelPlayer player) { + return "ewogICJ0aW1lc3RhbXAiIDogMTc0MTI3MjI2NDk0NiwKICAicHJvZmlsZUlkIiA6ICIzOWEzOTMzZWE4MjU0OGU3ODQwNzQ1YzBjNGY3MjU2ZCIsCiAgInByb2ZpbGVOYW1lIiA6ICJkZW1pbmVjcmFmdGVybG9sIiwKICAic2lnbmF0dXJlUmVxdWlyZWQiIDogdHJ1ZSwKICAidGV4dHVyZXMiIDogewogICAgIlNLSU4iIDogewogICAgICAidXJsIiA6ICJodHRwOi8vdGV4dHVyZXMubWluZWNyYWZ0Lm5ldC90ZXh0dXJlLzE3Y2FkOWYyN2Q3NGRlM2U1OWYyYTUxN2QwNGEyODJlMmNmODZlNGM1ZTQwNjM5ZGFlY2E3YjFhYWU3ZjVhNzEiCiAgICB9CiAgfQp9"; + } + + @Override + public Pos position(HypixelPlayer player) { + return new Pos(21.5, 78, -23.5, 135, 0); + } + + @Override + public boolean looking(HypixelPlayer player) { + return true; + } + }); + } + + @Override + public void onClick(NPCInteractEvent event) { + SkyBlockPlayer player = (SkyBlockPlayer) event.player(); + if (isInDialogue(player)) { + return; + } + + if (!player.getToggles().get(DatapointToggles.Toggles.ToggleType.HAS_SPOKEN_TO_RODDY)) { + setDialogue(player, "first-interaction").thenRun(() -> { + player.getToggles().set(DatapointToggles.Toggles.ToggleType.HAS_SPOKEN_TO_RODDY, true); + player.openView(new GUIFishingRodParts()); + }); + return; + } + + player.openView(new GUIFishingRodParts()); + } + + @Override + protected DialogueSet[] dialogues(HypixelPlayer player) { + return Stream.of( + DialogueSet.builder() + .key("first-interaction").lines(new String[]{ + "If your rod's missing some punch, you've come to the right mechanic.", + "Hooks, lines, and sinkers can change what your rod is best at catching.", + "Put a §aFishing Rod §fin the slot and I'll show you what parts fit." + }).build() + ).toArray(DialogueSet[]::new); + } +} diff --git a/type.crimsonisle/src/main/java/net/swofty/type/crimsonisle/TypeCrimsonIsleLoader.java b/type.crimsonisle/src/main/java/net/swofty/type/crimsonisle/TypeCrimsonIsleLoader.java index 272e68144..f15c0ca1e 100644 --- a/type.crimsonisle/src/main/java/net/swofty/type/crimsonisle/TypeCrimsonIsleLoader.java +++ b/type.crimsonisle/src/main/java/net/swofty/type/crimsonisle/TypeCrimsonIsleLoader.java @@ -42,9 +42,7 @@ public void afterInitialize(MinecraftServer server) { @Override public LoaderValues getLoaderValues() { return new LoaderValues( - (type) -> switch (type) { - default -> new Pos(-360.5, 80, -430.5, -180, 0); - }, // Spawn position + (type) -> new Pos(-360.5, 80, -430.5, -180, 0), // Spawn position true // Announce death messages ); } diff --git a/type.generic/src/main/java/net/swofty/type/generic/data/datapoints/DatapointToggles.java b/type.generic/src/main/java/net/swofty/type/generic/data/datapoints/DatapointToggles.java index 7b2503008..325191e64 100644 --- a/type.generic/src/main/java/net/swofty/type/generic/data/datapoints/DatapointToggles.java +++ b/type.generic/src/main/java/net/swofty/type/generic/data/datapoints/DatapointToggles.java @@ -118,6 +118,12 @@ public enum ToggleType { AUTO_ACCEPT_QUESTS(false), RUSTY_PURCHASE_CONFIRMATION(false), RUSTY_SORT_BY_RARITY(false), + HAS_SPOKEN_TO_FISHERWOMAN_ENID(false), + HAS_SPOKEN_TO_CAPTAIN_BAHA(false), + HAS_SPOKEN_TO_RODDY(false), + HAS_CAUGHT_FIRST_FISH(false), + HAS_UNLOCKED_SHIP(false), + HAS_VISITED_BACKWATER_BAYOU(false), ; private final boolean defaultValue; diff --git a/type.hub/src/main/java/net/swofty/type/hub/gui/GUIGFishingShip.java b/type.hub/src/main/java/net/swofty/type/hub/gui/fishing/GUIGFishingShip.java similarity index 99% rename from type.hub/src/main/java/net/swofty/type/hub/gui/GUIGFishingShip.java rename to type.hub/src/main/java/net/swofty/type/hub/gui/fishing/GUIGFishingShip.java index 5886b6a03..5a8eebfb6 100644 --- a/type.hub/src/main/java/net/swofty/type/hub/gui/GUIGFishingShip.java +++ b/type.hub/src/main/java/net/swofty/type/hub/gui/fishing/GUIGFishingShip.java @@ -1,4 +1,4 @@ -package net.swofty.type.hub.gui; +package net.swofty.type.hub.gui.fishing; import net.minestom.server.event.inventory.InventoryPreClickEvent; import net.minestom.server.inventory.InventoryType; diff --git a/type.hub/src/main/java/net/swofty/type/hub/gui/fishing/GUINavigator.java b/type.hub/src/main/java/net/swofty/type/hub/gui/fishing/GUINavigator.java new file mode 100644 index 000000000..7ffca738b --- /dev/null +++ b/type.hub/src/main/java/net/swofty/type/hub/gui/fishing/GUINavigator.java @@ -0,0 +1,57 @@ +package net.swofty.type.hub.gui.fishing; + +import net.minestom.server.inventory.InventoryType; +import net.minestom.server.item.Material; +import net.swofty.type.generic.gui.inventory.ItemStackCreator; +import net.swofty.type.generic.gui.v2.Components; +import net.swofty.type.generic.gui.v2.DefaultState; +import net.swofty.type.generic.gui.v2.Layouts; +import net.swofty.type.generic.gui.v2.StatelessView; +import net.swofty.type.generic.gui.v2.ViewConfiguration; +import net.swofty.type.generic.gui.v2.ViewLayout; +import net.swofty.type.generic.gui.v2.context.ViewContext; + +public class GUINavigator extends StatelessView { + + @Override + public ViewConfiguration configuration() { + return new ViewConfiguration<>("Navigator", InventoryType.CHEST_6_ROW); + } + + // todo: make this work with the mission + @Override + public void layout(ViewLayout layout, DefaultState state, ViewContext ctx) { + layout.slots(Layouts.row(0), (_, _) -> Components.FILLER); + layout.slots(Layouts.row(5), (_, _) -> Components.FILLER); + layout.slots(Layouts.rectangle(9, 45), (_, _) -> Components.FILLER.material(Material.BLUE_STAINED_GLASS_PANE)); + Components.close(layout, 49); + + layout.slot(10, ItemStackCreator.getStackHead( + "§2Backwater Bayou", + "1c0cd33590f64d346d98cdd01606938742e715dda6737353306a44f81c8ba426", + 1, + "§7A small, marshy outlet in the middle", + "§7of nowhere. Due to its isolated", + "§7nature, people frequently come here", + "§7to dump their trash.", + "", + "§7Activities:", + "§8 ■ §7Fish up §2Junk §7and trade it with §2Junker", + " §2Joel §7for useful items!", + "§8 ■ §7Apply §9Rod Parts §7with §2Roddy§7.", + "§8 ■ §7Fish §2Bayou Sea Creatures§7.", + "§8 ■ §7Learn about §dFishing Hotspots §7from", + " §dHattie§7.", + "", + "§eClick to travel!" + )); + layout.slot(40, ItemStackCreator.getStackHead( + "§bFishing Outpost", + "d7cc6687423d0570d556ac53e0676cb563bbdd9717cd8269bdebed6f6d4e7bf8", + 1, + "§7Your base of operations.", + "", + "§a§lYOU ARE HERE!" + )); + } +} diff --git a/type.hub/src/main/java/net/swofty/type/hub/npcs/NPCCaptainBaha.java b/type.hub/src/main/java/net/swofty/type/hub/npcs/NPCCaptainBaha.java index d5ade58e1..4e86e12fd 100644 --- a/type.hub/src/main/java/net/swofty/type/hub/npcs/NPCCaptainBaha.java +++ b/type.hub/src/main/java/net/swofty/type/hub/npcs/NPCCaptainBaha.java @@ -1,11 +1,19 @@ package net.swofty.type.hub.npcs; +import net.kyori.adventure.text.format.NamedTextColor; import net.minestom.server.coordinate.Pos; +import net.swofty.commons.skyblock.item.ItemType; import net.swofty.type.generic.data.datapoints.DatapointToggles; import net.swofty.type.generic.entity.npc.HypixelNPC; +import net.swofty.type.generic.entity.npc.NPCOption; import net.swofty.type.generic.entity.npc.configuration.HumanConfiguration; import net.swofty.type.generic.event.custom.NPCInteractEvent; import net.swofty.type.generic.user.HypixelPlayer; +import net.swofty.type.hub.gui.fishing.GUIGFishingShip; +import net.swofty.type.skyblockgeneric.fishing.FishingItemCatalog; +import net.swofty.type.skyblockgeneric.fishing.FishingShipService; +import net.swofty.type.skyblockgeneric.fishing.ShipPartDefinition; +import net.swofty.type.skyblockgeneric.user.SkyBlockPlayer; import java.util.stream.Stream; @@ -30,7 +38,7 @@ public String texture(HypixelPlayer player) { @Override public Pos position(HypixelPlayer player) { - return new Pos(179.5, 69, 55.5, 105, 0); + return new Pos(162.5, 69, -65.5, 105, 0); } @Override @@ -42,18 +50,49 @@ public boolean looking(HypixelPlayer player) { @Override public void onClick(NPCInteractEvent event) { - HypixelPlayer player = event.player(); + SkyBlockPlayer player = (SkyBlockPlayer) event.player(); if (isInDialogue(player)) return; - if(!player.getToggles().get(DatapointToggles.Toggles.ToggleType.HAS_SPOKEN_TO_GAVIN)) { + if (player.getToggles().get(DatapointToggles.Toggles.ToggleType.HAS_UNLOCKED_SHIP)) { + new GUIGFishingShip().open(player); + return; + } + + if (!player.getToggles().get(DatapointToggles.Toggles.ToggleType.HAS_SPOKEN_TO_CAPTAIN_BAHA)) { setDialogue(player, "first-interaction").thenRun(() -> { - player.getToggles().set(DatapointToggles.Toggles.ToggleType.HAS_SPOKEN_TO_GAVIN, true); + player.getToggles().set(DatapointToggles.Toggles.ToggleType.HAS_SPOKEN_TO_CAPTAIN_BAHA, true); }); return; } - setDialogue(player, "idle-" + (int)(Math.random() * 2 + 1)); - // TODO: new GUIFishingShip().open(player); + if (player.countItem(ItemType.RUSTY_SHIP_ENGINE) > 0) { + setDialogue(player, "rust-ship-engine").thenRun(() -> + NPCOption.sendOption(player, "captain_baha_engine", true, java.util.List.of( + NPCOption.Option.builder() + .key("yes") + .color(NamedTextColor.GREEN) + .bold(false) + .name("Yes!") + .action(ignored -> handleRustyShipEngine(player)) + .build() + ))); + return; + } + + setDialogue(player, "first-interaction"); + } + + private void handleRustyShipEngine(SkyBlockPlayer player) { + setDialogue(player, "dialogue-yes").thenRun(() -> { + ShipPartDefinition definition = FishingItemCatalog.getShipPart(ItemType.RUSTY_SHIP_ENGINE.name()); + if (definition != null) { + FishingShipService.installPart(player, definition); + } + player.takeItem(ItemType.RUSTY_SHIP_ENGINE, 1); + FishingShipService.unlockDestination(player, "BACKWATER_BAYOU"); + player.getToggles().set(DatapointToggles.Toggles.ToggleType.HAS_UNLOCKED_SHIP, true); + new GUIGFishingShip().open(player); + }); } @Override diff --git a/type.hub/src/main/java/net/swofty/type/hub/npcs/NPCFishermanGerald.java b/type.hub/src/main/java/net/swofty/type/hub/npcs/NPCFishermanGerald.java index 012fab80e..5be734429 100644 --- a/type.hub/src/main/java/net/swofty/type/hub/npcs/NPCFishermanGerald.java +++ b/type.hub/src/main/java/net/swofty/type/hub/npcs/NPCFishermanGerald.java @@ -1,6 +1,7 @@ package net.swofty.type.hub.npcs; import net.minestom.server.coordinate.Pos; +import net.swofty.commons.skyblock.item.ItemType; import net.swofty.type.generic.data.datapoints.DatapointToggles; import net.swofty.type.generic.entity.npc.HypixelNPC; import net.swofty.type.generic.entity.npc.configuration.HumanConfiguration; @@ -32,7 +33,7 @@ public String texture(HypixelPlayer player) { @Override public Pos position(HypixelPlayer player) { - return new Pos(153.5, 68.5, 55.5, -60, 0); + return new Pos(118.5, 71, -32.5, 180, 0); } @Override @@ -60,7 +61,22 @@ public void onClick(NPCInteractEvent event) { return; } - // TODO: finish this quest + if (!player.getToggles().get(DatapointToggles.Toggles.ToggleType.HAS_SPOKEN_TO_FISHERWOMAN_ENID)) { + setDialogue(player, "talk-to-enid-again"); + return; + } + + if (player.getToggles().get(DatapointToggles.Toggles.ToggleType.HAS_UNLOCKED_SHIP)) { + setDialogue(player, Math.random() < 0.5D ? "after-bringing-engine-to-baha" : "idle-" + (1 + (int) (Math.random() * 3))); + return; + } + + if (player.countItem(ItemType.RUSTY_SHIP_ENGINE) > 0 || "RUSTY_SHIP_ENGINE".equals(player.getShipState().getEngine())) { + setDialogue(player, "after-fishing-engine"); + return; + } + + setDialogue(player, "after-talking-to-enid"); } @Override @@ -77,6 +93,45 @@ protected DialogueSet[] dialogues(HypixelPlayer player) { "Keep the noise down, kid!", "If you want to learn about §aFishing§f, go talk to my wife, Fisherwoman Enid.", "She's fishing a bit §bupstream§f. Once she's shown you the ropes, come back and talk to me!", + }).build(), + DialogueSet.builder() + .key("talk-to-enid-again").lines(new String[]{ + "If you want to learn about §aFishing§f, go talk to my wife, Fisherwoman Enid.", + "She's fishing a bit §bupstream§f. Once she's shown you the ropes, come back and talk to me!" + }).build(), + DialogueSet.builder() + .key("after-talking-to-enid").lines(new String[]{ + "Can you fish up the §cRusty Ship Engine §ffor me?", + "It's somewhere in this pond here.", + "Once you fish it out, you can set sail to the §2Backwater Bayou§f!" + }).build(), + DialogueSet.builder() + .key("after-fishing-engine").lines(new String[]{ + "Ah! The §cRusty Ship Engine§f! Perfect!", + "Bring that to §6Captain Baha §fand he'll be able to help you set sail!", + "He's just behind the Fisherman's Hut, waiting by the §6Ship§f!", + "Just leave out the part about me dropping it, will ya?" + }).build(), + DialogueSet.builder() + .key("after-bringing-engine-to-baha").lines(new String[]{ + "Thanks for helping me find the §cRusty Ship Engine§f, " + (player == null ? "kid" : player.getUsername()) + "!", + "You can use the §6Ship Navigator §fto set sail to the §2Backwater Bayou§f!", + "Safe travels!" + }).build(), + DialogueSet.builder() + .key("idle-1").lines(new String[]{ + "Fishing is the family business.", + "Enid and I are thrilled that our two children love it as much as we do!" + }).build(), + DialogueSet.builder() + .key("idle-2").lines(new String[]{ + "I met Captain Baha when i was marooned on a distant pirate cove.", + "He saved my skin then, and I'm forever grateful to him." + }).build(), + DialogueSet.builder() + .key("idle-3").lines(new String[]{ + "I've only gone lava fishing a few times in my life.", + "I prefer the open water. More peaceful, less ghasts!" }).build() ).toArray(DialogueSet[]::new); } diff --git a/type.hub/src/main/java/net/swofty/type/hub/npcs/NPCFisherwomanEnid.java b/type.hub/src/main/java/net/swofty/type/hub/npcs/NPCFisherwomanEnid.java index 722208ae8..d9a35d276 100644 --- a/type.hub/src/main/java/net/swofty/type/hub/npcs/NPCFisherwomanEnid.java +++ b/type.hub/src/main/java/net/swofty/type/hub/npcs/NPCFisherwomanEnid.java @@ -1,10 +1,14 @@ package net.swofty.type.hub.npcs; import net.minestom.server.coordinate.Pos; +import net.swofty.type.generic.data.datapoints.DatapointToggles; import net.swofty.type.generic.entity.npc.HypixelNPC; import net.swofty.type.generic.entity.npc.configuration.HumanConfiguration; import net.swofty.type.generic.event.custom.NPCInteractEvent; import net.swofty.type.generic.user.HypixelPlayer; +import net.swofty.type.skyblockgeneric.user.SkyBlockPlayer; + +import java.util.stream.Stream; public class NPCFisherwomanEnid extends HypixelNPC { @@ -39,6 +43,66 @@ public boolean looking(HypixelPlayer player) { @Override public void onClick(NPCInteractEvent event) { + SkyBlockPlayer player = (SkyBlockPlayer) event.player(); + if (isInDialogue(player)) { + return; + } + + if (!player.getToggles().get(DatapointToggles.Toggles.ToggleType.HAS_SPOKEN_TO_FISHERWOMAN_ENID)) { + setDialogue(player, "first-interaction").thenRun(() -> + player.getToggles().set(DatapointToggles.Toggles.ToggleType.HAS_SPOKEN_TO_FISHERWOMAN_ENID, true)); + return; + } + + if (!player.getToggles().get(DatapointToggles.Toggles.ToggleType.HAS_CAUGHT_FIRST_FISH)) { + setDialogue(player, "first-interaction"); + return; + } + + if (player.getToggles().get(DatapointToggles.Toggles.ToggleType.HAS_UNLOCKED_SHIP)) { + setDialogue(player, Math.random() < 0.5D ? "after-gerald" : "idle-" + (1 + (int) (Math.random() * 3))); + return; + } + setDialogue(player, "after-catching-fish"); + } + + @Override + protected DialogueSet[] dialogues(HypixelPlayer player) { + return Stream.of( + DialogueSet.builder() + .key("first-interaction").lines(new String[]{ + "To fish, cast your rod into the water and wait for a fish to bite!" + }).build(), + DialogueSet.builder() + .key("after-catching-fish").lines(new String[]{ + "This part of the hub is a popular area for fishing because of the Fishing Outpost!", + "If you follow the river that flows under the bridge downstream, you'll find your way to it.", + "And tell Gerald I won't be home tonight! I'm tired of him making salmon." + }).build(), + DialogueSet.builder() + .key("after-gerald").lines(new String[]{ + "If you like fishin', you'll love the Backwater Bayou!", + "You should go there sometime soon!" + }).build(), + DialogueSet.builder() + .key("idle-1").lines(new String[]{ + "Using Bait is important to get better results!", + "My favorite kind of bait is Dark Bait because I prefer fishing at night.", + "Angler Angus knows a lot more about Bait than I do. I think he's fishing somewhere along this river if you're interested in learning more." + }).build(), + DialogueSet.builder() + .key("idle-2").lines(new String[]{ + "I know that Gavin uses /scg instead of looking in his Fishing Skill menu.", + "He thinks he's being sneaky, but everyone knows about it.", + "Little does he know, I use it too!" + }).build(), + DialogueSet.builder() + .key("idle-3").lines(new String[]{ + "The Backwater Bayou has all sorts of wild Sea Creatures native to the area.", + "I've heard stories of Frog Man, but I've never quite worked out if he's a frog or a man.", + "Perhaps he is both, perhaps neither." + }).build() + ).toArray(DialogueSet[]::new); } } diff --git a/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/SkyBlockGenericLoader.java b/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/SkyBlockGenericLoader.java index 9c1f868e7..2b3c82676 100644 --- a/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/SkyBlockGenericLoader.java +++ b/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/SkyBlockGenericLoader.java @@ -60,6 +60,7 @@ import net.swofty.type.skyblockgeneric.entity.mob.MobRegistry; import net.swofty.type.skyblockgeneric.entity.mob.SkyBlockMob; import net.swofty.type.skyblockgeneric.event.value.SkyBlockValueEvent; +import net.swofty.type.skyblockgeneric.fishing.FishingRegistry; import net.swofty.type.skyblockgeneric.item.ItemConfigParser; import net.swofty.type.skyblockgeneric.item.SkyBlockItem; import net.swofty.type.skyblockgeneric.item.components.CraftableComponent; @@ -174,6 +175,7 @@ public void initialize(MinecraftServer server) { } catch (IOException e) { Logger.error("Failed to scan for YAML files", e); } + FishingRegistry.loadAll(); /** * Register commands diff --git a/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/data/SkyBlockDataHandler.java b/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/data/SkyBlockDataHandler.java index 4b01c28b0..d55a4c4dc 100644 --- a/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/data/SkyBlockDataHandler.java +++ b/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/data/SkyBlockDataHandler.java @@ -11,7 +11,14 @@ import net.swofty.commons.skyblock.item.ItemType; import net.swofty.type.generic.data.DataHandler; import net.swofty.type.generic.data.Datapoint; -import net.swofty.type.generic.data.datapoints.*; +import net.swofty.type.generic.data.datapoints.DatapointBoolean; +import net.swofty.type.generic.data.datapoints.DatapointDouble; +import net.swofty.type.generic.data.datapoints.DatapointInteger; +import net.swofty.type.generic.data.datapoints.DatapointLong; +import net.swofty.type.generic.data.datapoints.DatapointMapStringLong; +import net.swofty.type.generic.data.datapoints.DatapointPresentYear; +import net.swofty.type.generic.data.datapoints.DatapointString; +import net.swofty.type.generic.data.datapoints.DatapointStringList; import net.swofty.type.generic.data.mongodb.ProfilesDatabase; import net.swofty.type.generic.data.mongodb.UserDatabase; import net.swofty.type.generic.user.HypixelPlayer; @@ -30,7 +37,11 @@ import org.tinylog.Logger; import tools.jackson.core.JacksonException; -import java.util.*; +import java.util.Arrays; +import java.util.HashMap; +import java.util.Map; +import java.util.Objects; +import java.util.UUID; import java.util.function.BiConsumer; import java.util.function.Function; @@ -362,6 +373,12 @@ DatapointPetData.class, new DatapointPetData("pet_data")), QUIVER("quiver", false, false, false, DatapointQuiver.class, new DatapointQuiver("quiver")), + SHIP_STATE("ship_state", false, false, false, + DatapointShipState.class, new DatapointShipState("ship_state")), + + TROPHY_FISH("trophy_fish", false, false, false, + DatapointTrophyFish.class, new DatapointTrophyFish("trophy_fish")), + RACE_BEST_TIME("race_best_time", false, false, false, DatapointMapStringLong.class, new DatapointMapStringLong("race_best_time")), @@ -512,4 +529,4 @@ public static void startRepeatSetValueLoop() { return TaskSchedule.nextTick(); }); } -} \ No newline at end of file +} diff --git a/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/data/datapoints/DatapointShipState.java b/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/data/datapoints/DatapointShipState.java new file mode 100644 index 000000000..5f761ba50 --- /dev/null +++ b/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/data/datapoints/DatapointShipState.java @@ -0,0 +1,97 @@ +package net.swofty.type.skyblockgeneric.data.datapoints; + +import lombok.AllArgsConstructor; +import lombok.Getter; +import lombok.NoArgsConstructor; +import lombok.Setter; +import net.swofty.commons.protocol.Serializer; +import net.swofty.type.skyblockgeneric.data.SkyBlockDatapoint; +import org.json.JSONArray; +import org.json.JSONObject; + +import java.util.ArrayList; +import java.util.List; + +public class DatapointShipState extends SkyBlockDatapoint { + private static final Serializer serializer = new Serializer<>() { + @Override + public String serialize(ShipState value) { + JSONObject object = new JSONObject(); + object.put("shipName", value.getShipName()); + object.put("helm", value.getHelm()); + object.put("engine", value.getEngine()); + object.put("hull", value.getHull()); + object.put("destinations", value.getUnlockedDestinations()); + return object.toString(); + } + + @Override + public ShipState deserialize(String json) { + if (json == null || json.isEmpty()) { + return new ShipState(); + } + + JSONObject object = new JSONObject(json); + List destinations = new ArrayList<>(); + JSONArray array = object.optJSONArray("destinations"); + if (array != null) { + for (Object entry : array) { + destinations.add(String.valueOf(entry)); + } + } + + return new ShipState( + object.optString("shipName", "Zephyr"), + object.optString("helm", "CRACKED_SHIP_HELM"), + emptyToNull(object.optString("engine", "")), + object.optString("hull", "RUSTY_SHIP_HULL"), + destinations + ); + } + + @Override + public ShipState clone(ShipState value) { + return new ShipState( + value.getShipName(), + value.getHelm(), + value.getEngine(), + value.getHull(), + new ArrayList<>(value.getUnlockedDestinations()) + ); + } + }; + + public DatapointShipState(String key, ShipState value) { + super(key, value, serializer); + } + + public DatapointShipState(String key) { + this(key, new ShipState()); + } + + private static String emptyToNull(String value) { + return value == null || value.isEmpty() ? null : value; + } + + @Getter + @Setter + @NoArgsConstructor + @AllArgsConstructor + public static class ShipState { + private String shipName = "Zephyr"; + private String helm = "CRACKED_SHIP_HELM"; + private String engine = null; + private String hull = "RUSTY_SHIP_HULL"; + private List unlockedDestinations = new ArrayList<>(); + + public boolean hasDestination(String destinationId) { + return unlockedDestinations.contains(destinationId); + } + + public void unlockDestination(String destinationId) { + if (!unlockedDestinations.contains(destinationId)) { + unlockedDestinations.add(destinationId); + } + } + } +} diff --git a/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/data/datapoints/DatapointTrophyFish.java b/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/data/datapoints/DatapointTrophyFish.java new file mode 100644 index 000000000..4193ff3bf --- /dev/null +++ b/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/data/datapoints/DatapointTrophyFish.java @@ -0,0 +1,124 @@ +package net.swofty.type.skyblockgeneric.data.datapoints; + +import lombok.AllArgsConstructor; +import lombok.Getter; +import lombok.NoArgsConstructor; +import lombok.Setter; +import net.swofty.commons.protocol.Serializer; +import net.swofty.type.skyblockgeneric.data.SkyBlockDatapoint; +import org.json.JSONObject; + +import java.util.HashMap; +import java.util.Map; + +public class DatapointTrophyFish extends SkyBlockDatapoint { + private static final Serializer serializer = new Serializer<>() { + @Override + public String serialize(TrophyFishData value) { + JSONObject object = new JSONObject(); + JSONObject fishObject = new JSONObject(); + value.getFish().forEach((fishId, progress) -> { + JSONObject progressObject = new JSONObject(); + progressObject.put("bronze", progress.getBronze()); + progressObject.put("silver", progress.getSilver()); + progressObject.put("gold", progress.getGold()); + progressObject.put("diamond", progress.getDiamond()); + progressObject.put("totalCatches", progress.getTotalCatches()); + fishObject.put(fishId, progressObject); + }); + object.put("fish", fishObject); + return object.toString(); + } + + @Override + public TrophyFishData deserialize(String json) { + TrophyFishData data = new TrophyFishData(); + if (json == null || json.isEmpty()) { + return data; + } + + JSONObject object = new JSONObject(json); + JSONObject fishObject = object.optJSONObject("fish"); + if (fishObject == null) { + return data; + } + + for (String fishId : fishObject.keySet()) { + JSONObject progressObject = fishObject.getJSONObject(fishId); + data.getFish().put(fishId, new FishProgress( + progressObject.optInt("bronze", 0), + progressObject.optInt("silver", 0), + progressObject.optInt("gold", 0), + progressObject.optInt("diamond", 0), + progressObject.optInt("totalCatches", 0) + )); + } + return data; + } + + @Override + public TrophyFishData clone(TrophyFishData value) { + Map fish = new HashMap<>(); + value.getFish().forEach((fishId, progress) -> + fish.put(fishId, new FishProgress( + progress.getBronze(), + progress.getSilver(), + progress.getGold(), + progress.getDiamond(), + progress.getTotalCatches() + ))); + return new TrophyFishData(fish); + } + }; + + public DatapointTrophyFish(String key, TrophyFishData value) { + super(key, value, serializer); + } + + public DatapointTrophyFish(String key) { + this(key, new TrophyFishData()); + } + + @Getter + @Setter + @NoArgsConstructor + @AllArgsConstructor + public static class TrophyFishData { + private Map fish = new HashMap<>(); + + public FishProgress getProgress(String fishId) { + return fish.computeIfAbsent(fishId, ignored -> new FishProgress()); + } + } + + @Getter + @Setter + @NoArgsConstructor + @AllArgsConstructor + public static class FishProgress { + private int bronze; + private int silver; + private int gold; + private int diamond; + private int totalCatches; + + public void increment(String tier) { + switch (tier.toUpperCase()) { + case "DIAMOND" -> diamond++; + case "GOLD" -> gold++; + case "SILVER" -> silver++; + default -> bronze++; + } + totalCatches++; + } + + public boolean hasTier(String tier) { + return switch (tier.toUpperCase()) { + case "DIAMOND" -> diamond > 0; + case "GOLD" -> gold > 0; + case "SILVER" -> silver > 0; + default -> bronze > 0; + }; + } + } +} diff --git a/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/enchantment/EnchantmentType.java b/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/enchantment/EnchantmentType.java index f8e00c296..04ef2c121 100644 --- a/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/enchantment/EnchantmentType.java +++ b/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/enchantment/EnchantmentType.java @@ -27,6 +27,21 @@ public enum EnchantmentType { GIANT_KILLER(EnchantmentGiantKiller.class), EXECUTE(EnchantmentExecute.class), IMPALING(EnchantmentImpaling.class), + CASTER(EnchantmentCaster.class), + CHARM(EnchantmentCharm.class), + ANGLER(EnchantmentAngler.class), + BLESSING(EnchantmentBlessing.class), + CORRUPTION(EnchantmentCorruption.class), + EXPERTISE(EnchantmentExpertise.class), + FLASH(EnchantmentFlash.class), + FRAIL(EnchantmentFrail.class), + LUCK_OF_THE_SEA(EnchantmentLuckOfTheSea.class), + LURE(EnchantmentLure.class), + MAGNET(EnchantmentMagnet.class), + PISCARY(EnchantmentPiscary.class), + QUICK_BITE(EnchantmentQuickBite.class), + SPIKED_HOOK(EnchantmentSpikedHook.class), + TABASCO(EnchantmentTabasco.class), BANE_OF_ARTHROPODS(EnchantmentBaneOfArthropods.class), CUBISM(EnchantmentCubism.class), FORTUNE(EnchantmentFortune.class), diff --git a/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/enchantment/impl/EnchantmentAngler.java b/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/enchantment/impl/EnchantmentAngler.java new file mode 100644 index 000000000..7b9fa0371 --- /dev/null +++ b/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/enchantment/impl/EnchantmentAngler.java @@ -0,0 +1,58 @@ +package net.swofty.type.skyblockgeneric.enchantment.impl; + +import lombok.NonNull; +import net.swofty.commons.skyblock.statistics.ItemStatistic; +import net.swofty.commons.skyblock.statistics.ItemStatistics; +import net.swofty.type.skyblockgeneric.enchantment.abstr.Ench; +import net.swofty.type.skyblockgeneric.enchantment.abstr.EnchFromTable; +import net.swofty.type.skyblockgeneric.user.SkyBlockPlayer; +import net.swofty.type.skyblockgeneric.utility.groups.EnchantItemGroups; + +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +public class EnchantmentAngler implements Ench, EnchFromTable { + @Override + public String getDescription(int level) { + return "Grants §3+" + level + "% Sea Creature Chance§7."; + } + + @Override + public ItemStatistics getStatistics(int level) { + return ItemStatistics.builder().withBase(ItemStatistic.SEA_CREATURE_CHANCE, (double) level).build(); + } + + @Override + public ApplyLevels getLevelsToApply(@NonNull SkyBlockPlayer player) { + return new ApplyLevels(new HashMap<>(Map.of( + 1, 10, + 2, 20, + 3, 30, + 4, 40, + 5, 50, + 6, 100 + ))); + } + + @Override + public List getGroups() { + return List.of(EnchantItemGroups.FISHING_ROD); + } + + @Override + public TableLevels getLevelsFromTableToApply(@NonNull SkyBlockPlayer player) { + return new TableLevels(new HashMap<>(Map.of( + 1, 10, + 2, 20, + 3, 30, + 4, 40, + 5, 50 + ))); + } + + @Override + public int getRequiredBookshelfPower() { + return 0; + } +} diff --git a/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/enchantment/impl/EnchantmentBlessing.java b/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/enchantment/impl/EnchantmentBlessing.java new file mode 100644 index 000000000..15f7600b1 --- /dev/null +++ b/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/enchantment/impl/EnchantmentBlessing.java @@ -0,0 +1,51 @@ +package net.swofty.type.skyblockgeneric.enchantment.impl; + +import lombok.NonNull; +import net.swofty.type.skyblockgeneric.enchantment.abstr.Ench; +import net.swofty.type.skyblockgeneric.enchantment.abstr.EnchFromTable; +import net.swofty.type.skyblockgeneric.user.SkyBlockPlayer; +import net.swofty.type.skyblockgeneric.utility.groups.EnchantItemGroups; + +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +public class EnchantmentBlessing implements Ench, EnchFromTable { + @Override + public String getDescription(int level) { + return "Grants §a+" + (level * 5) + "%§7 chance for a better §6Treasure§7 quality outcome."; + } + + @Override + public ApplyLevels getLevelsToApply(@NonNull SkyBlockPlayer player) { + return new ApplyLevels(new HashMap<>(Map.of( + 1, 10, + 2, 20, + 3, 30, + 4, 40, + 5, 50, + 6, 100 + ))); + } + + @Override + public List getGroups() { + return List.of(EnchantItemGroups.FISHING_ROD); + } + + @Override + public TableLevels getLevelsFromTableToApply(@NonNull SkyBlockPlayer player) { + return new TableLevels(new HashMap<>(Map.of( + 1, 10, + 2, 20, + 3, 30, + 4, 40, + 5, 50 + ))); + } + + @Override + public int getRequiredBookshelfPower() { + return 0; + } +} diff --git a/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/enchantment/impl/EnchantmentCaster.java b/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/enchantment/impl/EnchantmentCaster.java new file mode 100644 index 000000000..57016d46b --- /dev/null +++ b/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/enchantment/impl/EnchantmentCaster.java @@ -0,0 +1,51 @@ +package net.swofty.type.skyblockgeneric.enchantment.impl; + +import lombok.NonNull; +import net.swofty.type.skyblockgeneric.enchantment.abstr.Ench; +import net.swofty.type.skyblockgeneric.enchantment.abstr.EnchFromTable; +import net.swofty.type.skyblockgeneric.user.SkyBlockPlayer; +import net.swofty.type.skyblockgeneric.utility.groups.EnchantItemGroups; + +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +public class EnchantmentCaster implements Ench, EnchFromTable { + @Override + public String getDescription(int level) { + return "§a" + (level * 5) + "%§7 chance to not consume bait."; + } + + @Override + public ApplyLevels getLevelsToApply(@NonNull SkyBlockPlayer player) { + return new ApplyLevels(new HashMap<>(Map.of( + 1, 10, + 2, 15, + 3, 20, + 4, 25, + 5, 30, + 6, 60 + ))); + } + + @Override + public List getGroups() { + return List.of(EnchantItemGroups.FISHING_ROD, EnchantItemGroups.FISHING_WEAPON); + } + + @Override + public TableLevels getLevelsFromTableToApply(@NonNull SkyBlockPlayer player) { + return new TableLevels(new HashMap<>(Map.of( + 1, 10, + 2, 15, + 3, 20, + 4, 25, + 5, 30 + ))); + } + + @Override + public int getRequiredBookshelfPower() { + return 0; + } +} diff --git a/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/enchantment/impl/EnchantmentCharm.java b/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/enchantment/impl/EnchantmentCharm.java new file mode 100644 index 000000000..0e771ba22 --- /dev/null +++ b/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/enchantment/impl/EnchantmentCharm.java @@ -0,0 +1,34 @@ +package net.swofty.type.skyblockgeneric.enchantment.impl; + +import lombok.NonNull; +import net.swofty.type.skyblockgeneric.enchantment.abstr.Ench; +import net.swofty.type.skyblockgeneric.user.SkyBlockPlayer; +import net.swofty.type.skyblockgeneric.utility.groups.EnchantItemGroups; + +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +public class EnchantmentCharm implements Ench { + @Override + public String getDescription(int level) { + return "§7Increases the chance to receive higher-tiered Trophy Fish by §a" + (level * 2) + "%§7."; + } + + @Override + public ApplyLevels getLevelsToApply(@NonNull SkyBlockPlayer player) { + return new ApplyLevels(new HashMap<>(Map.ofEntries( + Map.entry(1, 10), + Map.entry(2, 20), + Map.entry(3, 30), + Map.entry(4, 40), + Map.entry(5, 50), + Map.entry(6, 100) + ))); + } + + @Override + public List getGroups() { + return List.of(EnchantItemGroups.FISHING_ROD); + } +} diff --git a/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/enchantment/impl/EnchantmentCorruption.java b/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/enchantment/impl/EnchantmentCorruption.java new file mode 100644 index 000000000..ba7a17de2 --- /dev/null +++ b/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/enchantment/impl/EnchantmentCorruption.java @@ -0,0 +1,50 @@ +package net.swofty.type.skyblockgeneric.enchantment.impl; + +import lombok.NonNull; +import net.swofty.type.skyblockgeneric.enchantment.abstr.Ench; +import net.swofty.type.skyblockgeneric.enchantment.abstr.EnchFromTable; +import net.swofty.type.skyblockgeneric.user.SkyBlockPlayer; +import net.swofty.type.skyblockgeneric.utility.groups.EnchantItemGroups; + +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +public class EnchantmentCorruption implements Ench, EnchFromTable { + @Override + public String getDescription(int level) { + return "§a" + (level * 10) + "%§7 chance to summon a §5Corrupted §7variant of a caught §3Sea Creature§7."; + } + + @Override + public ApplyLevels getLevelsToApply(@NonNull SkyBlockPlayer player) { + return new ApplyLevels(new HashMap<>(Map.of( + 1, 5, + 2, 10, + 3, 15, + 4, 20, + 5, 50 + ))); + } + + @Override + public List getGroups() { + return List.of(EnchantItemGroups.FISHING_ROD); + } + + @Override + public TableLevels getLevelsFromTableToApply(@NonNull SkyBlockPlayer player) { + return new TableLevels(new HashMap<>(Map.of( + 1, 5, + 2, 10, + 3, 15, + 4, 20, + 5, 50 + ))); + } + + @Override + public int getRequiredBookshelfPower() { + return 10; + } +} diff --git a/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/enchantment/impl/EnchantmentExpertise.java b/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/enchantment/impl/EnchantmentExpertise.java new file mode 100644 index 000000000..4a3bbd78a --- /dev/null +++ b/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/enchantment/impl/EnchantmentExpertise.java @@ -0,0 +1,52 @@ +package net.swofty.type.skyblockgeneric.enchantment.impl; + +import lombok.NonNull; +import net.swofty.commons.skyblock.statistics.ItemStatistic; +import net.swofty.commons.skyblock.statistics.ItemStatistics; +import net.swofty.type.skyblockgeneric.enchantment.abstr.Ench; +import net.swofty.type.skyblockgeneric.user.SkyBlockPlayer; +import net.swofty.type.skyblockgeneric.utility.groups.EnchantItemGroups; + +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +public class EnchantmentExpertise implements Ench { + private static final double[] SEA_CREATURE_CHANCE_BONUS = { + 0.5, 1.0, 1.5, 2.0, 2.5, 3.0, 3.5, 4.0, 4.5, 5.0 + }; + + @Override + public String getDescription(int level) { + return "Tracks §3Sea Creature §7kills on this rod. Every kill grants §b+0.1☂ Fishing Wisdom§7. " + + "Current tier grants §3+" + SEA_CREATURE_CHANCE_BONUS[level - 1] + "% Sea Creature Chance§7."; + } + + @Override + public ItemStatistics getStatistics(int level) { + return ItemStatistics.builder() + .withBase(ItemStatistic.SEA_CREATURE_CHANCE, SEA_CREATURE_CHANCE_BONUS[level - 1]) + .build(); + } + + @Override + public ApplyLevels getLevelsToApply(@NonNull SkyBlockPlayer player) { + return new ApplyLevels(new HashMap<>(Map.of( + 1, 50, + 2, 100, + 3, 200, + 4, 400, + 5, 800, + 6, 1600, + 7, 3200, + 8, 6400, + 9, 12800, + 10, 25600 + ))); + } + + @Override + public List getGroups() { + return List.of(EnchantItemGroups.FISHING_ROD); + } +} diff --git a/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/enchantment/impl/EnchantmentFlash.java b/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/enchantment/impl/EnchantmentFlash.java new file mode 100644 index 000000000..12e0d1ec6 --- /dev/null +++ b/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/enchantment/impl/EnchantmentFlash.java @@ -0,0 +1,57 @@ +package net.swofty.type.skyblockgeneric.enchantment.impl; + +import lombok.NonNull; +import net.swofty.commons.skyblock.statistics.ItemStatistic; +import net.swofty.commons.skyblock.statistics.ItemStatistics; +import net.swofty.type.skyblockgeneric.enchantment.abstr.Ench; +import net.swofty.type.skyblockgeneric.enchantment.abstr.EnchFromTable; +import net.swofty.type.skyblockgeneric.user.SkyBlockPlayer; +import net.swofty.type.skyblockgeneric.utility.groups.EnchantItemGroups; + +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +public class EnchantmentFlash implements Ench, EnchFromTable { + @Override + public String getDescription(int level) { + return "Grants §b+" + (level * 5) + "☂ Fishing Speed§7."; + } + + @Override + public ItemStatistics getStatistics(int level) { + return ItemStatistics.builder().withBase(ItemStatistic.FISHING_SPEED, level * 5.0).build(); + } + + @Override + public ApplyLevels getLevelsToApply(@NonNull SkyBlockPlayer player) { + return new ApplyLevels(new HashMap<>(Map.of( + 1, 10, + 2, 20, + 3, 30, + 4, 60, + 5, 100 + ))); + } + + @Override + public List getGroups() { + return List.of(EnchantItemGroups.FISHING_ROD); + } + + @Override + public TableLevels getLevelsFromTableToApply(@NonNull SkyBlockPlayer player) { + return new TableLevels(new HashMap<>(Map.of( + 1, 10, + 2, 20, + 3, 30, + 4, 60, + 5, 100 + ))); + } + + @Override + public int getRequiredBookshelfPower() { + return 0; + } +} diff --git a/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/enchantment/impl/EnchantmentFrail.java b/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/enchantment/impl/EnchantmentFrail.java new file mode 100644 index 000000000..aa9c437a8 --- /dev/null +++ b/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/enchantment/impl/EnchantmentFrail.java @@ -0,0 +1,52 @@ +package net.swofty.type.skyblockgeneric.enchantment.impl; + +import lombok.NonNull; +import net.swofty.type.skyblockgeneric.enchantment.abstr.Ench; +import net.swofty.type.skyblockgeneric.enchantment.abstr.EnchFromTable; +import net.swofty.type.skyblockgeneric.user.SkyBlockPlayer; +import net.swofty.type.skyblockgeneric.utility.groups.EnchantItemGroups; + +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +public class EnchantmentFrail implements Ench, EnchFromTable { + @Override + public String getDescription(int level) { + return "Reduces the defense of §3Sea Creatures §7you hit by §a" + (level * 10) + "%§7."; + } + + @Override + public ApplyLevels getLevelsToApply(@NonNull SkyBlockPlayer player) { + return new ApplyLevels(new HashMap<>(Map.of( + 1, 10, + 2, 20, + 3, 30, + 4, 40, + 5, 50, + 6, 80, + 7, 120 + ))); + } + + @Override + public List getGroups() { + return List.of(EnchantItemGroups.FISHING_ROD, EnchantItemGroups.FISHING_WEAPON); + } + + @Override + public TableLevels getLevelsFromTableToApply(@NonNull SkyBlockPlayer player) { + return new TableLevels(new HashMap<>(Map.of( + 1, 10, + 2, 20, + 3, 30, + 4, 40, + 5, 50 + ))); + } + + @Override + public int getRequiredBookshelfPower() { + return 0; + } +} diff --git a/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/enchantment/impl/EnchantmentLuckOfTheSea.java b/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/enchantment/impl/EnchantmentLuckOfTheSea.java new file mode 100644 index 000000000..4ed33f8b0 --- /dev/null +++ b/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/enchantment/impl/EnchantmentLuckOfTheSea.java @@ -0,0 +1,59 @@ +package net.swofty.type.skyblockgeneric.enchantment.impl; + +import lombok.NonNull; +import net.swofty.commons.skyblock.statistics.ItemStatistic; +import net.swofty.commons.skyblock.statistics.ItemStatistics; +import net.swofty.type.skyblockgeneric.enchantment.abstr.Ench; +import net.swofty.type.skyblockgeneric.enchantment.abstr.EnchFromTable; +import net.swofty.type.skyblockgeneric.user.SkyBlockPlayer; +import net.swofty.type.skyblockgeneric.utility.groups.EnchantItemGroups; + +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +public class EnchantmentLuckOfTheSea implements Ench, EnchFromTable { + @Override + public String getDescription(int level) { + return "Grants §b+" + level + "✯ Magic Find§7."; + } + + @Override + public ItemStatistics getStatistics(int level) { + return ItemStatistics.builder().withBase(ItemStatistic.MAGIC_FIND, (double) level).build(); + } + + @Override + public ApplyLevels getLevelsToApply(@NonNull SkyBlockPlayer player) { + return new ApplyLevels(new HashMap<>(Map.of( + 1, 10, + 2, 20, + 3, 30, + 4, 40, + 5, 50, + 6, 80, + 7, 120 + ))); + } + + @Override + public List getGroups() { + return List.of(EnchantItemGroups.FISHING_ROD); + } + + @Override + public TableLevels getLevelsFromTableToApply(@NonNull SkyBlockPlayer player) { + return new TableLevels(new HashMap<>(Map.of( + 1, 10, + 2, 20, + 3, 30, + 4, 40, + 5, 50 + ))); + } + + @Override + public int getRequiredBookshelfPower() { + return 0; + } +} diff --git a/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/enchantment/impl/EnchantmentLure.java b/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/enchantment/impl/EnchantmentLure.java new file mode 100644 index 000000000..daaf8248e --- /dev/null +++ b/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/enchantment/impl/EnchantmentLure.java @@ -0,0 +1,58 @@ +package net.swofty.type.skyblockgeneric.enchantment.impl; + +import lombok.NonNull; +import net.swofty.commons.skyblock.statistics.ItemStatistic; +import net.swofty.commons.skyblock.statistics.ItemStatistics; +import net.swofty.type.skyblockgeneric.enchantment.abstr.Ench; +import net.swofty.type.skyblockgeneric.enchantment.abstr.EnchFromTable; +import net.swofty.type.skyblockgeneric.user.SkyBlockPlayer; +import net.swofty.type.skyblockgeneric.utility.groups.EnchantItemGroups; + +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +public class EnchantmentLure implements Ench, EnchFromTable { + @Override + public String getDescription(int level) { + return "Grants §b+" + (level * 4) + "☂ Fishing Speed§7."; + } + + @Override + public ItemStatistics getStatistics(int level) { + return ItemStatistics.builder().withBase(ItemStatistic.FISHING_SPEED, level * 4.0).build(); + } + + @Override + public ApplyLevels getLevelsToApply(@NonNull SkyBlockPlayer player) { + return new ApplyLevels(new HashMap<>(Map.of( + 1, 10, + 2, 20, + 3, 30, + 4, 40, + 5, 50, + 6, 100 + ))); + } + + @Override + public List getGroups() { + return List.of(EnchantItemGroups.FISHING_ROD); + } + + @Override + public TableLevels getLevelsFromTableToApply(@NonNull SkyBlockPlayer player) { + return new TableLevels(new HashMap<>(Map.of( + 1, 10, + 2, 20, + 3, 30, + 4, 40, + 5, 50 + ))); + } + + @Override + public int getRequiredBookshelfPower() { + return 0; + } +} diff --git a/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/enchantment/impl/EnchantmentMagnet.java b/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/enchantment/impl/EnchantmentMagnet.java new file mode 100644 index 000000000..ec27affd3 --- /dev/null +++ b/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/enchantment/impl/EnchantmentMagnet.java @@ -0,0 +1,51 @@ +package net.swofty.type.skyblockgeneric.enchantment.impl; + +import lombok.NonNull; +import net.swofty.type.skyblockgeneric.enchantment.abstr.Ench; +import net.swofty.type.skyblockgeneric.enchantment.abstr.EnchFromTable; +import net.swofty.type.skyblockgeneric.user.SkyBlockPlayer; +import net.swofty.type.skyblockgeneric.utility.groups.EnchantItemGroups; + +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +public class EnchantmentMagnet implements Ench, EnchFromTable { + @Override + public String getDescription(int level) { + return "Instantly pulls nearby items to you within §a" + (level * 2) + " §7blocks."; + } + + @Override + public ApplyLevels getLevelsToApply(@NonNull SkyBlockPlayer player) { + return new ApplyLevels(new HashMap<>(Map.of( + 1, 10, + 2, 20, + 3, 30, + 4, 40, + 5, 50, + 6, 100 + ))); + } + + @Override + public List getGroups() { + return List.of(EnchantItemGroups.FISHING_ROD); + } + + @Override + public TableLevels getLevelsFromTableToApply(@NonNull SkyBlockPlayer player) { + return new TableLevels(new HashMap<>(Map.of( + 1, 10, + 2, 20, + 3, 30, + 4, 40, + 5, 50 + ))); + } + + @Override + public int getRequiredBookshelfPower() { + return 0; + } +} diff --git a/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/enchantment/impl/EnchantmentPiscary.java b/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/enchantment/impl/EnchantmentPiscary.java new file mode 100644 index 000000000..dd76b4ee5 --- /dev/null +++ b/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/enchantment/impl/EnchantmentPiscary.java @@ -0,0 +1,59 @@ +package net.swofty.type.skyblockgeneric.enchantment.impl; + +import lombok.NonNull; +import net.swofty.commons.skyblock.statistics.ItemStatistic; +import net.swofty.commons.skyblock.statistics.ItemStatistics; +import net.swofty.type.skyblockgeneric.enchantment.abstr.Ench; +import net.swofty.type.skyblockgeneric.enchantment.abstr.EnchFromTable; +import net.swofty.type.skyblockgeneric.user.SkyBlockPlayer; +import net.swofty.type.skyblockgeneric.utility.groups.EnchantItemGroups; + +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +public class EnchantmentPiscary implements Ench, EnchFromTable { + @Override + public String getDescription(int level) { + return "Grants §6+" + level + "% Trophy Fish Chance§7."; + } + + @Override + public ItemStatistics getStatistics(int level) { + return ItemStatistics.builder().withBase(ItemStatistic.TROPHY_FISH_CHANCE, (double) level).build(); + } + + @Override + public ApplyLevels getLevelsToApply(@NonNull SkyBlockPlayer player) { + return new ApplyLevels(new HashMap<>(Map.of( + 1, 10, + 2, 20, + 3, 30, + 4, 40, + 5, 50, + 6, 80, + 7, 120 + ))); + } + + @Override + public List getGroups() { + return List.of(EnchantItemGroups.FISHING_ROD); + } + + @Override + public TableLevels getLevelsFromTableToApply(@NonNull SkyBlockPlayer player) { + return new TableLevels(new HashMap<>(Map.of( + 1, 10, + 2, 20, + 3, 30, + 4, 40, + 5, 50 + ))); + } + + @Override + public int getRequiredBookshelfPower() { + return 0; + } +} diff --git a/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/enchantment/impl/EnchantmentQuickBite.java b/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/enchantment/impl/EnchantmentQuickBite.java new file mode 100644 index 000000000..d2331abb3 --- /dev/null +++ b/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/enchantment/impl/EnchantmentQuickBite.java @@ -0,0 +1,50 @@ +package net.swofty.type.skyblockgeneric.enchantment.impl; + +import lombok.NonNull; +import net.swofty.type.skyblockgeneric.enchantment.abstr.Ench; +import net.swofty.type.skyblockgeneric.enchantment.abstr.EnchFromTable; +import net.swofty.type.skyblockgeneric.user.SkyBlockPlayer; +import net.swofty.type.skyblockgeneric.utility.groups.EnchantItemGroups; + +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +public class EnchantmentQuickBite implements Ench, EnchFromTable { + @Override + public String getDescription(int level) { + return "Decreases the time for your hook to get a bite by §a" + (level * 5) + "%§7."; + } + + @Override + public ApplyLevels getLevelsToApply(@NonNull SkyBlockPlayer player) { + return new ApplyLevels(new HashMap<>(Map.of( + 1, 20, + 2, 40, + 3, 60, + 4, 80, + 5, 100 + ))); + } + + @Override + public List getGroups() { + return List.of(EnchantItemGroups.FISHING_ROD); + } + + @Override + public TableLevels getLevelsFromTableToApply(@NonNull SkyBlockPlayer player) { + return new TableLevels(new HashMap<>(Map.of( + 1, 20, + 2, 40, + 3, 60, + 4, 80, + 5, 100 + ))); + } + + @Override + public int getRequiredBookshelfPower() { + return 5; + } +} diff --git a/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/enchantment/impl/EnchantmentSpikedHook.java b/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/enchantment/impl/EnchantmentSpikedHook.java new file mode 100644 index 000000000..719ee96e8 --- /dev/null +++ b/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/enchantment/impl/EnchantmentSpikedHook.java @@ -0,0 +1,52 @@ +package net.swofty.type.skyblockgeneric.enchantment.impl; + +import lombok.NonNull; +import net.swofty.type.skyblockgeneric.enchantment.abstr.Ench; +import net.swofty.type.skyblockgeneric.enchantment.abstr.EnchFromTable; +import net.swofty.type.skyblockgeneric.user.SkyBlockPlayer; +import net.swofty.type.skyblockgeneric.utility.groups.EnchantItemGroups; + +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +public class EnchantmentSpikedHook implements Ench, EnchFromTable { + @Override + public String getDescription(int level) { + return "Deals §a" + (level * 5) + "%§7 more damage to §3Sea Creatures§7."; + } + + @Override + public ApplyLevels getLevelsToApply(@NonNull SkyBlockPlayer player) { + return new ApplyLevels(new HashMap<>(Map.of( + 1, 10, + 2, 20, + 3, 30, + 4, 40, + 5, 50, + 6, 80, + 7, 120 + ))); + } + + @Override + public List getGroups() { + return List.of(EnchantItemGroups.FISHING_ROD, EnchantItemGroups.FISHING_WEAPON); + } + + @Override + public TableLevels getLevelsFromTableToApply(@NonNull SkyBlockPlayer player) { + return new TableLevels(new HashMap<>(Map.of( + 1, 10, + 2, 20, + 3, 30, + 4, 40, + 5, 50 + ))); + } + + @Override + public int getRequiredBookshelfPower() { + return 0; + } +} diff --git a/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/enchantment/impl/EnchantmentTabasco.java b/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/enchantment/impl/EnchantmentTabasco.java new file mode 100644 index 000000000..2becbc3e5 --- /dev/null +++ b/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/enchantment/impl/EnchantmentTabasco.java @@ -0,0 +1,53 @@ +package net.swofty.type.skyblockgeneric.enchantment.impl; + +import lombok.NonNull; +import net.swofty.commons.skyblock.statistics.ItemStatistic; +import net.swofty.commons.skyblock.statistics.ItemStatistics; +import net.swofty.type.skyblockgeneric.enchantment.abstr.Ench; +import net.swofty.type.skyblockgeneric.enchantment.abstr.EnchFromTable; +import net.swofty.type.skyblockgeneric.user.SkyBlockPlayer; +import net.swofty.type.skyblockgeneric.utility.groups.EnchantItemGroups; + +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +public class EnchantmentTabasco implements Ench, EnchFromTable { + @Override + public String getDescription(int level) { + return "Grants §6+" + (level * 5) + "% Trophy Fish Chance §7while fishing in §clava§7."; + } + + @Override + public ItemStatistics getStatistics(int level) { + return ItemStatistics.builder().withBase(ItemStatistic.TROPHY_FISH_CHANCE, level * 5.0).build(); + } + + @Override + public ApplyLevels getLevelsToApply(@NonNull SkyBlockPlayer player) { + return new ApplyLevels(new HashMap<>(Map.of( + 1, 20, + 2, 40, + 3, 80 + ))); + } + + @Override + public List getGroups() { + return List.of(EnchantItemGroups.FISHING_ROD); + } + + @Override + public TableLevels getLevelsFromTableToApply(@NonNull SkyBlockPlayer player) { + return new TableLevels(new HashMap<>(Map.of( + 1, 20, + 2, 40, + 3, 80 + ))); + } + + @Override + public int getRequiredBookshelfPower() { + return 15; + } +} diff --git a/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/entity/FishingHook.java b/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/entity/FishingHook.java index 93033b42f..1686e8a5d 100644 --- a/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/entity/FishingHook.java +++ b/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/entity/FishingHook.java @@ -6,7 +6,6 @@ import net.minestom.server.coordinate.Pos; import net.minestom.server.entity.Entity; import net.minestom.server.entity.EntityType; -import net.minestom.server.entity.Player; import net.minestom.server.entity.metadata.other.FishingHookMeta; import net.minestom.server.event.entity.EntityTickEvent; import net.minestom.server.instance.Instance; @@ -16,6 +15,15 @@ import net.minestom.server.particle.Particle; import net.minestom.server.sound.SoundEvent; import net.minestom.server.timer.Scheduler; +import net.minestom.server.timer.Task; +import net.minestom.server.timer.TaskSchedule; +import net.swofty.type.skyblockgeneric.fishing.BaitDefinition; +import net.swofty.type.skyblockgeneric.fishing.FishingItemCatalog; +import net.swofty.type.skyblockgeneric.fishing.FishingMedium; +import net.swofty.type.skyblockgeneric.fishing.FishingService; +import net.swofty.type.skyblockgeneric.fishing.FishingSession; +import net.swofty.type.skyblockgeneric.item.SkyBlockItem; +import net.swofty.type.skyblockgeneric.user.SkyBlockPlayer; import org.jetbrains.annotations.NotNull; import java.util.ArrayList; @@ -32,7 +40,10 @@ public class FishingHook { private static final double PULL_DOWN_RECOVERY_SPEED = 0.016666666666666666; private static final double CONTROLLER_DRAG = 0.2; private static final double WATER_CHECK_OFFSET = -0.2; - private final Player owner; + private static final long BITE_WINDOW_TICKS = 20L; + private final SkyBlockPlayer owner; + private final SkyBlockItem rod; + private final FishingMedium requiredMedium; private final Entity hook; private final Entity controller; @Getter @@ -40,9 +51,16 @@ public class FishingHook { private double bobTick = 0; private double pullDownOffset = 0; private Double stableWaterY = null; + private Task nextBiteTask; + private Task biteExpiryTask; + private boolean sessionStarted = false; - public FishingHook(Player owner) { + public FishingHook(SkyBlockPlayer owner, SkyBlockItem rod) { this.owner = owner; + this.rod = rod; + String itemId = rod.getAttributeHandler().getPotentialType() == null ? null : rod.getAttributeHandler().getPotentialType().name(); + var rodDefinition = FishingItemCatalog.getRod(itemId); + this.requiredMedium = rodDefinition == null ? FishingMedium.WATER : rodDefinition.medium(); this.hook = new Entity(EntityType.FISHING_BOBBER); this.hook.editEntityMeta(FishingHookMeta.class, meta -> { @@ -56,7 +74,7 @@ public FishingHook(Player owner) { event -> tick(event.getEntity())); } - public static FishingHook getFishingHookForOwner(@NotNull Player owner) { + public static FishingHook getFishingHookForOwner(@NotNull SkyBlockPlayer owner) { for (FishingHook fishingHook : activeHooks) { if (fishingHook.owner.getUuid().equals(owner.getUuid())) { return fishingHook; @@ -65,8 +83,15 @@ public static FishingHook getFishingHookForOwner(@NotNull Player owner) { return null; } - private static boolean isNotWater(@NotNull Block block) { - return !block.isLiquid() || !block.name().contains("water"); + private static boolean blockMatchesMedium(@NotNull Block block, @NotNull FishingMedium medium) { + if (!block.isLiquid()) { + return false; + } + String blockName = block.name(); + return switch (medium) { + case WATER -> blockName.contains("water"); + case LAVA -> blockName.contains("lava"); + }; } public void spawn(Instance instance) { @@ -115,7 +140,24 @@ private void tick(@NotNull Entity controller) { return; } - // Hook is in water + FishingMedium mediumAtHook = getCurrentMedium(); + if (mediumAtHook == null) { + if (sessionStarted) { + FishingService.clearSession(owner.getUuid()); + sessionStarted = false; + } + stableWaterY = null; + cancelBiteTasks(); + controller.setNoGravity(false); + return; + } + + if (mediumAtHook != requiredMedium) { + remove(); + return; + } + + // Hook is in valid fishing liquid controller.setNoGravity(true); Block blockBelow = instance.getBlock(pos.add(0, WATER_CHECK_OFFSET, 0)); @@ -138,6 +180,7 @@ private void tick(@NotNull Entity controller) { new Pos(0.1, 0.001, 0.1), 0, 5 )); + startFishingSession(); } bobTick += BOB_SPEED; @@ -154,15 +197,8 @@ private void tick(@NotNull Entity controller) { public boolean notInWater() { Instance instance = controller.getInstance(); Pos pos = controller.getPosition(); - // Check the block at the entity's precise location - Block currentBlock = instance.getBlock(pos); - - // Check the block slightly below the entity's location - Block blockBelow = instance.getBlock(pos.add(0, WATER_CHECK_OFFSET, 0)); - - // The hook is considered "in water" if either its current block OR - // the block directly below it is water. - return isNotWater(currentBlock) && isNotWater(blockBelow); + return getMedium(instance.getBlock(pos)) == null + && getMedium(instance.getBlock(pos.add(0, WATER_CHECK_OFFSET, 0))) == null; } public void showBiteAnimation() { @@ -189,10 +225,21 @@ public void remove() { activeHooks.remove(this); if (this.isRemoved) return; this.isRemoved = true; + cancelBiteTasks(); + FishingService.clearSession(owner.getUuid()); hook.remove(); controller.remove(); } + public void tryRetrieve(SkyBlockItem rodInHand) { + FishingSession session = FishingService.getSession(owner.getUuid()); + if (session == null || !session.biteReady() || System.currentTimeMillis() > session.biteWindowEndsAt()) { + return; + } + + FishingService.resolveCatch(owner, rodInHand, this); + } + private double getWaterSurface(Block block, int blockY) { if (!block.isLiquid()) return blockY + 1.0; @@ -209,4 +256,85 @@ public Scheduler getScheduler() { public Instance getInstance() { return controller.getInstance(); } -} \ No newline at end of file + + public Pos getSpawnPosition() { + return controller.getPosition(); + } + + private void startFishingSession() { + if (sessionStarted) { + return; + } + + FishingSession session = FishingService.beginCast(owner, rod, requiredMedium); + sessionStarted = true; + BaitDefinition bait = FishingItemCatalog.getBait(session.baitItemId()); + long waitTicks = FishingService.computeWaitTicks(owner, rod, bait); + scheduleNextBite(waitTicks); + } + + private void scheduleNextBite(long delayTicks) { + cancelBiteTasks(); + nextBiteTask = hook.scheduler().buildTask(() -> { + if (isRemoved || notInWater()) { + return; + } + + FishingSession session = FishingService.getSession(owner.getUuid()); + if (session == null || session.resolved()) { + return; + } + + long now = System.currentTimeMillis(); + FishingService.updateSession(session.withBiteTiming(now, now + (BITE_WINDOW_TICKS * 50)).withBiteReady(true)); + showBiteAnimation(); + + biteExpiryTask = hook.scheduler().buildTask(() -> { + FishingSession activeSession = FishingService.getSession(owner.getUuid()); + if (activeSession == null || activeSession.resolved() || isRemoved) { + return; + } + + FishingService.updateSession(activeSession.withBiteReady(false)); + BaitDefinition bait = FishingItemCatalog.getBait(activeSession.baitItemId()); + long nextDelay = FishingService.computeWaitTicks(owner, rod, bait); + scheduleNextBite(nextDelay); + }).delay(TaskSchedule.tick((int) BITE_WINDOW_TICKS)).schedule(); + }).delay(TaskSchedule.tick((int) delayTicks)).schedule(); + } + + private void cancelBiteTasks() { + if (nextBiteTask != null) { + nextBiteTask.cancel(); + nextBiteTask = null; + } + if (biteExpiryTask != null) { + biteExpiryTask.cancel(); + biteExpiryTask = null; + } + } + + private FishingMedium getCurrentMedium() { + Instance instance = controller.getInstance(); + if (instance == null) { + return null; + } + + Pos pos = controller.getPosition(); + FishingMedium current = getMedium(instance.getBlock(pos)); + if (current != null) { + return current; + } + return getMedium(instance.getBlock(pos.add(0, WATER_CHECK_OFFSET, 0))); + } + + private FishingMedium getMedium(Block block) { + if (blockMatchesMedium(block, FishingMedium.WATER)) { + return FishingMedium.WATER; + } + if (blockMatchesMedium(block, FishingMedium.LAVA)) { + return FishingMedium.LAVA; + } + return null; + } +} diff --git a/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/fishing/BaitDefinition.java b/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/fishing/BaitDefinition.java new file mode 100644 index 000000000..a3266fd4c --- /dev/null +++ b/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/fishing/BaitDefinition.java @@ -0,0 +1,22 @@ +package net.swofty.type.skyblockgeneric.fishing; + +import net.swofty.commons.skyblock.statistics.ItemStatistics; +import org.jetbrains.annotations.Nullable; + +import java.util.List; +import java.util.Map; + +public record BaitDefinition( + String itemId, + String displayName, + ItemStatistics statistics, + List lore, + Map tagBonuses, + double treasureChanceBonus, + double treasureQualityBonus, + double trophyFishChanceBonus, + double doubleHookChanceBonus, + List mediums, + @Nullable String texture +) { +} diff --git a/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/fishing/FishingBaitService.java b/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/fishing/FishingBaitService.java new file mode 100644 index 000000000..3a0f8e48d --- /dev/null +++ b/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/fishing/FishingBaitService.java @@ -0,0 +1,54 @@ +package net.swofty.type.skyblockgeneric.fishing; + +import net.minestom.server.item.ItemStack; +import net.swofty.commons.skyblock.item.ItemType; +import net.swofty.type.skyblockgeneric.item.SkyBlockItem; +import net.swofty.type.skyblockgeneric.item.updater.PlayerItemUpdater; +import net.swofty.type.skyblockgeneric.user.SkyBlockPlayer; +import org.jetbrains.annotations.Nullable; + +public final class FishingBaitService { + private FishingBaitService() { + } + + public static @Nullable BaitDefinition getFirstAvailableBait(SkyBlockPlayer player, FishingMedium medium) { + for (int slot = 0; slot < 36; slot++) { + SkyBlockItem item = new SkyBlockItem(player.getInventory().getItemStack(slot)); + ItemType type = item.getAttributeHandler().getPotentialType(); + if (type == null) { + continue; + } + + BaitDefinition bait = FishingItemCatalog.getBait(type.name()); + if (bait == null) { + continue; + } + if (!bait.mediums().isEmpty() && !bait.mediums().contains(medium)) { + continue; + } + return bait; + } + return null; + } + + public static boolean consumeOneBait(SkyBlockPlayer player, String baitItemId) { + for (int slot = 0; slot < 36; slot++) { + SkyBlockItem item = new SkyBlockItem(player.getInventory().getItemStack(slot)); + if (item.getAttributeHandler().getPotentialType() == null) { + continue; + } + if (!item.getAttributeHandler().getPotentialType().name().equals(baitItemId)) { + continue; + } + + if (item.getAmount() > 1) { + item.setAmount(item.getAmount() - 1); + player.getInventory().setItemStack(slot, PlayerItemUpdater.playerUpdate(player, item.getItemStack()).build()); + } else { + player.getInventory().setItemStack(slot, ItemStack.AIR); + } + return true; + } + return false; + } +} diff --git a/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/fishing/FishingCatchKind.java b/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/fishing/FishingCatchKind.java new file mode 100644 index 000000000..2ec736f53 --- /dev/null +++ b/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/fishing/FishingCatchKind.java @@ -0,0 +1,10 @@ +package net.swofty.type.skyblockgeneric.fishing; + +public enum FishingCatchKind { + ITEM, + TREASURE, + SEA_CREATURE, + TROPHY_FISH, + QUEST, + SPECIAL +} diff --git a/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/fishing/FishingCatchResolver.java b/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/fishing/FishingCatchResolver.java new file mode 100644 index 000000000..f6a935071 --- /dev/null +++ b/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/fishing/FishingCatchResolver.java @@ -0,0 +1,10 @@ +package net.swofty.type.skyblockgeneric.fishing; + +public final class FishingCatchResolver { + private FishingCatchResolver() { + } + + public static FishingCatchResult resolve(FishingContext context) { + return FishingLootResolver.resolve(context); + } +} diff --git a/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/fishing/FishingCatchResult.java b/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/fishing/FishingCatchResult.java new file mode 100644 index 000000000..79d2ce265 --- /dev/null +++ b/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/fishing/FishingCatchResult.java @@ -0,0 +1,15 @@ +package net.swofty.type.skyblockgeneric.fishing; + +import org.jetbrains.annotations.Nullable; + +public record FishingCatchResult( + FishingCatchKind kind, + @Nullable String itemId, + @Nullable String seaCreatureId, + @Nullable String trophyFishId, + int amount, + double skillXp, + boolean corrupted, + @Nullable String message +) { +} diff --git a/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/fishing/FishingContext.java b/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/fishing/FishingContext.java new file mode 100644 index 000000000..9525d40df --- /dev/null +++ b/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/fishing/FishingContext.java @@ -0,0 +1,21 @@ +package net.swofty.type.skyblockgeneric.fishing; + +import net.swofty.commons.skyblock.statistics.ItemStatistics; +import net.swofty.type.skyblockgeneric.item.SkyBlockItem; +import net.swofty.type.skyblockgeneric.user.SkyBlockPlayer; +import org.jetbrains.annotations.Nullable; + +public record FishingContext( + SkyBlockPlayer player, + SkyBlockItem rod, + FishingMedium medium, + @Nullable BaitDefinition bait, + @Nullable RodPartDefinition hook, + @Nullable RodPartDefinition line, + @Nullable RodPartDefinition sinker, + @Nullable String regionId, + boolean hotspotActive, + ItemStatistics hotspotBuffs, + long castDurationMs +) { +} diff --git a/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/fishing/FishingHotspotService.java b/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/fishing/FishingHotspotService.java new file mode 100644 index 000000000..7fb4a1a1b --- /dev/null +++ b/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/fishing/FishingHotspotService.java @@ -0,0 +1,69 @@ +package net.swofty.type.skyblockgeneric.fishing; + +import net.minestom.server.coordinate.Pos; +import net.swofty.commons.skyblock.statistics.ItemStatistic; +import net.swofty.commons.skyblock.statistics.ItemStatistics; +import net.swofty.type.generic.HypixelConst; +import net.swofty.type.skyblockgeneric.region.SkyBlockRegion; +import net.swofty.type.skyblockgeneric.user.SkyBlockPlayer; + +public final class FishingHotspotService { + private static final double HOTSPOT_RADIUS_SQUARED = 25.0D; + + private FishingHotspotService() { + } + + public static boolean isBobberInHotspot(SkyBlockPlayer player, FishingMedium medium, Pos bobberPos) { + ItemStatistics buffs = getActiveHotspotBuffs(player, medium, bobberPos); + for (ItemStatistic statistic : ItemStatistic.values()) { + if (buffs.getOverall(statistic) != 0.0D) { + return true; + } + } + return false; + } + + public static ItemStatistics getActiveHotspotBuffs(SkyBlockPlayer player, FishingMedium medium, Pos bobberPos) { + String serverType = HypixelConst.getTypeLoader().getType().name(); + SkyBlockRegion playerRegion = player.getRegion(); + String regionId = playerRegion == null ? null : playerRegion.getType().name(); + + ItemStatistics.Builder builder = ItemStatistics.builder(); + for (HotspotDefinition hotspot : FishingRegistry.getHotspots()) { + if (hotspot.medium() != medium) { + continue; + } + if (!hotspot.regions().isEmpty() && (regionId == null || !hotspot.regions().contains(regionId))) { + continue; + } + if (!matchesAnyPoint(serverType, bobberPos, hotspot)) { + continue; + } + + for (ItemStatistic statistic : ItemStatistic.values()) { + double value = hotspot.buffs().getOverall(statistic); + if (value != 0.0D) { + builder.withBase(statistic, value); + } + } + } + return builder.build(); + } + + private static boolean matchesAnyPoint(String serverType, Pos bobberPos, HotspotDefinition hotspot) { + for (HotspotDefinition.SpawnPoint point : hotspot.spawnPoints()) { + if (point.serverType() != null && !point.serverType().equals(serverType)) { + continue; + } + double dx = bobberPos.x() - point.x(); + double dy = bobberPos.y() - point.y(); + double dz = bobberPos.z() - point.z(); + if ((dx * dx) + (dy * dy) + (dz * dz) <= HOTSPOT_RADIUS_SQUARED) { + return true; + } + } + return false; + } +} + + diff --git a/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/fishing/FishingItemBootstrap.java b/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/fishing/FishingItemBootstrap.java new file mode 100644 index 000000000..f2fd40efa --- /dev/null +++ b/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/fishing/FishingItemBootstrap.java @@ -0,0 +1,25 @@ +package net.swofty.type.skyblockgeneric.fishing; + +import net.swofty.type.skyblockgeneric.enchantment.SkyBlockEnchantment; +import net.swofty.type.skyblockgeneric.item.SkyBlockItem; + +public final class FishingItemBootstrap { + private FishingItemBootstrap() { + } + + public static void applyDefaults(SkyBlockItem item) { + if (item.getAttributeHandler().getPotentialType() == null) { + return; + } + + FishingRodDefinition definition = FishingItemCatalog.getRod(item.getAttributeHandler().getPotentialType().name()); + if (definition == null) { + return; + } + + if (item.getAttributeHandler().getEnchantments().findAny().isEmpty()) { + definition.enchantments().forEach((type, level) -> + item.getAttributeHandler().addEnchantment(new SkyBlockEnchantment(type, level))); + } + } +} diff --git a/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/fishing/FishingItemCatalog.java b/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/fishing/FishingItemCatalog.java new file mode 100644 index 000000000..2942d7f7e --- /dev/null +++ b/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/fishing/FishingItemCatalog.java @@ -0,0 +1,160 @@ +package net.swofty.type.skyblockgeneric.fishing; + +import net.swofty.commons.skyblock.item.ItemType; +import net.swofty.type.skyblockgeneric.item.ConfigurableSkyBlockItem; +import net.swofty.type.skyblockgeneric.item.components.FishingBaitComponent; +import net.swofty.type.skyblockgeneric.item.components.FishingRodMetadataComponent; +import net.swofty.type.skyblockgeneric.item.components.FishingRodPartComponent; +import net.swofty.type.skyblockgeneric.item.components.FishingShipPartComponent; +import org.jetbrains.annotations.Nullable; + +import java.util.Arrays; +import java.util.Comparator; +import java.util.List; +import java.util.Objects; + +public final class FishingItemCatalog { + private FishingItemCatalog() { + } + + public static @Nullable FishingRodDefinition getRod(@Nullable String itemId) { + if (itemId == null) { + return null; + } + + ConfigurableSkyBlockItem item = ConfigurableSkyBlockItem.getFromID(itemId); + if (item == null || !item.hasComponent(FishingRodMetadataComponent.class)) { + return null; + } + + FishingRodMetadataComponent component = item.getComponent(FishingRodMetadataComponent.class); + return new FishingRodDefinition( + itemId, + component.getDisplayName(), + component.getSubtitle(), + component.getMedium(), + component.getRequiredFishingLevel(), + item.getDefaultStatistics(), + component.getEnchantments(), + item.getLore(), + component.getLegacyConversionTarget(), + component.getLegacyConversionPart(), + component.isRodPartsEnabled() + ); + } + + public static @Nullable RodPartDefinition getRodPart(@Nullable String itemId) { + if (itemId == null) { + return null; + } + + ConfigurableSkyBlockItem item = ConfigurableSkyBlockItem.getFromID(itemId); + if (item == null || !item.hasComponent(FishingRodPartComponent.class)) { + return null; + } + + FishingRodPartComponent component = item.getComponent(FishingRodPartComponent.class); + return new RodPartDefinition( + itemId, + component.getDisplayName(), + component.getCategory(), + component.getRequiredFishingLevel(), + item.getDefaultStatistics(), + item.getLore(), + component.getTagBonuses(), + component.isTreasureOnly(), + component.isBayouTreasureToJunk(), + component.getMaterializedItemId(), + component.getMaterializedChance(), + component.getBaitPreservationChance(), + component.getHotspotBuffMultiplier(), + component.getTexture() + ); + } + + public static @Nullable BaitDefinition getBait(@Nullable String itemId) { + if (itemId == null) { + return null; + } + + ConfigurableSkyBlockItem item = ConfigurableSkyBlockItem.getFromID(itemId); + if (item == null || !item.hasComponent(FishingBaitComponent.class)) { + return null; + } + + FishingBaitComponent component = item.getComponent(FishingBaitComponent.class); + return new BaitDefinition( + itemId, + component.getDisplayName(), + item.getDefaultStatistics(), + item.getLore(), + component.getTagBonuses(), + component.getTreasureChanceBonus(), + component.getTreasureQualityBonus(), + component.getTrophyFishChanceBonus(), + component.getDoubleHookChanceBonus(), + component.getMediums(), + component.getTexture() + ); + } + + public static @Nullable ShipPartDefinition getShipPart(@Nullable String itemId) { + if (itemId == null) { + return null; + } + + ConfigurableSkyBlockItem item = ConfigurableSkyBlockItem.getFromID(itemId); + if (item == null || !item.hasComponent(FishingShipPartComponent.class)) { + return null; + } + + FishingShipPartComponent component = item.getComponent(FishingShipPartComponent.class); + return new ShipPartDefinition( + itemId, + component.getDisplayName(), + component.getSlot(), + item.getLore(), + component.getTexture() + ); + } + + public static List getRods() { + return Arrays.stream(ItemType.values()) + .map(ItemType::name) + .map(FishingItemCatalog::getRod) + .filter(Objects::nonNull) + .sorted(Comparator.comparingInt(FishingRodDefinition::requiredFishingLevel) + .thenComparing(FishingRodDefinition::displayName)) + .toList(); + } + + public static List getRodParts() { + return Arrays.stream(ItemType.values()) + .map(ItemType::name) + .map(FishingItemCatalog::getRodPart) + .filter(Objects::nonNull) + .sorted(Comparator.comparing(RodPartDefinition::category) + .thenComparingInt(RodPartDefinition::requiredFishingLevel) + .thenComparing(RodPartDefinition::displayName)) + .toList(); + } + + public static List getBaits() { + return Arrays.stream(ItemType.values()) + .map(ItemType::name) + .map(FishingItemCatalog::getBait) + .filter(Objects::nonNull) + .sorted(Comparator.comparing((BaitDefinition bait) -> ItemType.valueOf(bait.itemId()).rarity.ordinal()) + .thenComparing(BaitDefinition::displayName)) + .toList(); + } + + public static List getShipParts() { + return Arrays.stream(ItemType.values()) + .map(ItemType::name) + .map(FishingItemCatalog::getShipPart) + .filter(Objects::nonNull) + .sorted(Comparator.comparing(ShipPartDefinition::slot).thenComparing(ShipPartDefinition::displayName)) + .toList(); + } +} \ No newline at end of file diff --git a/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/fishing/FishingLootResolver.java b/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/fishing/FishingLootResolver.java new file mode 100644 index 000000000..24152bfc6 --- /dev/null +++ b/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/fishing/FishingLootResolver.java @@ -0,0 +1,259 @@ +package net.swofty.type.skyblockgeneric.fishing; + +import net.swofty.commons.skyblock.item.ItemType; +import net.swofty.commons.skyblock.statistics.ItemStatistic; +import net.swofty.type.generic.data.datapoints.DatapointToggles; + +import java.util.ArrayList; +import java.util.Comparator; +import java.util.List; + +public final class FishingLootResolver { + private FishingLootResolver() { + } + + public static FishingCatchResult resolve(FishingContext context) { + FishingCatchResult trophyFish = tryResolveTrophyFish(context); + if (trophyFish != null) { + return trophyFish; + } + + FishingCatchResult questCatch = tryResolveQuestCatch(context); + if (questCatch != null) { + return questCatch; + } + + FishingCatchResult seaCreature = tryResolveSeaCreature(context); + if (seaCreature != null) { + return seaCreature; + } + + return resolveItem(context); + } + + private static FishingCatchResult tryResolveTrophyFish(FishingContext context) { + if (context.medium() != FishingMedium.LAVA) { + return null; + } + + double bonus = getTotalStatistic(context, ItemStatistic.TROPHY_FISH_CHANCE); + if (context.bait() != null) { + bonus += context.bait().trophyFishChanceBonus(); + } + + List eligible = new ArrayList<>(); + for (TrophyFishDefinition definition : FishingRegistry.getTrophyFish()) { + if (!definition.regions().isEmpty() && context.regionId() != null && !definition.regions().contains(context.regionId())) { + continue; + } + if (context.player().getSkills().getCurrentLevel(net.swofty.type.skyblockgeneric.skill.SkillCategories.FISHING) < definition.requiredFishingLevel()) { + continue; + } + if (context.castDurationMs() < definition.minimumCastTimeMs()) { + continue; + } + eligible.add(definition); + } + + eligible.sort(Comparator.comparingDouble(TrophyFishDefinition::catchChance)); + for (TrophyFishDefinition definition : eligible) { + if (Math.random() * 100 <= definition.catchChance() + bonus) { + String tier = rollTrophyTier(context, definition); + String itemId = switch (tier) { + case "DIAMOND" -> definition.diamondItemId(); + case "GOLD" -> definition.goldItemId(); + case "SILVER" -> definition.silverItemId(); + default -> definition.bronzeItemId(); + }; + if (itemId == null) { + continue; + } + return new FishingCatchResult(FishingCatchKind.TROPHY_FISH, itemId, null, definition.id(), 1, 300.0D, false, null); + } + } + + return null; + } + + private static FishingCatchResult tryResolveQuestCatch(FishingContext context) { + if (context.medium() != FishingMedium.WATER) { + return null; + } + if (context.regionId() == null) { + return null; + } + if (!"FISHING_OUTPOST".equals(context.regionId()) && !"FISHERMANS_HUT".equals(context.regionId())) { + return null; + } + if (!context.player().getToggles().get(DatapointToggles.Toggles.ToggleType.HAS_SPOKEN_TO_FISHERWOMAN_ENID)) { + return null; + } + if (context.player().getToggles().get(DatapointToggles.Toggles.ToggleType.HAS_UNLOCKED_SHIP)) { + return null; + } + if (context.player().getShipState().getEngine() != null) { + return null; + } + if (context.player().countItem(ItemType.RUSTY_SHIP_ENGINE) > 0) { + return null; + } + if (Math.random() * 100 > 1.0D) { + return null; + } + + return new FishingCatchResult( + FishingCatchKind.QUEST, + ItemType.RUSTY_SHIP_ENGINE.name(), + null, + null, + 1, + 15.0D, + false, + "You fished up a Rusty Ship Engine!" + ); + } + + private static String rollTrophyTier(FishingContext context, TrophyFishDefinition definition) { + var progress = context.player().getTrophyFishData().getProgress(definition.id()); + if (progress.getTotalCatches() + 1 >= 600 && !progress.hasTier("DIAMOND")) { + return "DIAMOND"; + } + if (progress.getTotalCatches() + 1 >= 100 && !progress.hasTier("GOLD")) { + return "GOLD"; + } + + double charmBonus = 0.0D; + var charm = context.rod().getAttributeHandler().getEnchantment(net.swofty.type.skyblockgeneric.enchantment.EnchantmentType.CHARM); + if (charm != null) { + charmBonus = charm.level(); + } + + if (Math.random() <= (0.002D * (1 + charmBonus / 100D))) { + return "DIAMOND"; + } + if (Math.random() <= (0.02D * (1 + charmBonus / 100D))) { + return "GOLD"; + } + if (Math.random() <= (0.25D * (1 + charmBonus / 100D))) { + return "SILVER"; + } + return "BRONZE"; + } + + private static FishingCatchResult tryResolveSeaCreature(FishingContext context) { + FishingTableDefinition table = findTable(context); + if (table == null) { + return null; + } + + double seaCreatureChance = getTotalStatistic(context, ItemStatistic.SEA_CREATURE_CHANCE); + if (context.hook() != null && context.hook().treasureOnly()) { + return null; + } + + for (FishingTableDefinition.SeaCreatureRoll roll : table.seaCreatures()) { + SeaCreatureDefinition definition = FishingRegistry.getSeaCreature(roll.seaCreatureId()); + if (definition != null && context.player().getSkills().getCurrentLevel(net.swofty.type.skyblockgeneric.skill.SkillCategories.FISHING) < definition.requiredFishingLevel()) { + continue; + } + double tagBonus = definition == null ? 0.0D : getTagBonus(context, definition.tags()); + if (Math.random() * 100 <= roll.chance() + seaCreatureChance + tagBonus) { + double skillXp = definition == null ? 0.0D : definition.skillXp(); + return new FishingCatchResult(FishingCatchKind.SEA_CREATURE, null, roll.seaCreatureId(), null, 1, skillXp, false, null); + } + } + return null; + } + + private static FishingCatchResult resolveItem(FishingContext context) { + FishingTableDefinition table = findTable(context); + if (table == null) { + return new FishingCatchResult(FishingCatchKind.ITEM, "RAW_FISH", null, null, 1, 5.0D, false, null); + } + + List pool = table.items(); + double treasureChance = getTotalStatistic(context, ItemStatistic.TREASURE_CHANCE); + if (context.bait() != null) { + treasureChance += context.bait().treasureChanceBonus(); + } + if (context.sinker() != null && context.sinker().bayouTreasureToJunk()) { + treasureChance += 10.0D; + } + + if (!table.treasures().isEmpty() && Math.random() * 100 <= treasureChance) { + pool = context.sinker() != null && context.sinker().bayouTreasureToJunk() ? table.junk() : table.treasures(); + return pick(pool, FishingCatchKind.TREASURE); + } + + FishingCatchResult result = pick(pool, FishingCatchKind.ITEM); + if (result != null) { + return result; + } + if (!table.junk().isEmpty()) { + return pick(table.junk(), FishingCatchKind.ITEM); + } + return new FishingCatchResult(FishingCatchKind.ITEM, "RAW_FISH", null, null, 1, 5.0D, false, null); + } + + private static FishingCatchResult pick(List pool, FishingCatchKind kind) { + double roll = Math.random() * 100; + double cursor = 0; + for (FishingTableDefinition.LootEntry entry : pool) { + cursor += entry.chance(); + if (roll <= cursor) { + return new FishingCatchResult(kind, entry.itemId(), null, null, entry.amount(), entry.skillXp(), false, null); + } + } + return pool.isEmpty() ? null : new FishingCatchResult(kind, pool.getFirst().itemId(), null, null, pool.getFirst().amount(), pool.getFirst().skillXp(), false, null); + } + + private static FishingTableDefinition findTable(FishingContext context) { + for (FishingTableDefinition definition : FishingRegistry.getTables()) { + if (!definition.mediums().isEmpty() && !definition.mediums().contains(context.medium())) { + continue; + } + if (definition.regions().isEmpty()) { + return definition; + } + if (context.regionId() != null && definition.regions().contains(context.regionId())) { + return definition; + } + } + return null; + } + + private static double getTotalStatistic(FishingContext context, ItemStatistic statistic) { + double total = context.rod().getAttributeHandler().getStatistics().getOverall(statistic) + + FishingRodPartService.getStatistics(context.rod()).getOverall(statistic); + total += context.hotspotBuffs().getOverall(statistic); + if (context.bait() != null) { + total += context.bait().statistics().getOverall(statistic); + } + return total; + } + + private static double getTagBonus(FishingContext context, List tags) { + double total = 0.0D; + if (context.hook() != null) { + total += getTagBonus(context.hook().tagBonuses(), tags); + } + if (context.line() != null) { + total += getTagBonus(context.line().tagBonuses(), tags); + } + if (context.sinker() != null) { + total += getTagBonus(context.sinker().tagBonuses(), tags); + } + if (context.bait() != null) { + total += getTagBonus(context.bait().tagBonuses(), tags); + } + return total; + } + + private static double getTagBonus(java.util.Map bonuses, List tags) { + double total = 0.0D; + for (String tag : tags) { + total += bonuses.getOrDefault(tag, 0.0D); + } + return total; + } +} diff --git a/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/fishing/FishingMedium.java b/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/fishing/FishingMedium.java new file mode 100644 index 000000000..c9b135f64 --- /dev/null +++ b/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/fishing/FishingMedium.java @@ -0,0 +1,30 @@ +package net.swofty.type.skyblockgeneric.fishing; + +import net.minestom.server.instance.block.Block; +import org.jetbrains.annotations.Nullable; + +public enum FishingMedium { + WATER, + LAVA; + + public boolean matches(Block block) { + if (block == null || !block.isLiquid()) { + return false; + } + + String blockName = block.name(); + return switch (this) { + case WATER -> blockName.contains("water"); + case LAVA -> blockName.contains("lava"); + }; + } + + public static @Nullable FishingMedium fromBlock(Block block) { + for (FishingMedium medium : values()) { + if (medium.matches(block)) { + return medium; + } + } + return null; + } +} diff --git a/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/fishing/FishingRegistry.java b/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/fishing/FishingRegistry.java new file mode 100644 index 000000000..0befec050 --- /dev/null +++ b/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/fishing/FishingRegistry.java @@ -0,0 +1,438 @@ +package net.swofty.type.skyblockgeneric.fishing; + +import net.swofty.commons.ServerType; +import net.swofty.commons.YamlFileUtils; +import net.swofty.commons.skyblock.statistics.ItemStatistic; +import net.swofty.commons.skyblock.statistics.ItemStatistics; +import net.swofty.type.skyblockgeneric.entity.mob.MobType; +import org.jetbrains.annotations.Nullable; +import org.tinylog.Logger; + +import java.io.File; +import java.io.IOException; +import java.util.ArrayList; +import java.util.Collections; +import java.util.LinkedHashMap; +import java.util.List; +import java.util.Map; + +public final class FishingRegistry { + private static final File FISHING_DIR = new File("./configuration/skyblock/fishing"); + + private static final Map TABLES = new LinkedHashMap<>(); + private static final Map SEA_CREATURES = new LinkedHashMap<>(); + private static final Map TROPHY_FISH = new LinkedHashMap<>(); + private static final Map HOTSPOTS = new LinkedHashMap<>(); + + private FishingRegistry() { + } + + public static void loadAll() { + TABLES.clear(); + SEA_CREATURES.clear(); + TROPHY_FISH.clear(); + HOTSPOTS.clear(); + + if (!YamlFileUtils.ensureDirectoryExists(FISHING_DIR)) { + throw new IllegalStateException("Unable to create fishing configuration directory"); + } + + try { + loadTables(new File(FISHING_DIR, "tables.yml")); + loadSeaCreatures(new File(FISHING_DIR, "sea_creatures.yml")); + loadTrophyFish(new File(FISHING_DIR, "trophy_fish.yml")); + loadHotspots(new File(FISHING_DIR, "hotspots.yml")); + } catch (Exception exception) { + Logger.error(exception, "Failed to load fishing configuration"); + } + } + + public static @Nullable FishingTableDefinition getTable(String tableId) { + return TABLES.get(tableId); + } + + public static @Nullable TrophyFishDefinition getTrophyFish(String id) { + return TROPHY_FISH.get(id); + } + + public static @Nullable SeaCreatureDefinition getSeaCreature(String id) { + return SEA_CREATURES.get(id); + } + + + public static List getTables() { + return List.copyOf(TABLES.values()); + } + + public static List getHotspots() { + return List.copyOf(HOTSPOTS.values()); + } + + public static List getTrophyFish() { + return List.copyOf(TROPHY_FISH.values()); + } + + public static List getSeaCreatures() { + return List.copyOf(SEA_CREATURES.values()); + } + + + @SuppressWarnings("unchecked") + private static void loadTables(File file) throws IOException { + Map root = YamlFileUtils.loadYaml(file); + List> entries = (List>) root.getOrDefault("tables", Collections.emptyList()); + for (Map entry : entries) { + String id = string(entry, "id"); + TABLES.put(id, new FishingTableDefinition( + id, + stringList(entry.get("regions")), + parseMediums((List) entry.get("mediums")), + parseLootEntries((List>) entry.get("items")), + parseLootEntries((List>) entry.get("treasures")), + parseLootEntries((List>) entry.get("junk")), + parseSeaCreatureRolls((List>) entry.get("seaCreatures")) + )); + } + } + + @SuppressWarnings("unchecked") + private static void loadTrophyFish(File file) throws IOException { + Map root = YamlFileUtils.loadYaml(file); + List> entries = (List>) root.getOrDefault("trophyFish", Collections.emptyList()); + for (Map entry : entries) { + String id = string(entry, "id"); + TROPHY_FISH.put(id, new TrophyFishDefinition( + id, + string(entry, "displayName"), + doubleValue(entry, "catchChance", 0.0D), + stringList(entry.get("regions")), + intValue(entry, "requiredFishingLevel", 0), + longValue(entry, "minimumCastTimeMs", 0L), + nullableString(entry, "requiredRodId"), + nullableDouble(entry.get("minimumMana")), + nullableDouble(entry.get("minimumBobberDepth")), + nullableDouble(entry.get("maximumPlayerDistance")), + booleanValue(entry, "requiresStarterRodWithoutEnchantments", false), + booleanValue(entry, "specialGoldenFish", false), + nullableString(entry, "bronzeItemId"), + nullableString(entry, "silverItemId"), + nullableString(entry, "goldItemId"), + nullableString(entry, "diamondItemId") + )); + } + } + + @SuppressWarnings("unchecked") + private static void loadSeaCreatures(File file) throws IOException { + if (!file.exists()) { + return; + } + + Map root = YamlFileUtils.loadYaml(file); + List> entries = (List>) root.getOrDefault("seaCreatures", Collections.emptyList()); + for (Map entry : entries) { + String id = string(entry, "id"); + SEA_CREATURES.put(id, new SeaCreatureDefinition( + id, + string(entry, "displayName"), + intValue(entry, "requiredFishingLevel", 0), + doubleValue(entry, "skillXp", 0.0D), + stringList(entry.get("tags")), + nullableString(entry, "corruptedVariantId") + )); + } + } + + @SuppressWarnings("unchecked") + private static void loadHotspots(File file) throws IOException { + if (!file.exists()) { + return; + } + + Map root = YamlFileUtils.loadYaml(file); + List> entries = (List>) root.getOrDefault("hotspots", Collections.emptyList()); + int generatedId = 1; + for (Map entry : entries) { + if (entry.containsKey("x") && entry.containsKey("y") && entry.containsKey("z")) { + String serverType = normalizeServerType(nullableString(entry, "serverType")); + String region = nullableString(entry, "region"); + HOTSPOTS.put("POSITION_" + generatedId, new HotspotDefinition( + "POSITION_" + generatedId, + "Hotspot", + region == null ? List.of() : List.of(region.toUpperCase()), + enumValue(entry, "medium", FishingMedium.class, FishingMedium.WATER), + intValue(entry, "maxActive", defaultMaxActiveForServer(serverType)), + intValue(entry, "durationSeconds", 120), + parseStatistics((Map) entry.get("buffs"), defaultHotspotBuffs()), + stringList(entry.get("seaCreatures")), + List.of(new HotspotDefinition.SpawnPoint( + doubleValue(entry.get("x"), 0), + doubleValue(entry.get("y"), 0), + doubleValue(entry.get("z"), 0), + serverType + )) + )); + generatedId++; + continue; + } + + String id = string(entry, "id"); + HOTSPOTS.put(id, new HotspotDefinition( + id, + string(entry, "displayName"), + stringList(entry.get("regions")), + enumValue(entry, "medium", FishingMedium.class, FishingMedium.WATER), + intValue(entry, "maxActive", 1), + intValue(entry, "durationSeconds", 120), + parseStatistics((Map) entry.get("buffs"), defaultHotspotBuffs()), + stringList(entry.get("seaCreatures")), + parseHotspotSpawnPoints((List>) entry.get("positions"), nullableString(entry, "serverType")) + )); + } + } + + + private static ItemStatistics parseStatistics(@Nullable Map values) { + return parseStatistics(values, Map.of()); + } + + private static ItemStatistics parseStatistics(@Nullable Map values, Map defaults) { + if (values == null || values.isEmpty()) { + if (defaults.isEmpty()) { + return ItemStatistics.empty(); + } + values = new LinkedHashMap<>(); + } + + Map mergedValues = new LinkedHashMap<>(); + defaults.forEach(mergedValues::put); + mergedValues.putAll(values); + + if (mergedValues.isEmpty()) { + return ItemStatistics.empty(); + } + + ItemStatistics.Builder builder = ItemStatistics.builder(); + for (Map.Entry entry : mergedValues.entrySet()) { + builder.withBase(ItemStatistic.valueOf(entry.getKey().toUpperCase()), doubleValue(entry.getValue(), 0.0D)); + } + return builder.build(); + } + + + private static List parseMediums(@Nullable List mediums) { + if (mediums == null || mediums.isEmpty()) { + return List.of(FishingMedium.WATER); + } + + List result = new ArrayList<>(); + for (Object value : mediums) { + result.add(FishingMedium.valueOf(String.valueOf(value).toUpperCase())); + } + return result; + } + + private static List parseMobTypes(@Nullable List values) { + if (values == null || values.isEmpty()) { + return List.of(); + } + + List mobTypes = new ArrayList<>(); + for (Object value : values) { + mobTypes.add(MobType.valueOf(String.valueOf(value).toUpperCase())); + } + return mobTypes; + } + + private static List parseHotspotSpawnPoints(@Nullable List> entries, @Nullable String fallbackServerType) { + if (entries == null || entries.isEmpty()) { + return List.of(); + } + + List points = new ArrayList<>(); + for (Map entry : entries) { + points.add(new HotspotDefinition.SpawnPoint( + doubleValue(entry.get("x"), 0), + doubleValue(entry.get("y"), 0), + doubleValue(entry.get("z"), 0), + normalizeServerType(nullableString(entry, "serverType"), fallbackServerType) + )); + } + return points; + } + + private static String normalizeServerType(@Nullable String serverType) { + return normalizeServerType(serverType, null); + } + + private static String normalizeServerType(@Nullable String serverType, @Nullable String fallback) { + String value = serverType == null || serverType.isEmpty() ? fallback : serverType; + if (value == null || value.isEmpty()) { + return ServerType.SKYBLOCK_HUB.name(); + } + return ServerType.getSkyblockServer(value).name(); + } + + private static int defaultMaxActiveForServer(String serverType) { + return switch (serverType) { + case "SKYBLOCK_HUB", "SKYBLOCK_BACKWATER_BAYOU" -> 2; + case "SKYBLOCK_SPIDERS_DEN" -> 1; + case "SKYBLOCK_CRIMSON_ISLE" -> 3; + default -> 1; + }; + } + + private static Map defaultHotspotBuffs() { + Map defaults = new LinkedHashMap<>(); + defaults.put("FISHING_SPEED", 15.0D); + defaults.put("SEA_CREATURE_CHANCE", 5.0D); + defaults.put("DOUBLE_HOOK_CHANCE", 2.0D); + defaults.put("TROPHY_FISH_CHANCE", 5.0D); + defaults.put("TREASURE_CHANCE", 1.0D); + return defaults; + } + + private static List parseLootEntries(@Nullable List> entries) { + if (entries == null || entries.isEmpty()) { + return List.of(); + } + + List result = new ArrayList<>(); + for (Map entry : entries) { + result.add(new FishingTableDefinition.LootEntry( + string(entry, "itemId"), + doubleValue(entry, "chance", 0.0D), + intValue(entry, "amount", 1), + doubleValue(entry, "skillXp", 0.0D) + )); + } + return result; + } + + private static List parseSeaCreatureRolls(@Nullable List> entries) { + if (entries == null || entries.isEmpty()) { + return List.of(); + } + + List result = new ArrayList<>(); + for (Map entry : entries) { + result.add(new FishingTableDefinition.SeaCreatureRoll( + string(entry, "seaCreatureId"), + doubleValue(entry, "chance", 0.0D) + )); + } + return result; + } + + private static Map parseStringDoubleMap(@Nullable Map values) { + if (values == null || values.isEmpty()) { + return Map.of(); + } + + Map result = new LinkedHashMap<>(); + for (Map.Entry entry : values.entrySet()) { + result.put(entry.getKey(), doubleValue(entry.getValue(), 0.0D)); + } + return result; + } + + private static String string(Map entry, String key) { + Object value = entry.get(key); + if (value == null) { + throw new IllegalArgumentException("Missing fishing config key: " + key); + } + return String.valueOf(value); + } + + private static @Nullable String nullableString(Map entry, String key) { + Object value = entry.get(key); + if (value == null) { + return null; + } + String stringValue = String.valueOf(value); + return stringValue.isEmpty() ? null : stringValue; + } + + private static List stringList(@Nullable Object raw) { + if (!(raw instanceof List list)) { + return List.of(); + } + List values = new ArrayList<>(); + for (Object entry : list) { + values.add(String.valueOf(entry)); + } + return values; + } + + private static int intValue(Map entry, String key, int defaultValue) { + return intValue(entry.get(key), defaultValue); + } + + private static int intValue(@Nullable Object value, int defaultValue) { + if (value == null) { + return defaultValue; + } + if (value instanceof Number number) { + return number.intValue(); + } + return Integer.parseInt(String.valueOf(value)); + } + + private static long longValue(Map entry, String key, long defaultValue) { + return longValue(entry.get(key), defaultValue); + } + + private static long longValue(@Nullable Object value, long defaultValue) { + if (value == null) { + return defaultValue; + } + if (value instanceof Number number) { + return number.longValue(); + } + return Long.parseLong(String.valueOf(value)); + } + + private static double doubleValue(Map entry, String key, double defaultValue) { + return doubleValue(entry.get(key), defaultValue); + } + + private static double doubleValue(@Nullable Object value, double defaultValue) { + if (value == null) { + return defaultValue; + } + if (value instanceof Number number) { + return number.doubleValue(); + } + return Double.parseDouble(String.valueOf(value)); + } + + private static @Nullable Double nullableDouble(@Nullable Object value) { + if (value == null) { + return null; + } + if (value instanceof Number number) { + return number.doubleValue(); + } + String stringValue = String.valueOf(value); + return stringValue.isEmpty() ? null : Double.parseDouble(stringValue); + } + + private static boolean booleanValue(Map entry, String key, boolean defaultValue) { + Object value = entry.get(key); + if (value == null) { + return defaultValue; + } + if (value instanceof Boolean bool) { + return bool; + } + return Boolean.parseBoolean(String.valueOf(value)); + } + + private static > T enumValue(Map entry, String key, Class type, T defaultValue) { + Object value = entry.get(key); + if (value == null) { + return defaultValue; + } + return Enum.valueOf(type, String.valueOf(value).toUpperCase()); + } +} diff --git a/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/fishing/FishingRodDefinition.java b/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/fishing/FishingRodDefinition.java new file mode 100644 index 000000000..38d102af1 --- /dev/null +++ b/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/fishing/FishingRodDefinition.java @@ -0,0 +1,23 @@ +package net.swofty.type.skyblockgeneric.fishing; + +import net.swofty.commons.skyblock.statistics.ItemStatistics; +import net.swofty.type.skyblockgeneric.enchantment.EnchantmentType; +import org.jetbrains.annotations.Nullable; + +import java.util.List; +import java.util.Map; + +public record FishingRodDefinition( + String itemId, + String displayName, + @Nullable String subtitle, + FishingMedium medium, + int requiredFishingLevel, + ItemStatistics statistics, + Map enchantments, + List lore, + @Nullable String legacyConversionTarget, + @Nullable String legacyConversionPart, + boolean rodPartsEnabled +) { +} diff --git a/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/fishing/FishingRodLoreBuilder.java b/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/fishing/FishingRodLoreBuilder.java new file mode 100644 index 000000000..d108ad7bc --- /dev/null +++ b/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/fishing/FishingRodLoreBuilder.java @@ -0,0 +1,222 @@ +package net.swofty.type.skyblockgeneric.fishing; + +import net.swofty.commons.StringUtility; +import net.swofty.commons.skyblock.item.ItemType; +import net.swofty.commons.skyblock.item.Rarity; +import net.swofty.commons.skyblock.item.attribute.attributes.ItemAttributeHotPotatoBookData; +import net.swofty.commons.skyblock.item.reforge.Reforge; +import net.swofty.commons.skyblock.statistics.ItemStatistic; +import net.swofty.commons.skyblock.statistics.ItemStatistics; +import net.swofty.type.skyblockgeneric.enchantment.SkyBlockEnchantment; +import net.swofty.type.skyblockgeneric.item.SkyBlockItem; +import net.swofty.type.skyblockgeneric.user.SkyBlockPlayer; +import org.jetbrains.annotations.Nullable; + +import java.util.ArrayList; +import java.util.Comparator; +import java.util.List; +import java.util.Map; + +public final class FishingRodLoreBuilder { + private static final List STAT_ORDER = List.of( + ItemStatistic.DAMAGE, + ItemStatistic.STRENGTH, + ItemStatistic.FEROCITY, + ItemStatistic.FISHING_SPEED, + ItemStatistic.SEA_CREATURE_CHANCE, + ItemStatistic.TREASURE_CHANCE, + ItemStatistic.TROPHY_FISH_CHANCE, + ItemStatistic.MAGIC_FIND + ); + + private FishingRodLoreBuilder() { + } + + public static @Nullable FishingRodLore build(SkyBlockItem item, @Nullable SkyBlockPlayer player) { + ItemType itemType = item.getAttributeHandler().getPotentialType(); + if (itemType == null) { + return null; + } + + FishingRodDefinition definition = FishingItemCatalog.getRod(itemType.name()); + if (definition == null) { + return null; + } + + var handler = item.getAttributeHandler(); + Rarity rarity = handler.isRecombobulated() ? handler.getRarity().upgrade() : handler.getRarity(); + + String displayName = definition.displayName(); + Reforge reforge = handler.getReforge(); + if (reforge != null) { + displayName = reforge.getPrefix() + " " + displayName; + } + displayName = rarity.getColor() + displayName; + + List lore = new ArrayList<>(); + if (definition.subtitle() != null) { + lore.add("§8" + definition.subtitle()); + lore.add(""); + } + + for (ItemStatistic statistic : STAT_ORDER) { + String line = buildStatLine(item, definition, rarity, statistic); + if (line != null) { + lore.add(line); + } + } + + lore.addAll(definition.lore()); + if (!lore.isEmpty() && !lore.getLast().isEmpty()) { + lore.add(""); + } + + List enchantLines = buildEnchantLines(item, rarity); + lore.addAll(enchantLines); + if (!enchantLines.isEmpty()) { + lore.add(""); + } + + if (definition.rodPartsEnabled()) { + RodPartDefinition hook = FishingRodPartService.getHook(item); + RodPartDefinition line = FishingRodPartService.getLine(item); + RodPartDefinition sinker = FishingRodPartService.getSinker(item); + + lore.add(renderPartHeader("ථ", "Hook", hook)); + if (hook != null) { + lore.addAll(renderAppliedPartLore(hook, player)); + } + lore.add(renderPartHeader("ꨃ", "Line", line)); + if (line != null) { + lore.addAll(renderAppliedPartLore(line, player)); + } + lore.add(renderPartHeader("࿉", "Sinker", sinker)); + if (sinker != null) { + lore.addAll(renderAppliedPartLore(sinker, player)); + } + lore.add(""); + lore.add("§7Talk to §2Roddy §7in the §2Backwater"); + lore.add("§2Bayou §7to apply parts to this rod."); + lore.add(""); + } else if (definition.legacyConversionTarget() != null) { + lore.add("§7§cThis rod is broken and cannot be"); + lore.add("§cused to fish."); + lore.add(""); + lore.add("§7Bring it to §2Roddy §7in the §2Backwater"); + lore.add("§2Bayou §7to convert it into a §anew rod§7!"); + lore.add(""); + } + + lore.add("§8This item can be reforged!"); + + if (handler.getFishingExpertiseKills() > 0) { + lore.add("§fKills: §6" + StringUtility.commaify(handler.getFishingExpertiseKills())); + } + + if (handler.getSoulBoundData() != null) { + lore.add("§8§l* Co-op Soulbound §l*"); + } + + if (definition.requiredFishingLevel() > 0 && player != null && + player.getSkills().getCurrentLevel(net.swofty.type.skyblockgeneric.skill.SkillCategories.FISHING) < definition.requiredFishingLevel()) { + lore.add("§4❣ §cRequires §aFishing Skill " + definition.requiredFishingLevel() + "§c."); + } + + String footer = rarity.getDisplay() + " FISHING ROD"; + if (handler.isRecombobulated()) { + footer = rarity.getColor() + "§l§ka §l" + rarity.name() + " FISHING ROD §l§ka"; + } + lore.add(footer); + + return new FishingRodLore(displayName, lore); + } + + private static @Nullable String buildStatLine(SkyBlockItem item, FishingRodDefinition definition, Rarity rarity, ItemStatistic statistic) { + double base = definition.statistics().getOverall(statistic); + double reforge = 0.0D; + if (item.getAttributeHandler().getReforge() != null) { + reforge = item.getAttributeHandler().getReforge().getAfterCalculation(ItemStatistics.empty(), rarity.ordinal() + 1).getOverall(statistic); + } + + double part = FishingRodPartService.getStatistics(item).getOverall(statistic); + double dynamic = item.getAttributeHandler().getExtraDynamicStatistics().getOverall(statistic); + double hpb = getHotPotatoContribution(item, statistic); + double total = base + reforge + part + dynamic + hpb; + + if (total == 0) { + return null; + } + + String line = "§7" + statistic.getDisplayName() + ": " + statistic.getLoreColor() + + statistic.getPrefix() + formatNumber(total) + statistic.getSuffix(); + if (hpb != 0) { + line += " §e(" + (hpb > 0 ? "+" : "") + formatNumber(hpb) + ")"; + } + if (part != 0) { + line += " §d(" + (part > 0 ? "+" : "") + formatNumber(part) + ")"; + } else if (reforge != 0) { + line += " §9(" + (reforge > 0 ? "+" : "") + formatNumber(reforge) + ")"; + } + return line; + } + + private static double getHotPotatoContribution(SkyBlockItem item, ItemStatistic statistic) { + ItemAttributeHotPotatoBookData.HotPotatoBookData data = item.getAttributeHandler().getHotPotatoBookData(); + if (!data.hasAppliedItem()) { + return 0.0D; + } + + double total = 0.0D; + for (Map.Entry entry : data.getPotatoType().stats.entrySet()) { + if (entry.getKey() == statistic) { + total += entry.getValue(); + } + } + return total; + } + + private static List buildEnchantLines(SkyBlockItem item, Rarity rarity) { + List enchantments = item.getAttributeHandler().getEnchantments() + .sorted(Comparator.comparing(enchantment -> enchantment.type().getName())) + .toList(); + if (enchantments.isEmpty()) { + return List.of(); + } + + String enchantColor = rarity == Rarity.MYTHIC ? "§d" : "§9"; + String joined = enchantments.stream() + .map(enchantment -> enchantColor + enchantment.type().getName() + " " + StringUtility.getAsRomanNumeral(enchantment.level())) + .reduce((left, right) -> left + ", " + right) + .orElse(""); + return StringUtility.splitByWordAndLength(joined, 34); + } + + private static String renderPartHeader(String symbol, String label, @Nullable RodPartDefinition part) { + if (part == null) { + return "§9" + symbol + " " + label + " §8§lNONE"; + } + return ItemType.valueOf(part.itemId()).rarity.getColor() + symbol + " " + part.displayName(); + } + + private static List renderAppliedPartLore(RodPartDefinition part, @Nullable SkyBlockPlayer player) { + List lines = new ArrayList<>(); + for (String line : part.lore()) { + lines.add("§7" + line); + } + if (part.requiredFishingLevel() > 0 && player != null && + player.getSkills().getCurrentLevel(net.swofty.type.skyblockgeneric.skill.SkillCategories.FISHING) < part.requiredFishingLevel()) { + lines.add("§4❣ §cRequires §aFishing Skill " + part.requiredFishingLevel() + "§c."); + } + return lines; + } + + private static String formatNumber(double value) { + if (Math.abs(value - Math.rint(value)) < 0.0001D) { + return String.valueOf((long) Math.rint(value)); + } + return StringUtility.decimalify(value, 1); + } + + public record FishingRodLore(String displayName, List lore) { + } +} diff --git a/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/fishing/FishingRodPartService.java b/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/fishing/FishingRodPartService.java new file mode 100644 index 000000000..87ac626a1 --- /dev/null +++ b/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/fishing/FishingRodPartService.java @@ -0,0 +1,62 @@ +package net.swofty.type.skyblockgeneric.fishing; + +import net.swofty.commons.skyblock.statistics.ItemStatistics; +import net.swofty.type.skyblockgeneric.item.SkyBlockItem; +import org.jetbrains.annotations.Nullable; + +public final class FishingRodPartService { + private FishingRodPartService() { + } + + public static @Nullable RodPartDefinition getHook(SkyBlockItem rod) { + return getPart(FishingItemCatalog.getRodPart(rod.getAttributeHandler().getFishingHook())); + } + + public static @Nullable RodPartDefinition getLine(SkyBlockItem rod) { + return getPart(FishingItemCatalog.getRodPart(rod.getAttributeHandler().getFishingLine())); + } + + public static @Nullable RodPartDefinition getSinker(SkyBlockItem rod) { + return getPart(FishingItemCatalog.getRodPart(rod.getAttributeHandler().getFishingSinker())); + } + + public static ItemStatistics getStatistics(SkyBlockItem rod) { + ItemStatistics.Builder builder = ItemStatistics.builder(); + append(builder, getHook(rod)); + append(builder, getLine(rod)); + append(builder, getSinker(rod)); + return builder.build(); + } + + public static void applyPart(SkyBlockItem rod, RodPartDefinition part) { + switch (part.category()) { + case HOOK -> rod.getAttributeHandler().setFishingHook(part.itemId()); + case LINE -> rod.getAttributeHandler().setFishingLine(part.itemId()); + case SINKER -> rod.getAttributeHandler().setFishingSinker(part.itemId()); + } + } + + public static void removePart(SkyBlockItem rod, RodPartDefinition.PartCategory category) { + switch (category) { + case HOOK -> rod.getAttributeHandler().setFishingHook(null); + case LINE -> rod.getAttributeHandler().setFishingLine(null); + case SINKER -> rod.getAttributeHandler().setFishingSinker(null); + } + } + + private static @Nullable RodPartDefinition getPart(@Nullable RodPartDefinition definition) { + return definition; + } + + private static void append(ItemStatistics.Builder builder, @Nullable RodPartDefinition definition) { + if (definition == null) { + return; + } + for (var statistic : net.swofty.commons.skyblock.statistics.ItemStatistic.values()) { + double amount = definition.statistics().getOverall(statistic); + if (amount != 0) { + builder.withBase(statistic, amount); + } + } + } +} diff --git a/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/fishing/FishingService.java b/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/fishing/FishingService.java new file mode 100644 index 000000000..235e2a63a --- /dev/null +++ b/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/fishing/FishingService.java @@ -0,0 +1,158 @@ +package net.swofty.type.skyblockgeneric.fishing; + +import net.swofty.type.generic.data.datapoints.DatapointToggles; +import net.swofty.type.skyblockgeneric.data.SkyBlockDataHandler; +import net.swofty.type.skyblockgeneric.data.datapoints.DatapointCollection; +import net.swofty.type.skyblockgeneric.data.datapoints.DatapointTrophyFish; +import net.swofty.type.skyblockgeneric.entity.FishingHook; +import net.swofty.type.skyblockgeneric.item.SkyBlockItem; +import net.swofty.type.skyblockgeneric.region.SkyBlockRegion; +import net.swofty.type.skyblockgeneric.user.SkyBlockPlayer; +import org.jetbrains.annotations.Nullable; + +import java.util.Map; +import java.util.UUID; +import java.util.concurrent.ConcurrentHashMap; + +public final class FishingService { + private static final Map SESSIONS = new ConcurrentHashMap<>(); + + private FishingService() { + } + + public static FishingSession beginCast(SkyBlockPlayer player, SkyBlockItem rod, FishingMedium medium) { + BaitDefinition bait = FishingBaitService.getFirstAvailableBait(player, medium); + FishingSession session = new FishingSession( + player.getUuid(), + rod.getAttributeHandler().getPotentialType().name(), + medium, + bait == null ? null : bait.itemId(), + System.currentTimeMillis(), + 0L, + 0L, + false, + false + ); + SESSIONS.put(player.getUuid(), session); + return session; + } + + public static @Nullable FishingSession getSession(UUID playerUuid) { + return SESSIONS.get(playerUuid); + } + + public static void updateSession(FishingSession session) { + SESSIONS.put(session.ownerUuid(), session); + } + + public static void clearSession(UUID playerUuid) { + SESSIONS.remove(playerUuid); + } + + public static long computeWaitTicks(SkyBlockPlayer player, SkyBlockItem rod, @Nullable BaitDefinition bait) { + double fishingSpeed = player.getStatistics().allStatistics().getOverall(net.swofty.commons.skyblock.statistics.ItemStatistic.FISHING_SPEED) + + rod.getAttributeHandler().getStatistics().getOverall(net.swofty.commons.skyblock.statistics.ItemStatistic.FISHING_SPEED) + + FishingRodPartService.getStatistics(rod).getOverall(net.swofty.commons.skyblock.statistics.ItemStatistic.FISHING_SPEED); + if (bait != null) { + fishingSpeed += bait.statistics().getOverall(net.swofty.commons.skyblock.statistics.ItemStatistic.FISHING_SPEED); + if ("CORRUPTED_BAIT".equals(bait.itemId())) { + fishingSpeed /= 2.0D; + } + } + long baseTicks = 80L; + return Math.max(20L, Math.round(baseTicks - Math.min(50D, fishingSpeed / 2D))); + } + + public static @Nullable FishingCatchResult resolveCatch(SkyBlockPlayer player, SkyBlockItem rod, FishingHook hook) { + FishingSession session = getSession(player.getUuid()); + if (session == null || session.resolved()) { + return null; + } + + BaitDefinition bait = FishingItemCatalog.getBait(session.baitItemId()); + SkyBlockRegion region = player.getRegion(); + var hotspotBuffs = FishingHotspotService.getActiveHotspotBuffs(player, session.medium(), hook.getSpawnPosition()); + boolean hotspotActive = hasAnyBuffValue(hotspotBuffs); + FishingContext context = new FishingContext( + player, + rod, + session.medium(), + bait, + FishingRodPartService.getHook(rod), + FishingRodPartService.getLine(rod), + FishingRodPartService.getSinker(rod), + region == null ? null : region.getType().name(), + hotspotActive, + hotspotBuffs, + System.currentTimeMillis() - session.castAt() + ); + + FishingCatchResult result = FishingCatchResolver.resolve(context); + if (result == null) { + return null; + } + + if (session.baitItemId() != null) { + boolean preserve = false; + var caster = rod.getAttributeHandler().getEnchantment(net.swofty.type.skyblockgeneric.enchantment.EnchantmentType.CASTER); + if (caster != null) { + preserve |= Math.random() * 100 < caster.level(); + } + RodPartDefinition sinker = FishingRodPartService.getSinker(rod); + if (!preserve && sinker != null && sinker.baitPreservationChance() > 0) { + preserve = Math.random() * 100 < sinker.baitPreservationChance(); + } + if (!preserve) { + FishingBaitService.consumeOneBait(player, session.baitItemId()); + } + } + + awardCatch(player, rod, hook, result); + updateSession(session.withResolved(true)); + return result; + } + + private static void awardCatch(SkyBlockPlayer player, SkyBlockItem rod, FishingHook hook, FishingCatchResult result) { + if (!player.getToggles().get(DatapointToggles.Toggles.ToggleType.HAS_CAUGHT_FIRST_FISH)) { + player.getToggles().set(DatapointToggles.Toggles.ToggleType.HAS_CAUGHT_FIRST_FISH, true); + } + + if (result.itemId() != null) { + player.addAndUpdateItem(net.swofty.commons.skyblock.item.ItemType.valueOf(result.itemId()), result.amount()); + player.getCollection().increase(net.swofty.commons.skyblock.item.ItemType.valueOf(result.itemId()), result.amount()); + player.getSkyblockDataHandler().get(SkyBlockDataHandler.Data.COLLECTION, DatapointCollection.class).setValue(player.getCollection()); + } + + RodPartDefinition sinker = FishingRodPartService.getSinker(rod); + if (sinker != null && sinker.materializedItemId() != null && Math.random() <= sinker.materializedChance()) { + player.addAndUpdateItem(net.swofty.commons.skyblock.item.ItemType.valueOf(sinker.materializedItemId())); + } + + if (result.trophyFishId() != null) { + String tier = result.itemId() != null && result.itemId().contains("_DIAMOND") ? "DIAMOND" : + result.itemId() != null && result.itemId().contains("_GOLD") ? "GOLD" : + result.itemId() != null && result.itemId().contains("_SILVER") ? "SILVER" : "BRONZE"; + DatapointTrophyFish.TrophyFishData data = player.getTrophyFishData(); + data.getProgress(result.trophyFishId()).increment(tier); + player.getSkyblockDataHandler().get(SkyBlockDataHandler.Data.TROPHY_FISH, DatapointTrophyFish.class).setValue(data); + } + + if (result.kind() != FishingCatchKind.SEA_CREATURE && result.skillXp() > 0) { + player.getSkills().increase(player, net.swofty.type.skyblockgeneric.skill.SkillCategories.FISHING, result.skillXp()); + } + + if (result.kind() == FishingCatchKind.SEA_CREATURE && result.seaCreatureId() != null) { + // TODO: sea creatures + } + player.setItemInHand(rod); + } + + private static boolean hasAnyBuffValue(net.swofty.commons.skyblock.statistics.ItemStatistics statistics) { + for (net.swofty.commons.skyblock.statistics.ItemStatistic statistic : net.swofty.commons.skyblock.statistics.ItemStatistic.values()) { + if (statistics.getOverall(statistic) != 0.0D) { + return true; + } + } + return false; + } +} diff --git a/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/fishing/FishingSession.java b/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/fishing/FishingSession.java new file mode 100644 index 000000000..1b8c71a5b --- /dev/null +++ b/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/fishing/FishingSession.java @@ -0,0 +1,29 @@ +package net.swofty.type.skyblockgeneric.fishing; + +import org.jetbrains.annotations.Nullable; + +import java.util.UUID; + +public record FishingSession( + UUID ownerUuid, + String rodItemId, + FishingMedium medium, + @Nullable String baitItemId, + long castAt, + long biteReadyAt, + long biteWindowEndsAt, + boolean biteReady, + boolean resolved +) { + public FishingSession withBiteTiming(long readyAt, long windowEndsAt) { + return new FishingSession(ownerUuid, rodItemId, medium, baitItemId, castAt, readyAt, windowEndsAt, biteReady, resolved); + } + + public FishingSession withBiteReady(boolean ready) { + return new FishingSession(ownerUuid, rodItemId, medium, baitItemId, castAt, biteReadyAt, biteWindowEndsAt, ready, resolved); + } + + public FishingSession withResolved(boolean nextResolved) { + return new FishingSession(ownerUuid, rodItemId, medium, baitItemId, castAt, biteReadyAt, biteWindowEndsAt, biteReady, nextResolved); + } +} diff --git a/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/fishing/FishingShipService.java b/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/fishing/FishingShipService.java new file mode 100644 index 000000000..aa9167c0b --- /dev/null +++ b/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/fishing/FishingShipService.java @@ -0,0 +1,30 @@ +package net.swofty.type.skyblockgeneric.fishing; + +import net.swofty.type.skyblockgeneric.data.SkyBlockDataHandler; +import net.swofty.type.skyblockgeneric.data.datapoints.DatapointShipState; +import net.swofty.type.skyblockgeneric.user.SkyBlockPlayer; + +public final class FishingShipService { + private FishingShipService() { + } + + public static DatapointShipState.ShipState getState(SkyBlockPlayer player) { + return player.getSkyblockDataHandler().get(SkyBlockDataHandler.Data.SHIP_STATE, DatapointShipState.class).getValue(); + } + + public static void installPart(SkyBlockPlayer player, ShipPartDefinition definition) { + DatapointShipState.ShipState state = getState(player); + switch (definition.slot()) { + case HELM -> state.setHelm(definition.itemId()); + case ENGINE -> state.setEngine(definition.itemId()); + case HULL -> state.setHull(definition.itemId()); + } + player.getSkyblockDataHandler().get(SkyBlockDataHandler.Data.SHIP_STATE, DatapointShipState.class).setValue(state); + } + + public static void unlockDestination(SkyBlockPlayer player, String destinationId) { + DatapointShipState.ShipState state = getState(player); + state.unlockDestination(destinationId); + player.getSkyblockDataHandler().get(SkyBlockDataHandler.Data.SHIP_STATE, DatapointShipState.class).setValue(state); + } +} diff --git a/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/fishing/FishingTableDefinition.java b/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/fishing/FishingTableDefinition.java new file mode 100644 index 000000000..13d287fbd --- /dev/null +++ b/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/fishing/FishingTableDefinition.java @@ -0,0 +1,19 @@ +package net.swofty.type.skyblockgeneric.fishing; + +import java.util.List; + +public record FishingTableDefinition( + String id, + List regions, + List mediums, + List items, + List treasures, + List junk, + List seaCreatures +) { + public record LootEntry(String itemId, double chance, int amount, double skillXp) { + } + + public record SeaCreatureRoll(String seaCreatureId, double chance) { + } +} diff --git a/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/fishing/HotspotDefinition.java b/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/fishing/HotspotDefinition.java new file mode 100644 index 000000000..de0af4eb1 --- /dev/null +++ b/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/fishing/HotspotDefinition.java @@ -0,0 +1,20 @@ +package net.swofty.type.skyblockgeneric.fishing; + +import net.swofty.commons.skyblock.statistics.ItemStatistics; + +import java.util.List; + +public record HotspotDefinition( + String id, + String displayName, + List regions, + FishingMedium medium, + int maxActive, + int durationSeconds, + ItemStatistics buffs, + List seaCreatureIds, + List spawnPoints +) { + public record SpawnPoint(double x, double y, double z, String serverType) { + } +} diff --git a/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/fishing/RodPartDefinition.java b/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/fishing/RodPartDefinition.java new file mode 100644 index 000000000..fbd19e56a --- /dev/null +++ b/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/fishing/RodPartDefinition.java @@ -0,0 +1,30 @@ +package net.swofty.type.skyblockgeneric.fishing; + +import net.swofty.commons.skyblock.statistics.ItemStatistics; +import org.jetbrains.annotations.Nullable; + +import java.util.List; +import java.util.Map; + +public record RodPartDefinition( + String itemId, + String displayName, + PartCategory category, + int requiredFishingLevel, + ItemStatistics statistics, + List lore, + Map tagBonuses, + boolean treasureOnly, + boolean bayouTreasureToJunk, + @Nullable String materializedItemId, + double materializedChance, + double baitPreservationChance, + double hotspotBuffMultiplier, + @Nullable String texture +) { + public enum PartCategory { + HOOK, + LINE, + SINKER + } +} diff --git a/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/fishing/SeaCreatureDefinition.java b/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/fishing/SeaCreatureDefinition.java new file mode 100644 index 000000000..e9ceb5727 --- /dev/null +++ b/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/fishing/SeaCreatureDefinition.java @@ -0,0 +1,14 @@ +package net.swofty.type.skyblockgeneric.fishing; + +import java.util.List; + +public record SeaCreatureDefinition( + String id, + String displayName, + int requiredFishingLevel, + double skillXp, + List tags, + String corruptedVariantId +) { +} + diff --git a/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/fishing/ShipPartDefinition.java b/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/fishing/ShipPartDefinition.java new file mode 100644 index 000000000..60667cf38 --- /dev/null +++ b/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/fishing/ShipPartDefinition.java @@ -0,0 +1,19 @@ +package net.swofty.type.skyblockgeneric.fishing; + +import org.jetbrains.annotations.Nullable; + +import java.util.List; + +public record ShipPartDefinition( + String itemId, + String displayName, + ShipPartSlot slot, + List lore, + @Nullable String texture +) { + public enum ShipPartSlot { + HELM, + ENGINE, + HULL + } +} diff --git a/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/fishing/TrophyFishDefinition.java b/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/fishing/TrophyFishDefinition.java new file mode 100644 index 000000000..e3736b5ab --- /dev/null +++ b/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/fishing/TrophyFishDefinition.java @@ -0,0 +1,25 @@ +package net.swofty.type.skyblockgeneric.fishing; + +import org.jetbrains.annotations.Nullable; + +import java.util.List; + +public record TrophyFishDefinition( + String id, + String displayName, + double catchChance, + List regions, + int requiredFishingLevel, + long minimumCastTimeMs, + @Nullable String requiredRodId, + @Nullable Double minimumMana, + @Nullable Double minimumBobberDepth, + @Nullable Double maximumPlayerDistance, + boolean requiresStarterRodWithoutEnchantments, + boolean specialGoldenFish, + @Nullable String bronzeItemId, + @Nullable String silverItemId, + @Nullable String goldItemId, + @Nullable String diamondItemId +) { +} diff --git a/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/gui/inventories/fishing/FishingGuideStackFactory.java b/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/gui/inventories/fishing/FishingGuideStackFactory.java new file mode 100644 index 000000000..d8d9b39e6 --- /dev/null +++ b/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/gui/inventories/fishing/FishingGuideStackFactory.java @@ -0,0 +1,151 @@ +package net.swofty.type.skyblockgeneric.gui.inventories.fishing; + +import net.swofty.commons.StringUtility; +import net.swofty.commons.skyblock.item.ItemType; +import net.swofty.commons.skyblock.statistics.ItemStatistic; +import net.swofty.commons.skyblock.statistics.ItemStatistics; +import net.swofty.type.generic.gui.inventory.ItemStackCreator; +import net.swofty.type.skyblockgeneric.fishing.BaitDefinition; +import net.swofty.type.skyblockgeneric.fishing.FishingMedium; +import net.swofty.type.skyblockgeneric.fishing.RodPartDefinition; + +import java.util.ArrayList; +import java.util.List; +import java.util.Map; + +public final class FishingGuideStackFactory { + private static final List GUIDE_STAT_ORDER = List.of( + ItemStatistic.DAMAGE, + ItemStatistic.STRENGTH, + ItemStatistic.FEROCITY, + ItemStatistic.FISHING_SPEED, + ItemStatistic.SEA_CREATURE_CHANCE, + ItemStatistic.DOUBLE_HOOK_CHANCE, + ItemStatistic.TREASURE_CHANCE, + ItemStatistic.TROPHY_FISH_CHANCE, + ItemStatistic.MAGIC_FIND + ); + + private FishingGuideStackFactory() { + } + + public static net.minestom.server.item.ItemStack.Builder buildBaitStack(BaitDefinition bait) { + List lore = new ArrayList<>(); + lore.add("§8Fishing Bait"); + lore.add("§8Consumes on Cast"); + lore.add(""); + appendStatistics(lore, bait.statistics()); + appendTagBonuses(lore, bait.tagBonuses()); + + if (bait.treasureChanceBonus() > 0) { + lore.add("§7Grants §6+" + format(bait.treasureChanceBonus()) + " Treasure Chance§7."); + } + if (bait.treasureQualityBonus() > 0) { + lore.add("§7Increases treasure quality by §a" + format(bait.treasureQualityBonus()) + "%§7."); + } + if (bait.trophyFishChanceBonus() > 0) { + lore.add("§7Grants §6+" + format(bait.trophyFishChanceBonus()) + " Trophy Fish Chance§7."); + } + if (bait.doubleHookChanceBonus() > 0) { + lore.add("§7Grants §9+" + format(bait.doubleHookChanceBonus()) + " Double Hook Chance§7."); + } + if (bait.mediums().size() == 1) { + lore.add("§7Usable in §" + (bait.mediums().getFirst() == FishingMedium.WATER ? "bWater" : "cLava") + "§7."); + } + finishFooter(lore, bait.itemId(), "BAIT"); + + return ItemStackCreator.getStackHead( + coloredName(bait.itemId(), bait.displayName()), + bait.texture(), + 1, + lore.toArray(String[]::new) + ); + } + + public static net.minestom.server.item.ItemStack.Builder buildRodPartStack(RodPartDefinition part) { + List lore = new ArrayList<>(); + lore.add("§8" + StringUtility.toNormalCase(part.category().name()) + " Rod Part"); + lore.add(""); + appendStatistics(lore, part.statistics()); + appendTagBonuses(lore, part.tagBonuses()); + + if (part.treasureOnly()) { + lore.add("§7Only allows you to catch items and §6Treasure§7."); + } + if (part.bayouTreasureToJunk()) { + lore.add("§7Replaces §6Treasure §7catches with §2Junk §7in the §2Backwater Bayou§7."); + } + if (part.materializedItemId() != null) { + String itemName = ItemType.valueOf(part.materializedItemId()).getDisplayName(); + if (part.materializedChance() >= 1.0D) { + lore.add("§7Materializes §f" + itemName + " §7in your inventory whenever you catch something."); + } else { + lore.add("§7Has a §a" + format(part.materializedChance() * 100.0D) + "% §7chance to materialize §f" + itemName + "§7."); + } + } + if (part.baitPreservationChance() > 0) { + lore.add("§7Grants a §a" + format(part.baitPreservationChance()) + "% §7chance to not consume Bait."); + } + if (part.hotspotBuffMultiplier() > 1.0D) { + lore.add("§7Increases the bonuses of §dFishing Hotspots §7by §a" + format((part.hotspotBuffMultiplier() - 1.0D) * 100.0D) + "%§7."); + } + if (part.requiredFishingLevel() > 0) { + lore.add(""); + lore.add("§4❣ §cRequires §aFishing Skill " + part.requiredFishingLevel() + "§c."); + } + finishFooter(lore, part.itemId(), "ROD PART"); + + return ItemStackCreator.getStackHead( + coloredName(part.itemId(), part.displayName()), + part.texture(), + 1, + lore.toArray(String[]::new) + ); + } + + private static void appendStatistics(List lore, ItemStatistics statistics) { + for (ItemStatistic statistic : GUIDE_STAT_ORDER) { + double amount = statistics.getOverall(statistic); + if (amount == 0) { + continue; + } + lore.add("§7" + statistic.getDisplayName() + ": " + statistic.getLoreColor() + + statistic.getPrefix() + format(amount) + statistic.getSuffix()); + } + } + + private static void appendTagBonuses(List lore, Map bonuses) { + for (Map.Entry entry : bonuses.entrySet()) { + lore.add("§7Increases the chance to catch §e" + describeTag(entry.getKey()) + " §7by §a" + format(entry.getValue()) + "%§7."); + } + } + + private static void finishFooter(List lore, String itemId, String suffix) { + if (!lore.isEmpty() && !lore.getLast().isEmpty()) { + lore.add(""); + } + lore.add(ItemType.valueOf(itemId).rarity.getDisplay() + " " + suffix); + } + + private static String coloredName(String itemId, String displayName) { + return ItemType.valueOf(itemId).rarity.getColor() + displayName; + } + + private static String describeTag(String tag) { + return switch (tag.toUpperCase()) { + case "COMMON" -> "Common Sea Creatures"; + case "HOTSPOT" -> "Hotspot Sea Creatures"; + case "SPOOKY" -> "Spooky Sea Creatures"; + case "WINTER" -> "Winter Sea Creatures"; + case "SHARK" -> "Sharks"; + default -> StringUtility.toNormalCase(tag.toLowerCase().replace('_', ' ')); + }; + } + + private static String format(double value) { + if (Math.abs(value - Math.rint(value)) < 0.0001D) { + return String.valueOf((long) Math.rint(value)); + } + return StringUtility.decimalify(value, 1); + } +} \ No newline at end of file diff --git a/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/gui/inventories/fishing/GUI13SeaCreatureGuide.java b/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/gui/inventories/fishing/GUI13SeaCreatureGuide.java new file mode 100644 index 000000000..8a2fae43d --- /dev/null +++ b/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/gui/inventories/fishing/GUI13SeaCreatureGuide.java @@ -0,0 +1,645 @@ +package net.swofty.type.skyblockgeneric.gui.inventories.fishing; + +import net.minestom.server.inventory.InventoryType; +import net.minestom.server.item.Material; +import net.swofty.type.generic.gui.inventory.ItemStackCreator; +import net.swofty.type.generic.gui.v2.Components; +import net.swofty.type.generic.gui.v2.DefaultState; +import net.swofty.type.generic.gui.v2.StatelessView; +import net.swofty.type.generic.gui.v2.ViewConfiguration; +import net.swofty.type.generic.gui.v2.ViewLayout; +import net.swofty.type.generic.gui.v2.context.ViewContext; + +// make these actually paginated views +public class GUI13SeaCreatureGuide extends StatelessView { + + @Override + public ViewConfiguration configuration() { + return new ViewConfiguration<>("(1/3) Sea Creature Guide", InventoryType.CHEST_6_ROW); + } + + @Override + public void layout(ViewLayout layout, DefaultState state, ViewContext ctx) { + Components.close(layout, 49); + + layout.slot(4, ItemStackCreator.getStack( + "§aSea Creature Guide", + Material.BOOK, + 1, + "§7Your guide to the creatures of the", + "§7deep! Can also be accessed with", + "§a/scg§7!", + "", + "§7Beware, Sea Creatures spawn much", + "§7less often on your private island.", + "", + "§7Your Fishing: §aLevel XVIII" + )); + layout.slot(10, ItemStackCreator.getStackHead( + "§7[Lvl 1] Squid (§f§lCommon§7)", + "32581d564f01d712255125e1f101e534217f76e3599dab7f4ae0ffe328f729eb", + 1, + "§9⚓ Aquatic§7, §a☮ Animal", + "", + "§cDrops:", + "§7- Ink Sac", + "§7- Lily Pad", + "", + "§cRequirements:", + "§7- §aFishing Skill 1", + "§7- §bWater", + "", + "§cStats", + "§7- Kills: §b64" + )); + layout.slot(11, ItemStackCreator.getStackHead( + "§7[Lvl 4] Sea Walker (§f§lCommon§7)", + "d88ba8bb50b79e441e47b7e452764d5fff6693779d2dadd9f7f52f98d7ea0", + 1, + "§9⚓ Aquatic§7, §2༕ Undead", + "", + "§cDrops:", + "§7- Lily Pad", + "§7- Raw Cod", + "§7- Rotten Flesh", + "", + "§cRequirements:", + "§7- §aFishing Skill 1", + "§7- §bWater", + "", + "§cStats", + "§7- Kills: §b64" + )); + layout.slot(12, ItemStackCreator.getStackHead( + "§7[Lvl 6] Night Squid (§f§lCommon§7)", + "32581d564f01d712255125e1f101e534217f76e3599dab7f4ae0ffe328f729eb", + 1, + "§9⚓ Aquatic§7, §a☮ Animal", + "", + "§cDrops:", + "§7- Ink Sac", + "§7- Lily Pad", + "§7- §aFishing Exp Boost", + "§7- §aSquid Boots", + "§7- §9Fishing Exp Boost", + "", + "§cRequirements:", + "§7- §aFishing Skill 3", + "§7- §bWater", + "§7- Nighttime", + "§7- §fDark Bait" + )); + layout.slot(13, ItemStackCreator.getStackHead( + "§7[Lvl 10] Sea Guardian (§f§lCommon§7)", + "221025434045bda7025b3e514b316a4b770c6faa4ba9adb4be3809526db77f9d", + 1, + "§9⚓ Aquatic§7, §5♃ Arcane", + "", + "§cDrops:", + "§7- Lily Pad", + "§7- Prismarine Crystals", + "§7- Prismarine Shard", + "", + "§cRequirements:", + "§7- §aFishing Skill 5", + "§7- §bWater", + "", + "§cStats", + "§7- Kills: §b48" + )); + layout.slot(14, ItemStackCreator.getStackHead( + "§7[Lvl 10] Frog Man (§f§lCommon§7)", + "6157f19da077a3df49b2925fb6e8b400222ba6e559e86815f9b296d9e9667dd7", + 1, + "§9⚓ Aquatic§7, §a☮ Animal§7, §e✰ Humanoid", + "", + "§cDrops:", + "§7- Lily Pad", + "§7- Tropical Fish", + "§7- §aHalf-Eaten Mushroom", + "", + "§cRequirements:", + "§7- §aFishing Skill 5", + "§7- §bWater", + "§7- §dFishing Hotspot", + "", + "§cStats", + "§7- Kills: §b28" + )); + layout.slot(15, ItemStackCreator.getStackHead( + "§7[Lvl 8] Trash Gobbler (§f§lCommon§7)", + "18ae7046da98dcb33f3ed42f1dc41d08ac8dfa5db3a3860de5b1b5c056804187", + 1, + "§9⚓ Aquatic§7, §4Ж Arthropod", + "", + "§cDrops:", + "§7- Clay Ball", + "§7- Lily Pad", + "§7- Raw Cod", + "§7- §aCan of Worms", + "", + "§cRequirements:", + "§7- §aFishing Skill 5", + "§7- §bWater", + "§7- §2Backwater Bayou", + "", + "§cStats", + "§7- Kills: §b57" + )); + layout.slot(16, ItemStackCreator.getStackHead( + "§7[Lvl 10] Bogged (§f§lCommon§7)", + "a3b9003ba2d05562c75119b8a62185c67130e9282f7acbac4bc2824c21eb95d9", + 1, + "§f🦴 Skeletal§7, §9⚓ Aquatic", + "", + "§cDrops:", + "§7- Mangrove Log", + "§7- Sea Lumies", + "", + "§cRequirements:", + "§7- §aFishing Skill 5", + "§7- §bWater", + "§7- §2Galatea" + )); + layout.slot(19, ItemStackCreator.getStackHead( + "§7[Lvl 7] Frozen Steve (§f§lCommon§7)", + "54690f5aa6d0e800f9b8d1890fc158b921819a81dfd7342a2170e7efc46b9ed7", + 1, + "§9⚓ Aquatic§7, §f☃ Frozen§7, §e✰ Humanoid", + "", + "§cDrops:", + "§7- §9Ice Essence", + "§7- Ice", + "§7- Lily Pad", + "§7- Pufferfish", + "§7- Raw Cod", + "§7- Raw Salmon", + "§7- White Gift", + "§7- §aHunk of Ice", + "§7- §9Icy Sinker", + "", + "§cRequirements:", + "§7- §aFishing Skill 5", + "§7- §bWater", + "§7- §cJerry's Workshop", + "", + "§cStats", + "§7- Kills: §b9" + )); + layout.slot(20, ItemStackCreator.getStackHead( + "§7[Lvl 15] Dumpster Diver (§a§lUncommon§7)", + "f5c5eb5ee072c06580986d12a029e28010c1290875534810c53140bc76dabfeb", + 1, + "§9⚓ Aquatic§7, §e✰ Humanoid", + "", + "§cDrops:", + "§7- Clay Ball", + "§7- Lily Pad", + "§7- Raw Cod", + "§7- Sponge", + "§7- §aBronze Bowl", + "§7- §aOverflowing Trash Can", + "", + "§cRequirements:", + "§7- §aFishing Skill 5", + "§7- §bWater", + "§7- §2Backwater Bayou", + "", + "§cStats", + "§7- Kills: §b38" + )); + layout.slot(21, ItemStackCreator.getStackHead( + "§7[Lvl 6] Nurse Shark (§a§lUncommon§7)", + "2067ccefba5d811f47e3e18438556b704393aafcafccedd5d0981999286f598a", + 1, + "§9⚓ Aquatic§7, §a☮ Animal", + "", + "§cDrops:", + "§7- §aCarnival Ticket", + "§7- §aNurse Shark Tooth", + "§7- §9Shark Fin", + "", + "§cRequirements:", + "§7- §aFishing Skill 5", + "§7- §bWater", + "§7- §bFishing Festival" + )); + layout.slot(22, ItemStackCreator.getStack( + "§7[Lvl 13] Frosty (§f§lCommon§7)", + Material.CARVED_PUMPKIN, + 1, + "§9⚓ Aquatic§7, §f☃ Frozen§7, ⚙ Construct", + "", + "§cDrops:", + "§7- §9Ice Essence", + "§7- Carrot", + "§7- Ice", + "§7- Lily Pad", + "§7- Raw Cod", + "§7- Snow Block", + "§7- Sponge", + "§7- White Gift", + "§7- §aHunk of Ice", + "", + "§cRequirements:", + "§7- §aFishing Skill 6", + "§7- §bWater", + "§7- §cJerry's Workshop", + "", + "§cStats", + "§7- Kills: §b9" + )); + layout.slot(23, ItemStackCreator.getStackHead( + "§7[Lvl 15] Mithril Grubber (§a§lUncommon§7)", + "811a1173af3bead305e6339f555662e990d5faadb87e07299fa68ca828a6d2fb", + 1, + "§9⚓ Aquatic§7, §4Ж Arthropod", + "", + "§cDrops:", + "§7- §9Mithril Powder", + "§7- Mithril", + "§7- Raw Cod", + "§7- §9Enchanted Mithril", + "", + "§cRequirements:", + "§7- §aFishing Skill 6", + "§7- §bWater", + "§7- §2Abandoned Quarry" + )); + layout.slot(24, ItemStackCreator.getStackHead( + "§7[Lvl 18] Wetwing (§a§lUncommon§7)", + "dbc0f7c9e926c320ba472d4a88763ef932a660c470f786ac0c04c15a78fd505f", + 1, + "§9⚓ Aquatic§7, §2༕ Undead§7, §a☮ Animal", + "", + "§cDrops:", + "§7- Mangrove Log", + "§7- Sea Lumies", + "§7- §aWet Water", + "§7- §9Enchanted Mangrove Log", + "", + "§cRequirements:", + "§7- §aFishing Skill 7", + "§7- §bWater", + "§7- §2Galatea", + "", + "§cStats", + "§7- Kills: §b1" + )); + layout.slot(25, ItemStackCreator.getStackHead( + "§7[Lvl 15] Sea Witch (§a§lUncommon§7)", + "fce6604157fc4ab5591e4bcf507a749918ee9c41e357d47376e0ee7342074c90", + 1, + "§9⚓ Aquatic§7, §e✰ Humanoid§7, §5♃ Arcane", + "", + "§cDrops:", + "§7- Lily Pad", + "§7- Raw Salmon", + "§7- Tropical Fish", + "§7- §9Fairy's Fedora", + "§7- §9Fairy's Galoshes", + "§7- §9Fairy's Polo", + "§7- §9Fairy's Trousers", + "", + "§cRequirements:", + "§7- §aFishing Skill 7", + "§7- §bWater", + "", + "§cStats", + "§7- Kills: §b52" + )); + layout.slot(28, ItemStackCreator.getStack( + "§7[Lvl 9] Scarecrow (§f§lCommon§7)", + Material.CARVED_PUMPKIN, + 1, + "§9⚓ Aquatic§7, §6☽ Spooky", + "", + "§cDrops:", + "§7- Hay Bale", + "§7- Lily Pad", + "§7- §aGreen Candy", + "§7- §5Purple Candy", + "", + "§cRequirements:", + "§7- §aFishing Skill 9", + "§7- §bWater", + "§7- §6Spooky Festival" + )); + layout.slot(29, ItemStackCreator.getStack( + "§7[Lvl 15] Sea Archer (§a§lUncommon§7)", + Material.SKELETON_SKULL, + 1, + "§9⚓ Aquatic§7, §f🦴 Skeletal", + "", + "§cDrops:", + "§7- Bone", + "§7- Lily Pad", + "§7- Raw Cod", + "§7- §aEnchanted Bone", + "", + "§cRequirements:", + "§7- §aFishing Skill 9", + "§7- §bWater", + "", + "§cStats", + "§7- Kills: §b48" + )); + layout.slot(30, ItemStackCreator.getStackHead( + "§7[Lvl 8] Tadgang (§9§lRare§7)", + "1608d86ffb297bf93b7190d24bc3b2dc094f8086740f7541a752fbe661f175fc", + 1, + "§9⚓ Aquatic§7, §a☮ Animal", + "", + "§cDrops:", + "§7- Mangrove Log", + "§7- Sea Lumies", + "§7- §aEnchanted Sea Lumies", + "§7- §aGill Membrane", + "§7- §9Enchanted Mangrove Log", + "", + "§cRequirements:", + "§7- §aFishing Skill 9", + "§7- §bWater", + "§7- §2Galatea", + "", + "§cStats", + "§7- Kills: §b1" + )); + layout.slot(31, ItemStackCreator.getStackHead( + "§7[Lvl 10] Oasis Sheep (§a§lUncommon§7)", + "292df216ecd27624ac771bacfbfe006e1ed84a79e9270be0f88e9c8791d1ece4", + 1, + "§9⚓ Aquatic§7, §a☮ Animal", + "", + "§cDrops:", + "§7- Lily Pad", + "§7- Raw Mutton", + "§7- White Wool", + "§7- §aEnchanted Raw Mutton", + "§7- §9Enchanted Cooked Mutton", + "", + "§cRequirements:", + "§7- §aFishing Skill 10", + "§7- §bWater", + "§7- §bOasis" + )); + layout.slot(32, ItemStackCreator.getStackHead( + "§7[Lvl 10] Oasis Rabbit (§a§lUncommon§7)", + "b50459bcb08db5ce93e021079c1cfc038c9ebe7ad9a149516efe4d5ee8afb59f", + 1, + "§9⚓ Aquatic§7, §a☮ Animal", + "", + "§cDrops:", + "§7- Lily Pad", + "§7- Rabbit Hide", + "§7- Rabbit's Foot", + "§7- Raw Rabbit", + "§7- §aEnchanted Raw Rabbit", + "", + "§cRequirements:", + "§7- §aFishing Skill 10", + "§7- §bWater", + "§7- §bOasis" + )); + layout.slot(33, ItemStackCreator.getStackHead( + "§7[Lvl 10] Banshee (§9§lRare§7)", + "30ccc3c9a06de657b98f881e23a57ecaeb252c364ddb7b92564f5ed2b8087e3b", + 1, + "§9⚓ Aquatic§7, §e✰ Humanoid", + "", + "§cDrops:", + "§7- Clay Ball", + "§7- Lily Pad", + "§7- Raw Salmon", + "§7- Tropical Fish", + "§7- §aEnchanted Clay Ball", + "§7- §aTorn Cloth", + "§7- §9Calcified Heart", + "", + "§cRequirements:", + "§7- §aFishing Skill 10", + "§7- §bWater", + "§7- §2Backwater Bayou", + "", + "§cStats", + "§7- Kills: §b22" + )); + layout.slot(34, ItemStackCreator.getStackHead( + "§7[Lvl 20] Blue Shark (§9§lRare§7)", + "381e1d06e5f0654a682a3264905b5dc4b8e7b613ab6697ac45f2e0da3bc9b4fd", + 1, + "§9⚓ Aquatic§7, §a☮ Animal", + "", + "§cDrops:", + "§7- §aCarnival Ticket", + "§7- §9Blue Shark Tooth", + "§7- §9Shark Fin", + "", + "§cRequirements:", + "§7- §aFishing Skill 10", + "§7- §bWater", + "§7- §bFishing Festival" + )); + layout.slot(37, ItemStackCreator.getStackHead( + "§7[Lvl 30] Snapping Turtle (§9§lRare§7)", + "e08fc1ae87a7035d32b0b0da58de4801463aaf8b238618024aacb0c515ae3bba", + 1, + "§9⚓ Aquatic§7, §a☮ Animal", + "", + "§cDrops:", + "§7- Gold Ingot", + "§7- Lily Pad", + "§7- Raw Cod", + "§7- §aEnchanted Gold Ingot", + "§7- §9Broken Radar", + "§7- §9Edible Seaweed", + "", + "§cRequirements:", + "§7- §aFishing Skill 10", + "§7- §bWater", + "§7- §dFishing Hotspot", + "", + "§cStats", + "§7- Kills: §b5" + )); + layout.slot(38, ItemStackCreator.getStackHead( + "§7[Lvl 20] Rider of the Deep (§a§lUncommon§7)", + "cfb7dbbe002f69463768113c1e925848197f59b62694ce105792dd5a52dc17a1", + 1, + "§9⚓ Aquatic§7, §2༕ Undead§7, §a☮ Animal", + "", + "§cDrops:", + "§7- Dark Bait", + "§7- Lily Pad", + "§7- Sponge", + "§7- §9Enchanted Book", + "§7 (Magnet VI)", + "§7- §aEnchanted Feather", + "§7- §aEnchanted Rotten Flesh", + "", + "§cRequirements:", + "§7- §aFishing Skill 11", + "§7- §bWater", + "", + "§cStats", + "§7- Kills: §b36" + )); + layout.slot(39, ItemStackCreator.getStackHead( + "§7[Lvl 14] Ent (§5§lEpic§7)", + "30519f79e5829136c3df10b6bd727db255717c87e5c102892ef67e7f46929515", + 1, + "§2⸙ Woodland§7, §9⚓ Aquatic", + "", + "§cDrops:", + "§7- Sea Lumies", + "§7- §aEnchanted Sea Lumies", + "§7- §9Enchanted Mangrove Log", + "§7- §5Foraging Exp Boost", + "§7- §5Mangcore", + "", + "§cRequirements:", + "§7- §aFishing Skill 12", + "§7- §bWater", + "§7- §2Galatea" + )); + layout.slot(40, ItemStackCreator.getStackHead( + "§7[Lvl 21] Grinch (§a§lUncommon§7)", + "2508e4a2f88502c019652b2437b76c82fedff9091389d88118ecc673f628b547", + 1, + "§9⚓ Aquatic§7, §f☃ Frozen§7, §e✰ Humanoid", + "", + "§cDrops:", + "§7- §9Ice Essence", + "§7- White Gift", + "§7- §aGreen Gift", + "", + "§cRequirements:", + "§7- §aFishing Skill 13", + "§7- §bWater", + "§7- §cJerry's Workshop", + "", + "§cStats", + "§7- Kills: §b2" + )); + layout.slot(41, ItemStackCreator.getStackHead( + "§7[Lvl 23] Catfish (§9§lRare§7)", + "e18f77331b2cab64e2b430fa8e4273e4db7f78fcdfa4b1a9a418af47375056eb", + 1, + "§9⚓ Aquatic§7, §a☮ Animal", + "", + "§cDrops:", + "§7- Lily Pad", + "§7- Pufferfish", + "§7- Raw Cod", + "§7- Raw Salmon", + "§7- Sponge", + "§7- Tropical Fish", + "§7- §9Enchanted Book", + "§7 (Frail VI)", + "", + "§cRequirements:", + "§7- §aFishing Skill 13", + "§7- §bWater", + "", + "§cStats", + "§7- Kills: §b26" + )); + layout.slot(42, ItemStackCreator.getStack( + "§7[Lvl 30] Fried Chicken (§f§lCommon§7)", + Material.COOKED_CHICKEN, + 1, + "§c♆ Magmatic§7, §a☮ Animal", + "", + "§cDrops:", + "§7- Raw Chicken", + "§7- §aEnchanted Raw Chicken", + "§7- §aFried Feather", + "§7- §9Magmafish", + "", + "§cRequirements:", + "§7- §aFishing Skill 14", + "§7- §cLava", + "§7- §dFishing Hotspot", + "§7- §cCrimson Isle" + )); + layout.slot(43, ItemStackCreator.getStackHead( + "§7[Lvl 25] Carrot King (§9§lRare§7)", + "b50459bcb08db5ce93e021079c1cfc038c9ebe7ad9a149516efe4d5ee8afb59f", + 1, + "§9⚓ Aquatic§7, §a☮ Animal", + "", + "§cDrops:", + "§7- Lily Pad", + "§7- Sponge", + "§7- §9Enchanted Book", + "§7 (Caster VI)", + "§7- §aEnchanted Carrot", + "§7- §aRabbit Hat", + "§7- §9Enchanted Rabbit Foot", + "§7- §5Lucky Clover Core", + "", + "§cRequirements:", + "§7- §aFishing Skill 14", + "§7- §bWater", + "§7- §fCarrot Bait" + )); + layout.slot(48, ItemStackCreator.getStack( + "§aGo Back", + Material.ARROW, + 1, + "§7To Fishing Skill" + )); + layout.slot(50, ItemStackCreator.getStack( + "§aSort", + Material.HOPPER, + 1, + "", + "§b▶ Fishing Level Req", + "§7 Alphabetical", + "§7 Mob Level", + "§7 Killed Most", + "§7 Ascending Rarity", + "§7 Descending Rarity", + "", + "§bRight-click to go backwards!", + "§eClick to switch!" + )); + layout.slot(51, ItemStackCreator.getStack( + "§aFilter", + Material.ENDER_EYE, + 1, + "", + "§f▶ All Sea Creatures", + "§7 Has Level Requirement", + "§7 Has Never Killed", + "", + "§bRight-click to go backwards!", + "§eClick to switch!" + )); + layout.slot(52, ItemStackCreator.getStack( + "§aCategory", + Material.CAULDRON, + 1, + "", + "§a▶ Any Category", + "§7 Water", + "§7 Lava", + "§7 Winter", + "§7 Spooky", + "§7 Shark", + "§7 Oasis", + "§7 Bayou", + "§7 Hotspot", + "§7 Galatea", + "", + "§bRight-click to go backwards!", + "§eClick to switch!" + )); + layout.slot(53, ItemStackCreator.getStack( + "§aNext Page", + Material.ARROW, + 1, + "§ePage 2" + )); + } +} diff --git a/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/gui/inventories/fishing/GUI23SeaCreatureGuide.java b/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/gui/inventories/fishing/GUI23SeaCreatureGuide.java new file mode 100644 index 000000000..3a7c29f06 --- /dev/null +++ b/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/gui/inventories/fishing/GUI23SeaCreatureGuide.java @@ -0,0 +1,574 @@ +package net.swofty.type.skyblockgeneric.gui.inventories.fishing; + +import net.minestom.server.inventory.InventoryType; +import net.minestom.server.item.Material; +import net.swofty.type.generic.gui.inventory.ItemStackCreator; +import net.swofty.type.generic.gui.v2.Components; +import net.swofty.type.generic.gui.v2.DefaultState; +import net.swofty.type.generic.gui.v2.StatelessView; +import net.swofty.type.generic.gui.v2.ViewConfiguration; +import net.swofty.type.generic.gui.v2.ViewLayout; +import net.swofty.type.generic.gui.v2.context.ViewContext; + +// make these actually paginated views and data-driven +public class GUI23SeaCreatureGuide extends StatelessView { + + @Override + public ViewConfiguration configuration() { + return new ViewConfiguration<>("(2/3) Sea Creature Guide", InventoryType.CHEST_6_ROW); + } + + @Override + public void layout(ViewLayout layout, DefaultState state, ViewContext ctx) { + Components.close(layout, 49); + + layout.slot(4, ItemStackCreator.getStack( + "§aSea Creature Guide", + Material.BOOK, + 1, + "§7Your guide to the creatures of the", + "§7deep! Can also be accessed with", + "§a/scg§7!", + "", + "§7Beware, Sea Creatures spawn much", + "§7less often on your private island.", + "", + "§7Your Fishing: §aLevel XVIII" + )); + layout.slot(10, ItemStackCreator.getStackHead( + "§7[Lvl 24] Nightmare (§9§lRare§7)", + "578211e1b4d99d1c7bfda4838e48fc884c3eae376f58d932bc2f78b0a919f8e7", + 1, + "§9⚓ Aquatic§7, §6☽ Spooky§7, §2༕ Undead", + "", + "§cDrops:", + "§7- Lily Pad", + "§7- §aEnchanted Rotten Flesh", + "§7- §aGreen Candy", + "§7- §aLucky Hoof", + "§7- §5Purple Candy", + "", + "§cRequirements:", + "§7- §aFishing Skill 14", + "§7- §bWater", + "§7- §6Spooky Festival" + )); + layout.slot(11, ItemStackCreator.getStackHead( + "§7[Lvl 35] Agarimoo (§9§lRare§7)", + "3d597f77cde32c9ac9b06f82fcf7c9cb500facc14bff166222b24be39962f0ef", + 1, + "§9⚓ Aquatic§7, §a☮ Animal", + "", + "§cDrops:", + "§7- Red Mushroom", + "§7- §9Agarimoo Tongue", + "", + "§cRequirements:", + "§7- §aFishing Skill 15", + "§7- §aChumcap Bucket", + "§7- §bWater" + )); + layout.slot(12, ItemStackCreator.getStackHead( + "§7[Lvl 20] Water Worm (§9§lRare§7)", + "811a1173af3bead305e6339f555662e990d5faadb87e07299fa68ca828a6d2fb", + 1, + "§9⚓ Aquatic§7, §6⛏ Subterranean", + "", + "§cDrops:", + "§7- Hard Stone", + "§7- ⸕ Rough Amber Gemstone", + "§7- §aWorm Membrane", + "", + "§cRequirements:", + "§7- §aFishing Skill 15", + "§7- §bWater", + "§7- §6Goblin Holdout" + )); + layout.slot(13, ItemStackCreator.getStackHead( + "§7[Lvl 25] Bayou Sludge (§5§lEpic§7)", + "895aeec6b842ada8669f846d65bc49762597824ab944f22f45bf3bbb941abe6c", + 1, + "§9⚓ Aquatic§7, §a⚂ Cubic", + "", + "§cDrops:", + "§7- Clay Ball", + "§7- Enchanted Book", + "§7 (Respite I)", + "§7- Lily Pad", + "§7- Slimeball", + "§7- §9Enchanted Book", + "§7 (Blessing VI)", + "§7- §aEnchanted Slimeball", + "§7- §aPoison Sample", + "§7- §9Enchanted Slime Block", + "", + "§cRequirements:", + "§7- §aFishing Skill 15", + "§7- §bWater", + "§7- §2Backwater Bayou", + "", + "§cStats", + "§7- Kills: §b23" + )); + layout.slot(14, ItemStackCreator.getStackHead( + "§7[Lvl 30] Sea Leech (§9§lRare§7)", + "811a1173af3bead305e6339f555662e990d5faadb87e07299fa68ca828a6d2fb", + 1, + "§9⚓ Aquatic§7, §a☮ Animal", + "", + "§cDrops:", + "§7- Lily Pad", + "§7- Raw Cod", + "§7- Sponge", + "§7- Tropical Fish", + "§7- §9Enchanted Book", + "§7 (Spiked Hook VI)", + "§7- §9Fishing Exp Boost", + "§7- §5Fishing Exp Boost", + "", + "§cRequirements:", + "§7- §aFishing Skill 16", + "§7- §bWater", + "", + "§cStats", + "§7- Kills: §b15" + )); + layout.slot(15, ItemStackCreator.getStackHead( + "§7[Lvl 75] Fireproof Witch (§9§lRare§7)", + "fce6604157fc4ab5591e4bcf507a749918ee9c41e357d47376e0ee7342074c90", + 1, + "§c♆ Magmatic§7, §e✰ Humanoid§7, §5♃ Arcane", + "", + "§cDrops:", + "§7- §9Enchanted Book", + "§7 (Fire Protection VI)", + "§7- §aEnchanted Glowstone", + "§7- §aEnchanted Glowstone Dust", + "§7- §aSinged Powder", + "§7- §9Magmafish", + "", + "§cRequirements:", + "§7- §aFishing Skill 16", + "§7- §cLava", + "§7- §dFishing Hotspot", + "§7- §cCrimson Isle" + )); + layout.slot(16, ItemStackCreator.getStackHead( + "§7[Lvl 21] Stridersurfer (§9§lRare§7)", + "620971f4dd71592a6065944487da2adf22987d5d0cccf6085dff7a6767d1b21a", + 1, + "§c♆ Magmatic§7, §2༕ Undead§7, §2⸙ Woodland", + "", + "§cDrops:", + "§7- §aGill Membrane", + "§7- §9Sturdy Bone", + "", + "§cRequirements:", + "§7- §aFishing Skill 17", + "§7- §cLava", + "§7- §2Galatea", + "", + "§cStats", + "§7- Kills: §b8" + )); + layout.slot(19, ItemStackCreator.getStackHead( + "§7[Lvl 25] Poisoned Water Worm (§9§lRare§7)", + "18ae7046da98dcb33f3ed42f1dc41d08ac8dfa5db3a3860de5b1b5c056804187", + 1, + "§9⚓ Aquatic§7, §6⛏ Subterranean§7, §4Ж Arthropod", + "", + "§cDrops:", + "§7- Hard Stone", + "§7- ⸕ Rough Amber Gemstone", + "§7- §aWorm Membrane", + "", + "§cRequirements:", + "§7- §aFishing Skill 17", + "§7- §bWater", + "§7- §6Goblin Holdout" + )); + layout.slot(20, ItemStackCreator.getStackHead( + "§7[Lvl 45] Guardian Defender (§5§lEpic§7)", + "221025434045bda7025b3e514b316a4b770c6faa4ba9adb4be3809526db77f9d", + 1, + "§9⚓ Aquatic§7, §5♃ Arcane", + "", + "§cDrops:", + "§7- Lily Pad", + "§7- Raw Cod", + "§7- Sponge", + "§7- §9Enchanted Book", + "§7 (Lure VI)", + "§7- §aEnchanted Prismarine Crystals", + "§7- §aEnchanted Prismarine Shard", + "", + "§cRequirements:", + "§7- §aFishing Skill 17", + "§7- §bWater", + "", + "§cStats", + "§7- Kills: §b12" + )); + layout.slot(21, ItemStackCreator.getStackHead( + "§7[Lvl 50] Werewolf (§5§lEpic§7)", + "ce4606c6d973a999aec1687c7e075f7d37db8185e88b844507f16b3e2b3eb690", + 1, + "§9⚓ Aquatic§7, §6☽ Spooky§7, §a☮ Animal", + "", + "§cDrops:", + "§7- Lily Pad", + "§7- §aGreen Candy", + "§7- §9Werewolf Skin", + "§7- §5Deep Sea Orb", + "§7- §5Purple Candy", + "", + "§cRequirements:", + "§7- §aFishing Skill 17", + "§7- §bWater", + "§7- §6Spooky Festival" + )); + layout.slot(22, ItemStackCreator.getStackHead( + "§7[Lvl 50] Tiger Shark (§5§lEpic§7)", + "ea575977e6bd0c7add94e2d8fdcc2af77e36c44d6b4c67788862a94000be6399", + 1, + "§9⚓ Aquatic§7, §a☮ Animal", + "", + "§cDrops:", + "§7- §aCarnival Ticket", + "§7- §9Shark Fin", + "§7- §5Megalodon Pet", + "§7- §5Tiger Shark Tooth", + "", + "§cRequirements:", + "§7- §aFishing Skill 18", + "§7- §bWater", + "§7- §bFishing Festival" + )); + layout.slot(23, ItemStackCreator.getStackHead( + "§7[Lvl 60] Deep Sea Protector (§5§lEpic§7)", + "22bcaceeb4162f400d44743315932ac820d3119ac8986a0161a726161ccc93fc", + 1, + "§9⚓ Aquatic§7, ⚙ Construct", + "", + "§cDrops:", + "§7- Lily Pad", + "§7- Sponge", + "§7- Tropical Fish", + "§7- §9Enchanted Book", + "§7 (Angler VI)", + "§7- §aEnchanted Iron Ingot", + "§7- §5Fishing Exp Boost", + "", + "§cRequirements:", + "§7- §aFishing Skill 18", + "§7- §bWater", + "", + "§cStats", + "§7- Kills: §b7" + )); + layout.slot(24, ItemStackCreator.getStackHead( + "§7[Lvl §k?] §k????? (§9§lRare§7)", + "811a1173af3bead305e6339f555662e990d5faadb87e07299fa68ca828a6d2fb", + 1, + "§c♆ Magmatic§7, §4Ж Arthropod", + "", + "§cDrops:", + "§7- §k???????", + "", + "§cRequirements:", + "§7- §aFishing Skill 19", + "§7- §cLava", + "§7- §bPrecursor Remnants" + )); + layout.slot(25, ItemStackCreator.getStackHead( + "§7[Lvl §k?] §k????? (§6§lLegendary§7)", + "6d6bcd3bea0dff1f45d808e7a8550f95106af41b6d8d18a0793e19c9255ae845", + 1, + "§9⚓ Aquatic§7, §e✰ Humanoid", + "", + "§cDrops:", + "§7- §k???????", + "", + "§cRequirements:", + "§7- §aFishing Skill 19", + "§7- §bWater", + "", + "§cStats", + "§7- Kills: §b1" + )); + layout.slot(28, ItemStackCreator.getStackHead( + "§7[Lvl §k?] §k????? (§5§lEpic§7)", + "b78ef2e4cf2c41a2d14bfde9caff10219f5b1bf5b35a49eb51c6467882cb5f0", + 1, + "§c♆ Magmatic§7, §4♨ Infernal", + "", + "§cDrops:", + "§7- §k???????", + "", + "§cRequirements:", + "§7- §aFishing Skill 20", + "§7- §cLava", + "§7- §cMagma Fields" + )); + layout.slot(29, ItemStackCreator.getStackHead( + "§7[Lvl §k?] §k????? (§6§lLegendary§7)", + "5cf6abfbc778b1fac0d6db161e74438a1b468323b6f93fa4d650e42cd0f5802a", + 1, + "§9⚓ Aquatic§7, §a☮ Animal", + "", + "§cDrops:", + "§7- §k???????", + "", + "§cRequirements:", + "§7- §aFishing Skill 20", + "§7- §bWater", + "§7- §2Backwater Bayou", + "", + "§cStats", + "§7- Kills: §b6" + )); + layout.slot(30, ItemStackCreator.getStackHead( + "§7[Lvl §k?] §k????? (§6§lLegendary§7)", + "46c15b527e4872249c91797435521cb77651b567e57518304f5f131e49ded652", + 1, + "§9⚓ Aquatic§7, §f🦴 Skeletal§7, §5♃ Arcane", + "", + "§cDrops:", + "§7- §k???????", + "", + "§cRequirements:", + "§7- §aFishing Skill 20", + "§7- §bWater", + "§7- §2Galatea" + )); + layout.slot(31, ItemStackCreator.getStackHead( + "§7[Lvl §k?] §k????? (§6§lLegendary§7)", + "6c9bc01f299f98d565a27ba10a1293915ae8beeefb8a67845e2331dbe6fd6fd6", + 1, + "§9⚓ Aquatic§7, §6☽ Spooky§7, §5♃ Arcane", + "", + "§cDrops:", + "§7- §k???????", + "", + "§cRequirements:", + "§7- §aFishing Skill 21", + "§7- §bWater", + "§7- §6Spooky Festival" + )); + layout.slot(32, ItemStackCreator.getStackHead( + "§7[Lvl §k?] §k????? (§5§lEpic§7)", + "74e9c6e98582ffd8ff8feb3322cd1849c43fb16b158abb11ca7b42eda7743eb", + 1, + "§c♆ Magmatic§7, §2༕ Undead", + "", + "§cDrops:", + "§7- §k???????", + "", + "§cRequirements:", + "§7- §aFishing Skill 22", + "§7- §cLava", + "§7- §cMagma Fields" + )); + layout.slot(33, ItemStackCreator.getStackHead( + "§7[Lvl §k?] §k????? (§6§lLegendary§7)", + "58be05cfae2c6a7d47da2ce88b3e00c72a145cc3218f041b3dd5bd5fa5ca827", + 1, + "§9⚓ Aquatic§7, §2༕ Undead§7, §6⛏ Subterranean", + "", + "§cDrops:", + "§7- §k???????", + "", + "§cRequirements:", + "§7- §aFishing Skill 24", + "§7- §bWater", + "§7- §2Mithril Deposits", + "§7- §bPrecursor Remnants", + "§7- §2Jungle" + )); + layout.slot(34, ItemStackCreator.getStackHead( + "§7[Lvl §k?] §k????? (§6§lLegendary§7)", + "de2e5865429dd2520bbc703e4a9f2f1abd5e1cc5d31b8a9acbf74b7a97c937aa", + 1, + "§9⚓ Aquatic§7, §a☮ Animal", + "", + "§cDrops:", + "§7- §k???????", + "", + "§cRequirements:", + "§7- §aFishing Skill 24", + "§7- §bWater", + "§7- §bFishing Festival" + )); + layout.slot(37, ItemStackCreator.getStackHead( + "§7[Lvl §k?] §k????? (§6§lLegendary§7)", + "4dd2d3c6d01c276226c7b0d377122e1a647b2ffb5b9b54fa98eac37bb1d09d3a", + 1, + "§9⚓ Aquatic§7, §f☃ Frozen§7, §e✰ Humanoid", + "", + "§cDrops:", + "§7- §k???????", + "", + "§cRequirements:", + "§7- §aFishing Skill 25", + "§7- §bWater", + "§7- §cJerry's Workshop", + "", + "§cStats", + "§7- Kills: §b1" + )); + layout.slot(38, ItemStackCreator.getStackHead( + "§7[Lvl §k?] §k????? (§6§lLegendary§7)", + "68a6194a5b217b9f5a3dfecce5f3efe6967405039b82fa0c4e8959175f32e75a", + 1, + "§9⚓ Aquatic§7, §6☽ Spooky§7, §5♃ Arcane", + "", + "§cDrops:", + "§7- §k???????", + "", + "§cRequirements:", + "§7- §aFishing Skill 26", + "§7- §bWater", + "§7- §6Spooky Festival" + )); + layout.slot(39, ItemStackCreator.getStackHead( + "§7[Lvl §k?] §k????? (§a§lUncommon§7)", + "38957d5023c937c4c41aa2412d43410bda23cf79a9f6ab36b76fef2d7c429", + 1, + "§c♆ Magmatic§7, §a⚂ Cubic", + "", + "§cDrops:", + "§7- §k???????", + "", + "§cRequirements:", + "§7- §aFishing Skill 27", + "§7- §cLava", + "§7- §cCrimson Isle", + "", + "§cStats", + "§7- Kills: §b1" + )); + layout.slot(40, ItemStackCreator.getStackHead( + "§7[Lvl §k?] §k????? (§a§lUncommon§7)", + "47f1bc3fa91cd86cf4ba7745586d67207b58e7cf27bdf7a717780843785bf9b5", + 1, + "§c♆ Magmatic§7, §a☮ Animal", + "", + "§cDrops:", + "§7- §k???????", + "", + "§cRequirements:", + "§7- §aFishing Skill 28", + "§7- §cLava", + "§7- §cCrimson Isle" + )); + layout.slot(41, ItemStackCreator.getStackHead( + "§7[Lvl §k?] §k????? (§9§lRare§7)", + "c2407e66c81b1443c2e7dfc4d6583eb19c622fa22f34fbf99fe6c45f76a", + 1, + "§9⚓ Aquatic§7, §f☃ Frozen§7, §e✰ Humanoid", + "", + "§cDrops:", + "§7- §k???????", + "", + "§cRequirements:", + "§7- §aFishing Skill 28", + "§7- §bWater", + "§7- §cJerry's Workshop", + "", + "§cStats", + "§7- Kills: §b2" + )); + layout.slot(42, ItemStackCreator.getStackHead( + "§7[Lvl §k?] §k????? (§9§lRare§7)", + "18ae7046da98dcb33f3ed42f1dc41d08ac8dfa5db3a3860de5b1b5c056804187", + 1, + "§c♆ Magmatic§7, §4Ж Arthropod", + "", + "§cDrops:", + "§7- §k???????", + "", + "§cRequirements:", + "§7- §aFishing Skill 30", + "§7- §cLava", + "§7- §cCrimson Isle" + )); + layout.slot(43, ItemStackCreator.getStackHead( + "§7[Lvl §k?] §k????? (§d§lMythic§7)", + "645f2c0bbfe3b8b19b7452072db69a5f59da38ff61415545156e5701e1be756d", + 1, + "§9⚓ Aquatic§7, §a☮ Animal§7, §d❃ Elusive", + "", + "§cDrops:", + "§7- §k???????", + "", + "§cRequirements:", + "§7- §aFishing Skill 30", + "§7- §bWater", + "§7- §2Backwater Bayou" + )); + layout.slot(45, ItemStackCreator.getStack( + "§aPrevious Page", + Material.ARROW, + 1, + "§ePage 1" + )); + layout.slot(48, ItemStackCreator.getStack( + "§aGo Back", + Material.ARROW, + 1, + "§7To Fishing Skill" + )); + layout.slot(50, ItemStackCreator.getStack( + "§aSort", + Material.HOPPER, + 1, + "", + "§b▶ Fishing Level Req", + "§7 Alphabetical", + "§7 Mob Level", + "§7 Killed Most", + "§7 Ascending Rarity", + "§7 Descending Rarity", + "", + "§bRight-click to go backwards!", + "§eClick to switch!" + )); + layout.slot(51, ItemStackCreator.getStack( + "§aFilter", + Material.ENDER_EYE, + 1, + "", + "§f▶ All Sea Creatures", + "§7 Has Level Requirement", + "§7 Has Never Killed", + "", + "§bRight-click to go backwards!", + "§eClick to switch!" + )); + layout.slot(52, ItemStackCreator.getStack( + "§aCategory", + Material.CAULDRON, + 1, + "", + "§a▶ Any Category", + "§7 Water", + "§7 Lava", + "§7 Winter", + "§7 Spooky", + "§7 Shark", + "§7 Oasis", + "§7 Bayou", + "§7 Hotspot", + "§7 Galatea", + "", + "§bRight-click to go backwards!", + "§eClick to switch!" + )); + layout.slot(53, ItemStackCreator.getStack( + "§aNext Page", + Material.ARROW, + 1, + "§ePage 3" + )); + } +} diff --git a/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/gui/inventories/fishing/GUI33SeaCreatureGuide.java b/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/gui/inventories/fishing/GUI33SeaCreatureGuide.java new file mode 100644 index 000000000..8d484e0c1 --- /dev/null +++ b/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/gui/inventories/fishing/GUI33SeaCreatureGuide.java @@ -0,0 +1,272 @@ +package net.swofty.type.skyblockgeneric.gui.inventories.fishing; + +import net.minestom.server.inventory.InventoryType; +import net.minestom.server.item.Material; +import net.swofty.type.generic.gui.inventory.ItemStackCreator; +import net.swofty.type.generic.gui.v2.Components; +import net.swofty.type.generic.gui.v2.DefaultState; +import net.swofty.type.generic.gui.v2.StatelessView; +import net.swofty.type.generic.gui.v2.ViewConfiguration; +import net.swofty.type.generic.gui.v2.ViewLayout; +import net.swofty.type.generic.gui.v2.context.ViewContext; + +// make these actually paginated views +public class GUI33SeaCreatureGuide extends StatelessView { + + @Override + public ViewConfiguration configuration() { + return new ViewConfiguration<>("(3/3) Sea Creature Guide", InventoryType.CHEST_6_ROW); + } + + @Override + public void layout(ViewLayout layout, DefaultState state, ViewContext ctx) { + Components.close(layout, 49); + + layout.slot(4, ItemStackCreator.getStack( + "§aSea Creature Guide", + Material.BOOK, + 1, + "§7Your guide to the creatures of the", + "§7deep! Can also be accessed with", + "§a/scg§7!", + "", + "§7Beware, Sea Creatures spawn much", + "§7less often on your private island.", + "", + "§7Your Fishing: §aLevel XVIII" + )); + layout.slot(10, ItemStackCreator.getStackHead( + "§7[Lvl §k?] §k????? (§9§lRare§7)", + "38957d5023c937c4c41aa2412d43410bda23cf79a9f6ab36b76fef2d7c429", + 1, + "§c♆ Magmatic§7, §a⚂ Cubic", + "", + "§cDrops:", + "§7- §k???????", + "", + "§cRequirements:", + "§7- §aFishing Skill 31", + "§7- §cLava", + "§7- §cCrimson Isle" + )); + layout.slot(11, ItemStackCreator.getStackHead( + "§7[Lvl §k?] §k????? (§9§lRare§7)", + "b78ef2e4cf2c41a2d14bfde9caff10219f5b1bf5b35a49eb51c6467882cb5f0", + 1, + "§c♆ Magmatic§7, §4♨ Infernal", + "", + "§cDrops:", + "§7- §k???????", + "", + "§cRequirements:", + "§7- §aFishing Skill 33", + "§7- §cLava", + "§7- §cCrimson Isle" + )); + layout.slot(12, ItemStackCreator.getStackHead( + "§7[Lvl §k?] §k????? (§9§lRare§7)", + "c63704a7fc7d437f7b923e23e9a08ae3bbe28937df4dafa9e3e8725b2ce4afa5", + 1, + "§c♆ Magmatic§7, §a☮ Animal", + "", + "§cDrops:", + "§7- §k???????", + "", + "§cRequirements:", + "§7- §aFishing Skill 34", + "§7- §cLava", + "§7- §cCrimson Isle" + )); + layout.slot(13, ItemStackCreator.getStackHead( + "§7[Lvl §k?] §k????? (§5§lEpic§7)", + "1642a06cd75ef307c1913ba7a224fb2082d8a2c5254fd1bf006125a087a9a868", + 1, + "§c♆ Magmatic§7, §e✰ Humanoid§7, §a☮ Animal", + "", + "§cDrops:", + "§7- §k???????", + "", + "§cRequirements:", + "§7- §aFishing Skill 35", + "§7- §cLava", + "§7- §cCrimson Isle" + )); + layout.slot(14, ItemStackCreator.getStackHead( + "§7[Lvl §k?] §k????? (§6§lLegendary§7)", + "b2b6074d0c9d6b89a494cf4f74158282a64ee23ba8a0725633ad70932ada1a8f", + 1, + "§9⚓ Aquatic§7, §a☮ Animal", + "", + "§cDrops:", + "§7- §k???????", + "", + "§cRequirements:", + "§7- §aFishing Skill 35", + "§7- §bWater", + "§7- §dFishing Hotspot", + "", + "§cStats", + "§7- Kills: §b1" + )); + layout.slot(15, ItemStackCreator.getStack( + "§7[Lvl §k?] §k????? (§d§lMythic§7)", + Material.DRAGON_EGG, + 1, + "§f☃ Frozen§7, §e⛨ Shielded§7, §d❃ Elusive", + "", + "§cDrops:", + "§7- §k???????", + "", + "§cRequirements:", + "§7- §aFishing Skill 35", + "§7- §bWater", + "§7- §cJerry's Workshop" + )); + layout.slot(16, ItemStackCreator.getStackHead( + "§7[Lvl §k?] §k????? (§d§lMythic§7)", + "32581d564f01d712255125e1f101e534217f76e3599dab7f4ae0ffe328f729eb", + 1, + "§c♆ Magmatic§7, §d❃ Elusive§7, §a☮ Animal", + "", + "§cDrops:", + "§7- §k???????", + "", + "§cRequirements:", + "§7- §aFishing Skill 36", + "§7- §cLava", + "§7- §cCrimson Isle" + )); + layout.slot(19, ItemStackCreator.getStackHead( + "§7[Lvl §k?] §k????? (§d§lMythic§7)", + "a3f925d274ec65e002028c898e11aa9b76d6d67aa305ad9c7c69fe61cec5e664", + 1, + "§c♆ Magmatic§7, §5♃ Arcane§7, §d❃ Elusive", + "", + "§cDrops:", + "§7- §k???????", + "", + "§cRequirements:", + "§7- §aFishing Skill 36", + "§7- §cLava", + "§7- §cCrimson Isle", + "§7- §cNovice Trophy Fisher" + )); + layout.slot(20, ItemStackCreator.getStackHead( + "§7[Lvl §k?] §k????? (§6§lLegendary§7)", + "55b194025806687642e2bc239895d646a6d8c193d9253b61bfce908f6ce1b84a", + 1, + "§c♆ Magmatic§7, §a☮ Animal", + "", + "§cDrops:", + "§7- §k???????", + "", + "§cRequirements:", + "§7- §aFishing Skill 37", + "§7- §cLava", + "§7- §dFishing Hotspot", + "§7- §cCrimson Isle" + )); + layout.slot(21, ItemStackCreator.getStackHead( + "§7[Lvl §k?] §k????? (§d§lMythic§7)", + "f3c802e580bfefc18c4af94cceb82968b5b4aeab0d832346a633a7473a41dfac", + 1, + "§9⚓ Aquatic§7, ⚙ Construct, §d❃ Elusive", + "", + "§cDrops:", + "§7- §k???????", + "", + "§cRequirements:", + "§7- §aFishing Skill 40", + "§7- §bWater", + "§7- §dFishing Hotspot" + )); + layout.slot(22, ItemStackCreator.getStackHead( + "§7[Lvl §k?] §k????? (§d§lMythic§7)", + "22bcaceeb4162f400d44743315932ac820d3119ac8986a0161a726161ccc93fc", + 1, + "§c♆ Magmatic§7, ⚙ Construct, §d❃ Elusive", + "", + "§cDrops:", + "§7- §k???????", + "", + "§cRequirements:", + "§7- §aFishing Skill 45", + "§7- §cLava", + "§7- §cCrimson Isle", + "§7- §cAdept Trophy Fisher" + )); + layout.slot(23, ItemStackCreator.getStackHead( + "§7[Lvl §k?] §k????? (§d§lMythic§7)", + "a8e1fe214b71f6ea69c541a861c64bafda7bf9b85de5dd17ab2b6ccd1d32b039", + 1, + "§c♆ Magmatic§7, §f🦴 Skeletal§7, §d❃ Elusive", + "", + "§cDrops:", + "§7- §k???????", + "", + "§cRequirements:", + "§7- §aFishing Skill 47", + "§7- §cLava", + "§7- §dFishing Hotspot", + "§7- §cCrimson Isle" + )); + layout.slot(45, ItemStackCreator.getStack( + "§aPrevious Page", + Material.ARROW, + 1, + "§ePage 2" + )); + layout.slot(48, ItemStackCreator.getStack( + "§aGo Back", + Material.ARROW, + 1, + "§7To Fishing Skill" + )); + layout.slot(50, ItemStackCreator.getStack( + "§aSort", + Material.HOPPER, + 1, + "", + "§b▶ Fishing Level Req", + "§7 Alphabetical", + "§7 Mob Level", + "§7 Killed Most", + "§7 Ascending Rarity", + "§7 Descending Rarity", + "", + "§bRight-click to go backwards!", + "§eClick to switch!" + )); + layout.slot(51, ItemStackCreator.getStack( + "§aFilter", + Material.ENDER_EYE, + 1, + "", + "§f▶ All Sea Creatures", + "§7 Has Level Requirement", + "§7 Has Never Killed", + "", + "§bRight-click to go backwards!", + "§eClick to switch!" + )); + layout.slot(52, ItemStackCreator.getStack( + "§aCategory", + Material.CAULDRON, + 1, + "", + "§a▶ Any Category", + "§7 Water", + "§7 Lava", + "§7 Winter", + "§7 Spooky", + "§7 Shark", + "§7 Oasis", + "§7 Bayou", + "§7 Hotspot", + "§7 Galatea", + "", + "§bRight-click to go backwards!", + "§eClick to switch!" + )); + } +} diff --git a/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/gui/inventories/fishing/GUIBaitGuide.java b/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/gui/inventories/fishing/GUIBaitGuide.java new file mode 100644 index 000000000..5dd5df60a --- /dev/null +++ b/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/gui/inventories/fishing/GUIBaitGuide.java @@ -0,0 +1,42 @@ +package net.swofty.type.skyblockgeneric.gui.inventories.fishing; + +import net.minestom.server.inventory.InventoryType; +import net.minestom.server.item.Material; +import net.swofty.type.generic.gui.inventory.ItemStackCreator; +import net.swofty.type.generic.gui.v2.Components; +import net.swofty.type.generic.gui.v2.DefaultState; +import net.swofty.type.generic.gui.v2.StatelessView; +import net.swofty.type.generic.gui.v2.ViewConfiguration; +import net.swofty.type.generic.gui.v2.ViewLayout; +import net.swofty.type.generic.gui.v2.context.ViewContext; +import net.swofty.type.skyblockgeneric.fishing.FishingItemCatalog; + +public class GUIBaitGuide extends StatelessView { + private static final int[] BAIT_SLOTS = {10, 11, 12, 13, 14, 15, 16, 19, 20, 21, 22, 23, 24, 25, 28, 29, 30, 31, 32, 33, 34}; + + @Override + public ViewConfiguration configuration() { + return new ViewConfiguration<>("Bait Guide", InventoryType.CHEST_6_ROW); + } + + @Override + public void layout(ViewLayout layout, DefaultState state, ViewContext ctx) { + Components.close(layout, 49); + + layout.slot(4, ItemStackCreator.getStack( + "§6Bait Guide", + Material.BOOK, + 1, + "§7View §6Baits§7 and the effects they add", + "§7to your fishing catches." + )); + + int index = 0; + for (var bait : FishingItemCatalog.getBaits()) { + if (index >= BAIT_SLOTS.length) { + break; + } + layout.slot(BAIT_SLOTS[index++], FishingGuideStackFactory.buildBaitStack(bait)); + } + } +} diff --git a/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/gui/inventories/fishing/GUIFishingSkillExampleRemoveThis.java b/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/gui/inventories/fishing/GUIFishingSkillExampleRemoveThis.java new file mode 100644 index 000000000..b0e02bcdf --- /dev/null +++ b/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/gui/inventories/fishing/GUIFishingSkillExampleRemoveThis.java @@ -0,0 +1,450 @@ +package net.swofty.type.skyblockgeneric.gui.inventories.fishing; + +import net.minestom.server.inventory.InventoryType; +import net.minestom.server.item.Material; +import net.swofty.type.generic.gui.inventory.ItemStackCreator; +import net.swofty.type.generic.gui.v2.Components; +import net.swofty.type.generic.gui.v2.DefaultState; +import net.swofty.type.generic.gui.v2.StatelessView; +import net.swofty.type.generic.gui.v2.ViewConfiguration; +import net.swofty.type.generic.gui.v2.ViewLayout; +import net.swofty.type.generic.gui.v2.context.ViewContext; + +public class GUIFishingSkillExampleRemoveThis extends StatelessView { + + @Override + public ViewConfiguration configuration() { + return new ViewConfiguration<>("Fishing Skill", InventoryType.CHEST_6_ROW); + } + + @Override + public void layout(ViewLayout layout, DefaultState state, ViewContext ctx) { + Components.close(layout, 49); + + layout.slot(0, ItemStackCreator.getStack( + "§aFishing Skill", + Material.FISHING_ROD, + 1, + "§7Visit your local pond to fish and", + "§7earn Fishing XP!", + "", + "§7Progress to Level XIX: §e33.1%", + "§2§l§m §f§l§m §e33,082§6/§e100k", + "", + "§eTreasure Hunter XVIII", + " §fGrants §a+1.8§f §6⛃ Treasure Chance§f.", + "", + "§8Increase your Fishing Level to", + "§8unlock Perks, statistic bonuses, and", + "§8more!" + )); + layout.slot(2, ItemStackCreator.getStack( + "§aFishing Level VIII", + Material.LIME_STAINED_GLASS_PANE, + 8, + "§7Rewards:", + " §eTreasure Hunter VIII", + " §fGrants §a+§80.7➜§a0.8§f §6⛃ Treasure Chance§f.", + " §8+§a2 §c❤ Health", + " §8+§64,000 §7Coins", + " §8+§b5 SkyBlock XP", + "", + "§a§lUNLOCKED" + )); + layout.slot(3, ItemStackCreator.getStack( + "§aFishing Level IX", + Material.LIME_STAINED_GLASS_PANE, + 9, + "§7Rewards:", + " §fScarecrow§3 Sea Creature", + " §9Tadgang§3 Sea Creature", + " §aSea Archer§3 Sea Creature", + " §eTreasure Hunter IX", + " §fGrants §a+§80.8➜§a0.9§f §6⛃ Treasure Chance§f.", + " §8+§a2 §c❤ Health", + " §8+§65,000 §7Coins", + " §8+§b5 SkyBlock XP", + "", + "§a§lUNLOCKED" + )); + layout.slot(4, ItemStackCreator.getStack( + "§aFishing Level X", + Material.PRISMARINE, + 10, + "§7Rewards:", + " §9Banshee§3 Sea Creature", + " §aOasis Sheep§3 Sea Creature", + " §9Blue Shark§3 Sea Creature", + " §9Snapping Turtle§3 Sea Creature", + " §aOasis Rabbit§3 Sea Creature", + " §eTreasure Hunter X", + " §fGrants §a+§80.9➜§a1§f §6⛃ Treasure Chance§f.", + " §8+§a2 §c❤ Health", + " §8+§67,500 §7Coins", + " §8+§b5 SkyBlock XP", + "", + "§a§lUNLOCKED" + )); + layout.slot(6, ItemStackCreator.getStack( + "§aFishing Level XVIII", + Material.LIME_STAINED_GLASS_PANE, + 18, + "§7Rewards:", + " §5Tiger Shark§3 Sea Creature", + " §5Deep Sea Protector§3 Sea Creature", + " §eTreasure Hunter XVIII", + " §fGrants §a+§81.7➜§a1.8§f §6⛃ Treasure Chance§f.", + " §8+§a3 §c❤ Health", + " §8+§665,000 §7Coins", + " §8+§b10 SkyBlock XP", + "", + "§a§lUNLOCKED" + )); + layout.slot(7, ItemStackCreator.getStack( + "§eFishing Level XIX", + Material.YELLOW_STAINED_GLASS_PANE, + 19, + "§7Rewards:", + " §6???§3 Sea Creature", + " §9???§3 Sea Creature", + " §eTreasure Hunter XIX", + " §fGrants §a+§81.8➜§a1.9§f §6⛃ Treasure Chance§f.", + " §8+§a3 §c❤ Health", + " §8+§680,000 §7Coins", + " §8+§b10 SkyBlock XP", + "", + "§7Progress: §e33.1%", + "§2§l§m §f§l§m §e33,082§6/§e100k" + )); + layout.slot(8, ItemStackCreator.getStack( + "§cFishing Level XX", + Material.RED_STAINED_GLASS_PANE, + 20, + "§7Rewards:", + " §6???§3 Sea Creature", + " §5???§3 Sea Creature", + " §6???§3 Sea Creature", + " §eTreasure Hunter XX", + " §fGrants §a+§81.9➜§a2§f §6⛃ Treasure Chance§f.", + " §8+§a4 §c❤ Health", + " §8+§6100,000 §7Coins", + " §8+§b10 SkyBlock XP" + )); + layout.slot(9, ItemStackCreator.getStack( + "§aFishing Level I", + Material.LIME_STAINED_GLASS_PANE, + 1, + "§7Rewards:", + " §fSquid§3 Sea Creature", + " §fSea Walker§3 Sea Creature", + " §eTreasure Hunter I", + " §fGrants §a+0.1§f §6⛃ Treasure Chance§f.", + " §8+§a2 §c❤ Health", + " §8+§6100 §7Coins", + " §8+§b5 SkyBlock XP", + "", + "§a§lUNLOCKED" + )); + layout.slot(11, ItemStackCreator.getStack( + "§aFishing Level VII", + Material.LIME_STAINED_GLASS_PANE, + 7, + "§7Rewards:", + " §aWetwing§3 Sea Creature", + " §aSea Witch§3 Sea Creature", + " §eTreasure Hunter VII", + " §fGrants §a+§80.6➜§a0.7§f §6⛃ Treasure Chance§f.", + " §8+§a2 §c❤ Health", + " §8+§63,000 §7Coins", + " §8+§b5 SkyBlock XP", + "", + "§a§lUNLOCKED" + )); + layout.slot(13, ItemStackCreator.getStack( + "§aFishing Level XI", + Material.LIME_STAINED_GLASS_PANE, + 11, + "§7Rewards:", + " §aRider of the Deep§3 Sea Creature", + " §eTreasure Hunter XI", + " §fGrants §a+§81➜§a1.1§f §6⛃ Treasure Chance§f.", + " §8+§a2 §c❤ Health", + " §8+§610,000 §7Coins", + " §8+§b10 SkyBlock XP", + "", + "§a§lUNLOCKED" + )); + layout.slot(15, ItemStackCreator.getStack( + "§aFishing Level XVII", + Material.LIME_STAINED_GLASS_PANE, + 17, + "§7Rewards:", + " §5Guardian Defender§3 Sea Creature", + " §5Werewolf§3 Sea Creature", + " §9Stridersurfer§3 Sea Creature", + " §9Poisoned Water Worm§3 Sea Creature", + " §eTreasure Hunter XVII", + " §fGrants §a+§81.6➜§a1.7§f §6⛃ Treasure Chance§f.", + " §8+§a3 §c❤ Health", + " §8+§650,000 §7Coins", + " §8+§b10 SkyBlock XP", + "", + "§a§lUNLOCKED" + )); + layout.slot(17, ItemStackCreator.getStack( + "§cFishing Level XXI", + Material.RED_STAINED_GLASS_PANE, + 21, + "§7Rewards:", + " §6???§3 Sea Creature", + " §eTreasure Hunter XXI", + " §fGrants §a+§82➜§a2.1§f §6⛃ Treasure Chance§f.", + " §8+§a4 §c❤ Health", + " §8+§6125,000 §7Coins", + " §8+§b10 SkyBlock XP" + )); + layout.slot(18, ItemStackCreator.getStack( + "§aFishing Level II", + Material.LIME_STAINED_GLASS_PANE, + 2, + "§7Rewards:", + " §eTreasure Hunter II", + " §fGrants §a+§80.1➜§a0.2§f §6⛃ Treasure Chance§f.", + " §8+§a2 §c❤ Health", + " §8+§6250 §7Coins", + " §8+§b5 SkyBlock XP", + "", + "§a§lUNLOCKED" + )); + layout.slot(20, ItemStackCreator.getStack( + "§aFishing Level VI", + Material.LIME_STAINED_GLASS_PANE, + 6, + "§7Rewards:", + " §aMedium Mithril Grubber§3 Sea Creature", + " §aMithril Grubber§3 Sea Creature", + " §aBloated Mithril Grubber§3 Sea Creature", + " §aLarge Mithril Grubber§3 Sea Creature", + " §fFrosty§3 Sea Creature", + " §eTreasure Hunter VI", + " §fGrants §a+§80.5➜§a0.6§f §6⛃ Treasure Chance§f.", + " §8+§a2 §c❤ Health", + " §8+§62,000 §7Coins", + " §8+§b5 SkyBlock XP", + "", + "§a§lUNLOCKED" + )); + layout.slot(22, ItemStackCreator.getStack( + "§aFishing Level XII", + Material.LIME_STAINED_GLASS_PANE, + 12, + "§7Rewards:", + " §5Ent§3 Sea Creature", + " §eTreasure Hunter XII", + " §fGrants §a+§81.1➜§a1.2§f §6⛃ Treasure Chance§f.", + " §8+§a2 §c❤ Health", + " §8+§615,000 §7Coins", + " §8+§b10 SkyBlock XP", + "", + "§a§lUNLOCKED" + )); + layout.slot(24, ItemStackCreator.getStack( + "§aFishing Level XVI", + Material.LIME_STAINED_GLASS_PANE, + 16, + "§7Rewards:", + " §9Sea Leech§3 Sea Creature", + " §9Fireproof Witch§3 Sea Creature", + " §eTreasure Hunter XVI", + " §fGrants §a+§81.5➜§a1.6§f §6⛃ Treasure Chance§f.", + " §8+§a3 §c❤ Health", + " §8+§640,000 §7Coins", + " §8+§b10 SkyBlock XP", + "", + "§a§lUNLOCKED" + )); + layout.slot(26, ItemStackCreator.getStack( + "§cFishing Level XXII", + Material.RED_STAINED_GLASS_PANE, + 22, + "§7Rewards:", + " §5???§3 Sea Creature", + " §eTreasure Hunter XXII", + " §fGrants §a+§82.1➜§a2.2§f §6⛃ Treasure Chance§f.", + " §8+§a4 §c❤ Health", + " §8+§6150,000 §7Coins", + " §8+§b10 SkyBlock XP" + )); + layout.slot(27, ItemStackCreator.getStack( + "§aFishing Level III", + Material.LIME_STAINED_GLASS_PANE, + 3, + "§7Rewards:", + " §fNight Squid§3 Sea Creature", + " §eTreasure Hunter III", + " §fGrants §a+§80.2➜§a0.3§f §6⛃ Treasure Chance§f.", + " §8+§a2 §c❤ Health", + " §8+§6500 §7Coins", + " §8+§b5 SkyBlock XP", + "", + "§a§lUNLOCKED" + )); + layout.slot(28, ItemStackCreator.getStack( + "§aFishing Level IV", + Material.LIME_STAINED_GLASS_PANE, + 4, + "§7Rewards:", + " §eTreasure Hunter IV", + " §fGrants §a+§80.3➜§a0.4§f §6⛃ Treasure Chance§f.", + " §8+§a2 §c❤ Health", + " §8+§6750 §7Coins", + " §8+§b5 SkyBlock XP", + "", + "§a§lUNLOCKED" + )); + layout.slot(29, ItemStackCreator.getStack( + "§aFishing Level V", + Material.PRISMARINE, + 5, + "§7Rewards:", + " §fSea Guardian§3 Sea Creature", + " §aDumpster Diver§3 Sea Creature", + " §fFrog Man§3 Sea Creature", + " §fTrash Gobbler§3 Sea Creature", + " §fBogged§3 Sea Creature", + " §aNurse Shark§3 Sea Creature", + " §fFrozen Steve§3 Sea Creature", + " §eTreasure Hunter V", + " §fGrants §a+§80.4➜§a0.5§f §6⛃ Treasure Chance§f.", + " §8+§a2 §c❤ Health", + " §8+§61,000 §7Coins", + " §8+§b5 SkyBlock XP", + "", + "§a§lUNLOCKED" + )); + layout.slot(31, ItemStackCreator.getStack( + "§aFishing Level XIII", + Material.LIME_STAINED_GLASS_PANE, + 13, + "§7Rewards:", + " §9Catfish§3 Sea Creature", + " §aGrinch§3 Sea Creature", + " §eTreasure Hunter XIII", + " §fGrants §a+§81.2➜§a1.3§f §6⛃ Treasure Chance§f.", + " §8+§a2 §c❤ Health", + " §8+§620,000 §7Coins", + " §8+§b10 SkyBlock XP", + "", + "§a§lUNLOCKED" + )); + layout.slot(32, ItemStackCreator.getStack( + "§aFishing Level XIV", + Material.LIME_STAINED_GLASS_PANE, + 14, + "§7Rewards:", + " §fFried Chicken§3 Sea Creature", + " §9Carrot King§3 Sea Creature", + " §9Nightmare§3 Sea Creature", + " §eTreasure Hunter XIV", + " §fGrants §a+§81.3➜§a1.4§f §6⛃ Treasure Chance§f.", + " §8+§a2 §c❤ Health", + " §8+§625,000 §7Coins", + " §8+§b10 SkyBlock XP", + "", + "§a§lUNLOCKED" + )); + layout.slot(33, ItemStackCreator.getStack( + "§aFishing Level XV", + Material.PRISMARINE, + 15, + "§7Rewards:", + " §9Agarimoo§3 Sea Creature", + " §9Water Worm§3 Sea Creature", + " §5Bayou Sludge§3 Sea Creature", + " §eTreasure Hunter XV", + " §fGrants §a+§81.4➜§a1.5§f §6⛃ Treasure Chance§f.", + " §8+§a3 §c❤ Health", + " §8+§630,000 §7Coins", + " §8+§b10 SkyBlock XP", + "", + "§a§lUNLOCKED" + )); + layout.slot(35, ItemStackCreator.getStack( + "§cFishing Level XXIII", + Material.RED_STAINED_GLASS_PANE, + 23, + "§7Rewards:", + " §eTreasure Hunter XXIII", + " §fGrants §a+§82.2➜§a2.3§f §6⛃ Treasure Chance§f.", + " §8+§a4 §c❤ Health", + " §8+§6175,000 §7Coins", + " §8+§b10 SkyBlock XP" + )); + layout.slot(39, ItemStackCreator.getStack( + "§6Bait Guide", + Material.BOOK, + 1, + "§7View §6Baits§7, their uses, and how to", + "§7obtain them! Can also be accessed", + "§7with §a/bait§7!", + "", + "§eClick to view!" + )); + layout.slot(40, ItemStackCreator.getStack( + "§aSea Creature Guide", + Material.BOOK, + 1, + "§7Your guide to the creatures of the", + "§7deep! Can also be accessed with", + "§a/scg§7!", + "", + "§7Beware, Sea Creatures spawn much", + "§7less often on your private island.", + "", + "§7Your Fishing: §aLevel XVIII", + "", + "§eClick to view!" + )); + layout.slot(41, ItemStackCreator.getStack( + "§9Rod Part Guide", + Material.BOOK, + 1, + "§7View all of the §9Rod Parts §7that can be", + "§7applied to §aFishing Rods§7! Can also be", + "§7accessed with §a/rodparts§7!", + "", + "§eClick to view!" + )); + layout.slot(44, ItemStackCreator.getStack( + "§cFishing Level XXIV", + Material.RED_STAINED_GLASS_PANE, + 24, + "§7Rewards:", + " §6???§3 Sea Creature", + " §6???§3 Sea Creature", + " §eTreasure Hunter XXIV", + " §fGrants §a+§82.3➜§a2.4§f §6⛃ Treasure Chance§f.", + " §8+§a4 §c❤ Health", + " §8+§6200,000 §7Coins", + " §8+§b10 SkyBlock XP" + )); + layout.slot(48, ItemStackCreator.getStack( + "§aGo Back", + Material.ARROW, + 1, + "§7To Your Skills" + )); + layout.slot(53, ItemStackCreator.getStack( + "§cFishing Level XXV", + Material.RED_STAINED_GLASS_PANE, + 25, + "§7Rewards:", + " §6???§3 Sea Creature", + " §eTreasure Hunter XXV", + " §fGrants §a+§82.4➜§a2.5§f §6⛃ Treasure Chance§f.", + " §8+§a4 §c❤ Health", + " §8+§6225,000 §7Coins", + " §8+§b10 SkyBlock XP" + )); + } +} diff --git a/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/item/ItemAttributeHandler.java b/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/item/ItemAttributeHandler.java index 1b92de105..ab2cc5494 100644 --- a/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/item/ItemAttributeHandler.java +++ b/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/item/ItemAttributeHandler.java @@ -2,20 +2,27 @@ import net.minestom.server.color.Color; import net.swofty.commons.ServiceType; +import net.swofty.commons.protocol.objects.itemtracker.TrackedItemUpdateProtocolObject; import net.swofty.commons.skyblock.item.ItemType; import net.swofty.commons.skyblock.item.Rarity; import net.swofty.commons.skyblock.item.attribute.attributes.*; -import net.swofty.commons.skyblock.item.attribute.attributes.ItemAttributeExtraDynamicStatistics; import net.swofty.commons.skyblock.item.reforge.Reforge; import net.swofty.commons.skyblock.item.reforge.ReforgeLoader; -import net.swofty.commons.protocol.objects.itemtracker.TrackedItemUpdateProtocolObject; import net.swofty.commons.skyblock.statistics.ItemStatistics; import net.swofty.proxyapi.ProxyService; import net.swofty.type.skyblockgeneric.abiphone.AbiphoneNPC; import net.swofty.type.skyblockgeneric.abiphone.AbiphoneRegistry; import net.swofty.type.skyblockgeneric.enchantment.EnchantmentType; import net.swofty.type.skyblockgeneric.enchantment.SkyBlockEnchantment; -import net.swofty.type.skyblockgeneric.item.components.*; +import net.swofty.type.skyblockgeneric.item.components.BackpackComponent; +import net.swofty.type.skyblockgeneric.item.components.DefaultSoulboundComponent; +import net.swofty.type.skyblockgeneric.item.components.EnchantedComponent; +import net.swofty.type.skyblockgeneric.item.components.GemstoneComponent; +import net.swofty.type.skyblockgeneric.item.components.LeatherColorComponent; +import net.swofty.type.skyblockgeneric.item.components.MinionComponent; +import net.swofty.type.skyblockgeneric.item.components.PetComponent; +import net.swofty.type.skyblockgeneric.item.components.PetItemComponent; +import net.swofty.type.skyblockgeneric.item.components.RuneableComponent; import net.swofty.type.skyblockgeneric.minion.MinionRegistry; import net.swofty.type.skyblockgeneric.user.SkyBlockPlayer; import org.jetbrains.annotations.Nullable; @@ -78,6 +85,41 @@ public void setRuneData(ItemAttributeRuneInfusedWith.RuneData data) { ((ItemAttributeRuneInfusedWith) item.getAttribute("rune_infused_with")).setValue(data); } + public @Nullable String getFishingHook() { + String value = ((ItemAttributeFishingHook) item.getAttribute("fishing_hook")).getValue(); + return value == null || value.equalsIgnoreCase("none") ? null : value; + } + + public void setFishingHook(@Nullable String hookId) { + item.getAttribute("fishing_hook").setValue(hookId == null ? "none" : hookId); + } + + public @Nullable String getFishingLine() { + String value = ((ItemAttributeFishingLine) item.getAttribute("fishing_line")).getValue(); + return value == null || value.equalsIgnoreCase("none") ? null : value; + } + + public void setFishingLine(@Nullable String lineId) { + item.getAttribute("fishing_line").setValue(lineId == null ? "none" : lineId); + } + + public @Nullable String getFishingSinker() { + String value = ((ItemAttributeFishingSinker) item.getAttribute("fishing_sinker")).getValue(); + return value == null || value.equalsIgnoreCase("none") ? null : value; + } + + public void setFishingSinker(@Nullable String sinkerId) { + item.getAttribute("fishing_sinker").setValue(sinkerId == null ? "none" : sinkerId); + } + + public long getFishingExpertiseKills() { + return ((ItemAttributeFishingExpertiseKills) item.getAttribute("fishing_expertise_kills")).getValue(); + } + + public void setFishingExpertiseKills(long kills) { + item.getAttribute("fishing_expertise_kills").setValue(kills); + } + public boolean isPet() { return item.hasComponent(PetComponent.class); } diff --git a/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/item/ItemConfigParser.java b/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/item/ItemConfigParser.java index a65be2a27..cc4015e79 100644 --- a/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/item/ItemConfigParser.java +++ b/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/item/ItemConfigParser.java @@ -11,6 +11,10 @@ import net.swofty.commons.skyblock.item.reforge.ReforgeType; import net.swofty.commons.skyblock.statistics.ItemStatistic; import net.swofty.commons.skyblock.statistics.ItemStatistics; +import net.swofty.type.skyblockgeneric.enchantment.EnchantmentType; +import net.swofty.type.skyblockgeneric.fishing.FishingMedium; +import net.swofty.type.skyblockgeneric.fishing.RodPartDefinition; +import net.swofty.type.skyblockgeneric.fishing.ShipPartDefinition; import net.swofty.type.skyblockgeneric.gems.GemRarity; import net.swofty.type.skyblockgeneric.gems.Gemstone; import net.swofty.type.skyblockgeneric.item.components.*; @@ -163,6 +167,75 @@ yield new EnchantableComponent( ); } case "FISHING_ROD" -> new FishingRodComponent(); + case "FISHING_ROD_METADATA" -> { + String displayName = safeConfig.getString("display_name"); + String subtitle = safeConfig.getString("subtitle", null); + FishingMedium medium = safeConfig.containsKey("medium") + ? safeConfig.getEnum("medium", FishingMedium.class) + : FishingMedium.WATER; + int requiredFishingLevel = safeConfig.getInt("required_fishing_level", 0); + Map enchantments = new java.util.EnumMap<>(EnchantmentType.class); + for (Map.Entry entry : safeConfig.getMap("enchantments").entrySet()) { + enchantments.put(EnchantmentType.valueOf(entry.getKey().toUpperCase()), ((Number) entry.getValue()).intValue()); + } + yield new FishingRodMetadataComponent( + displayName, + subtitle, + medium, + requiredFishingLevel, + enchantments, + safeConfig.getString("legacy_conversion_target", null), + safeConfig.getString("legacy_conversion_part", null), + safeConfig.getBoolean("rod_parts_enabled", true) + ); + } + case "FISHING_ROD_PART" -> { + String displayName = safeConfig.getString("display_name"); + RodPartDefinition.PartCategory category = safeConfig.getEnum("category", RodPartDefinition.PartCategory.class); + int requiredFishingLevel = safeConfig.getInt("required_fishing_level", 0); + Map tagBonuses = new java.util.LinkedHashMap<>(); + for (Map.Entry entry : safeConfig.getMap("tag_bonuses").entrySet()) { + tagBonuses.put(entry.getKey(), ((Number) entry.getValue()).doubleValue()); + } + yield new FishingRodPartComponent( + displayName, + category, + requiredFishingLevel, + tagBonuses, + safeConfig.getBoolean("treasure_only", false), + safeConfig.getBoolean("bayou_treasure_to_junk", false), + safeConfig.getString("materialized_item_id", null), + safeConfig.getDouble("materialized_chance", 1.0), + safeConfig.getDouble("bait_preservation_chance", 0.0), + safeConfig.getDouble("hotspot_buff_multiplier", 1.0), + safeConfig.getString("texture", null) + ); + } + case "FISHING_BAIT" -> { + String displayName = safeConfig.getString("display_name"); + Map tagBonuses = new java.util.LinkedHashMap<>(); + for (Map.Entry entry : safeConfig.getMap("tag_bonuses").entrySet()) { + tagBonuses.put(entry.getKey(), ((Number) entry.getValue()).doubleValue()); + } + List mediums = safeConfig.containsKey("mediums") + ? safeConfig.getList("mediums", String.class).stream().map(value -> FishingMedium.valueOf(value.toUpperCase())).toList() + : List.of(FishingMedium.WATER, FishingMedium.LAVA); + yield new FishingBaitComponent( + displayName, + tagBonuses, + safeConfig.getDouble("treasure_chance_bonus", 0.0), + safeConfig.getDouble("treasure_quality_bonus", 0.0), + safeConfig.getDouble("trophy_fish_chance_bonus", 0.0), + safeConfig.getDouble("double_hook_chance_bonus", 0.0), + mediums, + safeConfig.getString("texture", null) + ); + } + case "FISHING_SHIP_PART" -> { + String displayName = safeConfig.getString("display_name"); + ShipPartDefinition.ShipPartSlot slot = safeConfig.getEnum("slot", ShipPartDefinition.ShipPartSlot.class); + yield new FishingShipPartComponent(displayName, slot, safeConfig.getString("texture", null)); + } case "ENCHANTED" -> { if (safeConfig.containsKey("recipes")) { List> recipeConfigs = safeConfig.getMapList("recipes"); diff --git a/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/item/SkyBlockItem.java b/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/item/SkyBlockItem.java index a823d800d..bfd3f5ae2 100644 --- a/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/item/SkyBlockItem.java +++ b/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/item/SkyBlockItem.java @@ -18,6 +18,7 @@ import net.swofty.commons.skyblock.item.attribute.attributes.ItemAttributeType; import net.swofty.commons.skyblock.statistics.ItemStatistics; import net.swofty.type.generic.gui.inventory.ItemStackCreator; +import net.swofty.type.skyblockgeneric.fishing.FishingItemBootstrap; import net.swofty.type.skyblockgeneric.item.components.EnchantedComponent; import net.swofty.type.skyblockgeneric.item.components.SkullHeadComponent; import net.swofty.type.skyblockgeneric.item.updater.NonPlayerItemUpdater; @@ -124,6 +125,8 @@ private void loadAsItemType(ItemType type) { ItemAttributeStatistics statisticsAttribute = (ItemAttributeStatistics) getAttribute("statistics"); statisticsAttribute.setValue(statistics.clone()); } + + FishingItemBootstrap.applyDefaults(this); } private void loadAsMaterial(Material material) { @@ -180,12 +183,37 @@ private void loadAsStack(ItemStack item) { } } + migrateLegacyFishingRodState(item); + if (config != null) { ItemAttributeStatistics statisticsAttribute = (ItemAttributeStatistics) getAttribute("statistics"); statisticsAttribute.setValue(config.getDefaultStatistics()); } } + private void migrateLegacyFishingRodState(ItemStack item) { + String legacy = item.getTag(Tag.String("fishing_rod_state")); + if (legacy == null || legacy.isBlank()) { + return; + } + + String[] parts = legacy.split(";", -1); + getAttributeHandler().setFishingHook(readLegacyFishingPart(parts, 0)); + getAttributeHandler().setFishingLine(readLegacyFishingPart(parts, 1)); + getAttributeHandler().setFishingSinker(readLegacyFishingPart(parts, 2)); + if (parts.length > 3 && !parts[3].isBlank()) { + getAttributeHandler().setFishingExpertiseKills(Long.parseLong(parts[3])); + } + } + + private @Nullable String readLegacyFishingPart(String[] parts, int index) { + if (index >= parts.length) { + return null; + } + String value = parts[index]; + return value == null || value.isBlank() || value.equalsIgnoreCase("none") ? null : value; + } + public ItemStack.Builder getDisplayItem() { ItemStack.Builder builder; diff --git a/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/item/components/FishingBaitComponent.java b/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/item/components/FishingBaitComponent.java new file mode 100644 index 000000000..29b78a3e4 --- /dev/null +++ b/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/item/components/FishingBaitComponent.java @@ -0,0 +1,46 @@ +package net.swofty.type.skyblockgeneric.item.components; + +import lombok.Getter; +import net.swofty.type.skyblockgeneric.fishing.FishingMedium; + +import java.util.List; +import java.util.Map; + +@Getter +public class FishingBaitComponent extends net.swofty.type.skyblockgeneric.item.SkyBlockItemComponent { + private final String displayName; + private final Map tagBonuses; + private final double treasureChanceBonus; + private final double treasureQualityBonus; + private final double trophyFishChanceBonus; + private final double doubleHookChanceBonus; + private final List mediums; + private final String texture; + + public FishingBaitComponent( + String displayName, + Map tagBonuses, + double treasureChanceBonus, + double treasureQualityBonus, + double trophyFishChanceBonus, + double doubleHookChanceBonus, + List mediums, + String texture + ) { + this.displayName = displayName; + this.tagBonuses = Map.copyOf(tagBonuses); + this.treasureChanceBonus = treasureChanceBonus; + this.treasureQualityBonus = treasureQualityBonus; + this.trophyFishChanceBonus = trophyFishChanceBonus; + this.doubleHookChanceBonus = doubleHookChanceBonus; + this.mediums = List.copyOf(mediums); + this.texture = texture; + + addInheritedComponent(new CustomDisplayNameComponent(ignored -> displayName)); + if (texture != null && !texture.isBlank()) { + addInheritedComponent(new SkullHeadComponent(ignored -> texture)); + } + addInheritedComponent(new ExtraUnderNameComponent(List.of("Fishing Bait", "Consumes on Cast"))); + addInheritedComponent(new ExtraRarityComponent("BAIT")); + } +} \ No newline at end of file diff --git a/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/item/components/FishingRodComponent.java b/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/item/components/FishingRodComponent.java index 2cbed8e14..7fdad90bb 100644 --- a/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/item/components/FishingRodComponent.java +++ b/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/item/components/FishingRodComponent.java @@ -3,6 +3,8 @@ import net.kyori.adventure.key.Key; import net.kyori.adventure.sound.Sound; import net.swofty.type.skyblockgeneric.entity.FishingHook; +import net.swofty.type.skyblockgeneric.fishing.FishingItemCatalog; +import net.swofty.type.skyblockgeneric.fishing.FishingService; import net.swofty.type.skyblockgeneric.item.SkyBlockItemComponent; public class FishingRodComponent extends SkyBlockItemComponent { @@ -13,7 +15,9 @@ public FishingRodComponent() { (player, item) -> { FishingHook hook = FishingHook.getFishingHookForOwner(player); if (hook != null) { + hook.tryRetrieve(item); hook.remove(); + FishingService.clearSession(player.getUuid()); float pitch = 0.8f + (float) (Math.random() * 0.4f); player.playSound( Sound.sound() @@ -24,7 +28,12 @@ public FishingRodComponent() { .build() ); } else { - new FishingHook(player).spawn(player.getInstance()); + String itemId = item.getAttributeHandler().getPotentialType() == null ? null : item.getAttributeHandler().getPotentialType().name(); + var definition = FishingItemCatalog.getRod(itemId); + if (definition != null && definition.legacyConversionTarget() != null) { + return; + } + new FishingHook(player, item).spawn(player.getInstance()); } }, null diff --git a/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/item/components/FishingRodMetadataComponent.java b/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/item/components/FishingRodMetadataComponent.java new file mode 100644 index 000000000..81a9b6faf --- /dev/null +++ b/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/item/components/FishingRodMetadataComponent.java @@ -0,0 +1,52 @@ +package net.swofty.type.skyblockgeneric.item.components; + +import lombok.Getter; +import net.swofty.commons.skyblock.item.reforge.ReforgeType; +import net.swofty.type.skyblockgeneric.enchantment.EnchantmentType; +import net.swofty.type.skyblockgeneric.fishing.FishingMedium; +import net.swofty.type.skyblockgeneric.utility.groups.EnchantItemGroups; + +import java.util.List; +import java.util.Map; + +@Getter +public class FishingRodMetadataComponent extends net.swofty.type.skyblockgeneric.item.SkyBlockItemComponent { + private final String displayName; + private final String subtitle; + private final FishingMedium medium; + private final int requiredFishingLevel; + private final Map enchantments; + private final String legacyConversionTarget; + private final String legacyConversionPart; + private final boolean rodPartsEnabled; + + public FishingRodMetadataComponent( + String displayName, + String subtitle, + FishingMedium medium, + int requiredFishingLevel, + Map enchantments, + String legacyConversionTarget, + String legacyConversionPart, + boolean rodPartsEnabled + ) { + this.displayName = displayName; + this.subtitle = subtitle; + this.medium = medium; + this.requiredFishingLevel = requiredFishingLevel; + this.enchantments = Map.copyOf(enchantments); + this.legacyConversionTarget = legacyConversionTarget; + this.legacyConversionPart = legacyConversionPart; + this.rodPartsEnabled = rodPartsEnabled; + + addInheritedComponent(new CustomDisplayNameComponent(ignored -> displayName)); + if (subtitle != null && !subtitle.isBlank()) { + addInheritedComponent(new ExtraUnderNameComponent(subtitle)); + } + addInheritedComponent(new FishingRodComponent()); + addInheritedComponent(new EnchantableComponent(List.of(EnchantItemGroups.FISHING_ROD), true)); + addInheritedComponent(new ReforgableComponent(ReforgeType.FISHING_RODS)); + addInheritedComponent(new DefaultSoulboundComponent(true)); + addInheritedComponent(new ExtraRarityComponent("FISHING ROD")); + } +} \ No newline at end of file diff --git a/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/item/components/FishingRodPartComponent.java b/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/item/components/FishingRodPartComponent.java new file mode 100644 index 000000000..16f6f2403 --- /dev/null +++ b/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/item/components/FishingRodPartComponent.java @@ -0,0 +1,53 @@ +package net.swofty.type.skyblockgeneric.item.components; + +import lombok.Getter; +import net.swofty.type.skyblockgeneric.fishing.RodPartDefinition; + +import java.util.Map; + +@Getter +public class FishingRodPartComponent extends net.swofty.type.skyblockgeneric.item.SkyBlockItemComponent { + private final String displayName; + private final RodPartDefinition.PartCategory category; + private final int requiredFishingLevel; + private final Map tagBonuses; + private final boolean treasureOnly; + private final boolean bayouTreasureToJunk; + private final String materializedItemId; + private final double materializedChance; + private final double baitPreservationChance; + private final double hotspotBuffMultiplier; + private final String texture; + + public FishingRodPartComponent( + String displayName, + RodPartDefinition.PartCategory category, + int requiredFishingLevel, + Map tagBonuses, + boolean treasureOnly, + boolean bayouTreasureToJunk, + String materializedItemId, + double materializedChance, + double baitPreservationChance, + double hotspotBuffMultiplier, + String texture + ) { + this.displayName = displayName; + this.category = category; + this.requiredFishingLevel = requiredFishingLevel; + this.tagBonuses = Map.copyOf(tagBonuses); + this.treasureOnly = treasureOnly; + this.bayouTreasureToJunk = bayouTreasureToJunk; + this.materializedItemId = materializedItemId; + this.materializedChance = materializedChance; + this.baitPreservationChance = baitPreservationChance; + this.hotspotBuffMultiplier = hotspotBuffMultiplier; + this.texture = texture; + + addInheritedComponent(new CustomDisplayNameComponent(ignored -> displayName)); + if (texture != null && !texture.isBlank()) { + addInheritedComponent(new SkullHeadComponent(ignored -> texture)); + } + addInheritedComponent(new ExtraRarityComponent("ROD PART")); + } +} \ No newline at end of file diff --git a/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/item/components/FishingShipPartComponent.java b/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/item/components/FishingShipPartComponent.java new file mode 100644 index 000000000..3a2aef7dd --- /dev/null +++ b/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/item/components/FishingShipPartComponent.java @@ -0,0 +1,22 @@ +package net.swofty.type.skyblockgeneric.item.components; + +import lombok.Getter; +import net.swofty.type.skyblockgeneric.fishing.ShipPartDefinition; + +@Getter +public class FishingShipPartComponent extends net.swofty.type.skyblockgeneric.item.SkyBlockItemComponent { + private final String displayName; + private final ShipPartDefinition.ShipPartSlot slot; + private final String texture; + + public FishingShipPartComponent(String displayName, ShipPartDefinition.ShipPartSlot slot, String texture) { + this.displayName = displayName; + this.slot = slot; + this.texture = texture; + + addInheritedComponent(new CustomDisplayNameComponent(ignored -> displayName)); + if (texture != null && !texture.isBlank()) { + addInheritedComponent(new SkullHeadComponent(ignored -> texture)); + } + } +} \ No newline at end of file diff --git a/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/region/RegionType.java b/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/region/RegionType.java index 9c3fb7d69..d092d6dd8 100644 --- a/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/region/RegionType.java +++ b/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/region/RegionType.java @@ -131,6 +131,17 @@ public enum RegionType { MURKWATER_SHALLOWS("Murkwater Shallows", "§3"), NORTH_WETLANDS("North Wetlands", "§2"), + // Backwater Bayou + BACKWATER_BAYOU("Backwater Bayou", "§2"), + CRIMSON_ISLE("Crimson Isle", "§c"), + BLAZING_VOLCANO("Blazing Volcano", "§4"), + DOJO("Dojo", "§6"), + MYSTIC_MARSH("Mystic Marsh", "§2"), + SCARLETON("Scarleton", "§c"), + BURNING_DESERT("Burning Desert", "§6"), + DRAGONTAIL("Dragontail", "§4"), + STRONGHOLD("Stronghold", "§4"), + DWARVEN_VILLAGE("Dwarven Village", DwarvenMinesConfiguration.class), DWARVEN_MINES("Dwarven Mines", "§2", DwarvenMinesConfiguration.class), GOBLIN_BURROWS("Goblin Burrows", DwarvenMinesConfiguration.class), diff --git a/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/user/SkyBlockPlayer.java b/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/user/SkyBlockPlayer.java index 17aca8a03..0f860ed9f 100644 --- a/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/user/SkyBlockPlayer.java +++ b/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/user/SkyBlockPlayer.java @@ -16,16 +16,21 @@ import net.minestom.server.network.packet.server.play.UpdateHealthPacket; import net.minestom.server.network.player.GameProfile; import net.minestom.server.network.player.PlayerConnection; +import net.swofty.commons.StringUtility; import net.swofty.commons.skyblock.PlayerShopData; import net.swofty.commons.skyblock.SkyBlockPlayerProfiles; -import net.swofty.commons.StringUtility; import net.swofty.commons.skyblock.item.ItemType; import net.swofty.commons.skyblock.item.Rarity; import net.swofty.commons.skyblock.item.UnderstandableSkyBlockItem; import net.swofty.commons.skyblock.statistics.ItemStatistic; import net.swofty.type.generic.HypixelConst; import net.swofty.type.generic.data.HypixelDataHandler; -import net.swofty.type.generic.data.datapoints.*; +import net.swofty.type.generic.data.datapoints.DatapointBoolean; +import net.swofty.type.generic.data.datapoints.DatapointDouble; +import net.swofty.type.generic.data.datapoints.DatapointInteger; +import net.swofty.type.generic.data.datapoints.DatapointLong; +import net.swofty.type.generic.data.datapoints.DatapointRank; +import net.swofty.type.generic.data.datapoints.DatapointString; import net.swofty.type.generic.gui.inventory.HypixelInventoryGUI; import net.swofty.type.generic.user.HypixelPlayer; import net.swofty.type.skyblockgeneric.SkyBlockGenericLoader; @@ -61,7 +66,11 @@ import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; -import java.util.*; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.UUID; import java.util.concurrent.atomic.AtomicInteger; import java.util.function.Consumer; import java.util.regex.Matcher; @@ -521,6 +530,14 @@ public DatapointQuiver.PlayerQuiver getQuiver() { return getSkyblockDataHandler().get(SkyBlockDataHandler.Data.QUIVER, DatapointQuiver.class).getValue(); } + public DatapointShipState.ShipState getShipState() { + return getSkyblockDataHandler().get(SkyBlockDataHandler.Data.SHIP_STATE, DatapointShipState.class).getValue(); + } + + public DatapointTrophyFish.TrophyFishData getTrophyFishData() { + return getSkyblockDataHandler().get(SkyBlockDataHandler.Data.TROPHY_FISH, DatapointTrophyFish.class).getValue(); + } + public DatapointAccessoryBag.PlayerAccessoryBag getAccessoryBag() { return getSkyblockDataHandler().get(SkyBlockDataHandler.Data.ACCESSORY_BAG, DatapointAccessoryBag.class).getValue(); } From 3ccfd40761befc17307bb176734dc80250a96c8a Mon Sep 17 00:00:00 2001 From: ArikSquad <75741608+ArikSquad@users.noreply.github.com> Date: Fri, 20 Mar 2026 11:06:52 +0200 Subject: [PATCH 007/113] feat: fishing stuff --- configuration/skyblock/fishing/hotspots.yml | 20 +- .../skyblock/items/fishing/baits.yml | 171 ++++ .../skyblock/items/fishing/fishingContent.yml | 735 ------------------ .../skyblock/items/fishing/parts.yml | 191 +++++ configuration/skyblock/items/fishing/rods.yml | 292 +++++++ configuration/skyblock/items/vanillaItems.yml | 5 +- .../gui/GUIFishingRodParts.java | 98 +-- .../type/backwaterbayou/gui/GUIHook.java | 46 +- .../type/backwaterbayou/gui/GUILine.java | 46 +- .../backwaterbayou/gui/GUIRodPartGuide.java | 62 +- .../type/backwaterbayou/gui/GUISinker.java | 46 +- .../type/hub/gui/fishing/GUIGFishingShip.java | 131 +--- .../type/hub/gui/fishing/GUINavigator.java | 55 +- .../swofty/type/hub/npcs/NPCCaptainBaha.java | 7 +- .../data/datapoints/DatapointTrophyFish.java | 28 +- .../skyblockgeneric/entity/FishingHook.java | 12 +- .../fishing/BaitDefinition.java | 22 - .../fishing/FishingBaitService.java | 11 +- .../fishing/FishingContext.java | 10 +- .../fishing/FishingHotspotService.java | 12 +- .../fishing/FishingItemBootstrap.java | 25 - .../fishing/FishingItemCatalog.java | 160 ---- .../fishing/FishingItemSupport.java | 93 +++ .../fishing/FishingLootResolver.java | 45 +- .../fishing/FishingPartCategory.java | 7 + .../fishing/FishingRegistry.java | 283 +++---- .../fishing/FishingRodDefinition.java | 23 - .../fishing/FishingRodLoreBuilder.java | 205 ++--- .../fishing/FishingRodPartService.java | 37 +- .../fishing/FishingService.java | 29 +- .../fishing/FishingShipPartSlot.java | 7 + .../fishing/FishingShipService.java | 11 +- .../fishing/HotspotDefinition.java | 7 +- .../fishing/RodPartDefinition.java | 30 - .../fishing/SeaCreatureDefinition.java | 5 +- .../fishing/ShipPartDefinition.java | 19 - .../fishing/FishingGuideStackFactory.java | 79 +- .../gui/inventories/fishing/GUIBaitGuide.java | 4 +- .../fishing/GUIFishingRodParts.java | 101 +++ .../inventories/fishing/GUIFishingShip.java | 155 ++++ .../gui/inventories/fishing/GUIHookGuide.java | 47 ++ .../gui/inventories/fishing/GUILineGuide.java | 47 ++ .../gui/inventories/fishing/GUINavigator.java | 89 +++ .../inventories/fishing/GUIRodPartGuide.java | 64 ++ .../inventories/fishing/GUISinkerGuide.java | 47 ++ .../item/ItemConfigParser.java | 35 +- .../type/skyblockgeneric/item/ItemLore.java | 14 +- .../skyblockgeneric/item/SkyBlockItem.java | 2 - .../item/components/FishingBaitComponent.java | 16 +- .../item/components/FishingRodComponent.java | 6 +- .../FishingRodMetadataComponent.java | 40 +- .../components/FishingRodPartComponent.java | 19 +- .../components/FishingShipPartComponent.java | 18 +- .../item/handlers/lore/LoreRegistry.java | 20 +- 54 files changed, 1778 insertions(+), 2011 deletions(-) create mode 100644 configuration/skyblock/items/fishing/baits.yml delete mode 100644 configuration/skyblock/items/fishing/fishingContent.yml create mode 100644 configuration/skyblock/items/fishing/parts.yml create mode 100644 configuration/skyblock/items/fishing/rods.yml delete mode 100644 type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/fishing/BaitDefinition.java delete mode 100644 type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/fishing/FishingItemBootstrap.java delete mode 100644 type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/fishing/FishingItemCatalog.java create mode 100644 type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/fishing/FishingItemSupport.java create mode 100644 type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/fishing/FishingPartCategory.java delete mode 100644 type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/fishing/FishingRodDefinition.java create mode 100644 type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/fishing/FishingShipPartSlot.java delete mode 100644 type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/fishing/RodPartDefinition.java delete mode 100644 type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/fishing/ShipPartDefinition.java create mode 100644 type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/gui/inventories/fishing/GUIFishingRodParts.java create mode 100644 type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/gui/inventories/fishing/GUIFishingShip.java create mode 100644 type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/gui/inventories/fishing/GUIHookGuide.java create mode 100644 type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/gui/inventories/fishing/GUILineGuide.java create mode 100644 type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/gui/inventories/fishing/GUINavigator.java create mode 100644 type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/gui/inventories/fishing/GUIRodPartGuide.java create mode 100644 type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/gui/inventories/fishing/GUISinkerGuide.java diff --git a/configuration/skyblock/fishing/hotspots.yml b/configuration/skyblock/fishing/hotspots.yml index 0168a99cc..c266f0dc0 100644 --- a/configuration/skyblock/fishing/hotspots.yml +++ b/configuration/skyblock/fishing/hotspots.yml @@ -1,5 +1,19 @@ hotspots: - - x: 100 - y: 50 - z: 100 + - id: BAYOU_WATER_1 + medium: WATER + regions: + - BACKWATER_BAYOU serverType: BACKWATER_BAYOU + durationSeconds: 120 + maxActive: 2 + buffs: + FISHING_SPEED: 15 + SEA_CREATURE_CHANCE: 5 + DOUBLE_HOOK_CHANCE: 2 + TROPHY_FISH_CHANCE: 5 + TREASURE_CHANCE: 1 + spawnPoints: + - serverType: BACKWATER_BAYOU + x: 100 + y: 50 + z: 100 diff --git a/configuration/skyblock/items/fishing/baits.yml b/configuration/skyblock/items/fishing/baits.yml new file mode 100644 index 000000000..cbc70be98 --- /dev/null +++ b/configuration/skyblock/items/fishing/baits.yml @@ -0,0 +1,171 @@ +items: + - id: MINNOW_BAIT + material: PLAYER_HEAD + rarity: COMMON + default_statistics: + FISHING_SPEED: 25 + components: + - id: FISHING_BAIT + texture: b8e749ba141c054bb0c125320b17677bdcb3a7e9807a57527c0877b94548a2e + + - id: FISH_BAIT + material: PLAYER_HEAD + rarity: COMMON + default_statistics: + FISHING_SPEED: 45 + components: + - id: FISHING_BAIT + texture: 49e8dc9fdc9f00e1d17666a4787d34cca7cc6dc030f0dc686195546f81c6f22 + + - id: LIGHT_BAIT + material: PLAYER_HEAD + rarity: COMMON + components: + - id: FISHING_BAIT + texture: e3bcc16f402342b4acd29aecac72d1d5a116e0abb478bb4960e734fd70686ba + + - id: DARK_BAIT + material: PLAYER_HEAD + rarity: COMMON + components: + - id: FISHING_BAIT + texture: 7281618a5c8239078fd43fef8eae14ea00665f635bd56d4451cccd5d0fa11821 + + - id: SPIKED_BAIT + material: PLAYER_HEAD + rarity: COMMON + default_statistics: + SEA_CREATURE_CHANCE: 6 + components: + - id: FISHING_BAIT + texture: e42c436c6580fad217323b9f045daa23a9f88219ac26506637669eff20901f74 + + - id: SPOOKY_BAIT + material: PLAYER_HEAD + rarity: COMMON + default_statistics: + FISHING_SPEED: 25 + components: + - id: FISHING_BAIT + tag_bonuses: + SPOOKY: 15 + texture: 977eab558e6a90f7cedd72c2416c891f47d71eb4e7bdcc299a6335286f5cba98 + + - id: CARROT_BAIT + material: PLAYER_HEAD + rarity: COMMON + components: + - id: FISHING_BAIT + texture: 4d3a6bd98ac1833c664c4909ff8d2dc62ce887bdcf3cc5b3848651ae5af6b + + - id: CORRUPTED_BAIT + material: PLAYER_HEAD + rarity: COMMON + components: + - id: FISHING_BAIT + texture: 4bbcddd45cd347865bceab3e3dc5d382723463963f85ecce81cdd61b53db14e4 + + - id: BLESSED_BAIT + material: PLAYER_HEAD + rarity: UNCOMMON + components: + - id: FISHING_BAIT + treasure_quality_bonus: 50 + texture: c2b910b5897cdb86b21ebfcba544afa470ae6d228bee3494427c9c7e8f33502b + + - id: ICE_BAIT + material: PLAYER_HEAD + rarity: UNCOMMON + components: + - id: FISHING_BAIT + tag_bonuses: + WINTER: 20 + texture: 609e161bdc325c71572a548a79bb15481c924d63e4fb821379d5dd6c8929f39f + + - id: SHARK_BAIT + material: PLAYER_HEAD + rarity: UNCOMMON + components: + - id: FISHING_BAIT + tag_bonuses: + SHARK: 20 + texture: edff904124efe486b3a54261dbb8072b0a4e11615ad8d7394d814e0e8c8ef9eb + + - id: GLOWY_CHUM_BAIT + material: PLAYER_HEAD + rarity: UNCOMMON + default_statistics: + FISHING_SPEED: 25 + SEA_CREATURE_CHANCE: 3 + components: + - id: FISHING_BAIT + texture: dfdc1eed684dd805eae96d132e3da53d64267d7361388d5e2c67f5969871e71d + + - id: HOT_BAIT + material: PLAYER_HEAD + rarity: UNCOMMON + components: + - id: FISHING_BAIT + trophy_fish_chance_bonus: 5 + texture: 213c6899d97109c6cacbbcdd01e8900abaf46432f197595baa15ad137d5fb9ba + + - id: WORM_BAIT + material: PLAYER_HEAD + rarity: UNCOMMON + default_statistics: + FISHING_SPEED: 60 + components: + - id: FISHING_BAIT + texture: df03ad96092f3f789902436709cdf69de6b727c121b3c2daef9ffa1ccaed186c + + - id: FROZEN_BAIT + material: PLAYER_HEAD + rarity: RARE + components: + - id: FISHING_BAIT + tag_bonuses: + WINTER: 35 + texture: 38dc68a97cefe92c8cdaa7cb1a7a4de8f16c161da736edf54f79b74beecd6513 + + - id: GOLDEN_BAIT + material: PLAYER_HEAD + rarity: UNCOMMON + components: + - id: FISHING_BAIT + treasure_chance_bonus: 4 + texture: 72e2908dbb112dcd0b367df43fafcc41a56d9cf803e90a367834b4911f84f391 + + - id: TREASURE_BAIT + material: PLAYER_HEAD + rarity: RARE + default_statistics: + FISHING_SPEED: 10 + components: + - id: FISHING_BAIT + treasure_chance_bonus: 2 + texture: c1695c80854447b5db5a0ee6d57ef0a7d91d815bd7e6318c516a39d12fe0639e + + - id: WOODEN_BAIT + material: PLAYER_HEAD + rarity: UNCOMMON + components: + - id: FISHING_BAIT + texture: 5b236a39e51a39dff9bced39333a73413984bc74db37c1318bfc4a4459f035d2 + + - id: HOTSPOT_BAIT + material: PLAYER_HEAD + rarity: RARE + components: + - id: FISHING_BAIT + tag_bonuses: + HOTSPOT: 50 + texture: de9b17db5c4cadef737e2fefb42a0123c32cbeaa1ca8932579eb2f05018612cd + + - id: WHALE_BAIT + material: PLAYER_HEAD + rarity: RARE + default_statistics: + FISHING_SPEED: 30 + components: + - id: FISHING_BAIT + texture: 5b4fb49ae77cfcf0b8f62df9c69cc96b27096ad2737d6d0aa450b50664fb2303 diff --git a/configuration/skyblock/items/fishing/fishingContent.yml b/configuration/skyblock/items/fishing/fishingContent.yml deleted file mode 100644 index 2d93a58d0..000000000 --- a/configuration/skyblock/items/fishing/fishingContent.yml +++ /dev/null @@ -1,735 +0,0 @@ -items: - - id: CHALLENGE_ROD - material: FISHING_ROD - rarity: UNCOMMON - default_statistics: - DAMAGE: 75 - STRENGTH: 75 - FISHING_SPEED: 40 - SEA_CREATURE_CHANCE: 7 - TREASURE_CHANCE: 2.5 - components: - - id: FISHING_ROD_METADATA - display_name: Challenging Rod - medium: WATER - required_fishing_level: 10 - rod_parts_enabled: true - enchantments: - ANGLER: 5 - CASTER: 5 - FRAIL: 5 - IMPALING: 3 - LOOTING: 3 - LUCK_OF_THE_SEA: 5 - LURE: 5 - MAGNET: 5 - PISCARY: 5 - SPIKED_HOOK: 5 - - id: CHAMP_ROD - material: FISHING_ROD - rarity: RARE - default_statistics: - DAMAGE: 100 - STRENGTH: 100 - FISHING_SPEED: 55 - SEA_CREATURE_CHANCE: 10 - TREASURE_CHANCE: 3.0 - components: - - id: FISHING_ROD_METADATA - display_name: Rod of Champions - medium: WATER - required_fishing_level: 15 - rod_parts_enabled: true - enchantments: - ANGLER: 6 - CASTER: 5 - CHARM: 3 - FRAIL: 6 - IMPALING: 4 - LOOTING: 4 - LUCK_OF_THE_SEA: 6 - LURE: 6 - MAGNET: 5 - PISCARY: 5 - SPIKED_HOOK: 6 - - id: LEGEND_ROD - material: FISHING_ROD - rarity: EPIC - default_statistics: - DAMAGE: 125 - STRENGTH: 125 - FISHING_SPEED: 70 - SEA_CREATURE_CHANCE: 14 - TREASURE_CHANCE: 3.5 - components: - - id: FISHING_ROD_METADATA - display_name: Rod of Legends - medium: WATER - required_fishing_level: 20 - rod_parts_enabled: true - enchantments: - ANGLER: 6 - CASTER: 6 - CHARM: 4 - FRAIL: 7 - IMPALING: 5 - LOOTING: 4 - LUCK_OF_THE_SEA: 7 - LURE: 6 - MAGNET: 6 - PISCARY: 6 - SPIKED_HOOK: 7 - - id: ROD_OF_THE_SEA - material: FISHING_ROD - rarity: LEGENDARY - default_statistics: - DAMAGE: 150 - STRENGTH: 150 - FISHING_SPEED: 95 - SEA_CREATURE_CHANCE: 20 - TREASURE_CHANCE: 3.5 - components: - - id: FISHING_ROD_METADATA - display_name: Rod of the Sea - medium: WATER - required_fishing_level: 24 - rod_parts_enabled: true - enchantments: - FLASH: 5 - ANGLER: 6 - BLESSING: 6 - CASTER: 6 - CHARM: 6 - CORRUPTION: 5 - EXPERTISE: 10 - FRAIL: 7 - IMPALING: 5 - LOOTING: 4 - LUCK_OF_THE_SEA: 7 - LURE: 6 - MAGNET: 6 - PISCARY: 7 - QUICK_BITE: 5 - SPIKED_HOOK: 7 - TABASCO: 3 - - id: GIANT_FISHING_ROD - material: FISHING_ROD - rarity: LEGENDARY - default_statistics: - DAMAGE: 20 - STRENGTH: 10 - FISHING_SPEED: 20 - DOUBLE_HOOK_CHANCE: 10 - components: - - id: FISHING_ROD_METADATA - display_name: Giant Fishing Rod - medium: WATER - rod_parts_enabled: true - - id: DIRT_ROD - material: FISHING_ROD - rarity: UNCOMMON - default_statistics: - FISHING_SPEED: 20 - components: - - id: FISHING_ROD_METADATA - display_name: Dirt Rod - medium: WATER - rod_parts_enabled: false - - id: STARTER_LAVA_ROD - material: FISHING_ROD - rarity: UNCOMMON - default_statistics: - DAMAGE: 50 - STRENGTH: 50 - FISHING_SPEED: 10 - TROPHY_FISH_CHANCE: 5 - components: - - id: FISHING_ROD_METADATA - display_name: Starter Lava Rod - subtitle: Lava Rod - medium: LAVA - required_fishing_level: 10 - rod_parts_enabled: true - - id: POLISHED_TOPAZ_ROD - material: FISHING_ROD - rarity: RARE - default_statistics: - DAMAGE: 80 - STRENGTH: 80 - FISHING_SPEED: 30 - TROPHY_FISH_CHANCE: 8 - components: - - id: FISHING_ROD_METADATA - display_name: Topaz Rod - subtitle: Lava Rod - medium: LAVA - required_fishing_level: 14 - rod_parts_enabled: true - - id: MAGMA_ROD - material: FISHING_ROD - rarity: RARE - default_statistics: - DAMAGE: 110 - STRENGTH: 110 - FISHING_SPEED: 50 - TROPHY_FISH_CHANCE: 12 - components: - - id: FISHING_ROD_METADATA - display_name: Magma Rod - subtitle: Lava Rod - medium: LAVA - required_fishing_level: 18 - rod_parts_enabled: true - - id: INFERNO_ROD - material: FISHING_ROD - rarity: EPIC - default_statistics: - DAMAGE: 140 - STRENGTH: 140 - FISHING_SPEED: 70 - TROPHY_FISH_CHANCE: 16 - components: - - id: FISHING_ROD_METADATA - display_name: Inferno Rod - subtitle: Lava Rod - medium: LAVA - required_fishing_level: 22 - rod_parts_enabled: true - - id: HELLFIRE_ROD - material: FISHING_ROD - rarity: LEGENDARY - default_statistics: - DAMAGE: 175 - STRENGTH: 175 - FISHING_SPEED: 95 - TROPHY_FISH_CHANCE: 22 - components: - - id: FISHING_ROD_METADATA - display_name: Hellfire Rod - subtitle: Lava Rod - medium: LAVA - required_fishing_level: 26 - rod_parts_enabled: true - - id: CHUM_ROD - material: FISHING_ROD - rarity: RARE - default_statistics: - DAMAGE: 20 - STRENGTH: 10 - FISHING_SPEED: 30 - components: - - id: FISHING_ROD_METADATA - display_name: Chum Rod - medium: WATER - required_fishing_level: 4 - rod_parts_enabled: false - legacy_conversion_target: CHALLENGE_ROD - legacy_conversion_part: CHUM_SINKER - - id: PRISMARINE_ROD - material: FISHING_ROD - rarity: COMMON - default_statistics: - DAMAGE: 10 - FISHING_SPEED: 10 - components: - - id: FISHING_ROD_METADATA - display_name: Prismarine Rod - medium: WATER - rod_parts_enabled: false - legacy_conversion_target: CHALLENGE_ROD - legacy_conversion_part: PRISMARINE_SINKER - - id: SPONGE_ROD - material: FISHING_ROD - rarity: COMMON - default_statistics: - DAMAGE: 10 - FISHING_SPEED: 10 - components: - - id: FISHING_ROD_METADATA - display_name: Sponge Rod - medium: WATER - rod_parts_enabled: false - legacy_conversion_target: CHALLENGE_ROD - legacy_conversion_part: SPONGE_SINKER - - id: SPEEDSTER_ROD - material: FISHING_ROD - rarity: UNCOMMON - default_statistics: - DAMAGE: 30 - STRENGTH: 15 - FISHING_SPEED: 45 - components: - - id: FISHING_ROD_METADATA - display_name: Speedster Rod - medium: WATER - required_fishing_level: 6 - rod_parts_enabled: false - legacy_conversion_target: CHALLENGE_ROD - legacy_conversion_part: SPEEDY_LINE - - id: FARMER_ROD - material: FISHING_ROD - rarity: UNCOMMON - default_statistics: - DAMAGE: 50 - STRENGTH: 20 - FISHING_SPEED: 60 - components: - - id: FISHING_ROD_METADATA - display_name: Farmer's Rod - medium: WATER - required_fishing_level: 8 - rod_parts_enabled: false - legacy_conversion_target: CHALLENGE_ROD - - id: ICE_ROD - material: FISHING_ROD - rarity: RARE - default_statistics: - DAMAGE: 30 - FISHING_SPEED: 15 - components: - - id: FISHING_ROD_METADATA - display_name: Ice Rod - medium: WATER - rod_parts_enabled: false - legacy_conversion_target: CHALLENGE_ROD - legacy_conversion_part: ICY_SINKER - - id: WINTER_ROD - material: FISHING_ROD - rarity: RARE - default_statistics: - DAMAGE: 50 - STRENGTH: 50 - FISHING_SPEED: 75 - components: - - id: FISHING_ROD_METADATA - display_name: Winter Rod - medium: WATER - required_fishing_level: 10 - rod_parts_enabled: false - legacy_conversion_target: CHALLENGE_ROD - legacy_conversion_part: FESTIVE_SINKER - - id: YETI_ROD - material: FISHING_ROD - rarity: EPIC - default_statistics: - DAMAGE: 150 - STRENGTH: 130 - FISHING_SPEED: 75 - components: - - id: FISHING_ROD_METADATA - display_name: Yeti Rod - medium: WATER - required_fishing_level: 25 - rod_parts_enabled: false - legacy_conversion_target: CHALLENGE_ROD - legacy_conversion_part: ICY_SINKER - - id: THE_SHREDDER - material: FISHING_ROD - rarity: LEGENDARY - default_statistics: - DAMAGE: 120 - STRENGTH: 15 - FEROCITY: 50 - FISHING_SPEED: 115 - components: - - id: FISHING_ROD_METADATA - display_name: Shredder - medium: WATER - required_fishing_level: 20 - rod_parts_enabled: false - legacy_conversion_target: CHALLENGE_ROD - legacy_conversion_part: SHREDDED_LINE - - id: PHANTOM_ROD - material: FISHING_ROD - rarity: LEGENDARY - default_statistics: - DAMAGE: 200 - STRENGTH: 125 - FISHING_SPEED: 100 - components: - - id: FISHING_ROD_METADATA - display_name: Phantom Rod - medium: WATER - required_fishing_level: 21 - rod_parts_enabled: false - legacy_conversion_target: CHALLENGE_ROD - legacy_conversion_part: PHANTOM_HOOK - - id: AUGER_ROD - material: FISHING_ROD - rarity: LEGENDARY - default_statistics: - DAMAGE: 135 - STRENGTH: 90 - FISHING_SPEED: 110 - components: - - id: FISHING_ROD_METADATA - display_name: Auger Rod - medium: WATER - required_fishing_level: 25 - rod_parts_enabled: false - legacy_conversion_target: ROD_OF_THE_SEA - legacy_conversion_part: ICY_SINKER - - id: COMMON_HOOK - material: PLAYER_HEAD - rarity: RARE - components: - - id: FISHING_ROD_PART - display_name: Common Hook - category: HOOK - required_fishing_level: 5 - tag_bonuses: - COMMON: 25 - texture: d235388f091b7fd13397151fca580fdf9a41c2a0a297f887838710f629aa3fd6 - - id: HOTSPOT_HOOK - material: PLAYER_HEAD - rarity: RARE - components: - - id: FISHING_ROD_PART - display_name: Hotspot Hook - category: HOOK - required_fishing_level: 20 - tag_bonuses: - HOTSPOT: 100 - texture: 17415df9f4c8cdabdacd442da80826188e46a3d166f56fd1509bba26faac76dd - - id: PHANTOM_HOOK - material: PLAYER_HEAD - rarity: RARE - components: - - id: FISHING_ROD_PART - display_name: Phantom Hook - category: HOOK - required_fishing_level: 21 - tag_bonuses: - SPOOKY: 100 - texture: c95eff1654366d5245238ddbfb65a7a7128468a9ce343861fe239e87c14c3f6d - - id: TREASURE_HOOK - material: PLAYER_HEAD - rarity: RARE - components: - - id: FISHING_ROD_PART - display_name: Treasure Hook - category: HOOK - required_fishing_level: 25 - treasure_only: true - texture: 9809753cbab0380c7a1c18925faf9b51e44caadd1e5748542b0f23835f4ef64e - - id: SPEEDY_LINE - material: PLAYER_HEAD - rarity: RARE - default_statistics: - FISHING_SPEED: 10 - components: - - id: FISHING_ROD_PART - display_name: Speedy Line - category: LINE - required_fishing_level: 5 - texture: 5cbac3c84e21e65ec88007604c4eba1da391e185544b90252fc16ca695c59b4b - - id: SHREDDED_LINE - material: PLAYER_HEAD - rarity: RARE - default_statistics: - DAMAGE: 250 - FEROCITY: 50 - components: - - id: FISHING_ROD_PART - display_name: Shredded Line - category: LINE - required_fishing_level: 20 - texture: f5424291868be6ae16512641666c5286a740f936e42f96e34987fb6f43d16e6e - - id: TITAN_LINE - material: PLAYER_HEAD - rarity: RARE - default_statistics: - DOUBLE_HOOK_CHANCE: 2 - components: - - id: FISHING_ROD_PART - display_name: Titan Line - category: LINE - required_fishing_level: 35 - texture: 9a850a4f721bc150bb72b067e5074c8251058a6b9111691da315b393467c1aa9 - - id: JUNK_SINKER - material: PLAYER_HEAD - rarity: RARE - components: - - id: FISHING_ROD_PART - display_name: Junk Sinker - category: SINKER - required_fishing_level: 5 - bayou_treasure_to_junk: true - texture: d24892a3142d2e130e5feb88b805b83de905489d2ccd1d031b9d7a2922b96500 - - id: PRISMARINE_SINKER - material: PLAYER_HEAD - rarity: RARE - components: - - id: FISHING_ROD_PART - display_name: Prismarine Sinker - category: SINKER - required_fishing_level: 5 - materialized_item_id: PRISMARINE_SHARD - texture: b9d2d0fe4c93fbc21309e93d985df37e1133d2ece58d2f96b6be5cffba53c181 - - id: SPONGE_SINKER - material: PLAYER_HEAD - rarity: RARE - components: - - id: FISHING_ROD_PART - display_name: Sponge Sinker - category: SINKER - required_fishing_level: 5 - materialized_item_id: SPONGE - texture: 8b24369807fcf3bd852e6da87ddeca9d38a04f32c78599f4c5823b9522278259 - - id: CHUM_SINKER - material: PLAYER_HEAD - rarity: RARE - components: - - id: FISHING_ROD_PART - display_name: Chum Sinker - category: SINKER - required_fishing_level: 5 - materialized_item_id: CHUM - texture: d02b855b4acc508086248ff468aaaaba0c0d8deaa2adc0321ed0809e416736ef - - id: FESTIVE_SINKER - material: PLAYER_HEAD - rarity: RARE - components: - - id: FISHING_ROD_PART - display_name: Festive Sinker - category: SINKER - required_fishing_level: 5 - materialized_chance: 0.05 - texture: 6f5840e5b76a2ed0de1c2280ae8be0edd90d83e5f8408af9f1e92f2db92e0383 - - id: ICY_SINKER - material: PLAYER_HEAD - rarity: RARE - components: - - id: FISHING_ROD_PART - display_name: Icy Sinker - category: SINKER - required_fishing_level: 5 - tag_bonuses: - WINTER: 200 - materialized_item_id: ICE - texture: 41dfb1861aa0dd49f7bd8a4ecb14fbda35055fbe9b06b4d7be5cdde0fc7cc60e - - id: STINGY_SINKER - material: PLAYER_HEAD - rarity: RARE - components: - - id: FISHING_ROD_PART - display_name: Stingy Sinker - category: SINKER - required_fishing_level: 5 - bait_preservation_chance: 10.0 - texture: e886d5cac32bd32fc07938908c552b7b27965d92065b3157dfc7ef849281ee9d - - id: HOTSPOT_SINKER - material: PLAYER_HEAD - rarity: RARE - components: - - id: FISHING_ROD_PART - display_name: Hotspot Sinker - category: SINKER - required_fishing_level: 20 - hotspot_buff_multiplier: 2.0 - texture: 88891d33b55dd1572814527b9c027ec724909c26281a197d0309fbfa925cbce4 - - id: MINNOW_BAIT - material: PLAYER_HEAD - rarity: COMMON - default_statistics: - FISHING_SPEED: 25 - components: - - id: FISHING_BAIT - display_name: Minnow Bait - texture: b8e749ba141c054bb0c125320b17677bdcb3a7e9807a57527c0877b94548a2e - - id: FISH_BAIT - material: PLAYER_HEAD - rarity: COMMON - default_statistics: - FISHING_SPEED: 45 - components: - - id: FISHING_BAIT - display_name: Fish Bait - texture: 49e8dc9fdc9f00e1d17666a4787d34cca7cc6dc030f0dc686195546f81c6f22 - - id: LIGHT_BAIT - material: PLAYER_HEAD - rarity: COMMON - components: - - id: FISHING_BAIT - display_name: Light Bait - texture: e3bcc16f402342b4acd29aecac72d1d5a116e0abb478bb4960e734fd70686ba - - id: DARK_BAIT - material: PLAYER_HEAD - rarity: COMMON - components: - - id: FISHING_BAIT - display_name: Dark Bait - texture: 7281618a5c8239078fd43fef8eae14ea00665f635bd56d4451cccd5d0fa11821 - - id: SPIKED_BAIT - material: PLAYER_HEAD - rarity: COMMON - default_statistics: - SEA_CREATURE_CHANCE: 6 - components: - - id: FISHING_BAIT - display_name: Spiked Bait - texture: e42c436c6580fad217323b9f045daa23a9f88219ac26506637669eff20901f74 - - id: SPOOKY_BAIT - material: PLAYER_HEAD - rarity: COMMON - default_statistics: - FISHING_SPEED: 25 - components: - - id: FISHING_BAIT - display_name: Spooky Bait - tag_bonuses: - SPOOKY: 15 - texture: 977eab558e6a90f7cedd72c2416c891f47d71eb4e7bdcc299a6335286f5cba98 - - id: CARROT_BAIT - material: PLAYER_HEAD - rarity: COMMON - components: - - id: FISHING_BAIT - display_name: Carrot Bait - texture: 4d3a6bd98ac1833c664c4909ff8d2dc62ce887bdcf3cc5b3848651ae5af6b - - id: CORRUPTED_BAIT - material: PLAYER_HEAD - rarity: COMMON - components: - - id: FISHING_BAIT - display_name: Corrupted Bait - texture: 4bbcddd45cd347865bceab3e3dc5d382723463963f85ecce81cdd61b53db14e4 - - id: BLESSED_BAIT - material: PLAYER_HEAD - rarity: UNCOMMON - components: - - id: FISHING_BAIT - display_name: Blessed Bait - treasure_quality_bonus: 50 - texture: c2b910b5897cdb86b21ebfcba544afa470ae6d228bee3494427c9c7e8f33502b - - id: ICE_BAIT - material: PLAYER_HEAD - rarity: UNCOMMON - components: - - id: FISHING_BAIT - display_name: Ice Bait - tag_bonuses: - WINTER: 20 - texture: 609e161bdc325c71572a548a79bb15481c924d63e4fb821379d5dd6c8929f39f - - id: SHARK_BAIT - material: PLAYER_HEAD - rarity: UNCOMMON - components: - - id: FISHING_BAIT - display_name: Shark Bait - tag_bonuses: - SHARK: 20 - texture: edff904124efe486b3a54261dbb8072b0a4e11615ad8d7394d814e0e8c8ef9eb - - id: GLOWY_CHUM_BAIT - material: PLAYER_HEAD - rarity: UNCOMMON - default_statistics: - FISHING_SPEED: 25 - SEA_CREATURE_CHANCE: 3 - components: - - id: FISHING_BAIT - display_name: Glowy Chum Bait - texture: dfdc1eed684dd805eae96d132e3da53d64267d7361388d5e2c67f5969871e71d - - id: HOT_BAIT - material: PLAYER_HEAD - rarity: UNCOMMON - default_statistics: - FISHING_SPEED: 15 - components: - - id: FISHING_BAIT - display_name: Hot Bait - trophy_fish_chance_bonus: 5 - texture: 213c6899d97109c6cacbbcdd01e8900abaf46432f197595baa15ad137d5fb9ba - - id: WORM_BAIT - material: PLAYER_HEAD - rarity: UNCOMMON - default_statistics: - FISHING_SPEED: 60 - components: - - id: FISHING_BAIT - display_name: Worm Bait - texture: df03ad96092f3f789902436709cdf69de6b727c121b3c2daef9ffa1ccaed186c - - id: FROZEN_BAIT - material: PLAYER_HEAD - rarity: RARE - components: - - id: FISHING_BAIT - display_name: Frozen Bait - tag_bonuses: - WINTER: 35 - texture: 38dc68a97cefe92c8cdaa7cb1a7a4de8f16c161da736edf54f79b74beecd6513 - - id: GOLDEN_BAIT - material: PLAYER_HEAD - rarity: UNCOMMON - components: - - id: FISHING_BAIT - display_name: Golden Bait - treasure_chance_bonus: 4 - texture: 72e2908dbb112dcd0b367df43fafcc41a56d9cf803e90a367834b4911f84f391 - - id: TREASURE_BAIT - material: PLAYER_HEAD - rarity: RARE - default_statistics: - FISHING_SPEED: 10 - components: - - id: FISHING_BAIT - display_name: Treasure Bait - treasure_chance_bonus: 2 - texture: c1695c80854447b5db5a0ee6d57ef0a7d91d815bd7e6318c516a39d12fe0639e - - id: WOODEN_BAIT - material: PLAYER_HEAD - rarity: UNCOMMON - components: - - id: FISHING_BAIT - display_name: Wooden Bait - texture: 5b236a39e51a39dff9bced39333a73413984bc74db37c1318bfc4a4459f035d2 - - id: HOTSPOT_BAIT - material: PLAYER_HEAD - rarity: RARE - components: - - id: FISHING_BAIT - display_name: Hotspot Bait - tag_bonuses: - HOTSPOT: 50 - texture: de9b17db5c4cadef737e2fefb42a0123c32cbeaa1ca8932579eb2f05018612cd - - id: WHALE_BAIT - material: PLAYER_HEAD - rarity: RARE - default_statistics: - FISHING_SPEED: 30 - components: - - id: FISHING_BAIT - display_name: Whale Bait - texture: 5b4fb49ae77cfcf0b8f62df9c69cc96b27096ad2737d6d0aa450b50664fb2303 - - id: RUSTY_SHIP_ENGINE - material: PLAYER_HEAD - rarity: SPECIAL - components: - - id: FISHING_SHIP_PART - display_name: Rusty Ship Engine - slot: ENGINE - texture: 53e84793917c890f7f8a2c4078a29e8ba939790498727af9342c2b6f6ac43c9c - - id: BRONZE_SHIP_ENGINE - material: PLAYER_HEAD - rarity: RARE - components: - - id: FISHING_SHIP_PART - display_name: Bronze Ship Engine - slot: ENGINE - texture: 9172c1e729e0ca00193ab5d43e893fabedf5a80fc647258176e8502432885925 - - id: BRONZE_SHIP_HELM - material: PLAYER_HEAD - rarity: RARE - components: - - id: FISHING_SHIP_PART - display_name: Bronze Ship Helm - slot: HELM - texture: 646c5393c3c57742c992c56a7b7a8b98d267538de947c1096fe76341431008f2 - - id: BRONZE_SHIP_HULL - material: PLAYER_HEAD - rarity: RARE - components: - - id: FISHING_SHIP_PART - display_name: Bronze Ship Hull - slot: HULL - texture: a4a7254f1ad8448097d83ddfc790c9f02bc889acbd304b414cee5a13ceadc1e diff --git a/configuration/skyblock/items/fishing/parts.yml b/configuration/skyblock/items/fishing/parts.yml new file mode 100644 index 000000000..5433e2fb1 --- /dev/null +++ b/configuration/skyblock/items/fishing/parts.yml @@ -0,0 +1,191 @@ +items: + - id: COMMON_HOOK + material: PLAYER_HEAD + rarity: RARE + components: + - id: FISHING_ROD_PART + category: HOOK + required_fishing_level: 5 + tag_bonuses: + COMMON: 25 + texture: d235388f091b7fd13397151fca580fdf9a41c2a0a297f887838710f629aa3fd6 + + - id: HOTSPOT_HOOK + material: PLAYER_HEAD + rarity: RARE + components: + - id: FISHING_ROD_PART + category: HOOK + required_fishing_level: 20 + tag_bonuses: + HOTSPOT: 100 + texture: 17415df9f4c8cdabdacd442da80826188e46a3d166f56fd1509bba26faac76dd + + - id: PHANTOM_HOOK + material: PLAYER_HEAD + rarity: RARE + components: + - id: FISHING_ROD_PART + category: HOOK + required_fishing_level: 21 + tag_bonuses: + SPOOKY: 100 + texture: c95eff1654366d5245238ddbfb65a7a7128468a9ce343861fe239e87c14c3f6d + + - id: TREASURE_HOOK + material: PLAYER_HEAD + rarity: RARE + components: + - id: FISHING_ROD_PART + category: HOOK + required_fishing_level: 25 + treasure_only: true + texture: 9809753cbab0380c7a1c18925faf9b51e44caadd1e5748542b0f23835f4ef64e + + - id: SPEEDY_LINE + material: PLAYER_HEAD + rarity: RARE + default_statistics: + FISHING_SPEED: 10 + components: + - id: FISHING_ROD_PART + category: LINE + required_fishing_level: 5 + texture: 5cbac3c84e21e65ec88007604c4eba1da391e185544b90252fc16ca695c59b4b + + - id: SHREDDED_LINE + material: PLAYER_HEAD + rarity: RARE + default_statistics: + DAMAGE: 250 + FEROCITY: 50 + components: + - id: FISHING_ROD_PART + category: LINE + required_fishing_level: 20 + texture: f5424291868be6ae16512641666c5286a740f936e42f96e34987fb6f43d16e6e + + - id: TITAN_LINE + material: PLAYER_HEAD + rarity: RARE + default_statistics: + DOUBLE_HOOK_CHANCE: 2 + components: + - id: FISHING_ROD_PART + category: LINE + required_fishing_level: 35 + texture: 9a850a4f721bc150bb72b067e5074c8251058a6b9111691da315b393467c1aa9 + + - id: JUNK_SINKER + material: PLAYER_HEAD + rarity: RARE + components: + - id: FISHING_ROD_PART + category: SINKER + required_fishing_level: 5 + bayou_treasure_to_junk: true + texture: d24892a3142d2e130e5feb88b805b83de905489d2ccd1d031b9d7a2922b96500 + + - id: PRISMARINE_SINKER + material: PLAYER_HEAD + rarity: RARE + components: + - id: FISHING_ROD_PART + category: SINKER + required_fishing_level: 5 + materialized_item_id: PRISMARINE_SHARD + texture: b9d2d0fe4c93fbc21309e93d985df37e1133d2ece58d2f96b6be5cffba53c181 + + - id: SPONGE_SINKER + material: PLAYER_HEAD + rarity: RARE + components: + - id: FISHING_ROD_PART + category: SINKER + required_fishing_level: 5 + materialized_item_id: SPONGE + texture: 8b24369807fcf3bd852e6da87ddeca9d38a04f32c78599f4c5823b9522278259 + + - id: CHUM_SINKER + material: PLAYER_HEAD + rarity: RARE + components: + - id: FISHING_ROD_PART + category: SINKER + required_fishing_level: 5 + materialized_item_id: CHUM + texture: d02b855b4acc508086248ff468aaaaba0c0d8deaa2adc0321ed0809e416736ef + + - id: FESTIVE_SINKER + material: PLAYER_HEAD + rarity: RARE + components: + - id: FISHING_ROD_PART + category: SINKER + required_fishing_level: 5 + materialized_chance: 0.05 + texture: 6f5840e5b76a2ed0de1c2280ae8be0edd90d83e5f8408af9f1e92f2db92e0383 + + - id: ICY_SINKER + material: PLAYER_HEAD + rarity: RARE + components: + - id: FISHING_ROD_PART + category: SINKER + required_fishing_level: 5 + tag_bonuses: + WINTER: 200 + materialized_item_id: ICE + texture: 41dfb1861aa0dd49f7bd8a4ecb14fbda35055fbe9b06b4d7be5cdde0fc7cc60e + + - id: STINGY_SINKER + material: PLAYER_HEAD + rarity: RARE + components: + - id: FISHING_ROD_PART + category: SINKER + required_fishing_level: 5 + bait_preservation_chance: 10.0 + texture: e886d5cac32bd32fc07938908c552b7b27965d92065b3157dfc7ef849281ee9d + + - id: HOTSPOT_SINKER + material: PLAYER_HEAD + rarity: RARE + components: + - id: FISHING_ROD_PART + category: SINKER + required_fishing_level: 20 + hotspot_buff_multiplier: 2.0 + texture: 88891d33b55dd1572814527b9c027ec724909c26281a197d0309fbfa925cbce4 + + - id: RUSTY_SHIP_ENGINE + material: PLAYER_HEAD + rarity: SPECIAL + components: + - id: FISHING_SHIP_PART + slot: ENGINE + texture: 53e84793917c890f7f8a2c4078a29e8ba939790498727af9342c2b6f6ac43c9c + + - id: BRONZE_SHIP_ENGINE + material: PLAYER_HEAD + rarity: RARE + components: + - id: FISHING_SHIP_PART + slot: ENGINE + texture: 9172c1e729e0ca00193ab5d43e893fabedf5a80fc647258176e8502432885925 + + - id: BRONZE_SHIP_HELM + material: PLAYER_HEAD + rarity: RARE + components: + - id: FISHING_SHIP_PART + slot: HELM + texture: 646c5393c3c57742c992c56a7b7a8b98d267538de947c1096fe76341431008f2 + + - id: BRONZE_SHIP_HULL + material: PLAYER_HEAD + rarity: RARE + components: + - id: FISHING_SHIP_PART + slot: HULL + texture: a4a7254f1ad8448097d83ddfc790c9f02bc889acbd304b414cee5a13ceadc1e diff --git a/configuration/skyblock/items/fishing/rods.yml b/configuration/skyblock/items/fishing/rods.yml new file mode 100644 index 000000000..0129732bc --- /dev/null +++ b/configuration/skyblock/items/fishing/rods.yml @@ -0,0 +1,292 @@ +items: + - id: CHALLENGE_ROD + material: FISHING_ROD + rarity: UNCOMMON + default_statistics: + DAMAGE: 75 + STRENGTH: 75 + FISHING_SPEED: 35 + SEA_CREATURE_CHANCE: 2 + components: + - id: FISHING_ROD_METADATA + medium: WATER + required_fishing_level: 10 + + - id: CHAMP_ROD + material: FISHING_ROD + rarity: RARE + default_statistics: + DAMAGE: 90 + STRENGTH: 80 + FISHING_SPEED: 90 + SEA_CREATURE_CHANCE: 4 + components: + - id: FISHING_ROD_METADATA + medium: WATER + required_fishing_level: 15 + + - id: LEGEND_ROD + material: FISHING_ROD + rarity: EPIC + default_statistics: + DAMAGE: 130 + STRENGTH: 120 + FISHING_SPEED: 105 + SEA_CREATURE_CHANCE: 6 + components: + - id: FISHING_ROD_METADATA + medium: WATER + required_fishing_level: 20 + + - id: ROD_OF_THE_SEA + material: FISHING_ROD + rarity: LEGENDARY + default_statistics: + DAMAGE: 150 + STRENGTH: 150 + FISHING_SPEED: 80 + SEA_CREATURE_CHANCE: 8 + components: + - id: FISHING_ROD_METADATA + medium: WATER + required_fishing_level: 24 + + - id: GIANT_FISHING_ROD + material: FISHING_ROD + rarity: LEGENDARY + default_statistics: + DAMAGE: 20 + STRENGTH: 10 + FISHING_SPEED: 20 + DOUBLE_HOOK_CHANCE: 10 + components: + - id: FISHING_ROD_METADATA + medium: WATER + + - id: DIRT_ROD + material: FISHING_ROD + rarity: UNCOMMON + default_statistics: + FISHING_SPEED: 20 + components: + - id: FISHING_ROD_METADATA + medium: WATER + rod_parts_enabled: false + + - id: STARTER_LAVA_ROD + material: FISHING_ROD + rarity: UNCOMMON + default_statistics: + DAMAGE: 50 + STRENGTH: 50 + FISHING_SPEED: 10 + TROPHY_FISH_CHANCE: 5 + components: + - id: FISHING_ROD_METADATA + subtitle: Lava Rod + medium: LAVA + required_fishing_level: 10 + + - id: POLISHED_TOPAZ_ROD + material: FISHING_ROD + rarity: RARE + default_statistics: + DAMAGE: 100 + STRENGTH: 100 + FISHING_SPEED: 50 + SEA_CREATURE_CHANCE: 2 + components: + - id: FISHING_ROD_METADATA + subtitle: Lava Rod + medium: LAVA + required_fishing_level: 19 + extra_requirements: + - "❣ Requires Heart of the Mountain Tier 5." + + - id: MAGMA_ROD + material: FISHING_ROD + rarity: RARE + default_statistics: + DAMAGE: 150 + STRENGTH: 120 + FISHING_SPEED: 40 + SEA_CREATURE_CHANCE: 6 + TROPHY_FISH_CHANCE: 10 + components: + - id: FISHING_ROD_METADATA + subtitle: Lava Rod + medium: LAVA + required_fishing_level: 27 + + - id: INFERNO_ROD + material: FISHING_ROD + rarity: EPIC + default_statistics: + DAMAGE: 210 + STRENGTH: 150 + FISHING_SPEED: 60 + SEA_CREATURE_CHANCE: 10 + TROPHY_FISH_CHANCE: 15 + components: + - id: FISHING_ROD_METADATA + subtitle: Lava Rod + medium: LAVA + required_fishing_level: 30 + + - id: HELLFIRE_ROD + material: FISHING_ROD + rarity: LEGENDARY + default_statistics: + DAMAGE: 225 + STRENGTH: 225 + FISHING_SPEED: 60 + SEA_CREATURE_CHANCE: 14 + TROPHY_FISH_CHANCE: 20 + components: + - id: FISHING_ROD_METADATA + subtitle: Lava Rod + medium: LAVA + required_fishing_level: 35 + + - id: CHUM_ROD + material: FISHING_ROD + rarity: RARE + default_statistics: + DAMAGE: 55 + STRENGTH: 40 + FISHING_SPEED: 70 + SEA_CREATURE_CHANCE: 2 + components: + - id: FISHING_ROD_METADATA + medium: WATER + required_fishing_level: 5 + legacy_conversion_target: CHALLENGE_ROD + + - id: PRISMARINE_ROD + material: FISHING_ROD + rarity: COMMON + default_statistics: + DAMAGE: 15 + STRENGTH: 10 + FISHING_SPEED: 15 + components: + - id: FISHING_ROD_METADATA + medium: WATER + required_fishing_level: 3 + legacy_conversion_target: CHALLENGE_ROD + + - id: SPONGE_ROD + material: FISHING_ROD + rarity: COMMON + default_statistics: + DAMAGE: 20 + STRENGTH: 15 + FISHING_SPEED: 30 + components: + - id: FISHING_ROD_METADATA + medium: WATER + required_fishing_level: 5 + legacy_conversion_target: CHALLENGE_ROD + + - id: SPEEDSTER_ROD + material: FISHING_ROD + rarity: UNCOMMON + default_statistics: + DAMAGE: 30 + STRENGTH: 15 + FISHING_SPEED: 45 + components: + - id: FISHING_ROD_METADATA + medium: WATER + required_fishing_level: 6 + legacy_conversion_target: CHALLENGE_ROD + + - id: FARMER_ROD + material: FISHING_ROD + rarity: UNCOMMON + default_statistics: + DAMAGE: 50 + STRENGTH: 20 + FISHING_SPEED: 60 + components: + - id: FISHING_ROD_METADATA + medium: WATER + required_fishing_level: 8 + legacy_conversion_target: CHALLENGE_ROD + + - id: ICE_ROD + material: FISHING_ROD + rarity: RARE + default_statistics: + DAMAGE: 30 + FISHING_SPEED: 15 + components: + - id: FISHING_ROD_METADATA + medium: WATER + required_fishing_level: 3 + legacy_conversion_target: CHALLENGE_ROD + + - id: WINTER_ROD + material: FISHING_ROD + rarity: RARE + default_statistics: + DAMAGE: 50 + STRENGTH: 50 + FISHING_SPEED: 75 + components: + - id: FISHING_ROD_METADATA + medium: WATER + required_fishing_level: 10 + legacy_conversion_target: CHALLENGE_ROD + + - id: YETI_ROD + material: FISHING_ROD + rarity: EPIC + default_statistics: + DAMAGE: 150 + STRENGTH: 130 + FISHING_SPEED: 75 + components: + - id: FISHING_ROD_METADATA + medium: WATER + required_fishing_level: 25 + legacy_conversion_target: CHALLENGE_ROD + + - id: THE_SHREDDER + material: FISHING_ROD + rarity: LEGENDARY + default_statistics: + DAMAGE: 120 + FEROCITY: 50 + FISHING_SPEED: 115 + components: + - id: FISHING_ROD_METADATA + medium: WATER + required_fishing_level: 20 + legacy_conversion_target: CHALLENGE_ROD + + - id: PHANTOM_ROD + material: FISHING_ROD + rarity: LEGENDARY + default_statistics: + DAMAGE: 200 + STRENGTH: 125 + FISHING_SPEED: 100 + components: + - id: FISHING_ROD_METADATA + medium: WATER + required_fishing_level: 21 + legacy_conversion_target: CHALLENGE_ROD + + - id: AUGER_ROD + material: FISHING_ROD + rarity: LEGENDARY + default_statistics: + DAMAGE: 135 + STRENGTH: 90 + FISHING_SPEED: 110 + components: + - id: FISHING_ROD_METADATA + medium: WATER + required_fishing_level: 25 + legacy_conversion_target: ROD_OF_THE_SEA diff --git a/configuration/skyblock/items/vanillaItems.yml b/configuration/skyblock/items/vanillaItems.yml index 523aebce3..d0e55dec2 100644 --- a/configuration/skyblock/items/vanillaItems.yml +++ b/configuration/skyblock/items/vanillaItems.yml @@ -187,6 +187,10 @@ items: rarity: COMMON components: - id: FISHING_ROD + - id: FISHING_ROD_METADATA + display_name: Fishing Rod + medium: WATER + rod_parts_enabled: true - id: DEFAULT_CRAFTABLE recipes: - type: SHAPED @@ -927,4 +931,3 @@ items: type: JUKEBOX amount: 1 - diff --git a/type.backwaterbayou/src/main/java/net/swofty/type/backwaterbayou/gui/GUIFishingRodParts.java b/type.backwaterbayou/src/main/java/net/swofty/type/backwaterbayou/gui/GUIFishingRodParts.java index 135a02aa8..ce4ab913c 100644 --- a/type.backwaterbayou/src/main/java/net/swofty/type/backwaterbayou/gui/GUIFishingRodParts.java +++ b/type.backwaterbayou/src/main/java/net/swofty/type/backwaterbayou/gui/GUIFishingRodParts.java @@ -1,100 +1,4 @@ package net.swofty.type.backwaterbayou.gui; -import net.minestom.server.inventory.InventoryType; -import net.minestom.server.item.ItemStack; -import net.minestom.server.item.Material; -import net.swofty.commons.skyblock.item.ItemType; -import net.swofty.type.generic.gui.inventory.ItemStackCreator; -import net.swofty.type.generic.gui.v2.Components; -import net.swofty.type.generic.gui.v2.DefaultState; -import net.swofty.type.generic.gui.v2.StatelessView; -import net.swofty.type.generic.gui.v2.ViewConfiguration; -import net.swofty.type.generic.gui.v2.ViewLayout; -import net.swofty.type.generic.gui.v2.ViewSession; -import net.swofty.type.generic.gui.v2.context.ViewContext; -import net.swofty.type.skyblockgeneric.fishing.FishingItemCatalog; -import net.swofty.type.skyblockgeneric.fishing.FishingRodDefinition; -import net.swofty.type.skyblockgeneric.item.SkyBlockItem; -import net.swofty.type.skyblockgeneric.user.SkyBlockPlayer; - -public class GUIFishingRodParts extends StatelessView { - - @Override - public ViewConfiguration configuration() { - return new ViewConfiguration<>("Fishing Rod Parts", InventoryType.CHEST_6_ROW); - } - - @Override - public void onClose(DefaultState state, ViewContext ctx, ViewSession.CloseReason reason) { - ItemStack rodItem = ctx.inventory().getItemStack(21); - if (!rodItem.isAir()) { - SkyBlockPlayer player = (SkyBlockPlayer) ctx.player(); - player.addAndUpdateItem(new SkyBlockItem(rodItem)); - ctx.inventory().setItemStack(21, ItemStack.AIR); - } - } - - @Override - public void layout(ViewLayout layout, DefaultState state, ViewContext ctx) { - Components.close(layout, 49); - - layout.editable(21, (_, _) -> ItemStackCreator.createNamedItemStack( - Material.FISHING_ROD, - "§7Place your §aFishing Rod §7here!" - ), (_, oldItem, newItem, _) -> { - if (newItem.isAir()) return; - SkyBlockItem rod = new SkyBlockItem(newItem); - ItemType type = rod.getAttributeHandler().getPotentialType(); - FishingRodDefinition def = type == null ? null : FishingItemCatalog.getRod(type.name()); - if (def == null || !def.rodPartsEnabled()) { - SkyBlockPlayer player = (SkyBlockPlayer) ctx.player(); - player.sendMessage("§cThat fishing rod does not support rod parts."); - ctx.inventory().setItemStack(21, oldItem); - if (!newItem.isAir()) { - player.addAndUpdateItem(new SkyBlockItem(newItem)); - } - } - }); - - layout.slot(22, ItemStackCreator.getStack( - "§9ථ Hook", - Material.LIGHT_BLUE_STAINED_GLASS_PANE, - 1, - "§7Place a §aFishing Rod §7in the slot to the", - "§7left to view and modify its §9Hook§7!", - "", - "§eClick to browse Hooks!" - ), (_, viewCtx) -> viewCtx.push(new GUIHook())); - - layout.slot(23, ItemStackCreator.getStack( - "§9ꨃ Line", - Material.LIGHT_BLUE_STAINED_GLASS_PANE, - 1, - "§7Place a §aFishing Rod §7in the slot to the", - "§7left to view and modify its §9Line§7!", - "", - "§eClick to browse Lines!" - ), (_, viewCtx) -> viewCtx.push(new GUILine())); - - layout.slot(24, ItemStackCreator.getStack( - "§9࿉ Sinker", - Material.LIGHT_BLUE_STAINED_GLASS_PANE, - 1, - "§7Place a §aFishing Rod §7in the slot to the", - "§7left to view and modify its §9Sinker§7!", - "", - "§eClick to browse Sinkers!" - ), (_, viewCtx) -> viewCtx.push(new GUISinker())); - - layout.slot(50, ItemStackCreator.getStack( - "§9Rod Part Guide", - Material.BOOK, - 1, - "§7View all of the §9Rod Parts §7that can be", - "§7applied to §aFishing Rods§7! Can also be", - "§7accessed with §a/rodparts§7!", - "", - "§eClick to view!" - ), (_, viewCtx) -> viewCtx.push(new GUIRodPartGuide())); - } +public class GUIFishingRodParts extends net.swofty.type.skyblockgeneric.gui.inventories.fishing.GUIFishingRodParts { } diff --git a/type.backwaterbayou/src/main/java/net/swofty/type/backwaterbayou/gui/GUIHook.java b/type.backwaterbayou/src/main/java/net/swofty/type/backwaterbayou/gui/GUIHook.java index 5dfd61149..1abe3f435 100644 --- a/type.backwaterbayou/src/main/java/net/swofty/type/backwaterbayou/gui/GUIHook.java +++ b/type.backwaterbayou/src/main/java/net/swofty/type/backwaterbayou/gui/GUIHook.java @@ -1,48 +1,4 @@ package net.swofty.type.backwaterbayou.gui; -import net.minestom.server.inventory.InventoryType; -import net.minestom.server.item.Material; -import net.swofty.type.generic.gui.inventory.ItemStackCreator; -import net.swofty.type.generic.gui.v2.Components; -import net.swofty.type.generic.gui.v2.DefaultState; -import net.swofty.type.generic.gui.v2.StatelessView; -import net.swofty.type.generic.gui.v2.ViewConfiguration; -import net.swofty.type.generic.gui.v2.ViewLayout; -import net.swofty.type.generic.gui.v2.context.ViewContext; -import net.swofty.type.skyblockgeneric.fishing.FishingItemCatalog; -import net.swofty.type.skyblockgeneric.fishing.RodPartDefinition; -import net.swofty.type.skyblockgeneric.gui.inventories.fishing.FishingGuideStackFactory; - -public class GUIHook extends StatelessView { - private static final int[] PART_SLOTS = {10, 11, 12, 13, 14, 15, 16}; - - @Override - public ViewConfiguration configuration() { - return new ViewConfiguration<>("Hook", InventoryType.CHEST_6_ROW); - } - - @Override - public void layout(ViewLayout layout, DefaultState state, ViewContext ctx) { - Components.close(layout, 49); - layout.slot(4, ItemStackCreator.getStackHead( - "§9ථ Hooks", - "9809753cbab0380c7a1c18925faf9b51e44caadd1e5748542b0f23835f4ef64e", - 1, - "§9Hooks §7change what your rod is better at catching." - )); - - int index = 0; - for (RodPartDefinition part : FishingItemCatalog.getRodParts()) { - if (part.category() != RodPartDefinition.PartCategory.HOOK || index >= PART_SLOTS.length) { - continue; - } - layout.slot(PART_SLOTS[index++], FishingGuideStackFactory.buildRodPartStack(part)); - } - layout.slot(48, ItemStackCreator.getStack( - "§aGo Back", - Material.ARROW, - 1, - "§7To Rod Part Guide" - ), (_, viewCtx) -> viewCtx.pop()); - } +public class GUIHook extends net.swofty.type.skyblockgeneric.gui.inventories.fishing.GUIHookGuide { } diff --git a/type.backwaterbayou/src/main/java/net/swofty/type/backwaterbayou/gui/GUILine.java b/type.backwaterbayou/src/main/java/net/swofty/type/backwaterbayou/gui/GUILine.java index 0572d1b34..3f9f8aa0e 100644 --- a/type.backwaterbayou/src/main/java/net/swofty/type/backwaterbayou/gui/GUILine.java +++ b/type.backwaterbayou/src/main/java/net/swofty/type/backwaterbayou/gui/GUILine.java @@ -1,48 +1,4 @@ package net.swofty.type.backwaterbayou.gui; -import net.minestom.server.inventory.InventoryType; -import net.minestom.server.item.Material; -import net.swofty.type.generic.gui.inventory.ItemStackCreator; -import net.swofty.type.generic.gui.v2.Components; -import net.swofty.type.generic.gui.v2.DefaultState; -import net.swofty.type.generic.gui.v2.StatelessView; -import net.swofty.type.generic.gui.v2.ViewConfiguration; -import net.swofty.type.generic.gui.v2.ViewLayout; -import net.swofty.type.generic.gui.v2.context.ViewContext; -import net.swofty.type.skyblockgeneric.fishing.FishingItemCatalog; -import net.swofty.type.skyblockgeneric.fishing.RodPartDefinition; -import net.swofty.type.skyblockgeneric.gui.inventories.fishing.FishingGuideStackFactory; - -public class GUILine extends StatelessView { - private static final int[] PART_SLOTS = {10, 11, 12, 13, 14, 15, 16}; - - @Override - public ViewConfiguration configuration() { - return new ViewConfiguration<>("Line", InventoryType.CHEST_6_ROW); - } - - @Override - public void layout(ViewLayout layout, DefaultState state, ViewContext ctx) { - Components.close(layout, 49); - layout.slot(4, ItemStackCreator.getStackHead( - "§9ꨃ Lines", - "9a850a4f721bc150bb72b067e5074c8251058a6b9111691da315b393467c1aa9", - 1, - "§9Lines §7grant stat bonuses to your rod everywhere." - )); - - int index = 0; - for (RodPartDefinition part : FishingItemCatalog.getRodParts()) { - if (part.category() != RodPartDefinition.PartCategory.LINE || index >= PART_SLOTS.length) { - continue; - } - layout.slot(PART_SLOTS[index++], FishingGuideStackFactory.buildRodPartStack(part)); - } - layout.slot(48, ItemStackCreator.getStack( - "§aGo Back", - Material.ARROW, - 1, - "§7To Rod Part Guide" - ), (_, viewCtx) -> viewCtx.pop()); - } +public class GUILine extends net.swofty.type.skyblockgeneric.gui.inventories.fishing.GUILineGuide { } diff --git a/type.backwaterbayou/src/main/java/net/swofty/type/backwaterbayou/gui/GUIRodPartGuide.java b/type.backwaterbayou/src/main/java/net/swofty/type/backwaterbayou/gui/GUIRodPartGuide.java index a1b29cff4..6591d0734 100644 --- a/type.backwaterbayou/src/main/java/net/swofty/type/backwaterbayou/gui/GUIRodPartGuide.java +++ b/type.backwaterbayou/src/main/java/net/swofty/type/backwaterbayou/gui/GUIRodPartGuide.java @@ -1,64 +1,4 @@ package net.swofty.type.backwaterbayou.gui; -import net.minestom.server.inventory.InventoryType; -import net.minestom.server.item.Material; -import net.swofty.type.generic.gui.inventory.ItemStackCreator; -import net.swofty.type.generic.gui.v2.Components; -import net.swofty.type.generic.gui.v2.DefaultState; -import net.swofty.type.generic.gui.v2.StatelessView; -import net.swofty.type.generic.gui.v2.ViewConfiguration; -import net.swofty.type.generic.gui.v2.ViewLayout; -import net.swofty.type.generic.gui.v2.context.ViewContext; - -public class GUIRodPartGuide extends StatelessView { - @Override - public ViewConfiguration configuration() { - return new ViewConfiguration<>("Rod Part Guide", InventoryType.CHEST_6_ROW); - } - - @Override - public void layout(ViewLayout layout, DefaultState state, ViewContext ctx) { - Components.close(layout, 49); - - layout.slot(4, ItemStackCreator.getStack( - "§9Rod Part Guide", - Material.BOOK, - 1, - "§7View all §9Rod Parts §7that can be applied", - "§7to your upgraded fishing rods." - )); - layout.slot(20, ItemStackCreator.getStackHead( - "§9ථ Hooks", - "9809753cbab0380c7a1c18925faf9b51e44caadd1e5748542b0f23835f4ef64e", - 1, - "§9Hooks §7make you more likely to catch", - "§7certain things.", - "", - "§eClick to view!" - ), (_, viewCtx) -> viewCtx.push(new GUIHook())); - layout.slot(22, ItemStackCreator.getStackHead( - "§9ꨃ Lines", - "9a850a4f721bc150bb72b067e5074c8251058a6b9111691da315b393467c1aa9", - 1, - "§9Lines §7grant you stat bonuses", - "§7everywhere.", - "", - "§eClick to view!" - ), (_, viewCtx) -> viewCtx.push(new GUILine())); - layout.slot(24, ItemStackCreator.getStackHead( - "§9࿉ Sinkers", - "d24892a3142d2e130e5feb88b805b83de905489d2ccd1d031b9d7a2922b96500", - 1, - "§9Sinkers §7add special fishing effects", - "§7to your rod.", - "", - "§eClick to view!" - ), (_, viewCtx) -> viewCtx.push(new GUISinker())); - layout.slot(48, ItemStackCreator.getStack( - "§aGo Back", - Material.ARROW, - 1, - "§7To Fishing Rod Parts" - ), (_, viewCtx) -> viewCtx.pop()); - } +public class GUIRodPartGuide extends net.swofty.type.skyblockgeneric.gui.inventories.fishing.GUIRodPartGuide { } diff --git a/type.backwaterbayou/src/main/java/net/swofty/type/backwaterbayou/gui/GUISinker.java b/type.backwaterbayou/src/main/java/net/swofty/type/backwaterbayou/gui/GUISinker.java index cbe71b12f..07fc59d6b 100644 --- a/type.backwaterbayou/src/main/java/net/swofty/type/backwaterbayou/gui/GUISinker.java +++ b/type.backwaterbayou/src/main/java/net/swofty/type/backwaterbayou/gui/GUISinker.java @@ -1,48 +1,4 @@ package net.swofty.type.backwaterbayou.gui; -import net.minestom.server.inventory.InventoryType; -import net.minestom.server.item.Material; -import net.swofty.type.generic.gui.inventory.ItemStackCreator; -import net.swofty.type.generic.gui.v2.Components; -import net.swofty.type.generic.gui.v2.DefaultState; -import net.swofty.type.generic.gui.v2.StatelessView; -import net.swofty.type.generic.gui.v2.ViewConfiguration; -import net.swofty.type.generic.gui.v2.ViewLayout; -import net.swofty.type.generic.gui.v2.context.ViewContext; -import net.swofty.type.skyblockgeneric.fishing.FishingItemCatalog; -import net.swofty.type.skyblockgeneric.fishing.RodPartDefinition; -import net.swofty.type.skyblockgeneric.gui.inventories.fishing.FishingGuideStackFactory; - -public class GUISinker extends StatelessView { - private static final int[] PART_SLOTS = {10, 11, 12, 13, 14, 15, 16, 19, 20}; - - @Override - public ViewConfiguration configuration() { - return new ViewConfiguration<>("Sinker", InventoryType.CHEST_6_ROW); - } - - @Override - public void layout(ViewLayout layout, DefaultState state, ViewContext ctx) { - Components.close(layout, 49); - layout.slot(4, ItemStackCreator.getStackHead( - "§9࿉ Sinkers", - "d24892a3142d2e130e5feb88b805b83de905489d2ccd1d031b9d7a2922b96500", - 1, - "§9Sinkers §7add special fishing effects to your rod." - )); - - int index = 0; - for (RodPartDefinition part : FishingItemCatalog.getRodParts()) { - if (part.category() != RodPartDefinition.PartCategory.SINKER || index >= PART_SLOTS.length) { - continue; - } - layout.slot(PART_SLOTS[index++], FishingGuideStackFactory.buildRodPartStack(part)); - } - layout.slot(48, ItemStackCreator.getStack( - "§aGo Back", - Material.ARROW, - 1, - "§7To Rod Part Guide" - ), (_, viewCtx) -> viewCtx.pop()); - } +public class GUISinker extends net.swofty.type.skyblockgeneric.gui.inventories.fishing.GUISinkerGuide { } diff --git a/type.hub/src/main/java/net/swofty/type/hub/gui/fishing/GUIGFishingShip.java b/type.hub/src/main/java/net/swofty/type/hub/gui/fishing/GUIGFishingShip.java index 5a8eebfb6..2b97b2735 100644 --- a/type.hub/src/main/java/net/swofty/type/hub/gui/fishing/GUIGFishingShip.java +++ b/type.hub/src/main/java/net/swofty/type/hub/gui/fishing/GUIGFishingShip.java @@ -1,133 +1,4 @@ package net.swofty.type.hub.gui.fishing; -import net.minestom.server.event.inventory.InventoryPreClickEvent; -import net.minestom.server.inventory.InventoryType; -import net.minestom.server.item.ItemStack; -import net.minestom.server.item.Material; -import net.swofty.type.generic.gui.inventory.HypixelInventoryGUI; -import net.swofty.type.generic.gui.inventory.ItemStackCreator; -import net.swofty.type.generic.gui.inventory.item.GUIClickableItem; -import net.swofty.type.generic.gui.inventory.item.GUIItem; -import net.swofty.type.generic.user.HypixelPlayer; - -// TOOD: Fishing ship name can be changed. And the parts can be changed -public class GUIGFishingShip extends HypixelInventoryGUI { - - public GUIGFishingShip() { - super("{Fishing Ship}", InventoryType.CHEST_5_ROW); - } - - @Override - public void onOpen(InventoryGUIOpenEvent e) { - fill(FILLER_ITEM); - set(new GUIItem(4) { - @Override - public ItemStack.Builder getItem(HypixelPlayer player) { - return ItemStackCreator.getStack( - "§6{Fishing Ship}", - Material.OAK_BOAT, - 1, - "§7Your §6Ship §7will help you travel to", - "§7different §9fishing islands §7in SkyBlock.", - "", - "§7For now, it can only get you to the", - "§2Backwater Bayou§7.", - "", - "§7Helm: §fCracked Ship Helm", - "§7Engine: §fRusty Ship Engine", - "§7Hull: §fRusty Ship Hull" - ); - } - }); - set(new GUIItem(21) { - @Override - public ItemStack.Builder getItem(HypixelPlayer player) { - return ItemStackCreator.getStackHead( - "§fCracked Ship Helm", - "d8d4a54d1fcf47b2efc99ba4cc772250aee5c2f26ed1a19052213e0f3323ca1d", - 1, - "§7A cracked ship helm, incapable of", - "§7changing its heading which appears", - "§7due east.", - "", - "§6§lUPGRADE TO §8➜ §9Bronze Ship Helm", - "§7Crafted from §aBronze Bowls§7, which", - "§7are rarely dropped by §cDumpster", - "§cDivers §7in the §2Backwater Bayou§7.", - "", - "§eClick a Ship Part in your inventory to", - "§eupgrade this part!" - ); - } - }); - // TODO: this is "missing" by default, need to implement that state - set(new GUIItem(22) { - @Override - public ItemStack.Builder getItem(HypixelPlayer player) { - return ItemStackCreator.getStackHead( - "§fRusty Ship Engine", - "53e84793917c890f7f8a2c4078a29e8ba939790498727af9342c2b6f6ac43c9c", - 1, - "§7Rusted by the waters, but it seems to", - "§7be able to run...for now.", - "", - "§6§lUPGRADE TO §8➜ §9Bronze Ship Engine", - "§7Purchased from §2Junker Joel §7in the", - "§2Backwater Bayou§7.", - "", - "§eClick a Ship Part in your inventory to", - "§eupgrade this part!" - ); - } - }); - set(new GUIItem(23) { - @Override - public ItemStack.Builder getItem(HypixelPlayer player) { - return ItemStackCreator.getStackHead( - "§fRusty Ship Hull", - "f42d53ca6e7d80a99a699c2036dcf6e233394feb9f46fb2ff9d9a819690894a9", - 1, - "§7A hull rusted and dilapidated beyond", - "§7repair. It's a miracle the ship", - "§7remains afloat.", - "", - "§6§lUPGRADE TO §8➜ §9Bronze Ship Hull", - "§7Crafted from §aTorn Cloth§7, which is", - "§7rarely dropped by §cBanshees §7in the", - "§2Backwater Bayou§7.", - "", - "§eClick a Ship Part in your inventory to", - "§eupgrade this part!" - ); - } - }); - set(new GUIItem(44) { - @Override - public ItemStack.Builder getItem(HypixelPlayer player) { - return ItemStackCreator.getStack( - "§aRename Ship", - Material.NAME_TAG, - 1, - "§7You may be going on long voyages", - "§7with your §6Ship§7, best to give it a name!", - "", - "§7Current Name: §6Zephyr", - "", - "§eClick to rename!" - ); - } - }); - set(GUIClickableItem.getCloseItem(40)); - updateItemStacks(getInventory(), getPlayer()); - } - - @Override - public boolean allowHotkeying() { - return false; - } - - @Override - public void onBottomClick(InventoryPreClickEvent e) { - e.setCancelled(true); - } +public class GUIGFishingShip extends net.swofty.type.skyblockgeneric.gui.inventories.fishing.GUIFishingShip { } diff --git a/type.hub/src/main/java/net/swofty/type/hub/gui/fishing/GUINavigator.java b/type.hub/src/main/java/net/swofty/type/hub/gui/fishing/GUINavigator.java index 7ffca738b..e85d9e93c 100644 --- a/type.hub/src/main/java/net/swofty/type/hub/gui/fishing/GUINavigator.java +++ b/type.hub/src/main/java/net/swofty/type/hub/gui/fishing/GUINavigator.java @@ -1,57 +1,4 @@ package net.swofty.type.hub.gui.fishing; -import net.minestom.server.inventory.InventoryType; -import net.minestom.server.item.Material; -import net.swofty.type.generic.gui.inventory.ItemStackCreator; -import net.swofty.type.generic.gui.v2.Components; -import net.swofty.type.generic.gui.v2.DefaultState; -import net.swofty.type.generic.gui.v2.Layouts; -import net.swofty.type.generic.gui.v2.StatelessView; -import net.swofty.type.generic.gui.v2.ViewConfiguration; -import net.swofty.type.generic.gui.v2.ViewLayout; -import net.swofty.type.generic.gui.v2.context.ViewContext; - -public class GUINavigator extends StatelessView { - - @Override - public ViewConfiguration configuration() { - return new ViewConfiguration<>("Navigator", InventoryType.CHEST_6_ROW); - } - - // todo: make this work with the mission - @Override - public void layout(ViewLayout layout, DefaultState state, ViewContext ctx) { - layout.slots(Layouts.row(0), (_, _) -> Components.FILLER); - layout.slots(Layouts.row(5), (_, _) -> Components.FILLER); - layout.slots(Layouts.rectangle(9, 45), (_, _) -> Components.FILLER.material(Material.BLUE_STAINED_GLASS_PANE)); - Components.close(layout, 49); - - layout.slot(10, ItemStackCreator.getStackHead( - "§2Backwater Bayou", - "1c0cd33590f64d346d98cdd01606938742e715dda6737353306a44f81c8ba426", - 1, - "§7A small, marshy outlet in the middle", - "§7of nowhere. Due to its isolated", - "§7nature, people frequently come here", - "§7to dump their trash.", - "", - "§7Activities:", - "§8 ■ §7Fish up §2Junk §7and trade it with §2Junker", - " §2Joel §7for useful items!", - "§8 ■ §7Apply §9Rod Parts §7with §2Roddy§7.", - "§8 ■ §7Fish §2Bayou Sea Creatures§7.", - "§8 ■ §7Learn about §dFishing Hotspots §7from", - " §dHattie§7.", - "", - "§eClick to travel!" - )); - layout.slot(40, ItemStackCreator.getStackHead( - "§bFishing Outpost", - "d7cc6687423d0570d556ac53e0676cb563bbdd9717cd8269bdebed6f6d4e7bf8", - 1, - "§7Your base of operations.", - "", - "§a§lYOU ARE HERE!" - )); - } +public class GUINavigator extends net.swofty.type.skyblockgeneric.gui.inventories.fishing.GUINavigator { } diff --git a/type.hub/src/main/java/net/swofty/type/hub/npcs/NPCCaptainBaha.java b/type.hub/src/main/java/net/swofty/type/hub/npcs/NPCCaptainBaha.java index 4e86e12fd..58702288e 100644 --- a/type.hub/src/main/java/net/swofty/type/hub/npcs/NPCCaptainBaha.java +++ b/type.hub/src/main/java/net/swofty/type/hub/npcs/NPCCaptainBaha.java @@ -10,9 +10,8 @@ import net.swofty.type.generic.event.custom.NPCInteractEvent; import net.swofty.type.generic.user.HypixelPlayer; import net.swofty.type.hub.gui.fishing.GUIGFishingShip; -import net.swofty.type.skyblockgeneric.fishing.FishingItemCatalog; +import net.swofty.type.skyblockgeneric.fishing.FishingItemSupport; import net.swofty.type.skyblockgeneric.fishing.FishingShipService; -import net.swofty.type.skyblockgeneric.fishing.ShipPartDefinition; import net.swofty.type.skyblockgeneric.user.SkyBlockPlayer; import java.util.stream.Stream; @@ -84,9 +83,9 @@ public void onClick(NPCInteractEvent event) { private void handleRustyShipEngine(SkyBlockPlayer player) { setDialogue(player, "dialogue-yes").thenRun(() -> { - ShipPartDefinition definition = FishingItemCatalog.getShipPart(ItemType.RUSTY_SHIP_ENGINE.name()); + var definition = FishingItemSupport.getShipPart(ItemType.RUSTY_SHIP_ENGINE.name()); if (definition != null) { - FishingShipService.installPart(player, definition); + FishingShipService.installPart(player, ItemType.RUSTY_SHIP_ENGINE.name(), definition); } player.takeItem(ItemType.RUSTY_SHIP_ENGINE, 1); FishingShipService.unlockDestination(player, "BACKWATER_BAYOU"); diff --git a/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/data/datapoints/DatapointTrophyFish.java b/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/data/datapoints/DatapointTrophyFish.java index 4193ff3bf..395512ca5 100644 --- a/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/data/datapoints/DatapointTrophyFish.java +++ b/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/data/datapoints/DatapointTrophyFish.java @@ -24,6 +24,8 @@ public String serialize(TrophyFishData value) { progressObject.put("gold", progress.getGold()); progressObject.put("diamond", progress.getDiamond()); progressObject.put("totalCatches", progress.getTotalCatches()); + progressObject.put("catchesSinceGoldPity", progress.getCatchesSinceGoldPity()); + progressObject.put("catchesSinceDiamondPity", progress.getCatchesSinceDiamondPity()); fishObject.put(fishId, progressObject); }); object.put("fish", fishObject); @@ -50,7 +52,9 @@ public TrophyFishData deserialize(String json) { progressObject.optInt("silver", 0), progressObject.optInt("gold", 0), progressObject.optInt("diamond", 0), - progressObject.optInt("totalCatches", 0) + progressObject.optInt("totalCatches", 0), + progressObject.optInt("catchesSinceGoldPity", progressObject.optInt("totalCatches", 0)), + progressObject.optInt("catchesSinceDiamondPity", progressObject.optInt("totalCatches", 0)) )); } return data; @@ -65,7 +69,9 @@ public TrophyFishData clone(TrophyFishData value) { progress.getSilver(), progress.getGold(), progress.getDiamond(), - progress.getTotalCatches() + progress.getTotalCatches(), + progress.getCatchesSinceGoldPity(), + progress.getCatchesSinceDiamondPity() ))); return new TrophyFishData(fish); } @@ -101,14 +107,28 @@ public static class FishProgress { private int gold; private int diamond; private int totalCatches; + private int catchesSinceGoldPity; + private int catchesSinceDiamondPity; public void increment(String tier) { switch (tier.toUpperCase()) { - case "DIAMOND" -> diamond++; - case "GOLD" -> gold++; + case "DIAMOND" -> { + diamond++; + catchesSinceDiamondPity = 0; + catchesSinceGoldPity = 0; + } + case "GOLD" -> { + gold++; + catchesSinceGoldPity = 0; + catchesSinceDiamondPity++; + } case "SILVER" -> silver++; default -> bronze++; } + if (!"GOLD".equalsIgnoreCase(tier) && !"DIAMOND".equalsIgnoreCase(tier)) { + catchesSinceGoldPity++; + catchesSinceDiamondPity++; + } totalCatches++; } diff --git a/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/entity/FishingHook.java b/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/entity/FishingHook.java index 1686e8a5d..23d854b30 100644 --- a/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/entity/FishingHook.java +++ b/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/entity/FishingHook.java @@ -17,12 +17,12 @@ import net.minestom.server.timer.Scheduler; import net.minestom.server.timer.Task; import net.minestom.server.timer.TaskSchedule; -import net.swofty.type.skyblockgeneric.fishing.BaitDefinition; -import net.swofty.type.skyblockgeneric.fishing.FishingItemCatalog; +import net.swofty.type.skyblockgeneric.fishing.FishingItemSupport; import net.swofty.type.skyblockgeneric.fishing.FishingMedium; import net.swofty.type.skyblockgeneric.fishing.FishingService; import net.swofty.type.skyblockgeneric.fishing.FishingSession; import net.swofty.type.skyblockgeneric.item.SkyBlockItem; +import net.swofty.type.skyblockgeneric.item.components.FishingBaitComponent; import net.swofty.type.skyblockgeneric.user.SkyBlockPlayer; import org.jetbrains.annotations.NotNull; @@ -59,8 +59,8 @@ public FishingHook(SkyBlockPlayer owner, SkyBlockItem rod) { this.owner = owner; this.rod = rod; String itemId = rod.getAttributeHandler().getPotentialType() == null ? null : rod.getAttributeHandler().getPotentialType().name(); - var rodDefinition = FishingItemCatalog.getRod(itemId); - this.requiredMedium = rodDefinition == null ? FishingMedium.WATER : rodDefinition.medium(); + var rodMetadata = FishingItemSupport.getRodMetadata(itemId); + this.requiredMedium = rodMetadata == null ? FishingMedium.WATER : rodMetadata.getMedium(); this.hook = new Entity(EntityType.FISHING_BOBBER); this.hook.editEntityMeta(FishingHookMeta.class, meta -> { @@ -268,7 +268,7 @@ private void startFishingSession() { FishingSession session = FishingService.beginCast(owner, rod, requiredMedium); sessionStarted = true; - BaitDefinition bait = FishingItemCatalog.getBait(session.baitItemId()); + FishingBaitComponent bait = FishingItemSupport.getBait(session.baitItemId()); long waitTicks = FishingService.computeWaitTicks(owner, rod, bait); scheduleNextBite(waitTicks); } @@ -296,7 +296,7 @@ private void scheduleNextBite(long delayTicks) { } FishingService.updateSession(activeSession.withBiteReady(false)); - BaitDefinition bait = FishingItemCatalog.getBait(activeSession.baitItemId()); + FishingBaitComponent bait = FishingItemSupport.getBait(activeSession.baitItemId()); long nextDelay = FishingService.computeWaitTicks(owner, rod, bait); scheduleNextBite(nextDelay); }).delay(TaskSchedule.tick((int) BITE_WINDOW_TICKS)).schedule(); diff --git a/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/fishing/BaitDefinition.java b/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/fishing/BaitDefinition.java deleted file mode 100644 index a3266fd4c..000000000 --- a/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/fishing/BaitDefinition.java +++ /dev/null @@ -1,22 +0,0 @@ -package net.swofty.type.skyblockgeneric.fishing; - -import net.swofty.commons.skyblock.statistics.ItemStatistics; -import org.jetbrains.annotations.Nullable; - -import java.util.List; -import java.util.Map; - -public record BaitDefinition( - String itemId, - String displayName, - ItemStatistics statistics, - List lore, - Map tagBonuses, - double treasureChanceBonus, - double treasureQualityBonus, - double trophyFishChanceBonus, - double doubleHookChanceBonus, - List mediums, - @Nullable String texture -) { -} diff --git a/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/fishing/FishingBaitService.java b/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/fishing/FishingBaitService.java index 3a0f8e48d..a95eecec4 100644 --- a/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/fishing/FishingBaitService.java +++ b/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/fishing/FishingBaitService.java @@ -3,6 +3,7 @@ import net.minestom.server.item.ItemStack; import net.swofty.commons.skyblock.item.ItemType; import net.swofty.type.skyblockgeneric.item.SkyBlockItem; +import net.swofty.type.skyblockgeneric.item.components.FishingBaitComponent; import net.swofty.type.skyblockgeneric.item.updater.PlayerItemUpdater; import net.swofty.type.skyblockgeneric.user.SkyBlockPlayer; import org.jetbrains.annotations.Nullable; @@ -11,7 +12,7 @@ public final class FishingBaitService { private FishingBaitService() { } - public static @Nullable BaitDefinition getFirstAvailableBait(SkyBlockPlayer player, FishingMedium medium) { + public static @Nullable FishingBaitComponent getFirstAvailableBait(SkyBlockPlayer player, FishingMedium medium) { for (int slot = 0; slot < 36; slot++) { SkyBlockItem item = new SkyBlockItem(player.getInventory().getItemStack(slot)); ItemType type = item.getAttributeHandler().getPotentialType(); @@ -19,14 +20,14 @@ private FishingBaitService() { continue; } - BaitDefinition bait = FishingItemCatalog.getBait(type.name()); - if (bait == null) { + FishingBaitComponent baitComponent = item.getComponent(FishingBaitComponent.class); + if (baitComponent == null) { continue; } - if (!bait.mediums().isEmpty() && !bait.mediums().contains(medium)) { + if (!baitComponent.getMediums().isEmpty() && !baitComponent.getMediums().contains(medium)) { continue; } - return bait; + return baitComponent; } return null; } diff --git a/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/fishing/FishingContext.java b/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/fishing/FishingContext.java index 9525d40df..232130275 100644 --- a/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/fishing/FishingContext.java +++ b/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/fishing/FishingContext.java @@ -2,6 +2,8 @@ import net.swofty.commons.skyblock.statistics.ItemStatistics; import net.swofty.type.skyblockgeneric.item.SkyBlockItem; +import net.swofty.type.skyblockgeneric.item.components.FishingBaitComponent; +import net.swofty.type.skyblockgeneric.item.components.FishingRodPartComponent; import net.swofty.type.skyblockgeneric.user.SkyBlockPlayer; import org.jetbrains.annotations.Nullable; @@ -9,10 +11,10 @@ public record FishingContext( SkyBlockPlayer player, SkyBlockItem rod, FishingMedium medium, - @Nullable BaitDefinition bait, - @Nullable RodPartDefinition hook, - @Nullable RodPartDefinition line, - @Nullable RodPartDefinition sinker, + @Nullable FishingBaitComponent bait, + @Nullable FishingRodPartComponent hook, + @Nullable FishingRodPartComponent line, + @Nullable FishingRodPartComponent sinker, @Nullable String regionId, boolean hotspotActive, ItemStatistics hotspotBuffs, diff --git a/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/fishing/FishingHotspotService.java b/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/fishing/FishingHotspotService.java index 7fb4a1a1b..babc132cc 100644 --- a/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/fishing/FishingHotspotService.java +++ b/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/fishing/FishingHotspotService.java @@ -27,6 +27,14 @@ public static ItemStatistics getActiveHotspotBuffs(SkyBlockPlayer player, Fishin String serverType = HypixelConst.getTypeLoader().getType().name(); SkyBlockRegion playerRegion = player.getRegion(); String regionId = playerRegion == null ? null : playerRegion.getType().name(); + double sinkerMultiplier = 1.0D; + if (player.getItemInMainHand() != null) { + var heldItem = new net.swofty.type.skyblockgeneric.item.SkyBlockItem(player.getItemInMainHand()); + var sinker = FishingRodPartService.getSinker(heldItem); + if (sinker != null && sinker.getHotspotBuffMultiplier() > 0) { + sinkerMultiplier = sinker.getHotspotBuffMultiplier(); + } + } ItemStatistics.Builder builder = ItemStatistics.builder(); for (HotspotDefinition hotspot : FishingRegistry.getHotspots()) { @@ -41,7 +49,7 @@ public static ItemStatistics getActiveHotspotBuffs(SkyBlockPlayer player, Fishin } for (ItemStatistic statistic : ItemStatistic.values()) { - double value = hotspot.buffs().getOverall(statistic); + double value = hotspot.buffs().getOverall(statistic) * sinkerMultiplier; if (value != 0.0D) { builder.withBase(statistic, value); } @@ -65,5 +73,3 @@ private static boolean matchesAnyPoint(String serverType, Pos bobberPos, Hotspot return false; } } - - diff --git a/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/fishing/FishingItemBootstrap.java b/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/fishing/FishingItemBootstrap.java deleted file mode 100644 index f2fd40efa..000000000 --- a/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/fishing/FishingItemBootstrap.java +++ /dev/null @@ -1,25 +0,0 @@ -package net.swofty.type.skyblockgeneric.fishing; - -import net.swofty.type.skyblockgeneric.enchantment.SkyBlockEnchantment; -import net.swofty.type.skyblockgeneric.item.SkyBlockItem; - -public final class FishingItemBootstrap { - private FishingItemBootstrap() { - } - - public static void applyDefaults(SkyBlockItem item) { - if (item.getAttributeHandler().getPotentialType() == null) { - return; - } - - FishingRodDefinition definition = FishingItemCatalog.getRod(item.getAttributeHandler().getPotentialType().name()); - if (definition == null) { - return; - } - - if (item.getAttributeHandler().getEnchantments().findAny().isEmpty()) { - definition.enchantments().forEach((type, level) -> - item.getAttributeHandler().addEnchantment(new SkyBlockEnchantment(type, level))); - } - } -} diff --git a/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/fishing/FishingItemCatalog.java b/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/fishing/FishingItemCatalog.java deleted file mode 100644 index 2942d7f7e..000000000 --- a/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/fishing/FishingItemCatalog.java +++ /dev/null @@ -1,160 +0,0 @@ -package net.swofty.type.skyblockgeneric.fishing; - -import net.swofty.commons.skyblock.item.ItemType; -import net.swofty.type.skyblockgeneric.item.ConfigurableSkyBlockItem; -import net.swofty.type.skyblockgeneric.item.components.FishingBaitComponent; -import net.swofty.type.skyblockgeneric.item.components.FishingRodMetadataComponent; -import net.swofty.type.skyblockgeneric.item.components.FishingRodPartComponent; -import net.swofty.type.skyblockgeneric.item.components.FishingShipPartComponent; -import org.jetbrains.annotations.Nullable; - -import java.util.Arrays; -import java.util.Comparator; -import java.util.List; -import java.util.Objects; - -public final class FishingItemCatalog { - private FishingItemCatalog() { - } - - public static @Nullable FishingRodDefinition getRod(@Nullable String itemId) { - if (itemId == null) { - return null; - } - - ConfigurableSkyBlockItem item = ConfigurableSkyBlockItem.getFromID(itemId); - if (item == null || !item.hasComponent(FishingRodMetadataComponent.class)) { - return null; - } - - FishingRodMetadataComponent component = item.getComponent(FishingRodMetadataComponent.class); - return new FishingRodDefinition( - itemId, - component.getDisplayName(), - component.getSubtitle(), - component.getMedium(), - component.getRequiredFishingLevel(), - item.getDefaultStatistics(), - component.getEnchantments(), - item.getLore(), - component.getLegacyConversionTarget(), - component.getLegacyConversionPart(), - component.isRodPartsEnabled() - ); - } - - public static @Nullable RodPartDefinition getRodPart(@Nullable String itemId) { - if (itemId == null) { - return null; - } - - ConfigurableSkyBlockItem item = ConfigurableSkyBlockItem.getFromID(itemId); - if (item == null || !item.hasComponent(FishingRodPartComponent.class)) { - return null; - } - - FishingRodPartComponent component = item.getComponent(FishingRodPartComponent.class); - return new RodPartDefinition( - itemId, - component.getDisplayName(), - component.getCategory(), - component.getRequiredFishingLevel(), - item.getDefaultStatistics(), - item.getLore(), - component.getTagBonuses(), - component.isTreasureOnly(), - component.isBayouTreasureToJunk(), - component.getMaterializedItemId(), - component.getMaterializedChance(), - component.getBaitPreservationChance(), - component.getHotspotBuffMultiplier(), - component.getTexture() - ); - } - - public static @Nullable BaitDefinition getBait(@Nullable String itemId) { - if (itemId == null) { - return null; - } - - ConfigurableSkyBlockItem item = ConfigurableSkyBlockItem.getFromID(itemId); - if (item == null || !item.hasComponent(FishingBaitComponent.class)) { - return null; - } - - FishingBaitComponent component = item.getComponent(FishingBaitComponent.class); - return new BaitDefinition( - itemId, - component.getDisplayName(), - item.getDefaultStatistics(), - item.getLore(), - component.getTagBonuses(), - component.getTreasureChanceBonus(), - component.getTreasureQualityBonus(), - component.getTrophyFishChanceBonus(), - component.getDoubleHookChanceBonus(), - component.getMediums(), - component.getTexture() - ); - } - - public static @Nullable ShipPartDefinition getShipPart(@Nullable String itemId) { - if (itemId == null) { - return null; - } - - ConfigurableSkyBlockItem item = ConfigurableSkyBlockItem.getFromID(itemId); - if (item == null || !item.hasComponent(FishingShipPartComponent.class)) { - return null; - } - - FishingShipPartComponent component = item.getComponent(FishingShipPartComponent.class); - return new ShipPartDefinition( - itemId, - component.getDisplayName(), - component.getSlot(), - item.getLore(), - component.getTexture() - ); - } - - public static List getRods() { - return Arrays.stream(ItemType.values()) - .map(ItemType::name) - .map(FishingItemCatalog::getRod) - .filter(Objects::nonNull) - .sorted(Comparator.comparingInt(FishingRodDefinition::requiredFishingLevel) - .thenComparing(FishingRodDefinition::displayName)) - .toList(); - } - - public static List getRodParts() { - return Arrays.stream(ItemType.values()) - .map(ItemType::name) - .map(FishingItemCatalog::getRodPart) - .filter(Objects::nonNull) - .sorted(Comparator.comparing(RodPartDefinition::category) - .thenComparingInt(RodPartDefinition::requiredFishingLevel) - .thenComparing(RodPartDefinition::displayName)) - .toList(); - } - - public static List getBaits() { - return Arrays.stream(ItemType.values()) - .map(ItemType::name) - .map(FishingItemCatalog::getBait) - .filter(Objects::nonNull) - .sorted(Comparator.comparing((BaitDefinition bait) -> ItemType.valueOf(bait.itemId()).rarity.ordinal()) - .thenComparing(BaitDefinition::displayName)) - .toList(); - } - - public static List getShipParts() { - return Arrays.stream(ItemType.values()) - .map(ItemType::name) - .map(FishingItemCatalog::getShipPart) - .filter(Objects::nonNull) - .sorted(Comparator.comparing(ShipPartDefinition::slot).thenComparing(ShipPartDefinition::displayName)) - .toList(); - } -} \ No newline at end of file diff --git a/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/fishing/FishingItemSupport.java b/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/fishing/FishingItemSupport.java new file mode 100644 index 000000000..3b5f39fa5 --- /dev/null +++ b/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/fishing/FishingItemSupport.java @@ -0,0 +1,93 @@ +package net.swofty.type.skyblockgeneric.fishing; + +import net.swofty.commons.skyblock.item.ItemType; +import net.swofty.type.skyblockgeneric.item.ConfigurableSkyBlockItem; +import net.swofty.type.skyblockgeneric.item.SkyBlockItem; +import net.swofty.type.skyblockgeneric.item.SkyBlockItemComponent; +import net.swofty.type.skyblockgeneric.item.components.FishingBaitComponent; +import net.swofty.type.skyblockgeneric.item.components.FishingRodMetadataComponent; +import net.swofty.type.skyblockgeneric.item.components.FishingRodPartComponent; +import net.swofty.type.skyblockgeneric.item.components.FishingShipPartComponent; +import org.jetbrains.annotations.Nullable; + +import java.util.ArrayList; +import java.util.Comparator; +import java.util.List; + +public final class FishingItemSupport { + private FishingItemSupport() { + } + + public static @Nullable FishingRodMetadataComponent getRodMetadata(@Nullable String itemId) { + return getComponent(itemId, FishingRodMetadataComponent.class); + } + + public static @Nullable FishingBaitComponent getBait(@Nullable String itemId) { + return getComponent(itemId, FishingBaitComponent.class); + } + + public static @Nullable FishingRodPartComponent getRodPart(@Nullable String itemId) { + return getComponent(itemId, FishingRodPartComponent.class); + } + + public static @Nullable FishingShipPartComponent getShipPart(@Nullable String itemId) { + return getComponent(itemId, FishingShipPartComponent.class); + } + + public static @Nullable SkyBlockItem getItem(@Nullable String itemId) { + if (itemId == null || itemId.isBlank()) { + return null; + } + ItemType type = ItemType.get(itemId); + return type == null ? null : new SkyBlockItem(type); + } + + public static List getBaits() { + return getItemsWith(FishingBaitComponent.class); + } + + public static List getRodParts() { + return getItemsWith(FishingRodPartComponent.class); + } + + public static List getShipParts() { + return getItemsWith(FishingShipPartComponent.class); + } + + private static @Nullable T getComponent(@Nullable String itemId, Class componentClass) { + if (itemId == null || itemId.isBlank()) { + return null; + } + + ItemType type = ItemType.get(itemId); + if (type == null) { + return null; + } + + SkyBlockItem item = new SkyBlockItem(type); + if (!item.hasComponent(componentClass)) { + return null; + } + return item.getComponent(componentClass); + } + + private static List getItemsWith(Class componentClass) { + List items = new ArrayList<>(); + for (String id : ConfigurableSkyBlockItem.getIDs()) { + ItemType type = ItemType.get(id); + if (type == null) { + continue; + } + + SkyBlockItem item = new SkyBlockItem(type); + if (!item.hasComponent(componentClass)) { + continue; + } + items.add(item); + } + + items.sort(Comparator.comparingInt(item -> item.getAttributeHandler().getRarity().ordinal()) + .thenComparing(SkyBlockItem::getDisplayName)); + return List.copyOf(items); + } +} diff --git a/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/fishing/FishingLootResolver.java b/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/fishing/FishingLootResolver.java index 24152bfc6..4a723c6e2 100644 --- a/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/fishing/FishingLootResolver.java +++ b/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/fishing/FishingLootResolver.java @@ -3,6 +3,7 @@ import net.swofty.commons.skyblock.item.ItemType; import net.swofty.commons.skyblock.statistics.ItemStatistic; import net.swofty.type.generic.data.datapoints.DatapointToggles; +import net.swofty.type.skyblockgeneric.item.SkyBlockItem; import java.util.ArrayList; import java.util.Comparator; @@ -13,16 +14,16 @@ private FishingLootResolver() { } public static FishingCatchResult resolve(FishingContext context) { - FishingCatchResult trophyFish = tryResolveTrophyFish(context); - if (trophyFish != null) { - return trophyFish; - } - FishingCatchResult questCatch = tryResolveQuestCatch(context); if (questCatch != null) { return questCatch; } + FishingCatchResult trophyFish = tryResolveTrophyFish(context); + if (trophyFish != null) { + return trophyFish; + } + FishingCatchResult seaCreature = tryResolveSeaCreature(context); if (seaCreature != null) { return seaCreature; @@ -38,7 +39,7 @@ private static FishingCatchResult tryResolveTrophyFish(FishingContext context) { double bonus = getTotalStatistic(context, ItemStatistic.TROPHY_FISH_CHANCE); if (context.bait() != null) { - bonus += context.bait().trophyFishChanceBonus(); + bonus += context.bait().getTrophyFishChanceBonus(); } List eligible = new ArrayList<>(); @@ -125,7 +126,7 @@ private static String rollTrophyTier(FishingContext context, TrophyFishDefinitio double charmBonus = 0.0D; var charm = context.rod().getAttributeHandler().getEnchantment(net.swofty.type.skyblockgeneric.enchantment.EnchantmentType.CHARM); if (charm != null) { - charmBonus = charm.level(); + charmBonus = charm.level() * 2.0D; } if (Math.random() <= (0.002D * (1 + charmBonus / 100D))) { @@ -147,7 +148,7 @@ private static FishingCatchResult tryResolveSeaCreature(FishingContext context) } double seaCreatureChance = getTotalStatistic(context, ItemStatistic.SEA_CREATURE_CHANCE); - if (context.hook() != null && context.hook().treasureOnly()) { + if (context.hook() != null && context.hook().isTreasureOnly()) { return null; } @@ -174,14 +175,14 @@ private static FishingCatchResult resolveItem(FishingContext context) { List pool = table.items(); double treasureChance = getTotalStatistic(context, ItemStatistic.TREASURE_CHANCE); if (context.bait() != null) { - treasureChance += context.bait().treasureChanceBonus(); + treasureChance += context.bait().getTreasureChanceBonus(); } - if (context.sinker() != null && context.sinker().bayouTreasureToJunk()) { + if (context.sinker() != null && context.sinker().isBayouTreasureToJunk()) { treasureChance += 10.0D; } if (!table.treasures().isEmpty() && Math.random() * 100 <= treasureChance) { - pool = context.sinker() != null && context.sinker().bayouTreasureToJunk() ? table.junk() : table.treasures(); + pool = context.sinker() != null && context.sinker().isBayouTreasureToJunk() ? table.junk() : table.treasures(); return pick(pool, FishingCatchKind.TREASURE); } @@ -208,18 +209,19 @@ private static FishingCatchResult pick(List po } private static FishingTableDefinition findTable(FishingContext context) { + FishingTableDefinition fallback = null; for (FishingTableDefinition definition : FishingRegistry.getTables()) { if (!definition.mediums().isEmpty() && !definition.mediums().contains(context.medium())) { continue; } - if (definition.regions().isEmpty()) { - return definition; - } if (context.regionId() != null && definition.regions().contains(context.regionId())) { return definition; } + if (definition.regions().isEmpty() && fallback == null) { + fallback = definition; + } } - return null; + return fallback; } private static double getTotalStatistic(FishingContext context, ItemStatistic statistic) { @@ -227,7 +229,10 @@ private static double getTotalStatistic(FishingContext context, ItemStatistic st + FishingRodPartService.getStatistics(context.rod()).getOverall(statistic); total += context.hotspotBuffs().getOverall(statistic); if (context.bait() != null) { - total += context.bait().statistics().getOverall(statistic); + SkyBlockItem baitItem = FishingItemSupport.getItem(context.bait().getItemId()); + if (baitItem != null) { + total += baitItem.getAttributeHandler().getStatistics().getOverall(statistic); + } } return total; } @@ -235,16 +240,16 @@ private static double getTotalStatistic(FishingContext context, ItemStatistic st private static double getTagBonus(FishingContext context, List tags) { double total = 0.0D; if (context.hook() != null) { - total += getTagBonus(context.hook().tagBonuses(), tags); + total += getTagBonus(context.hook().getTagBonuses(), tags); } if (context.line() != null) { - total += getTagBonus(context.line().tagBonuses(), tags); + total += getTagBonus(context.line().getTagBonuses(), tags); } if (context.sinker() != null) { - total += getTagBonus(context.sinker().tagBonuses(), tags); + total += getTagBonus(context.sinker().getTagBonuses(), tags); } if (context.bait() != null) { - total += getTagBonus(context.bait().tagBonuses(), tags); + total += getTagBonus(context.bait().getTagBonuses(), tags); } return total; } diff --git a/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/fishing/FishingPartCategory.java b/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/fishing/FishingPartCategory.java new file mode 100644 index 000000000..36995d73c --- /dev/null +++ b/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/fishing/FishingPartCategory.java @@ -0,0 +1,7 @@ +package net.swofty.type.skyblockgeneric.fishing; + +public enum FishingPartCategory { + HOOK, + LINE, + SINKER +} diff --git a/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/fishing/FishingRegistry.java b/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/fishing/FishingRegistry.java index 0befec050..cc9768e88 100644 --- a/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/fishing/FishingRegistry.java +++ b/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/fishing/FishingRegistry.java @@ -4,7 +4,6 @@ import net.swofty.commons.YamlFileUtils; import net.swofty.commons.skyblock.statistics.ItemStatistic; import net.swofty.commons.skyblock.statistics.ItemStatistics; -import net.swofty.type.skyblockgeneric.entity.mob.MobType; import org.jetbrains.annotations.Nullable; import org.tinylog.Logger; @@ -20,8 +19,8 @@ public final class FishingRegistry { private static final File FISHING_DIR = new File("./configuration/skyblock/fishing"); private static final Map TABLES = new LinkedHashMap<>(); - private static final Map SEA_CREATURES = new LinkedHashMap<>(); private static final Map TROPHY_FISH = new LinkedHashMap<>(); + private static final Map SEA_CREATURES = new LinkedHashMap<>(); private static final Map HOTSPOTS = new LinkedHashMap<>(); private FishingRegistry() { @@ -29,8 +28,8 @@ private FishingRegistry() { public static void loadAll() { TABLES.clear(); - SEA_CREATURES.clear(); TROPHY_FISH.clear(); + SEA_CREATURES.clear(); HOTSPOTS.clear(); if (!YamlFileUtils.ensureDirectoryExists(FISHING_DIR)) { @@ -39,8 +38,8 @@ public static void loadAll() { try { loadTables(new File(FISHING_DIR, "tables.yml")); - loadSeaCreatures(new File(FISHING_DIR, "sea_creatures.yml")); loadTrophyFish(new File(FISHING_DIR, "trophy_fish.yml")); + loadSeaCreatures(new File(FISHING_DIR, "sea_creatures.yml")); loadHotspots(new File(FISHING_DIR, "hotspots.yml")); } catch (Exception exception) { Logger.error(exception, "Failed to load fishing configuration"); @@ -97,6 +96,9 @@ private static void loadTables(File file) throws IOException { @SuppressWarnings("unchecked") private static void loadTrophyFish(File file) throws IOException { + if (!file.exists()) { + return; + } Map root = YamlFileUtils.loadYaml(file); List> entries = (List>) root.getOrDefault("trophyFish", Collections.emptyList()); for (Map entry : entries) { @@ -134,11 +136,9 @@ private static void loadSeaCreatures(File file) throws IOException { String id = string(entry, "id"); SEA_CREATURES.put(id, new SeaCreatureDefinition( id, - string(entry, "displayName"), intValue(entry, "requiredFishingLevel", 0), doubleValue(entry, "skillXp", 0.0D), - stringList(entry.get("tags")), - nullableString(entry, "corruptedVariantId") + stringList(entry.get("tags")) )); } } @@ -151,42 +151,44 @@ private static void loadHotspots(File file) throws IOException { Map root = YamlFileUtils.loadYaml(file); List> entries = (List>) root.getOrDefault("hotspots", Collections.emptyList()); - int generatedId = 1; for (Map entry : entries) { - if (entry.containsKey("x") && entry.containsKey("y") && entry.containsKey("z")) { - String serverType = normalizeServerType(nullableString(entry, "serverType")); - String region = nullableString(entry, "region"); - HOTSPOTS.put("POSITION_" + generatedId, new HotspotDefinition( - "POSITION_" + generatedId, - "Hotspot", - region == null ? List.of() : List.of(region.toUpperCase()), - enumValue(entry, "medium", FishingMedium.class, FishingMedium.WATER), - intValue(entry, "maxActive", defaultMaxActiveForServer(serverType)), - intValue(entry, "durationSeconds", 120), - parseStatistics((Map) entry.get("buffs"), defaultHotspotBuffs()), - stringList(entry.get("seaCreatures")), - List.of(new HotspotDefinition.SpawnPoint( - doubleValue(entry.get("x"), 0), - doubleValue(entry.get("y"), 0), - doubleValue(entry.get("z"), 0), - serverType - )) + String serverType = normalizeServerType(nullableString(entry, "serverType")); + List> rawSpawnPoints = (List>) entry.get("spawnPoints"); + List spawnPoints = new ArrayList<>(); + if (rawSpawnPoints == null || rawSpawnPoints.isEmpty()) { + spawnPoints.add(new HotspotDefinition.SpawnPoint( + serverType, + doubleValue(entry.get("x"), 0.0D), + doubleValue(entry.get("y"), 0.0D), + doubleValue(entry.get("z"), 0.0D) )); - generatedId++; - continue; + } else { + for (Map spawnPoint : rawSpawnPoints) { + spawnPoints.add(new HotspotDefinition.SpawnPoint( + normalizeServerType(nullableString(spawnPoint, "serverType"), serverType), + doubleValue(spawnPoint.get("x"), 0.0D), + doubleValue(spawnPoint.get("y"), 0.0D), + doubleValue(spawnPoint.get("z"), 0.0D) + )); + } } - String id = string(entry, "id"); + String id = nullableString(entry, "id"); + if (id == null || id.isBlank()) { + id = serverType + "_" + HOTSPOTS.size(); + } + + Map buffs = castMap(entry.get("buffs")); HOTSPOTS.put(id, new HotspotDefinition( id, - string(entry, "displayName"), + nullableString(entry, "displayName") == null ? "Hotspot" : nullableString(entry, "displayName"), stringList(entry.get("regions")), - enumValue(entry, "medium", FishingMedium.class, FishingMedium.WATER), - intValue(entry, "maxActive", 1), + entry.containsKey("medium") ? FishingMedium.valueOf(String.valueOf(entry.get("medium")).toUpperCase()) : FishingMedium.WATER, + intValue(entry, "maxActive", defaultMaxActiveForServer(serverType)), intValue(entry, "durationSeconds", 120), - parseStatistics((Map) entry.get("buffs"), defaultHotspotBuffs()), + parseStatistics(buffs, defaultHotspotBuffs()), stringList(entry.get("seaCreatures")), - parseHotspotSpawnPoints((List>) entry.get("positions"), nullableString(entry, "serverType")) + spawnPoints )); } } @@ -232,33 +234,98 @@ private static List parseMediums(@Nullable List mediums) return result; } - private static List parseMobTypes(@Nullable List values) { - if (values == null || values.isEmpty()) { + @SuppressWarnings("unchecked") + private static @Nullable Map castMap(@Nullable Object value) { + if (value instanceof Map map) { + return (Map) map; + } + return null; + } + + private static List stringList(@Nullable Object value) { + if (!(value instanceof List values) || values.isEmpty()) { return List.of(); } - List mobTypes = new ArrayList<>(); - for (Object value : values) { - mobTypes.add(MobType.valueOf(String.valueOf(value).toUpperCase())); + List result = new ArrayList<>(); + for (Object entry : values) { + result.add(String.valueOf(entry)); } - return mobTypes; + return result; } - private static List parseHotspotSpawnPoints(@Nullable List> entries, @Nullable String fallbackServerType) { - if (entries == null || entries.isEmpty()) { - return List.of(); + private static String string(Map values, String key) { + String value = nullableString(values, key); + if (value == null) { + throw new IllegalArgumentException("Missing fishing config key: " + key); } + return value; + } - List points = new ArrayList<>(); - for (Map entry : entries) { - points.add(new HotspotDefinition.SpawnPoint( - doubleValue(entry.get("x"), 0), - doubleValue(entry.get("y"), 0), - doubleValue(entry.get("z"), 0), - normalizeServerType(nullableString(entry, "serverType"), fallbackServerType) - )); + private static @Nullable String nullableString(Map values, String key) { + return nullableString(values.get(key)); + } + + private static @Nullable String nullableString(@Nullable Object value) { + if (value == null) { + return null; } - return points; + String stringValue = String.valueOf(value); + return stringValue.isBlank() ? null : stringValue; + } + + private static int intValue(Map values, String key, int defaultValue) { + return intValue(values.get(key), defaultValue); + } + + private static int intValue(@Nullable Object value, int defaultValue) { + if (value == null) { + return defaultValue; + } + return ((Number) value).intValue(); + } + + private static long longValue(Map values, String key, long defaultValue) { + return longValue(values.get(key), defaultValue); + } + + private static long longValue(@Nullable Object value, long defaultValue) { + if (value == null) { + return defaultValue; + } + return ((Number) value).longValue(); + } + + private static double doubleValue(Map values, String key, double defaultValue) { + return doubleValue(values.get(key), defaultValue); + } + + private static double doubleValue(@Nullable Object value, double defaultValue) { + if (value == null) { + return defaultValue; + } + return ((Number) value).doubleValue(); + } + + private static @Nullable Double nullableDouble(@Nullable Object value) { + if (value == null) { + return null; + } + return ((Number) value).doubleValue(); + } + + private static boolean booleanValue(Map values, String key, boolean defaultValue) { + return booleanValue(values.get(key), defaultValue); + } + + private static boolean booleanValue(@Nullable Object value, boolean defaultValue) { + if (value == null) { + return defaultValue; + } + if (value instanceof Boolean bool) { + return bool; + } + return Boolean.parseBoolean(String.valueOf(value)); } private static String normalizeServerType(@Nullable String serverType) { @@ -323,116 +390,4 @@ private static List parseSeaCreatureRoll } return result; } - - private static Map parseStringDoubleMap(@Nullable Map values) { - if (values == null || values.isEmpty()) { - return Map.of(); - } - - Map result = new LinkedHashMap<>(); - for (Map.Entry entry : values.entrySet()) { - result.put(entry.getKey(), doubleValue(entry.getValue(), 0.0D)); - } - return result; - } - - private static String string(Map entry, String key) { - Object value = entry.get(key); - if (value == null) { - throw new IllegalArgumentException("Missing fishing config key: " + key); - } - return String.valueOf(value); - } - - private static @Nullable String nullableString(Map entry, String key) { - Object value = entry.get(key); - if (value == null) { - return null; - } - String stringValue = String.valueOf(value); - return stringValue.isEmpty() ? null : stringValue; - } - - private static List stringList(@Nullable Object raw) { - if (!(raw instanceof List list)) { - return List.of(); - } - List values = new ArrayList<>(); - for (Object entry : list) { - values.add(String.valueOf(entry)); - } - return values; - } - - private static int intValue(Map entry, String key, int defaultValue) { - return intValue(entry.get(key), defaultValue); - } - - private static int intValue(@Nullable Object value, int defaultValue) { - if (value == null) { - return defaultValue; - } - if (value instanceof Number number) { - return number.intValue(); - } - return Integer.parseInt(String.valueOf(value)); - } - - private static long longValue(Map entry, String key, long defaultValue) { - return longValue(entry.get(key), defaultValue); - } - - private static long longValue(@Nullable Object value, long defaultValue) { - if (value == null) { - return defaultValue; - } - if (value instanceof Number number) { - return number.longValue(); - } - return Long.parseLong(String.valueOf(value)); - } - - private static double doubleValue(Map entry, String key, double defaultValue) { - return doubleValue(entry.get(key), defaultValue); - } - - private static double doubleValue(@Nullable Object value, double defaultValue) { - if (value == null) { - return defaultValue; - } - if (value instanceof Number number) { - return number.doubleValue(); - } - return Double.parseDouble(String.valueOf(value)); - } - - private static @Nullable Double nullableDouble(@Nullable Object value) { - if (value == null) { - return null; - } - if (value instanceof Number number) { - return number.doubleValue(); - } - String stringValue = String.valueOf(value); - return stringValue.isEmpty() ? null : Double.parseDouble(stringValue); - } - - private static boolean booleanValue(Map entry, String key, boolean defaultValue) { - Object value = entry.get(key); - if (value == null) { - return defaultValue; - } - if (value instanceof Boolean bool) { - return bool; - } - return Boolean.parseBoolean(String.valueOf(value)); - } - - private static > T enumValue(Map entry, String key, Class type, T defaultValue) { - Object value = entry.get(key); - if (value == null) { - return defaultValue; - } - return Enum.valueOf(type, String.valueOf(value).toUpperCase()); - } } diff --git a/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/fishing/FishingRodDefinition.java b/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/fishing/FishingRodDefinition.java deleted file mode 100644 index 38d102af1..000000000 --- a/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/fishing/FishingRodDefinition.java +++ /dev/null @@ -1,23 +0,0 @@ -package net.swofty.type.skyblockgeneric.fishing; - -import net.swofty.commons.skyblock.statistics.ItemStatistics; -import net.swofty.type.skyblockgeneric.enchantment.EnchantmentType; -import org.jetbrains.annotations.Nullable; - -import java.util.List; -import java.util.Map; - -public record FishingRodDefinition( - String itemId, - String displayName, - @Nullable String subtitle, - FishingMedium medium, - int requiredFishingLevel, - ItemStatistics statistics, - Map enchantments, - List lore, - @Nullable String legacyConversionTarget, - @Nullable String legacyConversionPart, - boolean rodPartsEnabled -) { -} diff --git a/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/fishing/FishingRodLoreBuilder.java b/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/fishing/FishingRodLoreBuilder.java index d108ad7bc..acdd1317b 100644 --- a/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/fishing/FishingRodLoreBuilder.java +++ b/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/fishing/FishingRodLoreBuilder.java @@ -2,20 +2,16 @@ import net.swofty.commons.StringUtility; import net.swofty.commons.skyblock.item.ItemType; -import net.swofty.commons.skyblock.item.Rarity; -import net.swofty.commons.skyblock.item.attribute.attributes.ItemAttributeHotPotatoBookData; -import net.swofty.commons.skyblock.item.reforge.Reforge; import net.swofty.commons.skyblock.statistics.ItemStatistic; -import net.swofty.commons.skyblock.statistics.ItemStatistics; -import net.swofty.type.skyblockgeneric.enchantment.SkyBlockEnchantment; import net.swofty.type.skyblockgeneric.item.SkyBlockItem; +import net.swofty.type.skyblockgeneric.item.components.DefaultSoulboundComponent; +import net.swofty.type.skyblockgeneric.item.components.FishingRodMetadataComponent; +import net.swofty.type.skyblockgeneric.item.components.GemstoneComponent; import net.swofty.type.skyblockgeneric.user.SkyBlockPlayer; import org.jetbrains.annotations.Nullable; import java.util.ArrayList; -import java.util.Comparator; import java.util.List; -import java.util.Map; public final class FishingRodLoreBuilder { private static final List STAT_ORDER = List.of( @@ -24,193 +20,86 @@ public final class FishingRodLoreBuilder { ItemStatistic.FEROCITY, ItemStatistic.FISHING_SPEED, ItemStatistic.SEA_CREATURE_CHANCE, - ItemStatistic.TREASURE_CHANCE, - ItemStatistic.TROPHY_FISH_CHANCE, - ItemStatistic.MAGIC_FIND + ItemStatistic.DOUBLE_HOOK_CHANCE, + ItemStatistic.TROPHY_FISH_CHANCE ); private FishingRodLoreBuilder() { } public static @Nullable FishingRodLore build(SkyBlockItem item, @Nullable SkyBlockPlayer player) { - ItemType itemType = item.getAttributeHandler().getPotentialType(); - if (itemType == null) { + if (!item.hasComponent(FishingRodMetadataComponent.class)) { return null; } - FishingRodDefinition definition = FishingItemCatalog.getRod(itemType.name()); - if (definition == null) { - return null; - } - - var handler = item.getAttributeHandler(); - Rarity rarity = handler.isRecombobulated() ? handler.getRarity().upgrade() : handler.getRarity(); - - String displayName = definition.displayName(); - Reforge reforge = handler.getReforge(); - if (reforge != null) { - displayName = reforge.getPrefix() + " " + displayName; - } - displayName = rarity.getColor() + displayName; - + FishingRodMetadataComponent metadata = item.getComponent(FishingRodMetadataComponent.class); List lore = new ArrayList<>(); - if (definition.subtitle() != null) { - lore.add("§8" + definition.subtitle()); - lore.add(""); + if (metadata.getSubtitle() != null && !metadata.getSubtitle().isBlank()) { + lore.add(metadata.getSubtitle()); } for (ItemStatistic statistic : STAT_ORDER) { - String line = buildStatLine(item, definition, rarity, statistic); - if (line != null) { - lore.add(line); + double amount = item.getAttributeHandler().getStatistics().getOverall(statistic) + + FishingRodPartService.getStatistics(item).getOverall(statistic); + if (amount == 0.0D) { + continue; } + lore.add(formatStatistic(statistic, amount)); } - lore.addAll(definition.lore()); - if (!lore.isEmpty() && !lore.getLast().isEmpty()) { - lore.add(""); - } - - List enchantLines = buildEnchantLines(item, rarity); - lore.addAll(enchantLines); - if (!enchantLines.isEmpty()) { - lore.add(""); + if (item.hasComponent(GemstoneComponent.class)) { + lore.add(renderGemSlots(item.getComponent(GemstoneComponent.class))); } - if (definition.rodPartsEnabled()) { - RodPartDefinition hook = FishingRodPartService.getHook(item); - RodPartDefinition line = FishingRodPartService.getLine(item); - RodPartDefinition sinker = FishingRodPartService.getSinker(item); + lore.add(partLine("ථ Hook ", item.getAttributeHandler().getFishingHook())); + lore.add(partLine("ꨃ Line ", item.getAttributeHandler().getFishingLine())); + lore.add(partLine("࿉ Sinker ", item.getAttributeHandler().getFishingSinker())); - lore.add(renderPartHeader("ථ", "Hook", hook)); - if (hook != null) { - lore.addAll(renderAppliedPartLore(hook, player)); - } - lore.add(renderPartHeader("ꨃ", "Line", line)); - if (line != null) { - lore.addAll(renderAppliedPartLore(line, player)); - } - lore.add(renderPartHeader("࿉", "Sinker", sinker)); - if (sinker != null) { - lore.addAll(renderAppliedPartLore(sinker, player)); - } - lore.add(""); - lore.add("§7Talk to §2Roddy §7in the §2Backwater"); - lore.add("§2Bayou §7to apply parts to this rod."); - lore.add(""); - } else if (definition.legacyConversionTarget() != null) { - lore.add("§7§cThis rod is broken and cannot be"); - lore.add("§cused to fish."); - lore.add(""); - lore.add("§7Bring it to §2Roddy §7in the §2Backwater"); - lore.add("§2Bayou §7to convert it into a §anew rod§7!"); - lore.add(""); + if (metadata.getLegacyConversionTarget() != null) { + lore.add("Talk to Roddy in the Backwater"); + lore.add("Bayou to convert this rod."); + } else if (metadata.isRodPartsEnabled()) { + lore.add("Talk to Roddy in the Backwater"); + lore.add("Bayou to apply parts to this rod."); } - lore.add("§8This item can be reforged!"); - - if (handler.getFishingExpertiseKills() > 0) { - lore.add("§fKills: §6" + StringUtility.commaify(handler.getFishingExpertiseKills())); + if (item.hasComponent(net.swofty.type.skyblockgeneric.item.components.ReforgableComponent.class)) { + lore.add("This item can be reforged!"); } - - if (handler.getSoulBoundData() != null) { - lore.add("§8§l* Co-op Soulbound §l*"); + if (metadata.getRequiredFishingLevel() > 0) { + lore.add("❣ Requires Fishing Skill " + metadata.getRequiredFishingLevel() + "."); } - - if (definition.requiredFishingLevel() > 0 && player != null && - player.getSkills().getCurrentLevel(net.swofty.type.skyblockgeneric.skill.SkillCategories.FISHING) < definition.requiredFishingLevel()) { - lore.add("§4❣ §cRequires §aFishing Skill " + definition.requiredFishingLevel() + "§c."); + if (metadata.getExtraRequirements() != null) { + lore.addAll(metadata.getExtraRequirements()); } - - String footer = rarity.getDisplay() + " FISHING ROD"; - if (handler.isRecombobulated()) { - footer = rarity.getColor() + "§l§ka §l" + rarity.name() + " FISHING ROD §l§ka"; + if (item.hasComponent(DefaultSoulboundComponent.class)) { + lore.add("* Co-op Soulbound *"); } - lore.add(footer); - return new FishingRodLore(displayName, lore); + lore.add(item.getAttributeHandler().getRarity().getDisplay() + " FISHING ROD"); + return new FishingRodLore(item.getDisplayName(), lore); } - private static @Nullable String buildStatLine(SkyBlockItem item, FishingRodDefinition definition, Rarity rarity, ItemStatistic statistic) { - double base = definition.statistics().getOverall(statistic); - double reforge = 0.0D; - if (item.getAttributeHandler().getReforge() != null) { - reforge = item.getAttributeHandler().getReforge().getAfterCalculation(ItemStatistics.empty(), rarity.ordinal() + 1).getOverall(statistic); - } - - double part = FishingRodPartService.getStatistics(item).getOverall(statistic); - double dynamic = item.getAttributeHandler().getExtraDynamicStatistics().getOverall(statistic); - double hpb = getHotPotatoContribution(item, statistic); - double total = base + reforge + part + dynamic + hpb; - - if (total == 0) { - return null; - } - - String line = "§7" + statistic.getDisplayName() + ": " + statistic.getLoreColor() - + statistic.getPrefix() + formatNumber(total) + statistic.getSuffix(); - if (hpb != 0) { - line += " §e(" + (hpb > 0 ? "+" : "") + formatNumber(hpb) + ")"; - } - if (part != 0) { - line += " §d(" + (part > 0 ? "+" : "") + formatNumber(part) + ")"; - } else if (reforge != 0) { - line += " §9(" + (reforge > 0 ? "+" : "") + formatNumber(reforge) + ")"; - } - return line; - } - - private static double getHotPotatoContribution(SkyBlockItem item, ItemStatistic statistic) { - ItemAttributeHotPotatoBookData.HotPotatoBookData data = item.getAttributeHandler().getHotPotatoBookData(); - if (!data.hasAppliedItem()) { - return 0.0D; - } - - double total = 0.0D; - for (Map.Entry entry : data.getPotatoType().stats.entrySet()) { - if (entry.getKey() == statistic) { - total += entry.getValue(); - } - } - return total; - } - - private static List buildEnchantLines(SkyBlockItem item, Rarity rarity) { - List enchantments = item.getAttributeHandler().getEnchantments() - .sorted(Comparator.comparing(enchantment -> enchantment.type().getName())) - .toList(); - if (enchantments.isEmpty()) { - return List.of(); - } - - String enchantColor = rarity == Rarity.MYTHIC ? "§d" : "§9"; - String joined = enchantments.stream() - .map(enchantment -> enchantColor + enchantment.type().getName() + " " + StringUtility.getAsRomanNumeral(enchantment.level())) - .reduce((left, right) -> left + ", " + right) + private static String renderGemSlots(GemstoneComponent gemstone) { + return gemstone.getSlots().stream() + .map(slot -> "[" + slot.slot().getSymbol() + "]") + .reduce((left, right) -> left + " " + right) .orElse(""); - return StringUtility.splitByWordAndLength(joined, 34); } - private static String renderPartHeader(String symbol, String label, @Nullable RodPartDefinition part) { - if (part == null) { - return "§9" + symbol + " " + label + " §8§lNONE"; + private static String partLine(String prefix, @Nullable String itemId) { + if (itemId == null) { + return prefix + "NONE"; } - return ItemType.valueOf(part.itemId()).rarity.getColor() + symbol + " " + part.displayName(); + ItemType type = ItemType.get(itemId); + return prefix + (type == null ? "NONE" : type.getDisplayName().replace("§", "")); } - private static List renderAppliedPartLore(RodPartDefinition part, @Nullable SkyBlockPlayer player) { - List lines = new ArrayList<>(); - for (String line : part.lore()) { - lines.add("§7" + line); - } - if (part.requiredFishingLevel() > 0 && player != null && - player.getSkills().getCurrentLevel(net.swofty.type.skyblockgeneric.skill.SkillCategories.FISHING) < part.requiredFishingLevel()) { - lines.add("§4❣ §cRequires §aFishing Skill " + part.requiredFishingLevel() + "§c."); - } - return lines; + private static String formatStatistic(ItemStatistic statistic, double amount) { + return statistic.getDisplayName() + ": " + statistic.getPrefix() + format(amount) + statistic.getSuffix(); } - private static String formatNumber(double value) { + private static String format(double value) { if (Math.abs(value - Math.rint(value)) < 0.0001D) { return String.valueOf((long) Math.rint(value)); } diff --git a/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/fishing/FishingRodPartService.java b/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/fishing/FishingRodPartService.java index 87ac626a1..3c5ebb102 100644 --- a/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/fishing/FishingRodPartService.java +++ b/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/fishing/FishingRodPartService.java @@ -2,22 +2,23 @@ import net.swofty.commons.skyblock.statistics.ItemStatistics; import net.swofty.type.skyblockgeneric.item.SkyBlockItem; +import net.swofty.type.skyblockgeneric.item.components.FishingRodPartComponent; import org.jetbrains.annotations.Nullable; public final class FishingRodPartService { private FishingRodPartService() { } - public static @Nullable RodPartDefinition getHook(SkyBlockItem rod) { - return getPart(FishingItemCatalog.getRodPart(rod.getAttributeHandler().getFishingHook())); + public static @Nullable FishingRodPartComponent getHook(SkyBlockItem rod) { + return FishingItemSupport.getRodPart(rod.getAttributeHandler().getFishingHook()); } - public static @Nullable RodPartDefinition getLine(SkyBlockItem rod) { - return getPart(FishingItemCatalog.getRodPart(rod.getAttributeHandler().getFishingLine())); + public static @Nullable FishingRodPartComponent getLine(SkyBlockItem rod) { + return FishingItemSupport.getRodPart(rod.getAttributeHandler().getFishingLine()); } - public static @Nullable RodPartDefinition getSinker(SkyBlockItem rod) { - return getPart(FishingItemCatalog.getRodPart(rod.getAttributeHandler().getFishingSinker())); + public static @Nullable FishingRodPartComponent getSinker(SkyBlockItem rod) { + return FishingItemSupport.getRodPart(rod.getAttributeHandler().getFishingSinker()); } public static ItemStatistics getStatistics(SkyBlockItem rod) { @@ -28,15 +29,15 @@ public static ItemStatistics getStatistics(SkyBlockItem rod) { return builder.build(); } - public static void applyPart(SkyBlockItem rod, RodPartDefinition part) { - switch (part.category()) { - case HOOK -> rod.getAttributeHandler().setFishingHook(part.itemId()); - case LINE -> rod.getAttributeHandler().setFishingLine(part.itemId()); - case SINKER -> rod.getAttributeHandler().setFishingSinker(part.itemId()); + public static void applyPart(SkyBlockItem rod, FishingRodPartComponent part) { + switch (part.getCategory()) { + case HOOK -> rod.getAttributeHandler().setFishingHook(part.getItemId()); + case LINE -> rod.getAttributeHandler().setFishingLine(part.getItemId()); + case SINKER -> rod.getAttributeHandler().setFishingSinker(part.getItemId()); } } - public static void removePart(SkyBlockItem rod, RodPartDefinition.PartCategory category) { + public static void removePart(SkyBlockItem rod, FishingPartCategory category) { switch (category) { case HOOK -> rod.getAttributeHandler().setFishingHook(null); case LINE -> rod.getAttributeHandler().setFishingLine(null); @@ -44,16 +45,16 @@ public static void removePart(SkyBlockItem rod, RodPartDefinition.PartCategory c } } - private static @Nullable RodPartDefinition getPart(@Nullable RodPartDefinition definition) { - return definition; - } - - private static void append(ItemStatistics.Builder builder, @Nullable RodPartDefinition definition) { + private static void append(ItemStatistics.Builder builder, @Nullable FishingRodPartComponent definition) { if (definition == null) { return; } + SkyBlockItem item = FishingItemSupport.getItem(definition.getItemId()); + if (item == null) { + return; + } for (var statistic : net.swofty.commons.skyblock.statistics.ItemStatistic.values()) { - double amount = definition.statistics().getOverall(statistic); + double amount = item.getAttributeHandler().getStatistics().getOverall(statistic); if (amount != 0) { builder.withBase(statistic, amount); } diff --git a/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/fishing/FishingService.java b/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/fishing/FishingService.java index 235e2a63a..fd0ba7fef 100644 --- a/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/fishing/FishingService.java +++ b/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/fishing/FishingService.java @@ -6,6 +6,8 @@ import net.swofty.type.skyblockgeneric.data.datapoints.DatapointTrophyFish; import net.swofty.type.skyblockgeneric.entity.FishingHook; import net.swofty.type.skyblockgeneric.item.SkyBlockItem; +import net.swofty.type.skyblockgeneric.item.components.FishingBaitComponent; +import net.swofty.type.skyblockgeneric.item.components.FishingRodPartComponent; import net.swofty.type.skyblockgeneric.region.SkyBlockRegion; import net.swofty.type.skyblockgeneric.user.SkyBlockPlayer; import org.jetbrains.annotations.Nullable; @@ -21,12 +23,12 @@ private FishingService() { } public static FishingSession beginCast(SkyBlockPlayer player, SkyBlockItem rod, FishingMedium medium) { - BaitDefinition bait = FishingBaitService.getFirstAvailableBait(player, medium); + FishingBaitComponent bait = FishingBaitService.getFirstAvailableBait(player, medium); FishingSession session = new FishingSession( player.getUuid(), rod.getAttributeHandler().getPotentialType().name(), medium, - bait == null ? null : bait.itemId(), + bait == null ? null : bait.getItemId(), System.currentTimeMillis(), 0L, 0L, @@ -49,13 +51,16 @@ public static void clearSession(UUID playerUuid) { SESSIONS.remove(playerUuid); } - public static long computeWaitTicks(SkyBlockPlayer player, SkyBlockItem rod, @Nullable BaitDefinition bait) { + public static long computeWaitTicks(SkyBlockPlayer player, SkyBlockItem rod, @Nullable FishingBaitComponent bait) { double fishingSpeed = player.getStatistics().allStatistics().getOverall(net.swofty.commons.skyblock.statistics.ItemStatistic.FISHING_SPEED) + rod.getAttributeHandler().getStatistics().getOverall(net.swofty.commons.skyblock.statistics.ItemStatistic.FISHING_SPEED) + FishingRodPartService.getStatistics(rod).getOverall(net.swofty.commons.skyblock.statistics.ItemStatistic.FISHING_SPEED); if (bait != null) { - fishingSpeed += bait.statistics().getOverall(net.swofty.commons.skyblock.statistics.ItemStatistic.FISHING_SPEED); - if ("CORRUPTED_BAIT".equals(bait.itemId())) { + SkyBlockItem baitItem = FishingItemSupport.getItem(bait.getItemId()); + if (baitItem != null) { + fishingSpeed += baitItem.getAttributeHandler().getStatistics().getOverall(net.swofty.commons.skyblock.statistics.ItemStatistic.FISHING_SPEED); + } + if ("CORRUPTED_BAIT".equals(bait.getItemId())) { fishingSpeed /= 2.0D; } } @@ -69,7 +74,7 @@ public static long computeWaitTicks(SkyBlockPlayer player, SkyBlockItem rod, @Nu return null; } - BaitDefinition bait = FishingItemCatalog.getBait(session.baitItemId()); + FishingBaitComponent bait = FishingItemSupport.getBait(session.baitItemId()); SkyBlockRegion region = player.getRegion(); var hotspotBuffs = FishingHotspotService.getActiveHotspotBuffs(player, session.medium(), hook.getSpawnPosition()); boolean hotspotActive = hasAnyBuffValue(hotspotBuffs); @@ -98,9 +103,9 @@ public static long computeWaitTicks(SkyBlockPlayer player, SkyBlockItem rod, @Nu if (caster != null) { preserve |= Math.random() * 100 < caster.level(); } - RodPartDefinition sinker = FishingRodPartService.getSinker(rod); - if (!preserve && sinker != null && sinker.baitPreservationChance() > 0) { - preserve = Math.random() * 100 < sinker.baitPreservationChance(); + FishingRodPartComponent sinker = FishingRodPartService.getSinker(rod); + if (!preserve && sinker != null && sinker.getBaitPreservationChance() > 0) { + preserve = Math.random() * 100 < sinker.getBaitPreservationChance(); } if (!preserve) { FishingBaitService.consumeOneBait(player, session.baitItemId()); @@ -123,9 +128,9 @@ private static void awardCatch(SkyBlockPlayer player, SkyBlockItem rod, FishingH player.getSkyblockDataHandler().get(SkyBlockDataHandler.Data.COLLECTION, DatapointCollection.class).setValue(player.getCollection()); } - RodPartDefinition sinker = FishingRodPartService.getSinker(rod); - if (sinker != null && sinker.materializedItemId() != null && Math.random() <= sinker.materializedChance()) { - player.addAndUpdateItem(net.swofty.commons.skyblock.item.ItemType.valueOf(sinker.materializedItemId())); + FishingRodPartComponent sinker = FishingRodPartService.getSinker(rod); + if (sinker != null && sinker.getMaterializedItemId() != null && Math.random() <= sinker.getMaterializedChance()) { + player.addAndUpdateItem(net.swofty.commons.skyblock.item.ItemType.valueOf(sinker.getMaterializedItemId())); } if (result.trophyFishId() != null) { diff --git a/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/fishing/FishingShipPartSlot.java b/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/fishing/FishingShipPartSlot.java new file mode 100644 index 000000000..7a93807a5 --- /dev/null +++ b/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/fishing/FishingShipPartSlot.java @@ -0,0 +1,7 @@ +package net.swofty.type.skyblockgeneric.fishing; + +public enum FishingShipPartSlot { + HELM, + ENGINE, + HULL +} diff --git a/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/fishing/FishingShipService.java b/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/fishing/FishingShipService.java index aa9167c0b..a2ae344c8 100644 --- a/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/fishing/FishingShipService.java +++ b/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/fishing/FishingShipService.java @@ -2,6 +2,7 @@ import net.swofty.type.skyblockgeneric.data.SkyBlockDataHandler; import net.swofty.type.skyblockgeneric.data.datapoints.DatapointShipState; +import net.swofty.type.skyblockgeneric.item.components.FishingShipPartComponent; import net.swofty.type.skyblockgeneric.user.SkyBlockPlayer; public final class FishingShipService { @@ -12,12 +13,12 @@ public static DatapointShipState.ShipState getState(SkyBlockPlayer player) { return player.getSkyblockDataHandler().get(SkyBlockDataHandler.Data.SHIP_STATE, DatapointShipState.class).getValue(); } - public static void installPart(SkyBlockPlayer player, ShipPartDefinition definition) { + public static void installPart(SkyBlockPlayer player, String itemId, FishingShipPartComponent definition) { DatapointShipState.ShipState state = getState(player); - switch (definition.slot()) { - case HELM -> state.setHelm(definition.itemId()); - case ENGINE -> state.setEngine(definition.itemId()); - case HULL -> state.setHull(definition.itemId()); + switch (definition.getSlot()) { + case HELM -> state.setHelm(itemId); + case ENGINE -> state.setEngine(itemId); + case HULL -> state.setHull(itemId); } player.getSkyblockDataHandler().get(SkyBlockDataHandler.Data.SHIP_STATE, DatapointShipState.class).setValue(state); } diff --git a/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/fishing/HotspotDefinition.java b/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/fishing/HotspotDefinition.java index de0af4eb1..a3c48b9c0 100644 --- a/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/fishing/HotspotDefinition.java +++ b/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/fishing/HotspotDefinition.java @@ -15,6 +15,11 @@ public record HotspotDefinition( List seaCreatureIds, List spawnPoints ) { - public record SpawnPoint(double x, double y, double z, String serverType) { + public record SpawnPoint( + String serverType, + double x, + double y, + double z + ) { } } diff --git a/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/fishing/RodPartDefinition.java b/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/fishing/RodPartDefinition.java deleted file mode 100644 index fbd19e56a..000000000 --- a/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/fishing/RodPartDefinition.java +++ /dev/null @@ -1,30 +0,0 @@ -package net.swofty.type.skyblockgeneric.fishing; - -import net.swofty.commons.skyblock.statistics.ItemStatistics; -import org.jetbrains.annotations.Nullable; - -import java.util.List; -import java.util.Map; - -public record RodPartDefinition( - String itemId, - String displayName, - PartCategory category, - int requiredFishingLevel, - ItemStatistics statistics, - List lore, - Map tagBonuses, - boolean treasureOnly, - boolean bayouTreasureToJunk, - @Nullable String materializedItemId, - double materializedChance, - double baitPreservationChance, - double hotspotBuffMultiplier, - @Nullable String texture -) { - public enum PartCategory { - HOOK, - LINE, - SINKER - } -} diff --git a/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/fishing/SeaCreatureDefinition.java b/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/fishing/SeaCreatureDefinition.java index e9ceb5727..d2ebd4041 100644 --- a/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/fishing/SeaCreatureDefinition.java +++ b/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/fishing/SeaCreatureDefinition.java @@ -4,11 +4,8 @@ public record SeaCreatureDefinition( String id, - String displayName, int requiredFishingLevel, double skillXp, - List tags, - String corruptedVariantId + List tags ) { } - diff --git a/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/fishing/ShipPartDefinition.java b/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/fishing/ShipPartDefinition.java deleted file mode 100644 index 60667cf38..000000000 --- a/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/fishing/ShipPartDefinition.java +++ /dev/null @@ -1,19 +0,0 @@ -package net.swofty.type.skyblockgeneric.fishing; - -import org.jetbrains.annotations.Nullable; - -import java.util.List; - -public record ShipPartDefinition( - String itemId, - String displayName, - ShipPartSlot slot, - List lore, - @Nullable String texture -) { - public enum ShipPartSlot { - HELM, - ENGINE, - HULL - } -} diff --git a/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/gui/inventories/fishing/FishingGuideStackFactory.java b/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/gui/inventories/fishing/FishingGuideStackFactory.java index d8d9b39e6..2857b9bd1 100644 --- a/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/gui/inventories/fishing/FishingGuideStackFactory.java +++ b/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/gui/inventories/fishing/FishingGuideStackFactory.java @@ -5,9 +5,10 @@ import net.swofty.commons.skyblock.statistics.ItemStatistic; import net.swofty.commons.skyblock.statistics.ItemStatistics; import net.swofty.type.generic.gui.inventory.ItemStackCreator; -import net.swofty.type.skyblockgeneric.fishing.BaitDefinition; import net.swofty.type.skyblockgeneric.fishing.FishingMedium; -import net.swofty.type.skyblockgeneric.fishing.RodPartDefinition; +import net.swofty.type.skyblockgeneric.item.SkyBlockItem; +import net.swofty.type.skyblockgeneric.item.components.FishingBaitComponent; +import net.swofty.type.skyblockgeneric.item.components.FishingRodPartComponent; import java.util.ArrayList; import java.util.List; @@ -29,75 +30,77 @@ public final class FishingGuideStackFactory { private FishingGuideStackFactory() { } - public static net.minestom.server.item.ItemStack.Builder buildBaitStack(BaitDefinition bait) { + public static net.minestom.server.item.ItemStack.Builder buildBaitStack(SkyBlockItem baitItem) { + FishingBaitComponent bait = baitItem.getComponent(FishingBaitComponent.class); List lore = new ArrayList<>(); lore.add("§8Fishing Bait"); lore.add("§8Consumes on Cast"); lore.add(""); - appendStatistics(lore, bait.statistics()); - appendTagBonuses(lore, bait.tagBonuses()); + appendStatistics(lore, baitItem.getAttributeHandler().getStatistics()); + appendTagBonuses(lore, bait.getTagBonuses()); - if (bait.treasureChanceBonus() > 0) { - lore.add("§7Grants §6+" + format(bait.treasureChanceBonus()) + " Treasure Chance§7."); + if (bait.getTreasureChanceBonus() > 0) { + lore.add("§7Grants §6+" + format(bait.getTreasureChanceBonus()) + " Treasure Chance§7."); } - if (bait.treasureQualityBonus() > 0) { - lore.add("§7Increases treasure quality by §a" + format(bait.treasureQualityBonus()) + "%§7."); + if (bait.getTreasureQualityBonus() > 0) { + lore.add("§7Increases treasure quality by §a" + format(bait.getTreasureQualityBonus()) + "%§7."); } - if (bait.trophyFishChanceBonus() > 0) { - lore.add("§7Grants §6+" + format(bait.trophyFishChanceBonus()) + " Trophy Fish Chance§7."); + if (bait.getTrophyFishChanceBonus() > 0) { + lore.add("§7Grants §6+" + format(bait.getTrophyFishChanceBonus()) + " Trophy Fish Chance§7."); } - if (bait.doubleHookChanceBonus() > 0) { - lore.add("§7Grants §9+" + format(bait.doubleHookChanceBonus()) + " Double Hook Chance§7."); + if (bait.getDoubleHookChanceBonus() > 0) { + lore.add("§7Grants §9+" + format(bait.getDoubleHookChanceBonus()) + " Double Hook Chance§7."); } - if (bait.mediums().size() == 1) { - lore.add("§7Usable in §" + (bait.mediums().getFirst() == FishingMedium.WATER ? "bWater" : "cLava") + "§7."); + if (bait.getMediums().size() == 1) { + lore.add("§7Usable in " + (bait.getMediums().getFirst() == FishingMedium.WATER ? "§bWater" : "§cLava") + "§7."); } - finishFooter(lore, bait.itemId(), "BAIT"); + finishFooter(lore, bait.getItemId(), "BAIT"); return ItemStackCreator.getStackHead( - coloredName(bait.itemId(), bait.displayName()), - bait.texture(), + coloredName(bait.getItemId(), bait.getDisplayName()), + bait.getTexture(), 1, lore.toArray(String[]::new) ); } - public static net.minestom.server.item.ItemStack.Builder buildRodPartStack(RodPartDefinition part) { + public static net.minestom.server.item.ItemStack.Builder buildRodPartStack(SkyBlockItem partItem) { + FishingRodPartComponent part = partItem.getComponent(FishingRodPartComponent.class); List lore = new ArrayList<>(); - lore.add("§8" + StringUtility.toNormalCase(part.category().name()) + " Rod Part"); + lore.add("§8" + StringUtility.toNormalCase(part.getCategory().name()) + " Rod Part"); lore.add(""); - appendStatistics(lore, part.statistics()); - appendTagBonuses(lore, part.tagBonuses()); + appendStatistics(lore, partItem.getAttributeHandler().getStatistics()); + appendTagBonuses(lore, part.getTagBonuses()); - if (part.treasureOnly()) { + if (part.isTreasureOnly()) { lore.add("§7Only allows you to catch items and §6Treasure§7."); } - if (part.bayouTreasureToJunk()) { + if (part.isBayouTreasureToJunk()) { lore.add("§7Replaces §6Treasure §7catches with §2Junk §7in the §2Backwater Bayou§7."); } - if (part.materializedItemId() != null) { - String itemName = ItemType.valueOf(part.materializedItemId()).getDisplayName(); - if (part.materializedChance() >= 1.0D) { + if (part.getMaterializedItemId() != null) { + String itemName = ItemType.valueOf(part.getMaterializedItemId()).getDisplayName(); + if (part.getMaterializedChance() >= 1.0D) { lore.add("§7Materializes §f" + itemName + " §7in your inventory whenever you catch something."); } else { - lore.add("§7Has a §a" + format(part.materializedChance() * 100.0D) + "% §7chance to materialize §f" + itemName + "§7."); + lore.add("§7Has a §a" + format(part.getMaterializedChance() * 100.0D) + "% §7chance to materialize §f" + itemName + "§7."); } } - if (part.baitPreservationChance() > 0) { - lore.add("§7Grants a §a" + format(part.baitPreservationChance()) + "% §7chance to not consume Bait."); + if (part.getBaitPreservationChance() > 0) { + lore.add("§7Grants a §a" + format(part.getBaitPreservationChance()) + "% §7chance to not consume Bait."); } - if (part.hotspotBuffMultiplier() > 1.0D) { - lore.add("§7Increases the bonuses of §dFishing Hotspots §7by §a" + format((part.hotspotBuffMultiplier() - 1.0D) * 100.0D) + "%§7."); + if (part.getHotspotBuffMultiplier() > 1.0D) { + lore.add("§7Increases the bonuses of §dFishing Hotspots §7by §a" + format((part.getHotspotBuffMultiplier() - 1.0D) * 100.0D) + "%§7."); } - if (part.requiredFishingLevel() > 0) { + if (part.getRequiredFishingLevel() > 0) { lore.add(""); - lore.add("§4❣ §cRequires §aFishing Skill " + part.requiredFishingLevel() + "§c."); + lore.add("§4❣ §cRequires §aFishing Skill " + part.getRequiredFishingLevel() + "§c."); } - finishFooter(lore, part.itemId(), "ROD PART"); + finishFooter(lore, part.getItemId(), "ROD PART"); return ItemStackCreator.getStackHead( - coloredName(part.itemId(), part.displayName()), - part.texture(), + coloredName(part.getItemId(), part.getDisplayName()), + part.getTexture(), 1, lore.toArray(String[]::new) ); @@ -148,4 +151,4 @@ private static String format(double value) { } return StringUtility.decimalify(value, 1); } -} \ No newline at end of file +} diff --git a/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/gui/inventories/fishing/GUIBaitGuide.java b/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/gui/inventories/fishing/GUIBaitGuide.java index 5dd5df60a..7b14e8009 100644 --- a/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/gui/inventories/fishing/GUIBaitGuide.java +++ b/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/gui/inventories/fishing/GUIBaitGuide.java @@ -9,7 +9,7 @@ import net.swofty.type.generic.gui.v2.ViewConfiguration; import net.swofty.type.generic.gui.v2.ViewLayout; import net.swofty.type.generic.gui.v2.context.ViewContext; -import net.swofty.type.skyblockgeneric.fishing.FishingItemCatalog; +import net.swofty.type.skyblockgeneric.fishing.FishingItemSupport; public class GUIBaitGuide extends StatelessView { private static final int[] BAIT_SLOTS = {10, 11, 12, 13, 14, 15, 16, 19, 20, 21, 22, 23, 24, 25, 28, 29, 30, 31, 32, 33, 34}; @@ -32,7 +32,7 @@ public void layout(ViewLayout layout, DefaultState state, ViewCont )); int index = 0; - for (var bait : FishingItemCatalog.getBaits()) { + for (var bait : FishingItemSupport.getBaits()) { if (index >= BAIT_SLOTS.length) { break; } diff --git a/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/gui/inventories/fishing/GUIFishingRodParts.java b/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/gui/inventories/fishing/GUIFishingRodParts.java new file mode 100644 index 000000000..6a8f4b2ed --- /dev/null +++ b/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/gui/inventories/fishing/GUIFishingRodParts.java @@ -0,0 +1,101 @@ +package net.swofty.type.skyblockgeneric.gui.inventories.fishing; + +import net.minestom.server.inventory.InventoryType; +import net.minestom.server.item.ItemStack; +import net.minestom.server.item.Material; +import net.swofty.commons.skyblock.item.ItemType; +import net.swofty.type.generic.gui.inventory.ItemStackCreator; +import net.swofty.type.generic.gui.v2.Components; +import net.swofty.type.generic.gui.v2.DefaultState; +import net.swofty.type.generic.gui.v2.StatelessView; +import net.swofty.type.generic.gui.v2.ViewConfiguration; +import net.swofty.type.generic.gui.v2.ViewLayout; +import net.swofty.type.generic.gui.v2.ViewSession; +import net.swofty.type.generic.gui.v2.context.ViewContext; +import net.swofty.type.skyblockgeneric.fishing.FishingItemSupport; +import net.swofty.type.skyblockgeneric.item.SkyBlockItem; +import net.swofty.type.skyblockgeneric.user.SkyBlockPlayer; + +public class GUIFishingRodParts extends StatelessView { + + @Override + public ViewConfiguration configuration() { + return new ViewConfiguration<>("Fishing Rod Parts", InventoryType.CHEST_6_ROW); + } + + @Override + public void onClose(DefaultState state, ViewContext ctx, ViewSession.CloseReason reason) { + ItemStack rodItem = ctx.inventory().getItemStack(21); + if (!rodItem.isAir()) { + SkyBlockPlayer player = (SkyBlockPlayer) ctx.player(); + player.addAndUpdateItem(new SkyBlockItem(rodItem)); + ctx.inventory().setItemStack(21, ItemStack.AIR); + } + } + + @Override + public void layout(ViewLayout layout, DefaultState state, ViewContext ctx) { + Components.close(layout, 49); + + layout.editable(21, (_, _) -> ItemStackCreator.createNamedItemStack( + Material.FISHING_ROD, + "§7Place your §aFishing Rod §7here!" + ), (_, oldItem, newItem, _) -> { + if (newItem.isAir()) { + return; + } + SkyBlockItem rod = new SkyBlockItem(newItem); + ItemType type = rod.getAttributeHandler().getPotentialType(); + var metadata = type == null ? null : FishingItemSupport.getRodMetadata(type.name()); + if (metadata == null || !metadata.isRodPartsEnabled() || metadata.getLegacyConversionTarget() != null) { + SkyBlockPlayer player = (SkyBlockPlayer) ctx.player(); + player.sendMessage("§cThat fishing rod does not support rod parts."); + ctx.inventory().setItemStack(21, oldItem); + if (!newItem.isAir()) { + player.addAndUpdateItem(new SkyBlockItem(newItem)); + } + } + }); + + layout.slot(22, ItemStackCreator.getStack( + "§9ථ Hook", + Material.LIGHT_BLUE_STAINED_GLASS_PANE, + 1, + "§7Place a §aFishing Rod §7in the slot to the", + "§7left to view and modify its §9Hook§7!", + "", + "§eClick to browse Hooks!" + ), (_, viewCtx) -> viewCtx.push(new GUIHookGuide())); + + layout.slot(23, ItemStackCreator.getStack( + "§9ꨃ Line", + Material.LIGHT_BLUE_STAINED_GLASS_PANE, + 1, + "§7Place a §aFishing Rod §7in the slot to the", + "§7left to view and modify its §9Line§7!", + "", + "§eClick to browse Lines!" + ), (_, viewCtx) -> viewCtx.push(new GUILineGuide())); + + layout.slot(24, ItemStackCreator.getStack( + "§9࿉ Sinker", + Material.LIGHT_BLUE_STAINED_GLASS_PANE, + 1, + "§7Place a §aFishing Rod §7in the slot to the", + "§7left to view and modify its §9Sinker§7!", + "", + "§eClick to browse Sinkers!" + ), (_, viewCtx) -> viewCtx.push(new GUISinkerGuide())); + + layout.slot(50, ItemStackCreator.getStack( + "§9Rod Part Guide", + Material.BOOK, + 1, + "§7View all of the §9Rod Parts §7that can be", + "§7applied to §aFishing Rods§7! Can also be", + "§7accessed with §a/rodparts§7!", + "", + "§eClick to view!" + ), (_, viewCtx) -> viewCtx.push(new GUIRodPartGuide())); + } +} diff --git a/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/gui/inventories/fishing/GUIFishingShip.java b/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/gui/inventories/fishing/GUIFishingShip.java new file mode 100644 index 000000000..0307a956b --- /dev/null +++ b/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/gui/inventories/fishing/GUIFishingShip.java @@ -0,0 +1,155 @@ +package net.swofty.type.skyblockgeneric.gui.inventories.fishing; + +import net.minestom.server.event.inventory.InventoryPreClickEvent; +import net.minestom.server.inventory.InventoryType; +import net.minestom.server.item.ItemStack; +import net.minestom.server.item.Material; +import net.swofty.type.generic.gui.inventory.HypixelInventoryGUI; +import net.swofty.type.generic.gui.inventory.ItemStackCreator; +import net.swofty.type.generic.gui.inventory.item.GUIClickableItem; +import net.swofty.type.generic.gui.inventory.item.GUIItem; +import net.swofty.type.generic.user.HypixelPlayer; +import net.swofty.type.skyblockgeneric.fishing.FishingItemSupport; +import net.swofty.type.skyblockgeneric.fishing.FishingShipService; +import net.swofty.type.skyblockgeneric.user.SkyBlockPlayer; + +public class GUIFishingShip extends HypixelInventoryGUI { + + public GUIFishingShip() { + super("{Fishing Ship}", InventoryType.CHEST_5_ROW); + } + + @Override + public void onOpen(InventoryGUIOpenEvent e) { + fill(FILLER_ITEM); + set(new GUIItem(4) { + @Override + public ItemStack.Builder getItem(HypixelPlayer player) { + SkyBlockPlayer skyBlockPlayer = (SkyBlockPlayer) player; + var state = FishingShipService.getState(skyBlockPlayer); + return ItemStackCreator.getStack( + "§6{Fishing Ship}", + Material.OAK_BOAT, + 1, + "§7Your §6Ship §7will help you travel to", + "§7different §9fishing islands §7in SkyBlock.", + "", + "§7For now, it can only get you to the", + "§2Backwater Bayou§7.", + "", + "§7Helm: §f" + resolvePartName(state.getHelm(), "Cracked Ship Helm"), + "§7Engine: §f" + resolvePartName(state.getEngine(), "Missing Engine"), + "§7Hull: §f" + resolvePartName(state.getHull(), "Rusty Ship Hull") + ); + } + }); + set(new GUIItem(21) { + @Override + public ItemStack.Builder getItem(HypixelPlayer player) { + SkyBlockPlayer skyBlockPlayer = (SkyBlockPlayer) player; + return buildShipPartStack( + FishingShipService.getState(skyBlockPlayer).getHelm(), + "Cracked Ship Helm", + "d8d4a54d1fcf47b2efc99ba4cc772250aee5c2f26ed1a19052213e0f3323ca1d", + "§7A cracked ship helm, incapable of", + "§7changing its heading which appears", + "§7due east." + ); + } + }); + set(new GUIItem(22) { + @Override + public ItemStack.Builder getItem(HypixelPlayer player) { + SkyBlockPlayer skyBlockPlayer = (SkyBlockPlayer) player; + return buildShipPartStack( + FishingShipService.getState(skyBlockPlayer).getEngine(), + "Missing Engine", + "53e84793917c890f7f8a2c4078a29e8ba939790498727af9342c2b6f6ac43c9c", + "§7This ship still needs an engine before", + "§7it can get you anywhere." + ); + } + }); + set(new GUIItem(23) { + @Override + public ItemStack.Builder getItem(HypixelPlayer player) { + SkyBlockPlayer skyBlockPlayer = (SkyBlockPlayer) player; + return buildShipPartStack( + FishingShipService.getState(skyBlockPlayer).getHull(), + "Rusty Ship Hull", + "f42d53ca6e7d80a99a699c2036dcf6e233394feb9f46fb2ff9d9a819690894a9", + "§7A hull rusted and dilapidated beyond", + "§7repair. It's a miracle the ship", + "§7remains afloat." + ); + } + }); + set(new GUIClickableItem(31) { + @Override + public ItemStack.Builder getItem(HypixelPlayer player) { + SkyBlockPlayer skyBlockPlayer = (SkyBlockPlayer) player; + boolean unlocked = FishingShipService.getState(skyBlockPlayer).hasDestination("BACKWATER_BAYOU"); + return ItemStackCreator.getStack( + unlocked ? "§aOpen Navigator" : "§cNavigator Locked", + Material.COMPASS, + 1, + "§7Choose where to set sail next.", + "", + unlocked ? "§eClick to browse destinations!" : "§cInstall an engine first." + ); + } + + @Override + public void run(InventoryPreClickEvent e, HypixelPlayer player) { + SkyBlockPlayer skyBlockPlayer = (SkyBlockPlayer) player; + if (!FishingShipService.getState(skyBlockPlayer).hasDestination("BACKWATER_BAYOU")) { + player.sendMessage("§cYour ship cannot travel anywhere yet."); + return; + } + skyBlockPlayer.openView(new GUINavigator()); + } + }); + set(new GUIItem(44) { + @Override + public ItemStack.Builder getItem(HypixelPlayer player) { + SkyBlockPlayer skyBlockPlayer = (SkyBlockPlayer) player; + return ItemStackCreator.getStack( + "§aRename Ship", + Material.NAME_TAG, + 1, + "§7You may be going on long voyages", + "§7with your §6Ship§7, best to give it a name!", + "", + "§7Current Name: §6" + FishingShipService.getState(skyBlockPlayer).getShipName(), + "", + "§7Renaming is not implemented yet." + ); + } + }); + set(GUIClickableItem.getCloseItem(40)); + updateItemStacks(getInventory(), getPlayer()); + } + + @Override + public boolean allowHotkeying() { + return false; + } + + @Override + public void onBottomClick(InventoryPreClickEvent e) { + e.setCancelled(true); + } + + private static String resolvePartName(String itemId, String fallback) { + var definition = FishingItemSupport.getShipPart(itemId); + return definition == null ? fallback : definition.getDisplayName(); + } + + private static ItemStack.Builder buildShipPartStack(String itemId, String fallbackName, String fallbackTexture, String... fallbackLore) { + var definition = FishingItemSupport.getShipPart(itemId); + String name = definition == null ? fallbackName : definition.getDisplayName(); + String texture = definition == null || definition.getTexture() == null ? fallbackTexture : definition.getTexture(); + String[] lore = fallbackLore; + return ItemStackCreator.getStackHead("§f" + name, texture, 1, lore); + } +} diff --git a/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/gui/inventories/fishing/GUIHookGuide.java b/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/gui/inventories/fishing/GUIHookGuide.java new file mode 100644 index 000000000..3fa81e827 --- /dev/null +++ b/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/gui/inventories/fishing/GUIHookGuide.java @@ -0,0 +1,47 @@ +package net.swofty.type.skyblockgeneric.gui.inventories.fishing; + +import net.minestom.server.inventory.InventoryType; +import net.minestom.server.item.Material; +import net.swofty.type.generic.gui.inventory.ItemStackCreator; +import net.swofty.type.generic.gui.v2.Components; +import net.swofty.type.generic.gui.v2.DefaultState; +import net.swofty.type.generic.gui.v2.StatelessView; +import net.swofty.type.generic.gui.v2.ViewConfiguration; +import net.swofty.type.generic.gui.v2.ViewLayout; +import net.swofty.type.generic.gui.v2.context.ViewContext; +import net.swofty.type.skyblockgeneric.fishing.FishingItemSupport; +import net.swofty.type.skyblockgeneric.fishing.FishingPartCategory; + +public class GUIHookGuide extends StatelessView { + private static final int[] PART_SLOTS = {10, 11, 12, 13, 14, 15, 16}; + + @Override + public ViewConfiguration configuration() { + return new ViewConfiguration<>("Hook", InventoryType.CHEST_6_ROW); + } + + @Override + public void layout(ViewLayout layout, DefaultState state, ViewContext ctx) { + Components.close(layout, 49); + layout.slot(4, ItemStackCreator.getStackHead( + "§9ථ Hooks", + "9809753cbab0380c7a1c18925faf9b51e44caadd1e5748542b0f23835f4ef64e", + 1, + "§9Hooks §7change what your rod is better at catching." + )); + + int index = 0; + for (var part : FishingItemSupport.getRodParts()) { + if (part.getComponent(net.swofty.type.skyblockgeneric.item.components.FishingRodPartComponent.class).getCategory() != FishingPartCategory.HOOK || index >= PART_SLOTS.length) { + continue; + } + layout.slot(PART_SLOTS[index++], FishingGuideStackFactory.buildRodPartStack(part)); + } + layout.slot(48, ItemStackCreator.getStack( + "§aGo Back", + Material.ARROW, + 1, + "§7To Rod Part Guide" + ), (_, viewCtx) -> viewCtx.pop()); + } +} diff --git a/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/gui/inventories/fishing/GUILineGuide.java b/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/gui/inventories/fishing/GUILineGuide.java new file mode 100644 index 000000000..6d53c13d8 --- /dev/null +++ b/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/gui/inventories/fishing/GUILineGuide.java @@ -0,0 +1,47 @@ +package net.swofty.type.skyblockgeneric.gui.inventories.fishing; + +import net.minestom.server.inventory.InventoryType; +import net.minestom.server.item.Material; +import net.swofty.type.generic.gui.inventory.ItemStackCreator; +import net.swofty.type.generic.gui.v2.Components; +import net.swofty.type.generic.gui.v2.DefaultState; +import net.swofty.type.generic.gui.v2.StatelessView; +import net.swofty.type.generic.gui.v2.ViewConfiguration; +import net.swofty.type.generic.gui.v2.ViewLayout; +import net.swofty.type.generic.gui.v2.context.ViewContext; +import net.swofty.type.skyblockgeneric.fishing.FishingItemSupport; +import net.swofty.type.skyblockgeneric.fishing.FishingPartCategory; + +public class GUILineGuide extends StatelessView { + private static final int[] PART_SLOTS = {10, 11, 12, 13, 14, 15, 16}; + + @Override + public ViewConfiguration configuration() { + return new ViewConfiguration<>("Line", InventoryType.CHEST_6_ROW); + } + + @Override + public void layout(ViewLayout layout, DefaultState state, ViewContext ctx) { + Components.close(layout, 49); + layout.slot(4, ItemStackCreator.getStackHead( + "§9ꨃ Lines", + "9a850a4f721bc150bb72b067e5074c8251058a6b9111691da315b393467c1aa9", + 1, + "§9Lines §7grant stat bonuses to your rod everywhere." + )); + + int index = 0; + for (var part : FishingItemSupport.getRodParts()) { + if (part.getComponent(net.swofty.type.skyblockgeneric.item.components.FishingRodPartComponent.class).getCategory() != FishingPartCategory.LINE || index >= PART_SLOTS.length) { + continue; + } + layout.slot(PART_SLOTS[index++], FishingGuideStackFactory.buildRodPartStack(part)); + } + layout.slot(48, ItemStackCreator.getStack( + "§aGo Back", + Material.ARROW, + 1, + "§7To Rod Part Guide" + ), (_, viewCtx) -> viewCtx.pop()); + } +} diff --git a/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/gui/inventories/fishing/GUINavigator.java b/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/gui/inventories/fishing/GUINavigator.java new file mode 100644 index 000000000..f47c10a82 --- /dev/null +++ b/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/gui/inventories/fishing/GUINavigator.java @@ -0,0 +1,89 @@ +package net.swofty.type.skyblockgeneric.gui.inventories.fishing; + +import net.minestom.server.inventory.InventoryType; +import net.minestom.server.item.Material; +import net.swofty.commons.ServerType; +import net.swofty.type.generic.HypixelConst; +import net.swofty.type.generic.gui.inventory.ItemStackCreator; +import net.swofty.type.generic.gui.v2.Components; +import net.swofty.type.generic.gui.v2.DefaultState; +import net.swofty.type.generic.gui.v2.Layouts; +import net.swofty.type.generic.gui.v2.StatelessView; +import net.swofty.type.generic.gui.v2.ViewConfiguration; +import net.swofty.type.generic.gui.v2.ViewLayout; +import net.swofty.type.generic.gui.v2.context.ViewContext; +import net.swofty.type.skyblockgeneric.user.SkyBlockPlayer; + +public class GUINavigator extends StatelessView { + + @Override + public ViewConfiguration configuration() { + return new ViewConfiguration<>("Navigator", InventoryType.CHEST_6_ROW); + } + + @Override + public void layout(ViewLayout layout, DefaultState state, ViewContext ctx) { + SkyBlockPlayer player = (SkyBlockPlayer) ctx.player(); + ServerType currentServer = HypixelConst.getTypeLoader().getType(); + boolean inBayou = currentServer == ServerType.SKYBLOCK_BACKWATER_BAYOU; + boolean unlocked = inBayou || player.getShipState().hasDestination("BACKWATER_BAYOU"); + + layout.slots(Layouts.row(0), (_, _) -> Components.FILLER); + layout.slots(Layouts.row(5), (_, _) -> Components.FILLER); + layout.slots(Layouts.rectangle(9, 45), (_, _) -> Components.FILLER.material(Material.BLUE_STAINED_GLASS_PANE)); + Components.close(layout, 49); + + if (inBayou) { + layout.slot(10, ItemStackCreator.getStackHead( + "§bFishing Outpost", + "d7cc6687423d0570d556ac53e0676cb563bbdd9717cd8269bdebed6f6d4e7bf8", + 1, + "§7Your base of operations.", + "", + "§eClick to travel!" + ), (_, viewCtx) -> ((SkyBlockPlayer) viewCtx.player()).sendTo(ServerType.SKYBLOCK_HUB)); + layout.slot(40, ItemStackCreator.getStackHead( + "§2Backwater Bayou", + "1c0cd33590f64d346d98cdd01606938742e715dda6737353306a44f81c8ba426", + 1, + "§7A small, marshy outlet in the middle", + "§7of nowhere. Due to its isolated", + "§7nature, people frequently come here", + "§7to dump their trash.", + "", + "§a§lYOU ARE HERE!" + )); + return; + } + + layout.slot(10, ItemStackCreator.getStackHead( + "§2Backwater Bayou", + "1c0cd33590f64d346d98cdd01606938742e715dda6737353306a44f81c8ba426", + 1, + "§7A small, marshy outlet in the middle", + "§7of nowhere. Due to its isolated", + "§7nature, people frequently come here", + "§7to dump their trash.", + "", + "§7Activities:", + "§8 ■ §7Fish up §2Junk §7and trade it with §2Junker", + " §2Joel §7for useful items!", + "§8 ■ §7Apply §9Rod Parts §7with §2Roddy§7.", + "§8 ■ §7Fish §2Bayou Sea Creatures§7.", + "§8 ■ §7Learn about §dFishing Hotspots §7from", + " §dHattie§7.", + "", + unlocked ? "§eClick to travel!" : "§cDestination Locked" + ), unlocked + ? (_, viewCtx) -> ((SkyBlockPlayer) viewCtx.player()).sendTo(ServerType.SKYBLOCK_BACKWATER_BAYOU) + : (_, viewCtx) -> viewCtx.player().sendMessage("§cYou have not unlocked this destination yet.")); + layout.slot(40, ItemStackCreator.getStackHead( + "§bFishing Outpost", + "d7cc6687423d0570d556ac53e0676cb563bbdd9717cd8269bdebed6f6d4e7bf8", + 1, + "§7Your base of operations.", + "", + "§a§lYOU ARE HERE!" + )); + } +} diff --git a/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/gui/inventories/fishing/GUIRodPartGuide.java b/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/gui/inventories/fishing/GUIRodPartGuide.java new file mode 100644 index 000000000..9dbeca20b --- /dev/null +++ b/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/gui/inventories/fishing/GUIRodPartGuide.java @@ -0,0 +1,64 @@ +package net.swofty.type.skyblockgeneric.gui.inventories.fishing; + +import net.minestom.server.inventory.InventoryType; +import net.minestom.server.item.Material; +import net.swofty.type.generic.gui.inventory.ItemStackCreator; +import net.swofty.type.generic.gui.v2.Components; +import net.swofty.type.generic.gui.v2.DefaultState; +import net.swofty.type.generic.gui.v2.StatelessView; +import net.swofty.type.generic.gui.v2.ViewConfiguration; +import net.swofty.type.generic.gui.v2.ViewLayout; +import net.swofty.type.generic.gui.v2.context.ViewContext; + +public class GUIRodPartGuide extends StatelessView { + @Override + public ViewConfiguration configuration() { + return new ViewConfiguration<>("Rod Part Guide", InventoryType.CHEST_6_ROW); + } + + @Override + public void layout(ViewLayout layout, DefaultState state, ViewContext ctx) { + Components.close(layout, 49); + + layout.slot(4, ItemStackCreator.getStack( + "§9Rod Part Guide", + Material.BOOK, + 1, + "§7View all §9Rod Parts §7that can be applied", + "§7to your upgraded fishing rods." + )); + layout.slot(20, ItemStackCreator.getStackHead( + "§9ථ Hooks", + "9809753cbab0380c7a1c18925faf9b51e44caadd1e5748542b0f23835f4ef64e", + 1, + "§9Hooks §7make you more likely to catch", + "§7certain things.", + "", + "§eClick to view!" + ), (_, viewCtx) -> viewCtx.push(new GUIHookGuide())); + layout.slot(22, ItemStackCreator.getStackHead( + "§9ꨃ Lines", + "9a850a4f721bc150bb72b067e5074c8251058a6b9111691da315b393467c1aa9", + 1, + "§9Lines §7grant you stat bonuses", + "§7everywhere.", + "", + "§eClick to view!" + ), (_, viewCtx) -> viewCtx.push(new GUILineGuide())); + layout.slot(24, ItemStackCreator.getStackHead( + "§9࿉ Sinkers", + "d24892a3142d2e130e5feb88b805b83de905489d2ccd1d031b9d7a2922b96500", + 1, + "§9Sinkers §7add special fishing effects", + "§7to your rod.", + "", + "§eClick to view!" + ), (_, viewCtx) -> viewCtx.push(new GUISinkerGuide())); + layout.slot(48, ItemStackCreator.getStack( + "§aGo Back", + Material.ARROW, + 1, + "§7To Fishing Rod Parts" + ), (_, viewCtx) -> viewCtx.pop()); + } +} diff --git a/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/gui/inventories/fishing/GUISinkerGuide.java b/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/gui/inventories/fishing/GUISinkerGuide.java new file mode 100644 index 000000000..420f50b1c --- /dev/null +++ b/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/gui/inventories/fishing/GUISinkerGuide.java @@ -0,0 +1,47 @@ +package net.swofty.type.skyblockgeneric.gui.inventories.fishing; + +import net.minestom.server.inventory.InventoryType; +import net.minestom.server.item.Material; +import net.swofty.type.generic.gui.inventory.ItemStackCreator; +import net.swofty.type.generic.gui.v2.Components; +import net.swofty.type.generic.gui.v2.DefaultState; +import net.swofty.type.generic.gui.v2.StatelessView; +import net.swofty.type.generic.gui.v2.ViewConfiguration; +import net.swofty.type.generic.gui.v2.ViewLayout; +import net.swofty.type.generic.gui.v2.context.ViewContext; +import net.swofty.type.skyblockgeneric.fishing.FishingItemSupport; +import net.swofty.type.skyblockgeneric.fishing.FishingPartCategory; + +public class GUISinkerGuide extends StatelessView { + private static final int[] PART_SLOTS = {10, 11, 12, 13, 14, 15, 16, 19, 20}; + + @Override + public ViewConfiguration configuration() { + return new ViewConfiguration<>("Sinker", InventoryType.CHEST_6_ROW); + } + + @Override + public void layout(ViewLayout layout, DefaultState state, ViewContext ctx) { + Components.close(layout, 49); + layout.slot(4, ItemStackCreator.getStackHead( + "§9࿉ Sinkers", + "d24892a3142d2e130e5feb88b805b83de905489d2ccd1d031b9d7a2922b96500", + 1, + "§9Sinkers §7add special fishing effects to your rod." + )); + + int index = 0; + for (var part : FishingItemSupport.getRodParts()) { + if (part.getComponent(net.swofty.type.skyblockgeneric.item.components.FishingRodPartComponent.class).getCategory() != FishingPartCategory.SINKER || index >= PART_SLOTS.length) { + continue; + } + layout.slot(PART_SLOTS[index++], FishingGuideStackFactory.buildRodPartStack(part)); + } + layout.slot(48, ItemStackCreator.getStack( + "§aGo Back", + Material.ARROW, + 1, + "§7To Rod Part Guide" + ), (_, viewCtx) -> viewCtx.pop()); + } +} diff --git a/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/item/ItemConfigParser.java b/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/item/ItemConfigParser.java index cc4015e79..f1cef59c0 100644 --- a/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/item/ItemConfigParser.java +++ b/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/item/ItemConfigParser.java @@ -11,10 +11,9 @@ import net.swofty.commons.skyblock.item.reforge.ReforgeType; import net.swofty.commons.skyblock.statistics.ItemStatistic; import net.swofty.commons.skyblock.statistics.ItemStatistics; -import net.swofty.type.skyblockgeneric.enchantment.EnchantmentType; import net.swofty.type.skyblockgeneric.fishing.FishingMedium; -import net.swofty.type.skyblockgeneric.fishing.RodPartDefinition; -import net.swofty.type.skyblockgeneric.fishing.ShipPartDefinition; +import net.swofty.type.skyblockgeneric.fishing.FishingPartCategory; +import net.swofty.type.skyblockgeneric.fishing.FishingShipPartSlot; import net.swofty.type.skyblockgeneric.gems.GemRarity; import net.swofty.type.skyblockgeneric.gems.Gemstone; import net.swofty.type.skyblockgeneric.item.components.*; @@ -168,36 +167,33 @@ yield new EnchantableComponent( } case "FISHING_ROD" -> new FishingRodComponent(); case "FISHING_ROD_METADATA" -> { - String displayName = safeConfig.getString("display_name"); - String subtitle = safeConfig.getString("subtitle", null); FishingMedium medium = safeConfig.containsKey("medium") ? safeConfig.getEnum("medium", FishingMedium.class) : FishingMedium.WATER; int requiredFishingLevel = safeConfig.getInt("required_fishing_level", 0); - Map enchantments = new java.util.EnumMap<>(EnchantmentType.class); - for (Map.Entry entry : safeConfig.getMap("enchantments").entrySet()) { - enchantments.put(EnchantmentType.valueOf(entry.getKey().toUpperCase()), ((Number) entry.getValue()).intValue()); - } + boolean rodPartsEnabled = safeConfig.getBoolean("rod_parts_enabled", true); + String legacyConversionTarget = safeConfig.getString("legacy_conversion_target", null); + String subtitle = safeConfig.getString("subtitle", null); + List extraRequirements = safeConfig.getList("extra_requirements", String.class); yield new FishingRodMetadataComponent( - displayName, - subtitle, medium, requiredFishingLevel, - enchantments, - safeConfig.getString("legacy_conversion_target", null), - safeConfig.getString("legacy_conversion_part", null), - safeConfig.getBoolean("rod_parts_enabled", true) + rodPartsEnabled, + legacyConversionTarget, + subtitle, + extraRequirements ); } case "FISHING_ROD_PART" -> { String displayName = safeConfig.getString("display_name"); - RodPartDefinition.PartCategory category = safeConfig.getEnum("category", RodPartDefinition.PartCategory.class); + FishingPartCategory category = safeConfig.getEnum("category", FishingPartCategory.class); int requiredFishingLevel = safeConfig.getInt("required_fishing_level", 0); Map tagBonuses = new java.util.LinkedHashMap<>(); for (Map.Entry entry : safeConfig.getMap("tag_bonuses").entrySet()) { tagBonuses.put(entry.getKey(), ((Number) entry.getValue()).doubleValue()); } yield new FishingRodPartComponent( + itemId, displayName, category, requiredFishingLevel, @@ -221,6 +217,7 @@ yield new FishingRodPartComponent( ? safeConfig.getList("mediums", String.class).stream().map(value -> FishingMedium.valueOf(value.toUpperCase())).toList() : List.of(FishingMedium.WATER, FishingMedium.LAVA); yield new FishingBaitComponent( + itemId, displayName, tagBonuses, safeConfig.getDouble("treasure_chance_bonus", 0.0), @@ -233,8 +230,8 @@ yield new FishingBaitComponent( } case "FISHING_SHIP_PART" -> { String displayName = safeConfig.getString("display_name"); - ShipPartDefinition.ShipPartSlot slot = safeConfig.getEnum("slot", ShipPartDefinition.ShipPartSlot.class); - yield new FishingShipPartComponent(displayName, slot, safeConfig.getString("texture", null)); + FishingShipPartSlot slot = safeConfig.getEnum("slot", FishingShipPartSlot.class); + yield new FishingShipPartComponent(itemId, displayName, slot, safeConfig.getString("texture", null)); } case "ENCHANTED" -> { if (safeConfig.containsKey("recipes")) { @@ -737,4 +734,4 @@ private static List parseGemstoneEntries(List tagBonuses; private final double treasureChanceBonus; @@ -18,6 +21,7 @@ public class FishingBaitComponent extends net.swofty.type.skyblockgeneric.item.S private final String texture; public FishingBaitComponent( + String itemId, String displayName, Map tagBonuses, double treasureChanceBonus, @@ -27,7 +31,11 @@ public FishingBaitComponent( List mediums, String texture ) { - this.displayName = displayName; + this.itemId = itemId; + ItemType type = ItemType.get(itemId); + this.displayName = displayName == null || displayName.isBlank() + ? (type == null ? itemId : type.getDisplayName()) + : displayName; this.tagBonuses = Map.copyOf(tagBonuses); this.treasureChanceBonus = treasureChanceBonus; this.treasureQualityBonus = treasureQualityBonus; @@ -36,11 +44,11 @@ public FishingBaitComponent( this.mediums = List.copyOf(mediums); this.texture = texture; - addInheritedComponent(new CustomDisplayNameComponent(ignored -> displayName)); + addInheritedComponent(new CustomDisplayNameComponent(ignored -> this.displayName)); if (texture != null && !texture.isBlank()) { addInheritedComponent(new SkullHeadComponent(ignored -> texture)); } addInheritedComponent(new ExtraUnderNameComponent(List.of("Fishing Bait", "Consumes on Cast"))); addInheritedComponent(new ExtraRarityComponent("BAIT")); } -} \ No newline at end of file +} diff --git a/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/item/components/FishingRodComponent.java b/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/item/components/FishingRodComponent.java index 7fdad90bb..c7dba0d77 100644 --- a/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/item/components/FishingRodComponent.java +++ b/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/item/components/FishingRodComponent.java @@ -3,7 +3,7 @@ import net.kyori.adventure.key.Key; import net.kyori.adventure.sound.Sound; import net.swofty.type.skyblockgeneric.entity.FishingHook; -import net.swofty.type.skyblockgeneric.fishing.FishingItemCatalog; +import net.swofty.type.skyblockgeneric.fishing.FishingItemSupport; import net.swofty.type.skyblockgeneric.fishing.FishingService; import net.swofty.type.skyblockgeneric.item.SkyBlockItemComponent; @@ -29,8 +29,8 @@ public FishingRodComponent() { ); } else { String itemId = item.getAttributeHandler().getPotentialType() == null ? null : item.getAttributeHandler().getPotentialType().name(); - var definition = FishingItemCatalog.getRod(itemId); - if (definition != null && definition.legacyConversionTarget() != null) { + var metadata = FishingItemSupport.getRodMetadata(itemId); + if (metadata != null && metadata.getLegacyConversionTarget() != null) { return; } new FishingHook(player, item).spawn(player.getInstance()); diff --git a/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/item/components/FishingRodMetadataComponent.java b/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/item/components/FishingRodMetadataComponent.java index 81a9b6faf..ccb7f8c8c 100644 --- a/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/item/components/FishingRodMetadataComponent.java +++ b/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/item/components/FishingRodMetadataComponent.java @@ -2,51 +2,41 @@ import lombok.Getter; import net.swofty.commons.skyblock.item.reforge.ReforgeType; -import net.swofty.type.skyblockgeneric.enchantment.EnchantmentType; import net.swofty.type.skyblockgeneric.fishing.FishingMedium; +import net.swofty.type.skyblockgeneric.item.SkyBlockItemComponent; import net.swofty.type.skyblockgeneric.utility.groups.EnchantItemGroups; +import org.jetbrains.annotations.Nullable; import java.util.List; -import java.util.Map; @Getter -public class FishingRodMetadataComponent extends net.swofty.type.skyblockgeneric.item.SkyBlockItemComponent { - private final String displayName; - private final String subtitle; +public class FishingRodMetadataComponent extends SkyBlockItemComponent { private final FishingMedium medium; private final int requiredFishingLevel; - private final Map enchantments; - private final String legacyConversionTarget; - private final String legacyConversionPart; private final boolean rodPartsEnabled; + private final @Nullable String legacyConversionTarget; + private final @Nullable String subtitle; + private final List extraRequirements; public FishingRodMetadataComponent( - String displayName, - String subtitle, FishingMedium medium, int requiredFishingLevel, - Map enchantments, - String legacyConversionTarget, - String legacyConversionPart, - boolean rodPartsEnabled + boolean rodPartsEnabled, + @Nullable String legacyConversionTarget, + @Nullable String subtitle, + List extraRequirements ) { - this.displayName = displayName; - this.subtitle = subtitle; this.medium = medium; this.requiredFishingLevel = requiredFishingLevel; - this.enchantments = Map.copyOf(enchantments); - this.legacyConversionTarget = legacyConversionTarget; - this.legacyConversionPart = legacyConversionPart; this.rodPartsEnabled = rodPartsEnabled; - - addInheritedComponent(new CustomDisplayNameComponent(ignored -> displayName)); - if (subtitle != null && !subtitle.isBlank()) { - addInheritedComponent(new ExtraUnderNameComponent(subtitle)); - } + this.legacyConversionTarget = legacyConversionTarget; + this.subtitle = subtitle; + this.extraRequirements = List.copyOf(extraRequirements); addInheritedComponent(new FishingRodComponent()); addInheritedComponent(new EnchantableComponent(List.of(EnchantItemGroups.FISHING_ROD), true)); addInheritedComponent(new ReforgableComponent(ReforgeType.FISHING_RODS)); addInheritedComponent(new DefaultSoulboundComponent(true)); addInheritedComponent(new ExtraRarityComponent("FISHING ROD")); + addInheritedComponent(new LoreUpdateComponent("FISHING_ROD", true)); } -} \ No newline at end of file +} diff --git a/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/item/components/FishingRodPartComponent.java b/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/item/components/FishingRodPartComponent.java index 16f6f2403..1cc4f105e 100644 --- a/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/item/components/FishingRodPartComponent.java +++ b/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/item/components/FishingRodPartComponent.java @@ -1,14 +1,16 @@ package net.swofty.type.skyblockgeneric.item.components; import lombok.Getter; -import net.swofty.type.skyblockgeneric.fishing.RodPartDefinition; +import net.swofty.commons.skyblock.item.ItemType; +import net.swofty.type.skyblockgeneric.fishing.FishingPartCategory; import java.util.Map; @Getter public class FishingRodPartComponent extends net.swofty.type.skyblockgeneric.item.SkyBlockItemComponent { + private final String itemId; private final String displayName; - private final RodPartDefinition.PartCategory category; + private final FishingPartCategory category; private final int requiredFishingLevel; private final Map tagBonuses; private final boolean treasureOnly; @@ -20,8 +22,9 @@ public class FishingRodPartComponent extends net.swofty.type.skyblockgeneric.ite private final String texture; public FishingRodPartComponent( + String itemId, String displayName, - RodPartDefinition.PartCategory category, + FishingPartCategory category, int requiredFishingLevel, Map tagBonuses, boolean treasureOnly, @@ -32,7 +35,11 @@ public FishingRodPartComponent( double hotspotBuffMultiplier, String texture ) { - this.displayName = displayName; + this.itemId = itemId; + ItemType type = ItemType.get(itemId); + this.displayName = displayName == null || displayName.isBlank() + ? (type == null ? itemId : type.getDisplayName()) + : displayName; this.category = category; this.requiredFishingLevel = requiredFishingLevel; this.tagBonuses = Map.copyOf(tagBonuses); @@ -44,10 +51,10 @@ public FishingRodPartComponent( this.hotspotBuffMultiplier = hotspotBuffMultiplier; this.texture = texture; - addInheritedComponent(new CustomDisplayNameComponent(ignored -> displayName)); + addInheritedComponent(new CustomDisplayNameComponent(ignored -> this.displayName)); if (texture != null && !texture.isBlank()) { addInheritedComponent(new SkullHeadComponent(ignored -> texture)); } addInheritedComponent(new ExtraRarityComponent("ROD PART")); } -} \ No newline at end of file +} diff --git a/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/item/components/FishingShipPartComponent.java b/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/item/components/FishingShipPartComponent.java index 3a2aef7dd..3ef56d3d2 100644 --- a/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/item/components/FishingShipPartComponent.java +++ b/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/item/components/FishingShipPartComponent.java @@ -1,22 +1,28 @@ package net.swofty.type.skyblockgeneric.item.components; import lombok.Getter; -import net.swofty.type.skyblockgeneric.fishing.ShipPartDefinition; +import net.swofty.commons.skyblock.item.ItemType; +import net.swofty.type.skyblockgeneric.fishing.FishingShipPartSlot; @Getter public class FishingShipPartComponent extends net.swofty.type.skyblockgeneric.item.SkyBlockItemComponent { + private final String itemId; private final String displayName; - private final ShipPartDefinition.ShipPartSlot slot; + private final FishingShipPartSlot slot; private final String texture; - public FishingShipPartComponent(String displayName, ShipPartDefinition.ShipPartSlot slot, String texture) { - this.displayName = displayName; + public FishingShipPartComponent(String itemId, String displayName, FishingShipPartSlot slot, String texture) { + this.itemId = itemId; + ItemType type = ItemType.get(itemId); + this.displayName = displayName == null || displayName.isBlank() + ? (type == null ? itemId : type.getDisplayName()) + : displayName; this.slot = slot; this.texture = texture; - addInheritedComponent(new CustomDisplayNameComponent(ignored -> displayName)); + addInheritedComponent(new CustomDisplayNameComponent(ignored -> this.displayName)); if (texture != null && !texture.isBlank()) { addInheritedComponent(new SkullHeadComponent(ignored -> texture)); } } -} \ No newline at end of file +} diff --git a/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/item/handlers/lore/LoreRegistry.java b/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/item/handlers/lore/LoreRegistry.java index 432c0a787..1b4a8bcde 100644 --- a/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/item/handlers/lore/LoreRegistry.java +++ b/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/item/handlers/lore/LoreRegistry.java @@ -3,9 +3,15 @@ import net.swofty.commons.StringUtility; import net.swofty.commons.skyblock.item.PotatoType; import net.swofty.type.skyblockgeneric.enchantment.SkyBlockEnchantment; +import net.swofty.type.skyblockgeneric.fishing.FishingRodLoreBuilder; import net.swofty.type.skyblockgeneric.utility.groups.EnchantItemGroups; -import java.util.*; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.Set; import java.util.stream.Collectors; public class LoreRegistry { @@ -70,6 +76,16 @@ public class LoreRegistry { "§eClick to open!" ), (item, player) -> "§aSkyBlock Menu §7(Click)")); register("HOT_POTATO_BOOK", new LoreConfig((item, player) -> PotatoType.allLores(), null)); + register("FISHING_ROD", new LoreConfig( + (item, player) -> { + var lore = FishingRodLoreBuilder.build(item, player); + return lore == null ? List.of() : lore.lore(); + }, + (item, player) -> { + var lore = FishingRodLoreBuilder.build(item, player); + return lore == null ? item.getDisplayName() : lore.displayName(); + } + )); register("MIDAS_SWORD", new LoreConfig((item, player) -> { List lore = new ArrayList<>(); long pricePaid = item.getAttributeHandler().getDarkAuctionPrice(); @@ -115,4 +131,4 @@ public static void register(String id, LoreConfig handler) { public static LoreConfig getHandler(String id) { return REGISTERED_HANDLERS.get(id); } -} \ No newline at end of file +} From 2aaa3ee8bea39337b58dbb2301ca7600a27cdf8b Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 9 Apr 2026 17:46:45 +0000 Subject: [PATCH 008/113] chore(deps): bump redis.clients:jedis from 7.2.0 to 7.4.1 Bumps [redis.clients:jedis](https://github.com/redis/jedis) from 7.2.0 to 7.4.1. - [Release notes](https://github.com/redis/jedis/releases) - [Commits](https://github.com/redis/jedis/compare/v7.2.0...v7.4.1) --- updated-dependencies: - dependency-name: redis.clients:jedis dependency-version: 7.4.1 dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- gradle/libs.versions.toml | 2 +- service.elections/build.gradle.kts | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index 3ae0feea3..e8c6fcf55 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -13,7 +13,7 @@ guava = "33.5.0-jre" jackson-annotations = "2.20" jackson-bom = "3.1.0" javapoet = "1.13.0" -jedis = "7.2.0" +jedis = "7.4.1" joml = "1.10.8" json = "20251224" junit = "4.13.2" diff --git a/service.elections/build.gradle.kts b/service.elections/build.gradle.kts index 4ec8e0379..fa45b2d09 100644 --- a/service.elections/build.gradle.kts +++ b/service.elections/build.gradle.kts @@ -31,7 +31,7 @@ dependencies { implementation("com.google.code.gson:gson:2.11.0") implementation("org.mongodb:bson:5.6.2") implementation("org.mongodb:mongodb-driver-sync:5.6.2") - implementation("redis.clients:jedis:7.2.0") + implementation("redis.clients:jedis:7.4.1") } application { From 874f096fb073558b50889b1a23522d891030cc28 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 9 Apr 2026 17:47:00 +0000 Subject: [PATCH 009/113] chore(deps): bump com.google.code.gson:gson from 2.11.0 to 2.13.2 Bumps [com.google.code.gson:gson](https://github.com/google/gson) from 2.11.0 to 2.13.2. - [Release notes](https://github.com/google/gson/releases) - [Changelog](https://github.com/google/gson/blob/main/CHANGELOG.md) - [Commits](https://github.com/google/gson/compare/gson-parent-2.11.0...gson-parent-2.13.2) --- updated-dependencies: - dependency-name: com.google.code.gson:gson dependency-version: 2.13.2 dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- gradle/libs.versions.toml | 2 +- service.elections/build.gradle.kts | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index 3ae0feea3..48797b3f1 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -8,7 +8,7 @@ configlib-yaml = "4.8.1" configurate-yaml = "4.2.0" creative = "1.7.3" fastutil = "8.5.18" -gson = "2.11.0" +gson = "2.13.2" guava = "33.5.0-jre" jackson-annotations = "2.20" jackson-bom = "3.1.0" diff --git a/service.elections/build.gradle.kts b/service.elections/build.gradle.kts index 4ec8e0379..b7ffba230 100644 --- a/service.elections/build.gradle.kts +++ b/service.elections/build.gradle.kts @@ -28,7 +28,7 @@ dependencies { implementation("com.github.ben-manes.caffeine:caffeine:3.2.3") implementation("org.tinylog:tinylog-api:2.7.0") implementation("org.tinylog:tinylog-impl:2.7.0") - implementation("com.google.code.gson:gson:2.11.0") + implementation("com.google.code.gson:gson:2.13.2") implementation("org.mongodb:bson:5.6.2") implementation("org.mongodb:mongodb-driver-sync:5.6.2") implementation("redis.clients:jedis:7.2.0") From 8371bc8d842c0c470891004a48bafe6573aad7ad Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 9 Apr 2026 17:47:15 +0000 Subject: [PATCH 010/113] chore(deps): bump com.gradleup.shadow from 9.3.1 to 9.4.1 Bumps [com.gradleup.shadow](https://github.com/GradleUp/shadow) from 9.3.1 to 9.4.1. - [Release notes](https://github.com/GradleUp/shadow/releases) - [Commits](https://github.com/GradleUp/shadow/compare/9.3.1...9.4.1) --- updated-dependencies: - dependency-name: com.gradleup.shadow dependency-version: 9.4.1 dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- loader/build.gradle.kts | 2 +- packer/build.gradle.kts | 2 +- service.api/build.gradle.kts | 2 +- service.auctionhouse/build.gradle.kts | 2 +- service.bazaar/build.gradle.kts | 2 +- service.datamutex/build.gradle.kts | 2 +- service.elections/build.gradle.kts | 2 +- service.friend/build.gradle.kts | 2 +- service.itemtracker/build.gradle.kts | 2 +- service.party/build.gradle.kts | 2 +- service.punishment/build.gradle.kts | 2 +- spark/build.gradle.kts | 2 +- velocity.extension/build.gradle.kts | 2 +- 13 files changed, 13 insertions(+), 13 deletions(-) diff --git a/loader/build.gradle.kts b/loader/build.gradle.kts index b43d82f95..c682b48cd 100644 --- a/loader/build.gradle.kts +++ b/loader/build.gradle.kts @@ -4,7 +4,7 @@ import java.util.* plugins { java application - id("com.gradleup.shadow") version "9.3.2" + id("com.gradleup.shadow") version "9.4.1" } group = "net.swofty" diff --git a/packer/build.gradle.kts b/packer/build.gradle.kts index 192644521..a65dc8c0e 100644 --- a/packer/build.gradle.kts +++ b/packer/build.gradle.kts @@ -3,7 +3,7 @@ import com.github.jengelman.gradle.plugins.shadow.tasks.ShadowJar plugins { `java-library` application - id("com.gradleup.shadow") version "9.3.2" + id("com.gradleup.shadow") version "9.4.1" } group = "net.swofty" diff --git a/service.api/build.gradle.kts b/service.api/build.gradle.kts index 27981c5ed..d84ecdace 100644 --- a/service.api/build.gradle.kts +++ b/service.api/build.gradle.kts @@ -3,7 +3,7 @@ import com.github.jengelman.gradle.plugins.shadow.tasks.ShadowJar plugins { java application - id("com.gradleup.shadow") version "9.3.2" + id("com.gradleup.shadow") version "9.4.1" } group = "net.swofty" diff --git a/service.auctionhouse/build.gradle.kts b/service.auctionhouse/build.gradle.kts index bd49f0610..c464be500 100644 --- a/service.auctionhouse/build.gradle.kts +++ b/service.auctionhouse/build.gradle.kts @@ -3,7 +3,7 @@ import com.github.jengelman.gradle.plugins.shadow.tasks.ShadowJar plugins { java application - id("com.gradleup.shadow") version "9.3.2" + id("com.gradleup.shadow") version "9.4.1" } group = "net.swofty" diff --git a/service.bazaar/build.gradle.kts b/service.bazaar/build.gradle.kts index 0690ef80e..6686c0516 100644 --- a/service.bazaar/build.gradle.kts +++ b/service.bazaar/build.gradle.kts @@ -3,7 +3,7 @@ import com.github.jengelman.gradle.plugins.shadow.tasks.ShadowJar plugins { java application - id("com.gradleup.shadow") version "9.3.2" + id("com.gradleup.shadow") version "9.4.1" } group = "net.swofty" diff --git a/service.datamutex/build.gradle.kts b/service.datamutex/build.gradle.kts index f55e9726f..e982cdabe 100644 --- a/service.datamutex/build.gradle.kts +++ b/service.datamutex/build.gradle.kts @@ -3,7 +3,7 @@ import com.github.jengelman.gradle.plugins.shadow.tasks.ShadowJar plugins { java application - id("com.gradleup.shadow") version "9.3.2" + id("com.gradleup.shadow") version "9.4.1" } group = "net.swofty" diff --git a/service.elections/build.gradle.kts b/service.elections/build.gradle.kts index 4ec8e0379..e646b3ca4 100644 --- a/service.elections/build.gradle.kts +++ b/service.elections/build.gradle.kts @@ -3,7 +3,7 @@ import com.github.jengelman.gradle.plugins.shadow.tasks.ShadowJar plugins { java application - id("com.gradleup.shadow") version "9.3.1" + id("com.gradleup.shadow") version "9.4.1" } group = "net.swofty" diff --git a/service.friend/build.gradle.kts b/service.friend/build.gradle.kts index ee385ed64..d0ef5349f 100644 --- a/service.friend/build.gradle.kts +++ b/service.friend/build.gradle.kts @@ -3,7 +3,7 @@ import com.github.jengelman.gradle.plugins.shadow.tasks.ShadowJar plugins { java application - id("com.gradleup.shadow") version "9.3.2" + id("com.gradleup.shadow") version "9.4.1" } group = "net.swofty" diff --git a/service.itemtracker/build.gradle.kts b/service.itemtracker/build.gradle.kts index 753c0c5f4..4a25341ed 100644 --- a/service.itemtracker/build.gradle.kts +++ b/service.itemtracker/build.gradle.kts @@ -3,7 +3,7 @@ import com.github.jengelman.gradle.plugins.shadow.tasks.ShadowJar plugins { java application - id("com.gradleup.shadow") version "9.3.2" + id("com.gradleup.shadow") version "9.4.1" } group = "net.swofty" diff --git a/service.party/build.gradle.kts b/service.party/build.gradle.kts index e60f3c4c9..fe105bbfb 100644 --- a/service.party/build.gradle.kts +++ b/service.party/build.gradle.kts @@ -3,7 +3,7 @@ import com.github.jengelman.gradle.plugins.shadow.tasks.ShadowJar plugins { java application - id("com.gradleup.shadow") version "9.3.2" + id("com.gradleup.shadow") version "9.4.1" } group = "net.swofty" diff --git a/service.punishment/build.gradle.kts b/service.punishment/build.gradle.kts index 677ae159f..e6ae798e6 100644 --- a/service.punishment/build.gradle.kts +++ b/service.punishment/build.gradle.kts @@ -3,7 +3,7 @@ import com.github.jengelman.gradle.plugins.shadow.tasks.ShadowJar plugins { java application - id("com.gradleup.shadow") version "9.3.2" + id("com.gradleup.shadow") version "9.4.1" } group = "net.swofty" diff --git a/spark/build.gradle.kts b/spark/build.gradle.kts index 0fe015dfa..ef30d1336 100644 --- a/spark/build.gradle.kts +++ b/spark/build.gradle.kts @@ -3,7 +3,7 @@ import com.github.jengelman.gradle.plugins.shadow.tasks.ShadowJar plugins { java application - id("com.gradleup.shadow") version "9.3.2" + id("com.gradleup.shadow") version "9.4.1" } group = "net.swofty" diff --git a/velocity.extension/build.gradle.kts b/velocity.extension/build.gradle.kts index ec2f68c65..12f86b178 100644 --- a/velocity.extension/build.gradle.kts +++ b/velocity.extension/build.gradle.kts @@ -4,7 +4,7 @@ plugins { java application `maven-publish` - id("com.gradleup.shadow") version "9.3.2" + id("com.gradleup.shadow") version "9.4.1" id("org.jetbrains.gradle.plugin.idea-ext") version "1.4.1" } From 1b960cc9922a0c2d6d1174d7974e63a4ed65fd7e Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 9 Apr 2026 17:48:10 +0000 Subject: [PATCH 011/113] chore(deps): bump io.sentry.jvm.gradle from 5.12.2 to 6.4.0 Bumps [io.sentry.jvm.gradle](https://github.com/getsentry/sentry-android-gradle-plugin) from 5.12.2 to 6.4.0. - [Release notes](https://github.com/getsentry/sentry-android-gradle-plugin/releases) - [Changelog](https://github.com/getsentry/sentry-android-gradle-plugin/blob/main/CHANGELOG.md) - [Commits](https://github.com/getsentry/sentry-android-gradle-plugin/compare/5.12.2...6.4.0) --- updated-dependencies: - dependency-name: io.sentry.jvm.gradle dependency-version: 6.4.0 dependency-type: direct:production update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] --- build.gradle.kts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build.gradle.kts b/build.gradle.kts index f80468c61..5e7227ba5 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -6,7 +6,7 @@ plugins { base java id("io.freefair.lombok") version "9.1.0" - id("io.sentry.jvm.gradle") version "5.12.2" + id("io.sentry.jvm.gradle") version "6.4.0" } group = "net.swofty" From 89ce2b1ec248f91dc9a2498c75d4127c5de53897 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 9 Apr 2026 17:48:14 +0000 Subject: [PATCH 012/113] chore(deps): bump com.viaversion:viaversion from 5.7.1 to 5.8.1 Bumps com.viaversion:viaversion from 5.7.1 to 5.8.1. --- updated-dependencies: - dependency-name: com.viaversion:viaversion dependency-version: 5.8.1 dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- gradle/libs.versions.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index 3ae0feea3..17a995edd 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -37,7 +37,7 @@ velocity-api = "3.5.0-SNAPSHOT" viabackwards = "5.7.2" vialoader = "4.0.6" viarewind = "4.0.15" -viaversion = "5.7.1" +viaversion = "5.8.1" [libraries] adventure-api = { module = "net.kyori:adventure-api", version.ref = "adventure" } From 1c5a4525bb9a68e96c7343a276dec050c7a59da1 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 7 May 2026 17:47:12 +0000 Subject: [PATCH 013/113] chore(deps-dev): bump vue from 3.5.31 to 3.5.34 in /website Bumps [vue](https://github.com/vuejs/core) from 3.5.31 to 3.5.34. - [Release notes](https://github.com/vuejs/core/releases) - [Changelog](https://github.com/vuejs/core/blob/main/CHANGELOG.md) - [Commits](https://github.com/vuejs/core/compare/v3.5.31...v3.5.34) --- updated-dependencies: - dependency-name: vue dependency-version: 3.5.34 dependency-type: direct:development update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- website/package-lock.json | 126 +++++++++++++++++++------------------- website/package.json | 2 +- 2 files changed, 64 insertions(+), 64 deletions(-) diff --git a/website/package-lock.json b/website/package-lock.json index 36f61b2bc..d485ab882 100644 --- a/website/package-lock.json +++ b/website/package-lock.json @@ -12,7 +12,7 @@ }, "devDependencies": { "vitepress": "^1.5.0", - "vue": "^3.5.31" + "vue": "^3.5.34" } }, "node_modules/@algolia/abtesting": { @@ -294,9 +294,9 @@ } }, "node_modules/@babel/parser": { - "version": "7.29.2", - "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.29.2.tgz", - "integrity": "sha512-4GgRzy/+fsBa72/RZVJmGKPmZu9Byn8o4MoLpmNe1m8ZfYnz5emHLQz3U4gLud6Zwl0RZIcgiLD7Uq7ySFuDLA==", + "version": "7.29.3", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.29.3.tgz", + "integrity": "sha512-b3ctpQwp+PROvU/cttc4OYl4MzfJUWy6FZg+PMXfzmt/+39iHVF0sDfqay8TQM3JA2EUOyKcFZt75jWriQijsA==", "dev": true, "license": "MIT", "dependencies": { @@ -1314,57 +1314,57 @@ } }, "node_modules/@vue/compiler-core": { - "version": "3.5.31", - "resolved": "https://registry.npmjs.org/@vue/compiler-core/-/compiler-core-3.5.31.tgz", - "integrity": "sha512-k/ueL14aNIEy5Onf0OVzR8kiqF/WThgLdFhxwa4e/KF/0qe38IwIdofoSWBTvvxQOesaz6riAFAUaYjoF9fLLQ==", + "version": "3.5.34", + "resolved": "https://registry.npmjs.org/@vue/compiler-core/-/compiler-core-3.5.34.tgz", + "integrity": "sha512-s9cLyK5mLcvZ4Agva5QgRsQyLKvts9WbU9DB6NqiZkkGEdwmcEiylj5Jbwkp680drF/NNCV8OlAJSe+yMLxaJw==", "dev": true, "license": "MIT", "dependencies": { - "@babel/parser": "^7.29.2", - "@vue/shared": "3.5.31", + "@babel/parser": "^7.29.3", + "@vue/shared": "3.5.34", "entities": "^7.0.1", "estree-walker": "^2.0.2", "source-map-js": "^1.2.1" } }, "node_modules/@vue/compiler-dom": { - "version": "3.5.31", - "resolved": "https://registry.npmjs.org/@vue/compiler-dom/-/compiler-dom-3.5.31.tgz", - "integrity": "sha512-BMY/ozS/xxjYqRFL+tKdRpATJYDTTgWSo0+AJvJNg4ig+Hgb0dOsHPXvloHQ5hmlivUqw1Yt2pPIqp4e0v1GUw==", + "version": "3.5.34", + "resolved": "https://registry.npmjs.org/@vue/compiler-dom/-/compiler-dom-3.5.34.tgz", + "integrity": "sha512-EbF/T++k0e2MMZlJsBhzK8Sgwt0HcIPOhzn1CTB/lv6sQcyk+OWf8YeiLxZp3ro7MbbLcAfAJ6sEvjFWuNgUCw==", "dev": true, "license": "MIT", "dependencies": { - "@vue/compiler-core": "3.5.31", - "@vue/shared": "3.5.31" + "@vue/compiler-core": "3.5.34", + "@vue/shared": "3.5.34" } }, "node_modules/@vue/compiler-sfc": { - "version": "3.5.31", - "resolved": "https://registry.npmjs.org/@vue/compiler-sfc/-/compiler-sfc-3.5.31.tgz", - "integrity": "sha512-M8wpPgR9UJ8MiRGjppvx9uWJfLV7A/T+/rL8s/y3QG3u0c2/YZgff3d6SuimKRIhcYnWg5fTfDMlz2E6seUW8Q==", + "version": "3.5.34", + "resolved": "https://registry.npmjs.org/@vue/compiler-sfc/-/compiler-sfc-3.5.34.tgz", + "integrity": "sha512-D/ihr6uZeIt6r+pVZf46RWT1fAsLFMbUP7k8G1VkiiWexriED9GrX3echHd4Abbt17zjlfiFJ8z7a3BxZOPNjg==", "dev": true, "license": "MIT", "dependencies": { - "@babel/parser": "^7.29.2", - "@vue/compiler-core": "3.5.31", - "@vue/compiler-dom": "3.5.31", - "@vue/compiler-ssr": "3.5.31", - "@vue/shared": "3.5.31", + "@babel/parser": "^7.29.3", + "@vue/compiler-core": "3.5.34", + "@vue/compiler-dom": "3.5.34", + "@vue/compiler-ssr": "3.5.34", + "@vue/shared": "3.5.34", "estree-walker": "^2.0.2", "magic-string": "^0.30.21", - "postcss": "^8.5.8", + "postcss": "^8.5.14", "source-map-js": "^1.2.1" } }, "node_modules/@vue/compiler-ssr": { - "version": "3.5.31", - "resolved": "https://registry.npmjs.org/@vue/compiler-ssr/-/compiler-ssr-3.5.31.tgz", - "integrity": "sha512-h0xIMxrt/LHOvJKMri+vdYT92BrK3HFLtDqq9Pr/lVVfE4IyKZKvWf0vJFW10Yr6nX02OR4MkJwI0c1HDa1hog==", + "version": "3.5.34", + "resolved": "https://registry.npmjs.org/@vue/compiler-ssr/-/compiler-ssr-3.5.34.tgz", + "integrity": "sha512-cDtTHKibkThKGHH1SP+WdccquNRYQDFH6rRjQCqT9G2ltFAfoR5pUftpab/z+aM5mW9HLLVQW7hfKKQe/1GBeQ==", "dev": true, "license": "MIT", "dependencies": { - "@vue/compiler-dom": "3.5.31", - "@vue/shared": "3.5.31" + "@vue/compiler-dom": "3.5.34", + "@vue/shared": "3.5.34" } }, "node_modules/@vue/devtools-api": { @@ -1404,57 +1404,57 @@ } }, "node_modules/@vue/reactivity": { - "version": "3.5.31", - "resolved": "https://registry.npmjs.org/@vue/reactivity/-/reactivity-3.5.31.tgz", - "integrity": "sha512-DtKXxk9E/KuVvt8VxWu+6Luc9I9ETNcqR1T1oW1gf02nXaZ1kuAx58oVu7uX9XxJR0iJCro6fqBLw9oSBELo5g==", + "version": "3.5.34", + "resolved": "https://registry.npmjs.org/@vue/reactivity/-/reactivity-3.5.34.tgz", + "integrity": "sha512-y9XDjCEuBp+98k+UL5dbYkh57AHU4o6cxZedOPXw3bmrZZYLQsVHguGurq7hVrPCSrQtrnz1f9dssyFr+dMXfQ==", "dev": true, "license": "MIT", "dependencies": { - "@vue/shared": "3.5.31" + "@vue/shared": "3.5.34" } }, "node_modules/@vue/runtime-core": { - "version": "3.5.31", - "resolved": "https://registry.npmjs.org/@vue/runtime-core/-/runtime-core-3.5.31.tgz", - "integrity": "sha512-AZPmIHXEAyhpkmN7aWlqjSfYynmkWlluDNPHMCZKFHH+lLtxP/30UJmoVhXmbDoP1Ng0jG0fyY2zCj1PnSSA6Q==", + "version": "3.5.34", + "resolved": "https://registry.npmjs.org/@vue/runtime-core/-/runtime-core-3.5.34.tgz", + "integrity": "sha512-mKeBYvu8tcMSLhypAHBmriUFfWXKTCF/23Z4jiCoYK3UtWepkliViNLuR90V9XOyD62mUxs9p1jsrpK3CCGIzw==", "dev": true, "license": "MIT", "dependencies": { - "@vue/reactivity": "3.5.31", - "@vue/shared": "3.5.31" + "@vue/reactivity": "3.5.34", + "@vue/shared": "3.5.34" } }, "node_modules/@vue/runtime-dom": { - "version": "3.5.31", - "resolved": "https://registry.npmjs.org/@vue/runtime-dom/-/runtime-dom-3.5.31.tgz", - "integrity": "sha512-xQJsNRmGPeDCJq/u813tyonNgWBFjzfVkBwDREdEWndBnGdHLHgkwNBQxLtg4zDrzKTEcnikUy1UUNecb3lJ6g==", + "version": "3.5.34", + "resolved": "https://registry.npmjs.org/@vue/runtime-dom/-/runtime-dom-3.5.34.tgz", + "integrity": "sha512-e8kZzERmCwUnBRVsgSQlAfrfU2rGoy0FFKPBXSlfEjc/O3KfA7QP0t1/2ZylrbchjmIKB4dPTd07A6WPr0eOrg==", "dev": true, "license": "MIT", "dependencies": { - "@vue/reactivity": "3.5.31", - "@vue/runtime-core": "3.5.31", - "@vue/shared": "3.5.31", + "@vue/reactivity": "3.5.34", + "@vue/runtime-core": "3.5.34", + "@vue/shared": "3.5.34", "csstype": "^3.2.3" } }, "node_modules/@vue/server-renderer": { - "version": "3.5.31", - "resolved": "https://registry.npmjs.org/@vue/server-renderer/-/server-renderer-3.5.31.tgz", - "integrity": "sha512-GJuwRvMcdZX/CriUnyIIOGkx3rMV3H6sOu0JhdKbduaeCji6zb60iOGMY7tFoN24NfsUYoFBhshZtGxGpxO4iA==", + "version": "3.5.34", + "resolved": "https://registry.npmjs.org/@vue/server-renderer/-/server-renderer-3.5.34.tgz", + "integrity": "sha512-nHxmJoTrKsmrkbILRhkC9gY1G3moZbJTqCzDd7DOOzG5KH9oeJ0Unqrff5f9v0pW//jES05ZkJcNtfE8JjOIew==", "dev": true, "license": "MIT", "dependencies": { - "@vue/compiler-ssr": "3.5.31", - "@vue/shared": "3.5.31" + "@vue/compiler-ssr": "3.5.34", + "@vue/shared": "3.5.34" }, "peerDependencies": { - "vue": "3.5.31" + "vue": "3.5.34" } }, "node_modules/@vue/shared": { - "version": "3.5.31", - "resolved": "https://registry.npmjs.org/@vue/shared/-/shared-3.5.31.tgz", - "integrity": "sha512-nBxuiuS9Lj5bPkPbWogPUnjxxWpkRniX7e5UBQDWl6Fsf4roq9wwV+cR7ezQ4zXswNvPIlsdj1slcLB7XCsRAw==", + "version": "3.5.34", + "resolved": "https://registry.npmjs.org/@vue/shared/-/shared-3.5.34.tgz", + "integrity": "sha512-24uqU4OIiX29ryC3MeWid/Xf2fa2EFRUVLb77nRhk+UrTVrh/XiGtFAFmJBAtBRbjwNdsPRP+jj/OL27Eg1NDA==", "dev": true, "license": "MIT" }, @@ -2050,9 +2050,9 @@ "license": "ISC" }, "node_modules/postcss": { - "version": "8.5.8", - "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.5.8.tgz", - "integrity": "sha512-OW/rX8O/jXnm82Ey1k44pObPtdblfiuWnrd8X7GJ7emImCOstunGbXUpp7HdBrFQX6rJzn3sPT397Wp5aCwCHg==", + "version": "8.5.14", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.5.14.tgz", + "integrity": "sha512-SoSL4+OSEtR99LHFZQiJLkT59C5B1amGO1NzTwj7TT1qCUgUO6hxOvzkOYxD+vMrXBM3XJIKzokoERdqQq/Zmg==", "dev": true, "funding": [ { @@ -2487,17 +2487,17 @@ } }, "node_modules/vue": { - "version": "3.5.31", - "resolved": "https://registry.npmjs.org/vue/-/vue-3.5.31.tgz", - "integrity": "sha512-iV/sU9SzOlmA/0tygSmjkEN6Jbs3nPoIPFhCMLD2STrjgOU8DX7ZtzMhg4ahVwf5Rp9KoFzcXeB1ZrVbLBp5/Q==", + "version": "3.5.34", + "resolved": "https://registry.npmjs.org/vue/-/vue-3.5.34.tgz", + "integrity": "sha512-WdLBG9gm02OgJIG9axd5Hpx0TFLdzVgfG2evFFu8Rur5O/IoGc5cMjnjh3tPL6GnRGsYvUhBSKVPYVcxRKpMCA==", "dev": true, "license": "MIT", "dependencies": { - "@vue/compiler-dom": "3.5.31", - "@vue/compiler-sfc": "3.5.31", - "@vue/runtime-dom": "3.5.31", - "@vue/server-renderer": "3.5.31", - "@vue/shared": "3.5.31" + "@vue/compiler-dom": "3.5.34", + "@vue/compiler-sfc": "3.5.34", + "@vue/runtime-dom": "3.5.34", + "@vue/server-renderer": "3.5.34", + "@vue/shared": "3.5.34" }, "peerDependencies": { "typescript": "*" diff --git a/website/package.json b/website/package.json index f939cac11..a911e1cf8 100644 --- a/website/package.json +++ b/website/package.json @@ -10,7 +10,7 @@ }, "devDependencies": { "vitepress": "^1.5.0", - "vue": "^3.5.31" + "vue": "^3.5.34" }, "dependencies": { "markdown-it-container": "^4.0.0" From 033c3e9237ea490046384deb6fc6cc0fe7d1b304 Mon Sep 17 00:00:00 2001 From: "Jacob Nardella (Swofty)" Date: Thu, 14 May 2026 23:31:16 +1000 Subject: [PATCH 014/113] build: declare root repositories so lombok plugin resolves The root project applies io.freefair.lombok which needs to resolve org.projectlombok:lombok at the root, but only subprojects had repositories declared. Adding the same repository block at root. --- build.gradle.kts | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/build.gradle.kts b/build.gradle.kts index f80468c61..8e4ac2cf5 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -14,6 +14,14 @@ version = "1.0" val libsCatalog: VersionCatalog = extensions.getByType().named("libs") +repositories { + mavenCentral() + mavenLocal() + maven("https://repo.viaversion.com") + maven("https://jitpack.io") + maven("https://repo.lucko.me/") +} + subprojects { apply(plugin = "java") apply(plugin = "java-library") From cce49ea204e17b0be1d0b957cdd65d6440c72da6 Mon Sep 17 00:00:00 2001 From: "Jacob Nardella (Swofty)" Date: Thu, 14 May 2026 23:42:37 +1000 Subject: [PATCH 015/113] refactor(tab): TablistSkinRegistry now wraps PlayerSkin Closes #715. Internally constructs a Minestom PlayerSkin from the embedded texture/signature pair, exposing it via getSkin() so callers can pass it around as a first-class value rather than juggling two parallel strings. Kept getTexture()/getSignature() so existing call sites in TablistManager keep working unchanged. --- .../swofty/commons/skyblock/item/ItemType.java | 8 ++++---- .../swofty/type/generic/tab/TablistManager.java | 5 +++-- .../type/generic/tab/TablistSkinRegistry.java | 15 +++++++++++---- 3 files changed, 18 insertions(+), 10 deletions(-) diff --git a/commons/src/generated/java/net/swofty/commons/skyblock/item/ItemType.java b/commons/src/generated/java/net/swofty/commons/skyblock/item/ItemType.java index 457d7a638..0021effb6 100644 --- a/commons/src/generated/java/net/swofty/commons/skyblock/item/ItemType.java +++ b/commons/src/generated/java/net/swofty/commons/skyblock/item/ItemType.java @@ -902,15 +902,15 @@ public enum ItemType { DIAMOND_BLOCK(Material.DIAMOND_BLOCK, Rarity.COMMON), - DIAMOND_BOOTS(Material.DIAMOND_BOOTS, Rarity.RARE), + DIAMOND_BOOTS(Material.DIAMOND_BOOTS, Rarity.COMMON), - DIAMOND_CHESTPLATE(Material.DIAMOND_CHESTPLATE, Rarity.RARE), + DIAMOND_CHESTPLATE(Material.DIAMOND_CHESTPLATE, Rarity.COMMON), - DIAMOND_HELMET(Material.DIAMOND_HELMET, Rarity.RARE), + DIAMOND_HELMET(Material.DIAMOND_HELMET, Rarity.COMMON), DIAMOND_HOE(Material.DIAMOND_HOE, Rarity.COMMON), - DIAMOND_LEGGINGS(Material.DIAMOND_LEGGINGS, Rarity.RARE), + DIAMOND_LEGGINGS(Material.DIAMOND_LEGGINGS, Rarity.COMMON), DIAMOND_MAGMAFISH(Material.PLAYER_HEAD, Rarity.COMMON), diff --git a/type.generic/src/main/java/net/swofty/type/generic/tab/TablistManager.java b/type.generic/src/main/java/net/swofty/type/generic/tab/TablistManager.java index 5762a885d..75138cba8 100644 --- a/type.generic/src/main/java/net/swofty/type/generic/tab/TablistManager.java +++ b/type.generic/src/main/java/net/swofty/type/generic/tab/TablistManager.java @@ -69,10 +69,11 @@ public void runScheduler(Scheduler scheduler) { String fakeProfileName = getFakeProfileName(slotIndex); List properties = new ArrayList<>(); + net.minestom.server.entity.PlayerSkin skin = entry.registry().getSkin(); properties.add(new PlayerInfoUpdatePacket.Property( "textures", - entry.registry().getTexture(), - entry.registry().getSignature())); + skin.textures(), + skin.signature())); if (cache.createdTeams.add(teamName)) { TeamsPacket teamPacket = new TeamsPacket(teamName, new TeamsPacket.CreateTeamAction( diff --git a/type.generic/src/main/java/net/swofty/type/generic/tab/TablistSkinRegistry.java b/type.generic/src/main/java/net/swofty/type/generic/tab/TablistSkinRegistry.java index ff8d722c2..562718d4f 100644 --- a/type.generic/src/main/java/net/swofty/type/generic/tab/TablistSkinRegistry.java +++ b/type.generic/src/main/java/net/swofty/type/generic/tab/TablistSkinRegistry.java @@ -1,6 +1,7 @@ package net.swofty.type.generic.tab; import lombok.Getter; +import net.minestom.server.entity.PlayerSkin; @Getter public enum TablistSkinRegistry { @@ -12,11 +13,17 @@ public enum TablistSkinRegistry { ORANGE("ewogICJ0aW1lc3RhbXAiIDogMTYwMjg1MDU1NTI0NCwKICAicHJvZmlsZUlkIiA6ICIwZjczMDA3NjEyNGU0NGM3YWYxMTE1NDY5YzQ5OTY3OSIsCiAgInByb2ZpbGVOYW1lIiA6ICJPcmVfTWluZXIxMjMiLAogICJzaWduYXR1cmVSZXF1aXJlZCIgOiB0cnVlLAogICJ0ZXh0dXJlcyIgOiB7CiAgICAiU0tJTiIgOiB7CiAgICAgICJ1cmwiIDogImh0dHA6Ly90ZXh0dXJlcy5taW5lY3JhZnQubmV0L3RleHR1cmUvOTEzMmIxYzY5NzQxMzEwM2QxNjkyN2IyMTRkYTY5MmY3ZmZmZjg1MjdkYThkMzg2NDg1ZThkOGZkMmUyYTNiOSIKICAgIH0KICB9Cn0=", "dY6A5XFXhA5wF9D5hROJmUnyBt8eYTGIB2i6W1+ffLfT7uebBbFw8ucafgWM6nFEzZ1hhdNRm6oFe0D9DLAedvo8ZY6yQklxtZ56U3hQUyiWiyQLHQk62JyFN2024cDhgt7XIvPGWIlsWMjHXYXxV5xA04JoHb+OqyTM64QCZa0SM0E5Kxq3vXs3aMLOC14XPkWxMMFGsUOccIDgIujEx8c1tZDzBUuJH/+KVS5GKrx/YsqNTJk7q1qOVTFXOtCCnvoIG3A6YMn5i2x162PUIxXyQK9aDk+DJs9zig/QhEr9coaOyoRUR9eRuHREsh/A18Fba7wSK7XPp+9XCZy4pPYfUEOmVWWzsMVPyG9UYwh79fM8r2zAcZIZdY3PqfbqbGftluQDVEKNfWRq79ZXuxLKIHHLeLzMNJCx1b0ud6nK0lER/1fvcNy5DRYMmH+GP1iW3+xcT29MYSPT+QTn27V24nrgG4vljDA7HhhQ5zJVMN/k2kB3L8wbdj8WYg2YoDWR2y+DMDsxazhXVFPzMjz55DHRnKBsygn1TTZzqNnBWYeDnh638TyYGp1Z12ATyRvT0XzjTPoWknNQaG8azz/XW7SOH9B2bL/lsFZ0pwoY6HwaccvjWjJoMc7cKlsR1LkIUIjyFq17GYrXfFeSRwR7pYFobHT/IfcxT5IHmkY="), ; - private final String texture; - private final String signature; + private final PlayerSkin skin; TablistSkinRegistry(String texture, String signature) { - this.texture = texture; - this.signature = signature; + this.skin = new PlayerSkin(texture, signature); + } + + public String getTexture() { + return skin.textures(); + } + + public String getSignature() { + return skin.signature(); } } From d842ecd9a9f6f217fc4e62ca01049f24f270d99c Mon Sep 17 00:00:00 2001 From: "Jacob Nardella (Swofty)" Date: Thu, 14 May 2026 23:44:55 +1000 Subject: [PATCH 016/113] feat(data): add safe lookups to mitigate DataHandler race MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Refs #742. The throwing getUser(UUID) is racy when a downstream event fires between AsyncPlayerConfigurationEvent and the moment the loader writes the entry into userCache — a high-latency rejoin reliably hits the gap. Adds three Optional-returning escape hatches: - findUser(UUID/Player) for code paths that should treat 'not loaded yet' as a normal state rather than an exception - awaitUser(UUID, timeoutMillis) which polls with exponential backoff (1ms → 16ms) up to the deadline before giving up - findHypixelUser / awaitHypixelUser typed wrappers on the subclass Also simplified the two getUser variants to share a single null-coalesce instead of try/catch as control flow. --- .../swofty/type/generic/data/DataHandler.java | 45 ++++++++++++++++++- .../type/generic/data/HypixelDataHandler.java | 15 +++++-- 2 files changed, 55 insertions(+), 5 deletions(-) diff --git a/type.generic/src/main/java/net/swofty/type/generic/data/DataHandler.java b/type.generic/src/main/java/net/swofty/type/generic/data/DataHandler.java index 862f4e7a4..eecd31351 100644 --- a/type.generic/src/main/java/net/swofty/type/generic/data/DataHandler.java +++ b/type.generic/src/main/java/net/swofty/type/generic/data/DataHandler.java @@ -7,8 +7,10 @@ import org.jetbrains.annotations.Nullable; import java.util.Map; +import java.util.Optional; import java.util.UUID; import java.util.concurrent.ConcurrentHashMap; +import java.util.concurrent.locks.LockSupport; @Getter public abstract class DataHandler { @@ -23,12 +25,51 @@ protected DataHandler() {} public Datapoint getDatapoint(String key) { return this.datapoints.get(key); } public static @NonNull DataHandler getUser(UUID uuid) { - if (!userCache.containsKey(uuid)) throw new RuntimeException("User " + uuid + " does not exist!"); - return userCache.get(uuid); + DataHandler handler = userCache.get(uuid); + if (handler == null) throw new RuntimeException("User " + uuid + " does not exist!"); + return handler; } public static DataHandler getUser(HypixelPlayer player) { return getUser(player.getUuid()); } + /** + * Non-throwing lookup. Prefer this in code paths that may run before + * {@code ActionPlayerDataLoad} has populated the cache, e.g. early + * disconnect handling or events flagged {@code requireDataLoaded = false}. + */ + public static Optional findUser(UUID uuid) { + return Optional.ofNullable(userCache.get(uuid)); + } + + public static Optional findUser(HypixelPlayer player) { + return findUser(player.getUuid()); + } + + /** + * Brief polling wait for the cache entry to appear. Addresses the race + * where a downstream listener fires between {@code AsyncPlayerConfiguration} + * and the moment {@code ActionPlayerDataLoad} writes into {@code userCache}. + * Returns empty if the data is still missing after the timeout. + */ + public static Optional awaitUser(UUID uuid, long timeoutMillis) { + DataHandler handler = userCache.get(uuid); + if (handler != null) return Optional.of(handler); + + final long deadline = System.nanoTime() + timeoutMillis * 1_000_000L; + long sleepNanos = 1_000_000L; // 1ms, grows up to ~16ms + while (System.nanoTime() < deadline) { + LockSupport.parkNanos(sleepNanos); + if (Thread.currentThread().isInterrupted()) { + Thread.currentThread().interrupt(); + return Optional.empty(); + } + handler = userCache.get(uuid); + if (handler != null) return Optional.of(handler); + sleepNanos = Math.min(sleepNanos * 2, 16_000_000L); + } + return Optional.empty(); + } + public abstract DataHandler fromDocument(Document document); public abstract Document toDocument(); public abstract void runOnLoad(HypixelPlayer player); diff --git a/type.generic/src/main/java/net/swofty/type/generic/data/HypixelDataHandler.java b/type.generic/src/main/java/net/swofty/type/generic/data/HypixelDataHandler.java index 4b4740c26..c869e598f 100644 --- a/type.generic/src/main/java/net/swofty/type/generic/data/HypixelDataHandler.java +++ b/type.generic/src/main/java/net/swofty/type/generic/data/HypixelDataHandler.java @@ -32,12 +32,21 @@ public class HypixelDataHandler extends DataHandler { public HypixelDataHandler(UUID uuid) { super(uuid); } public static HypixelDataHandler getUser(UUID uuid) { - if (!userCache.containsKey(uuid)) throw new RuntimeException("User " + uuid + " does not exist!"); - return (HypixelDataHandler) userCache.get(uuid); + HypixelDataHandler handler = (HypixelDataHandler) userCache.get(uuid); + if (handler == null) throw new RuntimeException("User " + uuid + " does not exist!"); + return handler; } public static @Nullable HypixelDataHandler getUser(Player player) { - try { return getUser(player.getUuid()); } catch (Exception e) { return null; } + return (HypixelDataHandler) userCache.get(player.getUuid()); + } + + public static java.util.Optional findHypixelUser(UUID uuid) { + return java.util.Optional.ofNullable((HypixelDataHandler) userCache.get(uuid)); + } + + public static java.util.Optional awaitHypixelUser(UUID uuid, long timeoutMillis) { + return awaitUser(uuid, timeoutMillis).map(h -> (HypixelDataHandler) h); } @Override From db6c3098e4f744300a3028b953650048f7981d75 Mon Sep 17 00:00:00 2001 From: "Jacob Nardella (Swofty)" Date: Thu, 14 May 2026 23:45:32 +1000 Subject: [PATCH 017/113] build: align shadow plugin in darkauction/orchestrator with the rest MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit These two were left behind on io.github.goooler.shadow 8.1.8 while the other services moved to com.gradleup.shadow 9.4.1 (the bump in PR #770). Same group/id, same gradle DSL — keeps the build consistent and unblocks future shadow updates. --- service.darkauction/build.gradle.kts | 2 +- service.orchestrator/build.gradle.kts | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/service.darkauction/build.gradle.kts b/service.darkauction/build.gradle.kts index 44275925b..b39805d44 100644 --- a/service.darkauction/build.gradle.kts +++ b/service.darkauction/build.gradle.kts @@ -3,7 +3,7 @@ import com.github.jengelman.gradle.plugins.shadow.tasks.ShadowJar plugins { java application - id("io.github.goooler.shadow") version "8.1.8" + id("com.gradleup.shadow") version "9.4.1" } group = "net.swofty" diff --git a/service.orchestrator/build.gradle.kts b/service.orchestrator/build.gradle.kts index f06fd7367..c95a5a84e 100644 --- a/service.orchestrator/build.gradle.kts +++ b/service.orchestrator/build.gradle.kts @@ -3,7 +3,7 @@ import com.github.jengelman.gradle.plugins.shadow.tasks.ShadowJar plugins { java application - id("io.github.goooler.shadow") version "8.1.8" + id("com.gradleup.shadow") version "9.4.1" } group = "net.swofty" From 6ee40c33dc1e8f23186fe2f93bea685a8fc0ca3e Mon Sep 17 00:00:00 2001 From: "Jacob Nardella (Swofty)" Date: Thu, 14 May 2026 23:46:41 +1000 Subject: [PATCH 018/113] refactor(fishing): replace null-returning resolvers with Optional chain FishingLootResolver had three private `tryResolveX` methods that returned null on miss and a top-level resolve() that hand-checked each in sequence. Same shape repeated for findTable() and pick(). The replacement makes the chain-of-responsibility explicit: the three specialised resolvers go in SPECIAL_CATCHES and resolve() walks the stream, taking the first non-empty Optional. New callers can drop in without modifying resolve(). Same behaviour, no nulls leaking out of internal methods. Also lifted the RAW_FISH fallback into a DEFAULT_CATCH constant so it isn't reconstructed on every empty-table cast. --- .../fishing/FishingLootResolver.java | 140 ++++++++---------- 1 file changed, 63 insertions(+), 77 deletions(-) diff --git a/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/fishing/FishingLootResolver.java b/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/fishing/FishingLootResolver.java index 4a723c6e2..6ec7f6c16 100644 --- a/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/fishing/FishingLootResolver.java +++ b/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/fishing/FishingLootResolver.java @@ -8,33 +8,35 @@ import java.util.ArrayList; import java.util.Comparator; import java.util.List; +import java.util.Optional; +import java.util.function.Function; +import java.util.stream.Stream; public final class FishingLootResolver { - private FishingLootResolver() { - } - public static FishingCatchResult resolve(FishingContext context) { - FishingCatchResult questCatch = tryResolveQuestCatch(context); - if (questCatch != null) { - return questCatch; - } + private static final List>> SPECIAL_CATCHES = List.of( + FishingLootResolver::tryResolveQuestCatch, + FishingLootResolver::tryResolveTrophyFish, + FishingLootResolver::tryResolveSeaCreature + ); - FishingCatchResult trophyFish = tryResolveTrophyFish(context); - if (trophyFish != null) { - return trophyFish; - } + private static final FishingCatchResult DEFAULT_CATCH = + new FishingCatchResult(FishingCatchKind.ITEM, "RAW_FISH", null, null, 1, 5.0D, false, null); - FishingCatchResult seaCreature = tryResolveSeaCreature(context); - if (seaCreature != null) { - return seaCreature; - } + private FishingLootResolver() { + } - return resolveItem(context); + public static FishingCatchResult resolve(FishingContext context) { + return SPECIAL_CATCHES.stream() + .map(resolver -> resolver.apply(context)) + .flatMap(Optional::stream) + .findFirst() + .orElseGet(() -> resolveItem(context)); } - private static FishingCatchResult tryResolveTrophyFish(FishingContext context) { + private static Optional tryResolveTrophyFish(FishingContext context) { if (context.medium() != FishingMedium.LAVA) { - return null; + return Optional.empty(); } double bonus = getTotalStatistic(context, ItemStatistic.TROPHY_FISH_CHANCE); @@ -69,40 +71,31 @@ private static FishingCatchResult tryResolveTrophyFish(FishingContext context) { if (itemId == null) { continue; } - return new FishingCatchResult(FishingCatchKind.TROPHY_FISH, itemId, null, definition.id(), 1, 300.0D, false, null); + return Optional.of(new FishingCatchResult( + FishingCatchKind.TROPHY_FISH, itemId, null, definition.id(), 1, 300.0D, false, null)); } } - return null; + return Optional.empty(); } - private static FishingCatchResult tryResolveQuestCatch(FishingContext context) { - if (context.medium() != FishingMedium.WATER) { - return null; - } - if (context.regionId() == null) { - return null; - } + private static Optional tryResolveQuestCatch(FishingContext context) { + if (context.medium() != FishingMedium.WATER) return Optional.empty(); + if (context.regionId() == null) return Optional.empty(); if (!"FISHING_OUTPOST".equals(context.regionId()) && !"FISHERMANS_HUT".equals(context.regionId())) { - return null; + return Optional.empty(); } if (!context.player().getToggles().get(DatapointToggles.Toggles.ToggleType.HAS_SPOKEN_TO_FISHERWOMAN_ENID)) { - return null; + return Optional.empty(); } if (context.player().getToggles().get(DatapointToggles.Toggles.ToggleType.HAS_UNLOCKED_SHIP)) { - return null; - } - if (context.player().getShipState().getEngine() != null) { - return null; - } - if (context.player().countItem(ItemType.RUSTY_SHIP_ENGINE) > 0) { - return null; - } - if (Math.random() * 100 > 1.0D) { - return null; + return Optional.empty(); } + if (context.player().getShipState().getEngine() != null) return Optional.empty(); + if (context.player().countItem(ItemType.RUSTY_SHIP_ENGINE) > 0) return Optional.empty(); + if (Math.random() * 100 > 1.0D) return Optional.empty(); - return new FishingCatchResult( + return Optional.of(new FishingCatchResult( FishingCatchKind.QUEST, ItemType.RUSTY_SHIP_ENGINE.name(), null, @@ -111,7 +104,7 @@ private static FishingCatchResult tryResolveQuestCatch(FishingContext context) { 15.0D, false, "You fished up a Rusty Ship Engine!" - ); + )); } private static String rollTrophyTier(FishingContext context, TrophyFishDefinition definition) { @@ -129,27 +122,20 @@ private static String rollTrophyTier(FishingContext context, TrophyFishDefinitio charmBonus = charm.level() * 2.0D; } - if (Math.random() <= (0.002D * (1 + charmBonus / 100D))) { - return "DIAMOND"; - } - if (Math.random() <= (0.02D * (1 + charmBonus / 100D))) { - return "GOLD"; - } - if (Math.random() <= (0.25D * (1 + charmBonus / 100D))) { - return "SILVER"; - } + if (Math.random() <= (0.002D * (1 + charmBonus / 100D))) return "DIAMOND"; + if (Math.random() <= (0.02D * (1 + charmBonus / 100D))) return "GOLD"; + if (Math.random() <= (0.25D * (1 + charmBonus / 100D))) return "SILVER"; return "BRONZE"; } - private static FishingCatchResult tryResolveSeaCreature(FishingContext context) { - FishingTableDefinition table = findTable(context); - if (table == null) { - return null; - } + private static Optional tryResolveSeaCreature(FishingContext context) { + Optional tableOpt = findTable(context); + if (tableOpt.isEmpty()) return Optional.empty(); + FishingTableDefinition table = tableOpt.get(); double seaCreatureChance = getTotalStatistic(context, ItemStatistic.SEA_CREATURE_CHANCE); if (context.hook() != null && context.hook().isTreasureOnly()) { - return null; + return Optional.empty(); } for (FishingTableDefinition.SeaCreatureRoll roll : table.seaCreatures()) { @@ -160,17 +146,17 @@ private static FishingCatchResult tryResolveSeaCreature(FishingContext context) double tagBonus = definition == null ? 0.0D : getTagBonus(context, definition.tags()); if (Math.random() * 100 <= roll.chance() + seaCreatureChance + tagBonus) { double skillXp = definition == null ? 0.0D : definition.skillXp(); - return new FishingCatchResult(FishingCatchKind.SEA_CREATURE, null, roll.seaCreatureId(), null, 1, skillXp, false, null); + return Optional.of(new FishingCatchResult( + FishingCatchKind.SEA_CREATURE, null, roll.seaCreatureId(), null, 1, skillXp, false, null)); } } - return null; + return Optional.empty(); } private static FishingCatchResult resolveItem(FishingContext context) { - FishingTableDefinition table = findTable(context); - if (table == null) { - return new FishingCatchResult(FishingCatchKind.ITEM, "RAW_FISH", null, null, 1, 5.0D, false, null); - } + Optional tableOpt = findTable(context); + if (tableOpt.isEmpty()) return DEFAULT_CATCH; + FishingTableDefinition table = tableOpt.get(); List pool = table.items(); double treasureChance = getTotalStatistic(context, ItemStatistic.TREASURE_CHANCE); @@ -183,45 +169,45 @@ private static FishingCatchResult resolveItem(FishingContext context) { if (!table.treasures().isEmpty() && Math.random() * 100 <= treasureChance) { pool = context.sinker() != null && context.sinker().isBayouTreasureToJunk() ? table.junk() : table.treasures(); - return pick(pool, FishingCatchKind.TREASURE); + return pick(pool, FishingCatchKind.TREASURE).orElse(DEFAULT_CATCH); } - FishingCatchResult result = pick(pool, FishingCatchKind.ITEM); - if (result != null) { - return result; - } - if (!table.junk().isEmpty()) { - return pick(table.junk(), FishingCatchKind.ITEM); - } - return new FishingCatchResult(FishingCatchKind.ITEM, "RAW_FISH", null, null, 1, 5.0D, false, null); + return pick(pool, FishingCatchKind.ITEM) + .or(() -> table.junk().isEmpty() ? Optional.empty() : pick(table.junk(), FishingCatchKind.ITEM)) + .orElse(DEFAULT_CATCH); } - private static FishingCatchResult pick(List pool, FishingCatchKind kind) { + private static Optional pick(List pool, FishingCatchKind kind) { + if (pool.isEmpty()) return Optional.empty(); + double roll = Math.random() * 100; double cursor = 0; for (FishingTableDefinition.LootEntry entry : pool) { cursor += entry.chance(); if (roll <= cursor) { - return new FishingCatchResult(kind, entry.itemId(), null, null, entry.amount(), entry.skillXp(), false, null); + return Optional.of(new FishingCatchResult( + kind, entry.itemId(), null, null, entry.amount(), entry.skillXp(), false, null)); } } - return pool.isEmpty() ? null : new FishingCatchResult(kind, pool.getFirst().itemId(), null, null, pool.getFirst().amount(), pool.getFirst().skillXp(), false, null); + FishingTableDefinition.LootEntry first = pool.getFirst(); + return Optional.of(new FishingCatchResult( + kind, first.itemId(), null, null, first.amount(), first.skillXp(), false, null)); } - private static FishingTableDefinition findTable(FishingContext context) { + private static Optional findTable(FishingContext context) { FishingTableDefinition fallback = null; for (FishingTableDefinition definition : FishingRegistry.getTables()) { if (!definition.mediums().isEmpty() && !definition.mediums().contains(context.medium())) { continue; } if (context.regionId() != null && definition.regions().contains(context.regionId())) { - return definition; + return Optional.of(definition); } if (definition.regions().isEmpty() && fallback == null) { fallback = definition; } } - return fallback; + return Optional.ofNullable(fallback); } private static double getTotalStatistic(FishingContext context, ItemStatistic statistic) { From f563a5c635f3ea2de59f7541e9e246be1e3f046a Mon Sep 17 00:00:00 2001 From: "Jacob Nardella (Swofty)" Date: Thu, 14 May 2026 23:48:29 +1000 Subject: [PATCH 019/113] fix(skyblock): cancel item drops while in launchpad Closes #571. The launchpad animation flips player.isInLaunchpad() on when a player steps on a slime block and back off when the bezier trajectory completes. ActionItemDrop already cancelled drops with an open inventory; this extends the same guard to in-flight launchpad warps so items can't be permanently lost mid-transfer. --- .../skyblockgeneric/event/actions/item/ActionItemDrop.java | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/event/actions/item/ActionItemDrop.java b/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/event/actions/item/ActionItemDrop.java index 7f064cce1..41da19388 100644 --- a/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/event/actions/item/ActionItemDrop.java +++ b/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/event/actions/item/ActionItemDrop.java @@ -27,6 +27,11 @@ public void run(ItemDropEvent event) { return; } + if (player.isInLaunchpad()) { + event.setCancelled(true); + return; + } + boolean hideMessage = player.getToggles().get(DatapointToggles.Toggles.ToggleType.DISABLE_DROP_MESSAGES); if (!hideMessage) { From 44c11298c2f28399b17ab61aba6e6598552417a8 Mon Sep 17 00:00:00 2001 From: "Jacob Nardella (Swofty)" Date: Thu, 14 May 2026 23:50:39 +1000 Subject: [PATCH 020/113] fix(skyblock): rescue items stuck in vanilla crafting slots MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Closes #777. ActionPlayerInteractWithCrafting intercepts clicks on slots 37-40 to open the SkyBlock crafting GUI in place of the vanilla 2x2 grid. The cursor was deposited into the inventory, but anything already sitting in the slot itself was left behind — clicking it re-opened the menu without returning the item, so it stayed stuck. Now the slot is drained back to the player's inventory before the GUI opens, and the cursor-deposit short-circuits on air to avoid an extra inventory update. --- .../gui/ActionPlayerInteractWithCrafting.java | 17 ++++++++++++++--- 1 file changed, 14 insertions(+), 3 deletions(-) diff --git a/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/event/actions/player/gui/ActionPlayerInteractWithCrafting.java b/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/event/actions/player/gui/ActionPlayerInteractWithCrafting.java index 277d537ac..03586de6b 100644 --- a/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/event/actions/player/gui/ActionPlayerInteractWithCrafting.java +++ b/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/event/actions/player/gui/ActionPlayerInteractWithCrafting.java @@ -18,10 +18,21 @@ public void run(InventoryPreClickEvent event) { if (event.getSlot() < 37 || event.getSlot() > 40) return; event.setCancelled(true); - player.addAndUpdateItem(player.getInventory().getCursorItem()); - player.getInventory().setCursorItem(ItemStack.AIR); - player.getInventory().update(); + ItemStack cursor = player.getInventory().getCursorItem(); + if (!cursor.isAir()) { + player.addAndUpdateItem(cursor); + player.getInventory().setCursorItem(ItemStack.AIR); + } + + // Rescue any item already sitting in the vanilla crafting slot — see #777 + ItemStack inSlot = player.getInventory().getItemStack(event.getSlot()); + if (!inSlot.isAir()) { + player.addAndUpdateItem(inSlot); + player.getInventory().setItemStack(event.getSlot(), ItemStack.AIR); + } + + player.getInventory().update(); player.openView(new GUICrafting()); } } From a201f3897054cbb834989cf4f253b79283511f08 Mon Sep 17 00:00:00 2001 From: "Jacob Nardella (Swofty)" Date: Thu, 14 May 2026 23:52:23 +1000 Subject: [PATCH 021/113] build: declare lombok and sentry plugins with 'apply false' at root MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The configuration cache choked on serializing the lombok plugin task state at root (LombokConfig holds a DefaultConfigurableFileCollection that isn't cc-serialisable in plugin v9.1.0). Root has no Java sources, so neither plugin needs to apply there — subprojects already opt in explicitly. Same for sentry. With apply=false the cc stores and reuses cleanly, no more --no-configuration-cache workaround. --- build.gradle.kts | 12 ++---------- 1 file changed, 2 insertions(+), 10 deletions(-) diff --git a/build.gradle.kts b/build.gradle.kts index 930ab502d..1034ffc3e 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -1,8 +1,8 @@ plugins { base java - id("io.freefair.lombok") version "9.1.0" - id("io.sentry.jvm.gradle") version "6.4.0" + id("io.freefair.lombok") version "9.1.0" apply false + id("io.sentry.jvm.gradle") version "6.4.0" apply false } group = "net.swofty" @@ -10,14 +10,6 @@ version = "1.0" val libsCatalog: VersionCatalog = extensions.getByType().named("libs") -repositories { - mavenCentral() - mavenLocal() - maven("https://repo.viaversion.com") - maven("https://jitpack.io") - maven("https://repo.lucko.me/") -} - subprojects { apply(plugin = "java") apply(plugin = "java-library") From 054c9f388fc7d5ddd741c487688c82c20c269c94 Mon Sep 17 00:00:00 2001 From: "Jacob Nardella (Swofty)" Date: Thu, 14 May 2026 23:55:52 +1000 Subject: [PATCH 022/113] refactor(fishing): unify the three SeaCreatureGuide pages MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Replaces 1785 lines of near-duplicated layout code with a 168-line sealed SeaCreatureGuidePage base and three data-only subclasses totalling 982 lines. The shared chrome (header book, page navigation, sort/filter/category controls, back arrow) now lives in one place. Each page becomes 'which entries' rather than 'how to draw an entry': - pageNumber() identifies the page (1, 2, 3) - entries() returns a List, built via head(...) or block(...) helpers - Entry is a sealed interface with Head (player skull) and Block (regular material) records — adding a new render style means adding a permitted record, not touching the layout loop Previous/Next page buttons appear automatically based on pageNumber() vs the constant TOTAL_PAGES, so adding a fourth page is now a one-line change. --- .../fishing/GUI13SeaCreatureGuide.java | 319 ++++------------- .../fishing/GUI23SeaCreatureGuide.java | 325 ++++-------------- .../fishing/GUI33SeaCreatureGuide.java | 191 ++-------- .../fishing/SeaCreatureGuidePage.java | 169 +++++++++ 4 files changed, 332 insertions(+), 672 deletions(-) create mode 100644 type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/gui/inventories/fishing/SeaCreatureGuidePage.java diff --git a/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/gui/inventories/fishing/GUI13SeaCreatureGuide.java b/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/gui/inventories/fishing/GUI13SeaCreatureGuide.java index 8a2fae43d..3d266dd68 100644 --- a/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/gui/inventories/fishing/GUI13SeaCreatureGuide.java +++ b/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/gui/inventories/fishing/GUI13SeaCreatureGuide.java @@ -1,44 +1,20 @@ package net.swofty.type.skyblockgeneric.gui.inventories.fishing; -import net.minestom.server.inventory.InventoryType; import net.minestom.server.item.Material; -import net.swofty.type.generic.gui.inventory.ItemStackCreator; -import net.swofty.type.generic.gui.v2.Components; -import net.swofty.type.generic.gui.v2.DefaultState; -import net.swofty.type.generic.gui.v2.StatelessView; -import net.swofty.type.generic.gui.v2.ViewConfiguration; -import net.swofty.type.generic.gui.v2.ViewLayout; -import net.swofty.type.generic.gui.v2.context.ViewContext; -// make these actually paginated views -public class GUI13SeaCreatureGuide extends StatelessView { +import java.util.List; + +public final class GUI13SeaCreatureGuide extends SeaCreatureGuidePage { @Override - public ViewConfiguration configuration() { - return new ViewConfiguration<>("(1/3) Sea Creature Guide", InventoryType.CHEST_6_ROW); + protected int pageNumber() { + return 1; } @Override - public void layout(ViewLayout layout, DefaultState state, ViewContext ctx) { - Components.close(layout, 49); - - layout.slot(4, ItemStackCreator.getStack( - "§aSea Creature Guide", - Material.BOOK, - 1, - "§7Your guide to the creatures of the", - "§7deep! Can also be accessed with", - "§a/scg§7!", - "", - "§7Beware, Sea Creatures spawn much", - "§7less often on your private island.", - "", - "§7Your Fishing: §aLevel XVIII" - )); - layout.slot(10, ItemStackCreator.getStackHead( - "§7[Lvl 1] Squid (§f§lCommon§7)", - "32581d564f01d712255125e1f101e534217f76e3599dab7f4ae0ffe328f729eb", - 1, + protected List entries() { + return List.of( + head(10, "§7[Lvl 1] Squid (§f§lCommon§7)", "32581d564f01d712255125e1f101e534217f76e3599dab7f4ae0ffe328f729eb", "§9⚓ Aquatic§7, §a☮ Animal", "", "§cDrops:", @@ -50,12 +26,8 @@ public void layout(ViewLayout layout, DefaultState state, ViewCont "§7- §bWater", "", "§cStats", - "§7- Kills: §b64" - )); - layout.slot(11, ItemStackCreator.getStackHead( - "§7[Lvl 4] Sea Walker (§f§lCommon§7)", - "d88ba8bb50b79e441e47b7e452764d5fff6693779d2dadd9f7f52f98d7ea0", - 1, + "§7- Kills: §b64"), + head(11, "§7[Lvl 4] Sea Walker (§f§lCommon§7)", "d88ba8bb50b79e441e47b7e452764d5fff6693779d2dadd9f7f52f98d7ea0", "§9⚓ Aquatic§7, §2༕ Undead", "", "§cDrops:", @@ -68,12 +40,8 @@ public void layout(ViewLayout layout, DefaultState state, ViewCont "§7- §bWater", "", "§cStats", - "§7- Kills: §b64" - )); - layout.slot(12, ItemStackCreator.getStackHead( - "§7[Lvl 6] Night Squid (§f§lCommon§7)", - "32581d564f01d712255125e1f101e534217f76e3599dab7f4ae0ffe328f729eb", - 1, + "§7- Kills: §b64"), + head(12, "§7[Lvl 6] Night Squid (§f§lCommon§7)", "32581d564f01d712255125e1f101e534217f76e3599dab7f4ae0ffe328f729eb", "§9⚓ Aquatic§7, §a☮ Animal", "", "§cDrops:", @@ -87,12 +55,8 @@ public void layout(ViewLayout layout, DefaultState state, ViewCont "§7- §aFishing Skill 3", "§7- §bWater", "§7- Nighttime", - "§7- §fDark Bait" - )); - layout.slot(13, ItemStackCreator.getStackHead( - "§7[Lvl 10] Sea Guardian (§f§lCommon§7)", - "221025434045bda7025b3e514b316a4b770c6faa4ba9adb4be3809526db77f9d", - 1, + "§7- §fDark Bait"), + head(13, "§7[Lvl 10] Sea Guardian (§f§lCommon§7)", "221025434045bda7025b3e514b316a4b770c6faa4ba9adb4be3809526db77f9d", "§9⚓ Aquatic§7, §5♃ Arcane", "", "§cDrops:", @@ -105,12 +69,8 @@ public void layout(ViewLayout layout, DefaultState state, ViewCont "§7- §bWater", "", "§cStats", - "§7- Kills: §b48" - )); - layout.slot(14, ItemStackCreator.getStackHead( - "§7[Lvl 10] Frog Man (§f§lCommon§7)", - "6157f19da077a3df49b2925fb6e8b400222ba6e559e86815f9b296d9e9667dd7", - 1, + "§7- Kills: §b48"), + head(14, "§7[Lvl 10] Frog Man (§f§lCommon§7)", "6157f19da077a3df49b2925fb6e8b400222ba6e559e86815f9b296d9e9667dd7", "§9⚓ Aquatic§7, §a☮ Animal§7, §e✰ Humanoid", "", "§cDrops:", @@ -124,12 +84,8 @@ public void layout(ViewLayout layout, DefaultState state, ViewCont "§7- §dFishing Hotspot", "", "§cStats", - "§7- Kills: §b28" - )); - layout.slot(15, ItemStackCreator.getStackHead( - "§7[Lvl 8] Trash Gobbler (§f§lCommon§7)", - "18ae7046da98dcb33f3ed42f1dc41d08ac8dfa5db3a3860de5b1b5c056804187", - 1, + "§7- Kills: §b28"), + head(15, "§7[Lvl 8] Trash Gobbler (§f§lCommon§7)", "18ae7046da98dcb33f3ed42f1dc41d08ac8dfa5db3a3860de5b1b5c056804187", "§9⚓ Aquatic§7, §4Ж Arthropod", "", "§cDrops:", @@ -144,12 +100,8 @@ public void layout(ViewLayout layout, DefaultState state, ViewCont "§7- §2Backwater Bayou", "", "§cStats", - "§7- Kills: §b57" - )); - layout.slot(16, ItemStackCreator.getStackHead( - "§7[Lvl 10] Bogged (§f§lCommon§7)", - "a3b9003ba2d05562c75119b8a62185c67130e9282f7acbac4bc2824c21eb95d9", - 1, + "§7- Kills: §b57"), + head(16, "§7[Lvl 10] Bogged (§f§lCommon§7)", "a3b9003ba2d05562c75119b8a62185c67130e9282f7acbac4bc2824c21eb95d9", "§f🦴 Skeletal§7, §9⚓ Aquatic", "", "§cDrops:", @@ -159,12 +111,8 @@ public void layout(ViewLayout layout, DefaultState state, ViewCont "§cRequirements:", "§7- §aFishing Skill 5", "§7- §bWater", - "§7- §2Galatea" - )); - layout.slot(19, ItemStackCreator.getStackHead( - "§7[Lvl 7] Frozen Steve (§f§lCommon§7)", - "54690f5aa6d0e800f9b8d1890fc158b921819a81dfd7342a2170e7efc46b9ed7", - 1, + "§7- §2Galatea"), + head(19, "§7[Lvl 7] Frozen Steve (§f§lCommon§7)", "54690f5aa6d0e800f9b8d1890fc158b921819a81dfd7342a2170e7efc46b9ed7", "§9⚓ Aquatic§7, §f☃ Frozen§7, §e✰ Humanoid", "", "§cDrops:", @@ -184,12 +132,8 @@ public void layout(ViewLayout layout, DefaultState state, ViewCont "§7- §cJerry's Workshop", "", "§cStats", - "§7- Kills: §b9" - )); - layout.slot(20, ItemStackCreator.getStackHead( - "§7[Lvl 15] Dumpster Diver (§a§lUncommon§7)", - "f5c5eb5ee072c06580986d12a029e28010c1290875534810c53140bc76dabfeb", - 1, + "§7- Kills: §b9"), + head(20, "§7[Lvl 15] Dumpster Diver (§a§lUncommon§7)", "f5c5eb5ee072c06580986d12a029e28010c1290875534810c53140bc76dabfeb", "§9⚓ Aquatic§7, §e✰ Humanoid", "", "§cDrops:", @@ -206,12 +150,8 @@ public void layout(ViewLayout layout, DefaultState state, ViewCont "§7- §2Backwater Bayou", "", "§cStats", - "§7- Kills: §b38" - )); - layout.slot(21, ItemStackCreator.getStackHead( - "§7[Lvl 6] Nurse Shark (§a§lUncommon§7)", - "2067ccefba5d811f47e3e18438556b704393aafcafccedd5d0981999286f598a", - 1, + "§7- Kills: §b38"), + head(21, "§7[Lvl 6] Nurse Shark (§a§lUncommon§7)", "2067ccefba5d811f47e3e18438556b704393aafcafccedd5d0981999286f598a", "§9⚓ Aquatic§7, §a☮ Animal", "", "§cDrops:", @@ -222,12 +162,8 @@ public void layout(ViewLayout layout, DefaultState state, ViewCont "§cRequirements:", "§7- §aFishing Skill 5", "§7- §bWater", - "§7- §bFishing Festival" - )); - layout.slot(22, ItemStackCreator.getStack( - "§7[Lvl 13] Frosty (§f§lCommon§7)", - Material.CARVED_PUMPKIN, - 1, + "§7- §bFishing Festival"), + block(22, "§7[Lvl 13] Frosty (§f§lCommon§7)", Material.CARVED_PUMPKIN, "§9⚓ Aquatic§7, §f☃ Frozen§7, ⚙ Construct", "", "§cDrops:", @@ -247,12 +183,8 @@ public void layout(ViewLayout layout, DefaultState state, ViewCont "§7- §cJerry's Workshop", "", "§cStats", - "§7- Kills: §b9" - )); - layout.slot(23, ItemStackCreator.getStackHead( - "§7[Lvl 15] Mithril Grubber (§a§lUncommon§7)", - "811a1173af3bead305e6339f555662e990d5faadb87e07299fa68ca828a6d2fb", - 1, + "§7- Kills: §b9"), + head(23, "§7[Lvl 15] Mithril Grubber (§a§lUncommon§7)", "811a1173af3bead305e6339f555662e990d5faadb87e07299fa68ca828a6d2fb", "§9⚓ Aquatic§7, §4Ж Arthropod", "", "§cDrops:", @@ -264,12 +196,8 @@ public void layout(ViewLayout layout, DefaultState state, ViewCont "§cRequirements:", "§7- §aFishing Skill 6", "§7- §bWater", - "§7- §2Abandoned Quarry" - )); - layout.slot(24, ItemStackCreator.getStackHead( - "§7[Lvl 18] Wetwing (§a§lUncommon§7)", - "dbc0f7c9e926c320ba472d4a88763ef932a660c470f786ac0c04c15a78fd505f", - 1, + "§7- §2Abandoned Quarry"), + head(24, "§7[Lvl 18] Wetwing (§a§lUncommon§7)", "dbc0f7c9e926c320ba472d4a88763ef932a660c470f786ac0c04c15a78fd505f", "§9⚓ Aquatic§7, §2༕ Undead§7, §a☮ Animal", "", "§cDrops:", @@ -284,12 +212,8 @@ public void layout(ViewLayout layout, DefaultState state, ViewCont "§7- §2Galatea", "", "§cStats", - "§7- Kills: §b1" - )); - layout.slot(25, ItemStackCreator.getStackHead( - "§7[Lvl 15] Sea Witch (§a§lUncommon§7)", - "fce6604157fc4ab5591e4bcf507a749918ee9c41e357d47376e0ee7342074c90", - 1, + "§7- Kills: §b1"), + head(25, "§7[Lvl 15] Sea Witch (§a§lUncommon§7)", "fce6604157fc4ab5591e4bcf507a749918ee9c41e357d47376e0ee7342074c90", "§9⚓ Aquatic§7, §e✰ Humanoid§7, §5♃ Arcane", "", "§cDrops:", @@ -306,12 +230,8 @@ public void layout(ViewLayout layout, DefaultState state, ViewCont "§7- §bWater", "", "§cStats", - "§7- Kills: §b52" - )); - layout.slot(28, ItemStackCreator.getStack( - "§7[Lvl 9] Scarecrow (§f§lCommon§7)", - Material.CARVED_PUMPKIN, - 1, + "§7- Kills: §b52"), + block(28, "§7[Lvl 9] Scarecrow (§f§lCommon§7)", Material.CARVED_PUMPKIN, "§9⚓ Aquatic§7, §6☽ Spooky", "", "§cDrops:", @@ -323,12 +243,8 @@ public void layout(ViewLayout layout, DefaultState state, ViewCont "§cRequirements:", "§7- §aFishing Skill 9", "§7- §bWater", - "§7- §6Spooky Festival" - )); - layout.slot(29, ItemStackCreator.getStack( - "§7[Lvl 15] Sea Archer (§a§lUncommon§7)", - Material.SKELETON_SKULL, - 1, + "§7- §6Spooky Festival"), + block(29, "§7[Lvl 15] Sea Archer (§a§lUncommon§7)", Material.SKELETON_SKULL, "§9⚓ Aquatic§7, §f🦴 Skeletal", "", "§cDrops:", @@ -342,12 +258,8 @@ public void layout(ViewLayout layout, DefaultState state, ViewCont "§7- §bWater", "", "§cStats", - "§7- Kills: §b48" - )); - layout.slot(30, ItemStackCreator.getStackHead( - "§7[Lvl 8] Tadgang (§9§lRare§7)", - "1608d86ffb297bf93b7190d24bc3b2dc094f8086740f7541a752fbe661f175fc", - 1, + "§7- Kills: §b48"), + head(30, "§7[Lvl 8] Tadgang (§9§lRare§7)", "1608d86ffb297bf93b7190d24bc3b2dc094f8086740f7541a752fbe661f175fc", "§9⚓ Aquatic§7, §a☮ Animal", "", "§cDrops:", @@ -363,12 +275,8 @@ public void layout(ViewLayout layout, DefaultState state, ViewCont "§7- §2Galatea", "", "§cStats", - "§7- Kills: §b1" - )); - layout.slot(31, ItemStackCreator.getStackHead( - "§7[Lvl 10] Oasis Sheep (§a§lUncommon§7)", - "292df216ecd27624ac771bacfbfe006e1ed84a79e9270be0f88e9c8791d1ece4", - 1, + "§7- Kills: §b1"), + head(31, "§7[Lvl 10] Oasis Sheep (§a§lUncommon§7)", "292df216ecd27624ac771bacfbfe006e1ed84a79e9270be0f88e9c8791d1ece4", "§9⚓ Aquatic§7, §a☮ Animal", "", "§cDrops:", @@ -381,12 +289,8 @@ public void layout(ViewLayout layout, DefaultState state, ViewCont "§cRequirements:", "§7- §aFishing Skill 10", "§7- §bWater", - "§7- §bOasis" - )); - layout.slot(32, ItemStackCreator.getStackHead( - "§7[Lvl 10] Oasis Rabbit (§a§lUncommon§7)", - "b50459bcb08db5ce93e021079c1cfc038c9ebe7ad9a149516efe4d5ee8afb59f", - 1, + "§7- §bOasis"), + head(32, "§7[Lvl 10] Oasis Rabbit (§a§lUncommon§7)", "b50459bcb08db5ce93e021079c1cfc038c9ebe7ad9a149516efe4d5ee8afb59f", "§9⚓ Aquatic§7, §a☮ Animal", "", "§cDrops:", @@ -399,12 +303,8 @@ public void layout(ViewLayout layout, DefaultState state, ViewCont "§cRequirements:", "§7- §aFishing Skill 10", "§7- §bWater", - "§7- §bOasis" - )); - layout.slot(33, ItemStackCreator.getStackHead( - "§7[Lvl 10] Banshee (§9§lRare§7)", - "30ccc3c9a06de657b98f881e23a57ecaeb252c364ddb7b92564f5ed2b8087e3b", - 1, + "§7- §bOasis"), + head(33, "§7[Lvl 10] Banshee (§9§lRare§7)", "30ccc3c9a06de657b98f881e23a57ecaeb252c364ddb7b92564f5ed2b8087e3b", "§9⚓ Aquatic§7, §e✰ Humanoid", "", "§cDrops:", @@ -422,12 +322,8 @@ public void layout(ViewLayout layout, DefaultState state, ViewCont "§7- §2Backwater Bayou", "", "§cStats", - "§7- Kills: §b22" - )); - layout.slot(34, ItemStackCreator.getStackHead( - "§7[Lvl 20] Blue Shark (§9§lRare§7)", - "381e1d06e5f0654a682a3264905b5dc4b8e7b613ab6697ac45f2e0da3bc9b4fd", - 1, + "§7- Kills: §b22"), + head(34, "§7[Lvl 20] Blue Shark (§9§lRare§7)", "381e1d06e5f0654a682a3264905b5dc4b8e7b613ab6697ac45f2e0da3bc9b4fd", "§9⚓ Aquatic§7, §a☮ Animal", "", "§cDrops:", @@ -438,12 +334,8 @@ public void layout(ViewLayout layout, DefaultState state, ViewCont "§cRequirements:", "§7- §aFishing Skill 10", "§7- §bWater", - "§7- §bFishing Festival" - )); - layout.slot(37, ItemStackCreator.getStackHead( - "§7[Lvl 30] Snapping Turtle (§9§lRare§7)", - "e08fc1ae87a7035d32b0b0da58de4801463aaf8b238618024aacb0c515ae3bba", - 1, + "§7- §bFishing Festival"), + head(37, "§7[Lvl 30] Snapping Turtle (§9§lRare§7)", "e08fc1ae87a7035d32b0b0da58de4801463aaf8b238618024aacb0c515ae3bba", "§9⚓ Aquatic§7, §a☮ Animal", "", "§cDrops:", @@ -460,12 +352,8 @@ public void layout(ViewLayout layout, DefaultState state, ViewCont "§7- §dFishing Hotspot", "", "§cStats", - "§7- Kills: §b5" - )); - layout.slot(38, ItemStackCreator.getStackHead( - "§7[Lvl 20] Rider of the Deep (§a§lUncommon§7)", - "cfb7dbbe002f69463768113c1e925848197f59b62694ce105792dd5a52dc17a1", - 1, + "§7- Kills: §b5"), + head(38, "§7[Lvl 20] Rider of the Deep (§a§lUncommon§7)", "cfb7dbbe002f69463768113c1e925848197f59b62694ce105792dd5a52dc17a1", "§9⚓ Aquatic§7, §2༕ Undead§7, §a☮ Animal", "", "§cDrops:", @@ -482,12 +370,8 @@ public void layout(ViewLayout layout, DefaultState state, ViewCont "§7- §bWater", "", "§cStats", - "§7- Kills: §b36" - )); - layout.slot(39, ItemStackCreator.getStackHead( - "§7[Lvl 14] Ent (§5§lEpic§7)", - "30519f79e5829136c3df10b6bd727db255717c87e5c102892ef67e7f46929515", - 1, + "§7- Kills: §b36"), + head(39, "§7[Lvl 14] Ent (§5§lEpic§7)", "30519f79e5829136c3df10b6bd727db255717c87e5c102892ef67e7f46929515", "§2⸙ Woodland§7, §9⚓ Aquatic", "", "§cDrops:", @@ -500,12 +384,8 @@ public void layout(ViewLayout layout, DefaultState state, ViewCont "§cRequirements:", "§7- §aFishing Skill 12", "§7- §bWater", - "§7- §2Galatea" - )); - layout.slot(40, ItemStackCreator.getStackHead( - "§7[Lvl 21] Grinch (§a§lUncommon§7)", - "2508e4a2f88502c019652b2437b76c82fedff9091389d88118ecc673f628b547", - 1, + "§7- §2Galatea"), + head(40, "§7[Lvl 21] Grinch (§a§lUncommon§7)", "2508e4a2f88502c019652b2437b76c82fedff9091389d88118ecc673f628b547", "§9⚓ Aquatic§7, §f☃ Frozen§7, §e✰ Humanoid", "", "§cDrops:", @@ -519,12 +399,8 @@ public void layout(ViewLayout layout, DefaultState state, ViewCont "§7- §cJerry's Workshop", "", "§cStats", - "§7- Kills: §b2" - )); - layout.slot(41, ItemStackCreator.getStackHead( - "§7[Lvl 23] Catfish (§9§lRare§7)", - "e18f77331b2cab64e2b430fa8e4273e4db7f78fcdfa4b1a9a418af47375056eb", - 1, + "§7- Kills: §b2"), + head(41, "§7[Lvl 23] Catfish (§9§lRare§7)", "e18f77331b2cab64e2b430fa8e4273e4db7f78fcdfa4b1a9a418af47375056eb", "§9⚓ Aquatic§7, §a☮ Animal", "", "§cDrops:", @@ -542,12 +418,8 @@ public void layout(ViewLayout layout, DefaultState state, ViewCont "§7- §bWater", "", "§cStats", - "§7- Kills: §b26" - )); - layout.slot(42, ItemStackCreator.getStack( - "§7[Lvl 30] Fried Chicken (§f§lCommon§7)", - Material.COOKED_CHICKEN, - 1, + "§7- Kills: §b26"), + block(42, "§7[Lvl 30] Fried Chicken (§f§lCommon§7)", Material.COOKED_CHICKEN, "§c♆ Magmatic§7, §a☮ Animal", "", "§cDrops:", @@ -560,12 +432,8 @@ public void layout(ViewLayout layout, DefaultState state, ViewCont "§7- §aFishing Skill 14", "§7- §cLava", "§7- §dFishing Hotspot", - "§7- §cCrimson Isle" - )); - layout.slot(43, ItemStackCreator.getStackHead( - "§7[Lvl 25] Carrot King (§9§lRare§7)", - "b50459bcb08db5ce93e021079c1cfc038c9ebe7ad9a149516efe4d5ee8afb59f", - 1, + "§7- §cCrimson Isle"), + head(43, "§7[Lvl 25] Carrot King (§9§lRare§7)", "b50459bcb08db5ce93e021079c1cfc038c9ebe7ad9a149516efe4d5ee8afb59f", "§9⚓ Aquatic§7, §a☮ Animal", "", "§cDrops:", @@ -581,65 +449,8 @@ public void layout(ViewLayout layout, DefaultState state, ViewCont "§cRequirements:", "§7- §aFishing Skill 14", "§7- §bWater", - "§7- §fCarrot Bait" - )); - layout.slot(48, ItemStackCreator.getStack( - "§aGo Back", - Material.ARROW, - 1, - "§7To Fishing Skill" - )); - layout.slot(50, ItemStackCreator.getStack( - "§aSort", - Material.HOPPER, - 1, - "", - "§b▶ Fishing Level Req", - "§7 Alphabetical", - "§7 Mob Level", - "§7 Killed Most", - "§7 Ascending Rarity", - "§7 Descending Rarity", - "", - "§bRight-click to go backwards!", - "§eClick to switch!" - )); - layout.slot(51, ItemStackCreator.getStack( - "§aFilter", - Material.ENDER_EYE, - 1, - "", - "§f▶ All Sea Creatures", - "§7 Has Level Requirement", - "§7 Has Never Killed", - "", - "§bRight-click to go backwards!", - "§eClick to switch!" - )); - layout.slot(52, ItemStackCreator.getStack( - "§aCategory", - Material.CAULDRON, - 1, - "", - "§a▶ Any Category", - "§7 Water", - "§7 Lava", - "§7 Winter", - "§7 Spooky", - "§7 Shark", - "§7 Oasis", - "§7 Bayou", - "§7 Hotspot", - "§7 Galatea", - "", - "§bRight-click to go backwards!", - "§eClick to switch!" - )); - layout.slot(53, ItemStackCreator.getStack( - "§aNext Page", - Material.ARROW, - 1, - "§ePage 2" - )); + "§7- §fCarrot Bait") + ); } } + diff --git a/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/gui/inventories/fishing/GUI23SeaCreatureGuide.java b/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/gui/inventories/fishing/GUI23SeaCreatureGuide.java index 3a7c29f06..4c8872320 100644 --- a/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/gui/inventories/fishing/GUI23SeaCreatureGuide.java +++ b/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/gui/inventories/fishing/GUI23SeaCreatureGuide.java @@ -1,44 +1,20 @@ package net.swofty.type.skyblockgeneric.gui.inventories.fishing; -import net.minestom.server.inventory.InventoryType; import net.minestom.server.item.Material; -import net.swofty.type.generic.gui.inventory.ItemStackCreator; -import net.swofty.type.generic.gui.v2.Components; -import net.swofty.type.generic.gui.v2.DefaultState; -import net.swofty.type.generic.gui.v2.StatelessView; -import net.swofty.type.generic.gui.v2.ViewConfiguration; -import net.swofty.type.generic.gui.v2.ViewLayout; -import net.swofty.type.generic.gui.v2.context.ViewContext; -// make these actually paginated views and data-driven -public class GUI23SeaCreatureGuide extends StatelessView { +import java.util.List; + +public final class GUI23SeaCreatureGuide extends SeaCreatureGuidePage { @Override - public ViewConfiguration configuration() { - return new ViewConfiguration<>("(2/3) Sea Creature Guide", InventoryType.CHEST_6_ROW); + protected int pageNumber() { + return 2; } @Override - public void layout(ViewLayout layout, DefaultState state, ViewContext ctx) { - Components.close(layout, 49); - - layout.slot(4, ItemStackCreator.getStack( - "§aSea Creature Guide", - Material.BOOK, - 1, - "§7Your guide to the creatures of the", - "§7deep! Can also be accessed with", - "§a/scg§7!", - "", - "§7Beware, Sea Creatures spawn much", - "§7less often on your private island.", - "", - "§7Your Fishing: §aLevel XVIII" - )); - layout.slot(10, ItemStackCreator.getStackHead( - "§7[Lvl 24] Nightmare (§9§lRare§7)", - "578211e1b4d99d1c7bfda4838e48fc884c3eae376f58d932bc2f78b0a919f8e7", - 1, + protected List entries() { + return List.of( + head(10, "§7[Lvl 24] Nightmare (§9§lRare§7)", "578211e1b4d99d1c7bfda4838e48fc884c3eae376f58d932bc2f78b0a919f8e7", "§9⚓ Aquatic§7, §6☽ Spooky§7, §2༕ Undead", "", "§cDrops:", @@ -51,12 +27,8 @@ public void layout(ViewLayout layout, DefaultState state, ViewCont "§cRequirements:", "§7- §aFishing Skill 14", "§7- §bWater", - "§7- §6Spooky Festival" - )); - layout.slot(11, ItemStackCreator.getStackHead( - "§7[Lvl 35] Agarimoo (§9§lRare§7)", - "3d597f77cde32c9ac9b06f82fcf7c9cb500facc14bff166222b24be39962f0ef", - 1, + "§7- §6Spooky Festival"), + head(11, "§7[Lvl 35] Agarimoo (§9§lRare§7)", "3d597f77cde32c9ac9b06f82fcf7c9cb500facc14bff166222b24be39962f0ef", "§9⚓ Aquatic§7, §a☮ Animal", "", "§cDrops:", @@ -66,12 +38,8 @@ public void layout(ViewLayout layout, DefaultState state, ViewCont "§cRequirements:", "§7- §aFishing Skill 15", "§7- §aChumcap Bucket", - "§7- §bWater" - )); - layout.slot(12, ItemStackCreator.getStackHead( - "§7[Lvl 20] Water Worm (§9§lRare§7)", - "811a1173af3bead305e6339f555662e990d5faadb87e07299fa68ca828a6d2fb", - 1, + "§7- §bWater"), + head(12, "§7[Lvl 20] Water Worm (§9§lRare§7)", "811a1173af3bead305e6339f555662e990d5faadb87e07299fa68ca828a6d2fb", "§9⚓ Aquatic§7, §6⛏ Subterranean", "", "§cDrops:", @@ -82,12 +50,8 @@ public void layout(ViewLayout layout, DefaultState state, ViewCont "§cRequirements:", "§7- §aFishing Skill 15", "§7- §bWater", - "§7- §6Goblin Holdout" - )); - layout.slot(13, ItemStackCreator.getStackHead( - "§7[Lvl 25] Bayou Sludge (§5§lEpic§7)", - "895aeec6b842ada8669f846d65bc49762597824ab944f22f45bf3bbb941abe6c", - 1, + "§7- §6Goblin Holdout"), + head(13, "§7[Lvl 25] Bayou Sludge (§5§lEpic§7)", "895aeec6b842ada8669f846d65bc49762597824ab944f22f45bf3bbb941abe6c", "§9⚓ Aquatic§7, §a⚂ Cubic", "", "§cDrops:", @@ -108,12 +72,8 @@ public void layout(ViewLayout layout, DefaultState state, ViewCont "§7- §2Backwater Bayou", "", "§cStats", - "§7- Kills: §b23" - )); - layout.slot(14, ItemStackCreator.getStackHead( - "§7[Lvl 30] Sea Leech (§9§lRare§7)", - "811a1173af3bead305e6339f555662e990d5faadb87e07299fa68ca828a6d2fb", - 1, + "§7- Kills: §b23"), + head(14, "§7[Lvl 30] Sea Leech (§9§lRare§7)", "811a1173af3bead305e6339f555662e990d5faadb87e07299fa68ca828a6d2fb", "§9⚓ Aquatic§7, §a☮ Animal", "", "§cDrops:", @@ -131,12 +91,8 @@ public void layout(ViewLayout layout, DefaultState state, ViewCont "§7- §bWater", "", "§cStats", - "§7- Kills: §b15" - )); - layout.slot(15, ItemStackCreator.getStackHead( - "§7[Lvl 75] Fireproof Witch (§9§lRare§7)", - "fce6604157fc4ab5591e4bcf507a749918ee9c41e357d47376e0ee7342074c90", - 1, + "§7- Kills: §b15"), + head(15, "§7[Lvl 75] Fireproof Witch (§9§lRare§7)", "fce6604157fc4ab5591e4bcf507a749918ee9c41e357d47376e0ee7342074c90", "§c♆ Magmatic§7, §e✰ Humanoid§7, §5♃ Arcane", "", "§cDrops:", @@ -151,12 +107,8 @@ public void layout(ViewLayout layout, DefaultState state, ViewCont "§7- §aFishing Skill 16", "§7- §cLava", "§7- §dFishing Hotspot", - "§7- §cCrimson Isle" - )); - layout.slot(16, ItemStackCreator.getStackHead( - "§7[Lvl 21] Stridersurfer (§9§lRare§7)", - "620971f4dd71592a6065944487da2adf22987d5d0cccf6085dff7a6767d1b21a", - 1, + "§7- §cCrimson Isle"), + head(16, "§7[Lvl 21] Stridersurfer (§9§lRare§7)", "620971f4dd71592a6065944487da2adf22987d5d0cccf6085dff7a6767d1b21a", "§c♆ Magmatic§7, §2༕ Undead§7, §2⸙ Woodland", "", "§cDrops:", @@ -169,12 +121,8 @@ public void layout(ViewLayout layout, DefaultState state, ViewCont "§7- §2Galatea", "", "§cStats", - "§7- Kills: §b8" - )); - layout.slot(19, ItemStackCreator.getStackHead( - "§7[Lvl 25] Poisoned Water Worm (§9§lRare§7)", - "18ae7046da98dcb33f3ed42f1dc41d08ac8dfa5db3a3860de5b1b5c056804187", - 1, + "§7- Kills: §b8"), + head(19, "§7[Lvl 25] Poisoned Water Worm (§9§lRare§7)", "18ae7046da98dcb33f3ed42f1dc41d08ac8dfa5db3a3860de5b1b5c056804187", "§9⚓ Aquatic§7, §6⛏ Subterranean§7, §4Ж Arthropod", "", "§cDrops:", @@ -185,12 +133,8 @@ public void layout(ViewLayout layout, DefaultState state, ViewCont "§cRequirements:", "§7- §aFishing Skill 17", "§7- §bWater", - "§7- §6Goblin Holdout" - )); - layout.slot(20, ItemStackCreator.getStackHead( - "§7[Lvl 45] Guardian Defender (§5§lEpic§7)", - "221025434045bda7025b3e514b316a4b770c6faa4ba9adb4be3809526db77f9d", - 1, + "§7- §6Goblin Holdout"), + head(20, "§7[Lvl 45] Guardian Defender (§5§lEpic§7)", "221025434045bda7025b3e514b316a4b770c6faa4ba9adb4be3809526db77f9d", "§9⚓ Aquatic§7, §5♃ Arcane", "", "§cDrops:", @@ -207,12 +151,8 @@ public void layout(ViewLayout layout, DefaultState state, ViewCont "§7- §bWater", "", "§cStats", - "§7- Kills: §b12" - )); - layout.slot(21, ItemStackCreator.getStackHead( - "§7[Lvl 50] Werewolf (§5§lEpic§7)", - "ce4606c6d973a999aec1687c7e075f7d37db8185e88b844507f16b3e2b3eb690", - 1, + "§7- Kills: §b12"), + head(21, "§7[Lvl 50] Werewolf (§5§lEpic§7)", "ce4606c6d973a999aec1687c7e075f7d37db8185e88b844507f16b3e2b3eb690", "§9⚓ Aquatic§7, §6☽ Spooky§7, §a☮ Animal", "", "§cDrops:", @@ -225,12 +165,8 @@ public void layout(ViewLayout layout, DefaultState state, ViewCont "§cRequirements:", "§7- §aFishing Skill 17", "§7- §bWater", - "§7- §6Spooky Festival" - )); - layout.slot(22, ItemStackCreator.getStackHead( - "§7[Lvl 50] Tiger Shark (§5§lEpic§7)", - "ea575977e6bd0c7add94e2d8fdcc2af77e36c44d6b4c67788862a94000be6399", - 1, + "§7- §6Spooky Festival"), + head(22, "§7[Lvl 50] Tiger Shark (§5§lEpic§7)", "ea575977e6bd0c7add94e2d8fdcc2af77e36c44d6b4c67788862a94000be6399", "§9⚓ Aquatic§7, §a☮ Animal", "", "§cDrops:", @@ -242,12 +178,8 @@ public void layout(ViewLayout layout, DefaultState state, ViewCont "§cRequirements:", "§7- §aFishing Skill 18", "§7- §bWater", - "§7- §bFishing Festival" - )); - layout.slot(23, ItemStackCreator.getStackHead( - "§7[Lvl 60] Deep Sea Protector (§5§lEpic§7)", - "22bcaceeb4162f400d44743315932ac820d3119ac8986a0161a726161ccc93fc", - 1, + "§7- §bFishing Festival"), + head(23, "§7[Lvl 60] Deep Sea Protector (§5§lEpic§7)", "22bcaceeb4162f400d44743315932ac820d3119ac8986a0161a726161ccc93fc", "§9⚓ Aquatic§7, ⚙ Construct", "", "§cDrops:", @@ -264,12 +196,8 @@ public void layout(ViewLayout layout, DefaultState state, ViewCont "§7- §bWater", "", "§cStats", - "§7- Kills: §b7" - )); - layout.slot(24, ItemStackCreator.getStackHead( - "§7[Lvl §k?] §k????? (§9§lRare§7)", - "811a1173af3bead305e6339f555662e990d5faadb87e07299fa68ca828a6d2fb", - 1, + "§7- Kills: §b7"), + head(24, "§7[Lvl §k?] §k????? (§9§lRare§7)", "811a1173af3bead305e6339f555662e990d5faadb87e07299fa68ca828a6d2fb", "§c♆ Magmatic§7, §4Ж Arthropod", "", "§cDrops:", @@ -278,12 +206,8 @@ public void layout(ViewLayout layout, DefaultState state, ViewCont "§cRequirements:", "§7- §aFishing Skill 19", "§7- §cLava", - "§7- §bPrecursor Remnants" - )); - layout.slot(25, ItemStackCreator.getStackHead( - "§7[Lvl §k?] §k????? (§6§lLegendary§7)", - "6d6bcd3bea0dff1f45d808e7a8550f95106af41b6d8d18a0793e19c9255ae845", - 1, + "§7- §bPrecursor Remnants"), + head(25, "§7[Lvl §k?] §k????? (§6§lLegendary§7)", "6d6bcd3bea0dff1f45d808e7a8550f95106af41b6d8d18a0793e19c9255ae845", "§9⚓ Aquatic§7, §e✰ Humanoid", "", "§cDrops:", @@ -294,12 +218,8 @@ public void layout(ViewLayout layout, DefaultState state, ViewCont "§7- §bWater", "", "§cStats", - "§7- Kills: §b1" - )); - layout.slot(28, ItemStackCreator.getStackHead( - "§7[Lvl §k?] §k????? (§5§lEpic§7)", - "b78ef2e4cf2c41a2d14bfde9caff10219f5b1bf5b35a49eb51c6467882cb5f0", - 1, + "§7- Kills: §b1"), + head(28, "§7[Lvl §k?] §k????? (§5§lEpic§7)", "b78ef2e4cf2c41a2d14bfde9caff10219f5b1bf5b35a49eb51c6467882cb5f0", "§c♆ Magmatic§7, §4♨ Infernal", "", "§cDrops:", @@ -308,12 +228,8 @@ public void layout(ViewLayout layout, DefaultState state, ViewCont "§cRequirements:", "§7- §aFishing Skill 20", "§7- §cLava", - "§7- §cMagma Fields" - )); - layout.slot(29, ItemStackCreator.getStackHead( - "§7[Lvl §k?] §k????? (§6§lLegendary§7)", - "5cf6abfbc778b1fac0d6db161e74438a1b468323b6f93fa4d650e42cd0f5802a", - 1, + "§7- §cMagma Fields"), + head(29, "§7[Lvl §k?] §k????? (§6§lLegendary§7)", "5cf6abfbc778b1fac0d6db161e74438a1b468323b6f93fa4d650e42cd0f5802a", "§9⚓ Aquatic§7, §a☮ Animal", "", "§cDrops:", @@ -325,12 +241,8 @@ public void layout(ViewLayout layout, DefaultState state, ViewCont "§7- §2Backwater Bayou", "", "§cStats", - "§7- Kills: §b6" - )); - layout.slot(30, ItemStackCreator.getStackHead( - "§7[Lvl §k?] §k????? (§6§lLegendary§7)", - "46c15b527e4872249c91797435521cb77651b567e57518304f5f131e49ded652", - 1, + "§7- Kills: §b6"), + head(30, "§7[Lvl §k?] §k????? (§6§lLegendary§7)", "46c15b527e4872249c91797435521cb77651b567e57518304f5f131e49ded652", "§9⚓ Aquatic§7, §f🦴 Skeletal§7, §5♃ Arcane", "", "§cDrops:", @@ -339,12 +251,8 @@ public void layout(ViewLayout layout, DefaultState state, ViewCont "§cRequirements:", "§7- §aFishing Skill 20", "§7- §bWater", - "§7- §2Galatea" - )); - layout.slot(31, ItemStackCreator.getStackHead( - "§7[Lvl §k?] §k????? (§6§lLegendary§7)", - "6c9bc01f299f98d565a27ba10a1293915ae8beeefb8a67845e2331dbe6fd6fd6", - 1, + "§7- §2Galatea"), + head(31, "§7[Lvl §k?] §k????? (§6§lLegendary§7)", "6c9bc01f299f98d565a27ba10a1293915ae8beeefb8a67845e2331dbe6fd6fd6", "§9⚓ Aquatic§7, §6☽ Spooky§7, §5♃ Arcane", "", "§cDrops:", @@ -353,12 +261,8 @@ public void layout(ViewLayout layout, DefaultState state, ViewCont "§cRequirements:", "§7- §aFishing Skill 21", "§7- §bWater", - "§7- §6Spooky Festival" - )); - layout.slot(32, ItemStackCreator.getStackHead( - "§7[Lvl §k?] §k????? (§5§lEpic§7)", - "74e9c6e98582ffd8ff8feb3322cd1849c43fb16b158abb11ca7b42eda7743eb", - 1, + "§7- §6Spooky Festival"), + head(32, "§7[Lvl §k?] §k????? (§5§lEpic§7)", "74e9c6e98582ffd8ff8feb3322cd1849c43fb16b158abb11ca7b42eda7743eb", "§c♆ Magmatic§7, §2༕ Undead", "", "§cDrops:", @@ -367,12 +271,8 @@ public void layout(ViewLayout layout, DefaultState state, ViewCont "§cRequirements:", "§7- §aFishing Skill 22", "§7- §cLava", - "§7- §cMagma Fields" - )); - layout.slot(33, ItemStackCreator.getStackHead( - "§7[Lvl §k?] §k????? (§6§lLegendary§7)", - "58be05cfae2c6a7d47da2ce88b3e00c72a145cc3218f041b3dd5bd5fa5ca827", - 1, + "§7- §cMagma Fields"), + head(33, "§7[Lvl §k?] §k????? (§6§lLegendary§7)", "58be05cfae2c6a7d47da2ce88b3e00c72a145cc3218f041b3dd5bd5fa5ca827", "§9⚓ Aquatic§7, §2༕ Undead§7, §6⛏ Subterranean", "", "§cDrops:", @@ -383,12 +283,8 @@ public void layout(ViewLayout layout, DefaultState state, ViewCont "§7- §bWater", "§7- §2Mithril Deposits", "§7- §bPrecursor Remnants", - "§7- §2Jungle" - )); - layout.slot(34, ItemStackCreator.getStackHead( - "§7[Lvl §k?] §k????? (§6§lLegendary§7)", - "de2e5865429dd2520bbc703e4a9f2f1abd5e1cc5d31b8a9acbf74b7a97c937aa", - 1, + "§7- §2Jungle"), + head(34, "§7[Lvl §k?] §k????? (§6§lLegendary§7)", "de2e5865429dd2520bbc703e4a9f2f1abd5e1cc5d31b8a9acbf74b7a97c937aa", "§9⚓ Aquatic§7, §a☮ Animal", "", "§cDrops:", @@ -397,12 +293,8 @@ public void layout(ViewLayout layout, DefaultState state, ViewCont "§cRequirements:", "§7- §aFishing Skill 24", "§7- §bWater", - "§7- §bFishing Festival" - )); - layout.slot(37, ItemStackCreator.getStackHead( - "§7[Lvl §k?] §k????? (§6§lLegendary§7)", - "4dd2d3c6d01c276226c7b0d377122e1a647b2ffb5b9b54fa98eac37bb1d09d3a", - 1, + "§7- §bFishing Festival"), + head(37, "§7[Lvl §k?] §k????? (§6§lLegendary§7)", "4dd2d3c6d01c276226c7b0d377122e1a647b2ffb5b9b54fa98eac37bb1d09d3a", "§9⚓ Aquatic§7, §f☃ Frozen§7, §e✰ Humanoid", "", "§cDrops:", @@ -414,12 +306,8 @@ public void layout(ViewLayout layout, DefaultState state, ViewCont "§7- §cJerry's Workshop", "", "§cStats", - "§7- Kills: §b1" - )); - layout.slot(38, ItemStackCreator.getStackHead( - "§7[Lvl §k?] §k????? (§6§lLegendary§7)", - "68a6194a5b217b9f5a3dfecce5f3efe6967405039b82fa0c4e8959175f32e75a", - 1, + "§7- Kills: §b1"), + head(38, "§7[Lvl §k?] §k????? (§6§lLegendary§7)", "68a6194a5b217b9f5a3dfecce5f3efe6967405039b82fa0c4e8959175f32e75a", "§9⚓ Aquatic§7, §6☽ Spooky§7, §5♃ Arcane", "", "§cDrops:", @@ -428,12 +316,8 @@ public void layout(ViewLayout layout, DefaultState state, ViewCont "§cRequirements:", "§7- §aFishing Skill 26", "§7- §bWater", - "§7- §6Spooky Festival" - )); - layout.slot(39, ItemStackCreator.getStackHead( - "§7[Lvl §k?] §k????? (§a§lUncommon§7)", - "38957d5023c937c4c41aa2412d43410bda23cf79a9f6ab36b76fef2d7c429", - 1, + "§7- §6Spooky Festival"), + head(39, "§7[Lvl §k?] §k????? (§a§lUncommon§7)", "38957d5023c937c4c41aa2412d43410bda23cf79a9f6ab36b76fef2d7c429", "§c♆ Magmatic§7, §a⚂ Cubic", "", "§cDrops:", @@ -445,12 +329,8 @@ public void layout(ViewLayout layout, DefaultState state, ViewCont "§7- §cCrimson Isle", "", "§cStats", - "§7- Kills: §b1" - )); - layout.slot(40, ItemStackCreator.getStackHead( - "§7[Lvl §k?] §k????? (§a§lUncommon§7)", - "47f1bc3fa91cd86cf4ba7745586d67207b58e7cf27bdf7a717780843785bf9b5", - 1, + "§7- Kills: §b1"), + head(40, "§7[Lvl §k?] §k????? (§a§lUncommon§7)", "47f1bc3fa91cd86cf4ba7745586d67207b58e7cf27bdf7a717780843785bf9b5", "§c♆ Magmatic§7, §a☮ Animal", "", "§cDrops:", @@ -459,12 +339,8 @@ public void layout(ViewLayout layout, DefaultState state, ViewCont "§cRequirements:", "§7- §aFishing Skill 28", "§7- §cLava", - "§7- §cCrimson Isle" - )); - layout.slot(41, ItemStackCreator.getStackHead( - "§7[Lvl §k?] §k????? (§9§lRare§7)", - "c2407e66c81b1443c2e7dfc4d6583eb19c622fa22f34fbf99fe6c45f76a", - 1, + "§7- §cCrimson Isle"), + head(41, "§7[Lvl §k?] §k????? (§9§lRare§7)", "c2407e66c81b1443c2e7dfc4d6583eb19c622fa22f34fbf99fe6c45f76a", "§9⚓ Aquatic§7, §f☃ Frozen§7, §e✰ Humanoid", "", "§cDrops:", @@ -476,12 +352,8 @@ public void layout(ViewLayout layout, DefaultState state, ViewCont "§7- §cJerry's Workshop", "", "§cStats", - "§7- Kills: §b2" - )); - layout.slot(42, ItemStackCreator.getStackHead( - "§7[Lvl §k?] §k????? (§9§lRare§7)", - "18ae7046da98dcb33f3ed42f1dc41d08ac8dfa5db3a3860de5b1b5c056804187", - 1, + "§7- Kills: §b2"), + head(42, "§7[Lvl §k?] §k????? (§9§lRare§7)", "18ae7046da98dcb33f3ed42f1dc41d08ac8dfa5db3a3860de5b1b5c056804187", "§c♆ Magmatic§7, §4Ж Arthropod", "", "§cDrops:", @@ -490,12 +362,8 @@ public void layout(ViewLayout layout, DefaultState state, ViewCont "§cRequirements:", "§7- §aFishing Skill 30", "§7- §cLava", - "§7- §cCrimson Isle" - )); - layout.slot(43, ItemStackCreator.getStackHead( - "§7[Lvl §k?] §k????? (§d§lMythic§7)", - "645f2c0bbfe3b8b19b7452072db69a5f59da38ff61415545156e5701e1be756d", - 1, + "§7- §cCrimson Isle"), + head(43, "§7[Lvl §k?] §k????? (§d§lMythic§7)", "645f2c0bbfe3b8b19b7452072db69a5f59da38ff61415545156e5701e1be756d", "§9⚓ Aquatic§7, §a☮ Animal§7, §d❃ Elusive", "", "§cDrops:", @@ -504,71 +372,8 @@ public void layout(ViewLayout layout, DefaultState state, ViewCont "§cRequirements:", "§7- §aFishing Skill 30", "§7- §bWater", - "§7- §2Backwater Bayou" - )); - layout.slot(45, ItemStackCreator.getStack( - "§aPrevious Page", - Material.ARROW, - 1, - "§ePage 1" - )); - layout.slot(48, ItemStackCreator.getStack( - "§aGo Back", - Material.ARROW, - 1, - "§7To Fishing Skill" - )); - layout.slot(50, ItemStackCreator.getStack( - "§aSort", - Material.HOPPER, - 1, - "", - "§b▶ Fishing Level Req", - "§7 Alphabetical", - "§7 Mob Level", - "§7 Killed Most", - "§7 Ascending Rarity", - "§7 Descending Rarity", - "", - "§bRight-click to go backwards!", - "§eClick to switch!" - )); - layout.slot(51, ItemStackCreator.getStack( - "§aFilter", - Material.ENDER_EYE, - 1, - "", - "§f▶ All Sea Creatures", - "§7 Has Level Requirement", - "§7 Has Never Killed", - "", - "§bRight-click to go backwards!", - "§eClick to switch!" - )); - layout.slot(52, ItemStackCreator.getStack( - "§aCategory", - Material.CAULDRON, - 1, - "", - "§a▶ Any Category", - "§7 Water", - "§7 Lava", - "§7 Winter", - "§7 Spooky", - "§7 Shark", - "§7 Oasis", - "§7 Bayou", - "§7 Hotspot", - "§7 Galatea", - "", - "§bRight-click to go backwards!", - "§eClick to switch!" - )); - layout.slot(53, ItemStackCreator.getStack( - "§aNext Page", - Material.ARROW, - 1, - "§ePage 3" - )); + "§7- §2Backwater Bayou") + ); } } + diff --git a/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/gui/inventories/fishing/GUI33SeaCreatureGuide.java b/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/gui/inventories/fishing/GUI33SeaCreatureGuide.java index 8d484e0c1..222ec89f9 100644 --- a/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/gui/inventories/fishing/GUI33SeaCreatureGuide.java +++ b/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/gui/inventories/fishing/GUI33SeaCreatureGuide.java @@ -1,44 +1,20 @@ package net.swofty.type.skyblockgeneric.gui.inventories.fishing; -import net.minestom.server.inventory.InventoryType; import net.minestom.server.item.Material; -import net.swofty.type.generic.gui.inventory.ItemStackCreator; -import net.swofty.type.generic.gui.v2.Components; -import net.swofty.type.generic.gui.v2.DefaultState; -import net.swofty.type.generic.gui.v2.StatelessView; -import net.swofty.type.generic.gui.v2.ViewConfiguration; -import net.swofty.type.generic.gui.v2.ViewLayout; -import net.swofty.type.generic.gui.v2.context.ViewContext; -// make these actually paginated views -public class GUI33SeaCreatureGuide extends StatelessView { +import java.util.List; + +public final class GUI33SeaCreatureGuide extends SeaCreatureGuidePage { @Override - public ViewConfiguration configuration() { - return new ViewConfiguration<>("(3/3) Sea Creature Guide", InventoryType.CHEST_6_ROW); + protected int pageNumber() { + return 3; } @Override - public void layout(ViewLayout layout, DefaultState state, ViewContext ctx) { - Components.close(layout, 49); - - layout.slot(4, ItemStackCreator.getStack( - "§aSea Creature Guide", - Material.BOOK, - 1, - "§7Your guide to the creatures of the", - "§7deep! Can also be accessed with", - "§a/scg§7!", - "", - "§7Beware, Sea Creatures spawn much", - "§7less often on your private island.", - "", - "§7Your Fishing: §aLevel XVIII" - )); - layout.slot(10, ItemStackCreator.getStackHead( - "§7[Lvl §k?] §k????? (§9§lRare§7)", - "38957d5023c937c4c41aa2412d43410bda23cf79a9f6ab36b76fef2d7c429", - 1, + protected List entries() { + return List.of( + head(10, "§7[Lvl §k?] §k????? (§9§lRare§7)", "38957d5023c937c4c41aa2412d43410bda23cf79a9f6ab36b76fef2d7c429", "§c♆ Magmatic§7, §a⚂ Cubic", "", "§cDrops:", @@ -47,12 +23,8 @@ public void layout(ViewLayout layout, DefaultState state, ViewCont "§cRequirements:", "§7- §aFishing Skill 31", "§7- §cLava", - "§7- §cCrimson Isle" - )); - layout.slot(11, ItemStackCreator.getStackHead( - "§7[Lvl §k?] §k????? (§9§lRare§7)", - "b78ef2e4cf2c41a2d14bfde9caff10219f5b1bf5b35a49eb51c6467882cb5f0", - 1, + "§7- §cCrimson Isle"), + head(11, "§7[Lvl §k?] §k????? (§9§lRare§7)", "b78ef2e4cf2c41a2d14bfde9caff10219f5b1bf5b35a49eb51c6467882cb5f0", "§c♆ Magmatic§7, §4♨ Infernal", "", "§cDrops:", @@ -61,12 +33,8 @@ public void layout(ViewLayout layout, DefaultState state, ViewCont "§cRequirements:", "§7- §aFishing Skill 33", "§7- §cLava", - "§7- §cCrimson Isle" - )); - layout.slot(12, ItemStackCreator.getStackHead( - "§7[Lvl §k?] §k????? (§9§lRare§7)", - "c63704a7fc7d437f7b923e23e9a08ae3bbe28937df4dafa9e3e8725b2ce4afa5", - 1, + "§7- §cCrimson Isle"), + head(12, "§7[Lvl §k?] §k????? (§9§lRare§7)", "c63704a7fc7d437f7b923e23e9a08ae3bbe28937df4dafa9e3e8725b2ce4afa5", "§c♆ Magmatic§7, §a☮ Animal", "", "§cDrops:", @@ -75,12 +43,8 @@ public void layout(ViewLayout layout, DefaultState state, ViewCont "§cRequirements:", "§7- §aFishing Skill 34", "§7- §cLava", - "§7- §cCrimson Isle" - )); - layout.slot(13, ItemStackCreator.getStackHead( - "§7[Lvl §k?] §k????? (§5§lEpic§7)", - "1642a06cd75ef307c1913ba7a224fb2082d8a2c5254fd1bf006125a087a9a868", - 1, + "§7- §cCrimson Isle"), + head(13, "§7[Lvl §k?] §k????? (§5§lEpic§7)", "1642a06cd75ef307c1913ba7a224fb2082d8a2c5254fd1bf006125a087a9a868", "§c♆ Magmatic§7, §e✰ Humanoid§7, §a☮ Animal", "", "§cDrops:", @@ -89,12 +53,8 @@ public void layout(ViewLayout layout, DefaultState state, ViewCont "§cRequirements:", "§7- §aFishing Skill 35", "§7- §cLava", - "§7- §cCrimson Isle" - )); - layout.slot(14, ItemStackCreator.getStackHead( - "§7[Lvl §k?] §k????? (§6§lLegendary§7)", - "b2b6074d0c9d6b89a494cf4f74158282a64ee23ba8a0725633ad70932ada1a8f", - 1, + "§7- §cCrimson Isle"), + head(14, "§7[Lvl §k?] §k????? (§6§lLegendary§7)", "b2b6074d0c9d6b89a494cf4f74158282a64ee23ba8a0725633ad70932ada1a8f", "§9⚓ Aquatic§7, §a☮ Animal", "", "§cDrops:", @@ -106,12 +66,8 @@ public void layout(ViewLayout layout, DefaultState state, ViewCont "§7- §dFishing Hotspot", "", "§cStats", - "§7- Kills: §b1" - )); - layout.slot(15, ItemStackCreator.getStack( - "§7[Lvl §k?] §k????? (§d§lMythic§7)", - Material.DRAGON_EGG, - 1, + "§7- Kills: §b1"), + block(15, "§7[Lvl §k?] §k????? (§d§lMythic§7)", Material.DRAGON_EGG, "§f☃ Frozen§7, §e⛨ Shielded§7, §d❃ Elusive", "", "§cDrops:", @@ -120,12 +76,8 @@ public void layout(ViewLayout layout, DefaultState state, ViewCont "§cRequirements:", "§7- §aFishing Skill 35", "§7- §bWater", - "§7- §cJerry's Workshop" - )); - layout.slot(16, ItemStackCreator.getStackHead( - "§7[Lvl §k?] §k????? (§d§lMythic§7)", - "32581d564f01d712255125e1f101e534217f76e3599dab7f4ae0ffe328f729eb", - 1, + "§7- §cJerry's Workshop"), + head(16, "§7[Lvl §k?] §k????? (§d§lMythic§7)", "32581d564f01d712255125e1f101e534217f76e3599dab7f4ae0ffe328f729eb", "§c♆ Magmatic§7, §d❃ Elusive§7, §a☮ Animal", "", "§cDrops:", @@ -134,12 +86,8 @@ public void layout(ViewLayout layout, DefaultState state, ViewCont "§cRequirements:", "§7- §aFishing Skill 36", "§7- §cLava", - "§7- §cCrimson Isle" - )); - layout.slot(19, ItemStackCreator.getStackHead( - "§7[Lvl §k?] §k????? (§d§lMythic§7)", - "a3f925d274ec65e002028c898e11aa9b76d6d67aa305ad9c7c69fe61cec5e664", - 1, + "§7- §cCrimson Isle"), + head(19, "§7[Lvl §k?] §k????? (§d§lMythic§7)", "a3f925d274ec65e002028c898e11aa9b76d6d67aa305ad9c7c69fe61cec5e664", "§c♆ Magmatic§7, §5♃ Arcane§7, §d❃ Elusive", "", "§cDrops:", @@ -149,12 +97,8 @@ public void layout(ViewLayout layout, DefaultState state, ViewCont "§7- §aFishing Skill 36", "§7- §cLava", "§7- §cCrimson Isle", - "§7- §cNovice Trophy Fisher" - )); - layout.slot(20, ItemStackCreator.getStackHead( - "§7[Lvl §k?] §k????? (§6§lLegendary§7)", - "55b194025806687642e2bc239895d646a6d8c193d9253b61bfce908f6ce1b84a", - 1, + "§7- §cNovice Trophy Fisher"), + head(20, "§7[Lvl §k?] §k????? (§6§lLegendary§7)", "55b194025806687642e2bc239895d646a6d8c193d9253b61bfce908f6ce1b84a", "§c♆ Magmatic§7, §a☮ Animal", "", "§cDrops:", @@ -164,12 +108,8 @@ public void layout(ViewLayout layout, DefaultState state, ViewCont "§7- §aFishing Skill 37", "§7- §cLava", "§7- §dFishing Hotspot", - "§7- §cCrimson Isle" - )); - layout.slot(21, ItemStackCreator.getStackHead( - "§7[Lvl §k?] §k????? (§d§lMythic§7)", - "f3c802e580bfefc18c4af94cceb82968b5b4aeab0d832346a633a7473a41dfac", - 1, + "§7- §cCrimson Isle"), + head(21, "§7[Lvl §k?] §k????? (§d§lMythic§7)", "f3c802e580bfefc18c4af94cceb82968b5b4aeab0d832346a633a7473a41dfac", "§9⚓ Aquatic§7, ⚙ Construct, §d❃ Elusive", "", "§cDrops:", @@ -178,12 +118,8 @@ public void layout(ViewLayout layout, DefaultState state, ViewCont "§cRequirements:", "§7- §aFishing Skill 40", "§7- §bWater", - "§7- §dFishing Hotspot" - )); - layout.slot(22, ItemStackCreator.getStackHead( - "§7[Lvl §k?] §k????? (§d§lMythic§7)", - "22bcaceeb4162f400d44743315932ac820d3119ac8986a0161a726161ccc93fc", - 1, + "§7- §dFishing Hotspot"), + head(22, "§7[Lvl §k?] §k????? (§d§lMythic§7)", "22bcaceeb4162f400d44743315932ac820d3119ac8986a0161a726161ccc93fc", "§c♆ Magmatic§7, ⚙ Construct, §d❃ Elusive", "", "§cDrops:", @@ -193,12 +129,8 @@ public void layout(ViewLayout layout, DefaultState state, ViewCont "§7- §aFishing Skill 45", "§7- §cLava", "§7- §cCrimson Isle", - "§7- §cAdept Trophy Fisher" - )); - layout.slot(23, ItemStackCreator.getStackHead( - "§7[Lvl §k?] §k????? (§d§lMythic§7)", - "a8e1fe214b71f6ea69c541a861c64bafda7bf9b85de5dd17ab2b6ccd1d32b039", - 1, + "§7- §cAdept Trophy Fisher"), + head(23, "§7[Lvl §k?] §k????? (§d§lMythic§7)", "a8e1fe214b71f6ea69c541a861c64bafda7bf9b85de5dd17ab2b6ccd1d32b039", "§c♆ Magmatic§7, §f🦴 Skeletal§7, §d❃ Elusive", "", "§cDrops:", @@ -208,65 +140,8 @@ public void layout(ViewLayout layout, DefaultState state, ViewCont "§7- §aFishing Skill 47", "§7- §cLava", "§7- §dFishing Hotspot", - "§7- §cCrimson Isle" - )); - layout.slot(45, ItemStackCreator.getStack( - "§aPrevious Page", - Material.ARROW, - 1, - "§ePage 2" - )); - layout.slot(48, ItemStackCreator.getStack( - "§aGo Back", - Material.ARROW, - 1, - "§7To Fishing Skill" - )); - layout.slot(50, ItemStackCreator.getStack( - "§aSort", - Material.HOPPER, - 1, - "", - "§b▶ Fishing Level Req", - "§7 Alphabetical", - "§7 Mob Level", - "§7 Killed Most", - "§7 Ascending Rarity", - "§7 Descending Rarity", - "", - "§bRight-click to go backwards!", - "§eClick to switch!" - )); - layout.slot(51, ItemStackCreator.getStack( - "§aFilter", - Material.ENDER_EYE, - 1, - "", - "§f▶ All Sea Creatures", - "§7 Has Level Requirement", - "§7 Has Never Killed", - "", - "§bRight-click to go backwards!", - "§eClick to switch!" - )); - layout.slot(52, ItemStackCreator.getStack( - "§aCategory", - Material.CAULDRON, - 1, - "", - "§a▶ Any Category", - "§7 Water", - "§7 Lava", - "§7 Winter", - "§7 Spooky", - "§7 Shark", - "§7 Oasis", - "§7 Bayou", - "§7 Hotspot", - "§7 Galatea", - "", - "§bRight-click to go backwards!", - "§eClick to switch!" - )); + "§7- §cCrimson Isle") + ); } } + diff --git a/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/gui/inventories/fishing/SeaCreatureGuidePage.java b/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/gui/inventories/fishing/SeaCreatureGuidePage.java new file mode 100644 index 000000000..575c71408 --- /dev/null +++ b/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/gui/inventories/fishing/SeaCreatureGuidePage.java @@ -0,0 +1,169 @@ +package net.swofty.type.skyblockgeneric.gui.inventories.fishing; + +import net.minestom.server.inventory.InventoryType; +import net.minestom.server.item.ItemStack; + +import net.minestom.server.item.Material; +import net.swofty.type.generic.gui.inventory.ItemStackCreator; +import net.swofty.type.generic.gui.v2.Components; +import net.swofty.type.generic.gui.v2.DefaultState; +import net.swofty.type.generic.gui.v2.StatelessView; +import net.swofty.type.generic.gui.v2.ViewConfiguration; +import net.swofty.type.generic.gui.v2.ViewLayout; +import net.swofty.type.generic.gui.v2.context.ViewContext; + +import java.util.List; + +/** + * Shared chrome for the 3-page sea creature guide. Subclasses only need to + * declare which page they are and which entries to show; layout, navigation, + * sort/filter/category buttons all live here. + * + * Entries are modelled as a sealed {@link Entry} hierarchy: {@code Head} for + * player heads (the common case — most creatures use one) and {@code Block} + * for the handful that render as a regular item (dragon eggs, etc.). + */ +public abstract sealed class SeaCreatureGuidePage extends StatelessView + permits GUI13SeaCreatureGuide, GUI23SeaCreatureGuide, GUI33SeaCreatureGuide { + + private static final int TOTAL_PAGES = 3; + + protected abstract int pageNumber(); + + protected abstract List entries(); + + @Override + public final ViewConfiguration configuration() { + return new ViewConfiguration<>( + "(" + pageNumber() + "/" + TOTAL_PAGES + ") Sea Creature Guide", + InventoryType.CHEST_6_ROW + ); + } + + @Override + public final void layout(ViewLayout layout, DefaultState state, ViewContext ctx) { + Components.close(layout, 49); + + layout.slot(4, ItemStackCreator.getStack( + "§aSea Creature Guide", + Material.BOOK, + 1, + "§7Your guide to the creatures of the", + "§7deep! Can also be accessed with", + "§a/scg§7!", + "", + "§7Beware, Sea Creatures spawn much", + "§7less often on your private island.", + "", + "§7Your Fishing: §aLevel XVIII" + )); + + for (Entry entry : entries()) { + layout.slot(entry.slot(), entry.render()); + } + + if (pageNumber() > 1) { + layout.slot(45, ItemStackCreator.getStack( + "§aPrevious Page", + Material.ARROW, + 1, + "§ePage " + (pageNumber() - 1) + )); + } + + layout.slot(48, ItemStackCreator.getStack( + "§aGo Back", + Material.ARROW, + 1, + "§7To Fishing Skill" + )); + + layout.slot(50, ItemStackCreator.getStack( + "§aSort", + Material.HOPPER, + 1, + "", + "§b▶ Fishing Level Req", + "§7 Alphabetical", + "§7 Mob Level", + "§7 Killed Most", + "§7 Ascending Rarity", + "§7 Descending Rarity", + "", + "§bRight-click to go backwards!", + "§eClick to switch!" + )); + + layout.slot(51, ItemStackCreator.getStack( + "§aFilter", + Material.ENDER_EYE, + 1, + "", + "§f▶ All Sea Creatures", + "§7 Has Level Requirement", + "§7 Has Never Killed", + "", + "§bRight-click to go backwards!", + "§eClick to switch!" + )); + + layout.slot(52, ItemStackCreator.getStack( + "§aCategory", + Material.CAULDRON, + 1, + "", + "§a▶ Any Category", + "§7 Water", + "§7 Lava", + "§7 Winter", + "§7 Spooky", + "§7 Shark", + "§7 Oasis", + "§7 Bayou", + "§7 Hotspot", + "§7 Galatea", + "", + "§bRight-click to go backwards!", + "§eClick to switch!" + )); + + if (pageNumber() < TOTAL_PAGES) { + layout.slot(53, ItemStackCreator.getStack( + "§aNext Page", + Material.ARROW, + 1, + "§ePage " + (pageNumber() + 1) + )); + } + } + + /** Convenience builder for a head-rendered entry. */ + protected static Entry head(int slot, String name, String texture, String... lore) { + return new Entry.Head(slot, name, texture, lore); + } + + /** Convenience builder for a material-rendered entry. */ + protected static Entry block(int slot, String name, Material material, String... lore) { + return new Entry.Block(slot, name, material, lore); + } + + public sealed interface Entry { + int slot(); + + ItemStack.Builder render(); + + record Head(int slot, String name, String texture, String... lore) implements Entry { + @Override + public ItemStack.Builder render() { + return ItemStackCreator.getStackHead(name, texture, 1, lore); + } + } + + record Block(int slot, String name, Material material, String... lore) implements Entry { + @Override + public ItemStack.Builder render() { + return ItemStackCreator.getStack(name, material, 1, lore); + } + } + } +} From 35522387a38a5d38936b5c6826a99293e41da0eb Mon Sep 17 00:00:00 2001 From: "Jacob Nardella (Swofty)" Date: Thu, 14 May 2026 23:58:13 +1000 Subject: [PATCH 023/113] refactor(bedwars): extract undroppable tools to a constant Set MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The fall-through switch in ItemDropEvent had 8 cases that all did the same thing — a Set lookup says it directly and lets new tools be added to one obvious place. The default branch flattens to a guard return instead of a labelled block, dropping a level of nesting in the actual drop path. --- .../events/ActionGamePlayerEvent.java | 39 ++++++++++--------- 1 file changed, 21 insertions(+), 18 deletions(-) diff --git a/type.bedwarsgame/src/main/java/net/swofty/type/bedwarsgame/events/ActionGamePlayerEvent.java b/type.bedwarsgame/src/main/java/net/swofty/type/bedwarsgame/events/ActionGamePlayerEvent.java index 0ee3904a3..7cc7efef7 100644 --- a/type.bedwarsgame/src/main/java/net/swofty/type/bedwarsgame/events/ActionGamePlayerEvent.java +++ b/type.bedwarsgame/src/main/java/net/swofty/type/bedwarsgame/events/ActionGamePlayerEvent.java @@ -53,27 +53,30 @@ public void run(InventoryPreClickEvent event) { } } + private static final java.util.Set UNDROPPABLE_TOOLS = java.util.Set.of( + "wooden_sword", + "wooden_pickaxe", + "wooden_axe", + "stone_axe", + "iron_pickaxe", + "iron_axe", + "diamond_pickaxe", + "diamond_axe" + ); + @HypixelEvent(node = EventNodes.PLAYER, requireDataLoaded = false) public void run(ItemDropEvent event) { - switch (event.getItemStack().material().name()) { - case "wooden_sword": - case "wooden_pickaxe": - case "wooden_axe": - case "stone_axe": - case "iron_pickaxe": - case "iron_axe": - case "diamond_pickaxe": - case "diamond_axe": - event.setCancelled(true); - event.getPlayer().sendMessage("§cYou cannot drop your tools!"); - break; - default: - ItemEntity itemEntity = new ItemEntity(event.getItemStack()); - itemEntity.setInstance(event.getPlayer().getInstance(), event.getPlayer().getPosition().add(0, event.getPlayer().getEyeHeight(), 0)); - itemEntity.setVelocity(event.getPlayer().getPosition().add(0, 0.3, 0).direction().mul(6)); - itemEntity.setPickupDelay(Duration.ofMillis(500)); - break; + if (UNDROPPABLE_TOOLS.contains(event.getItemStack().material().name())) { + event.setCancelled(true); + event.getPlayer().sendMessage("§cYou cannot drop your tools!"); + return; } + + ItemEntity itemEntity = new ItemEntity(event.getItemStack()); + itemEntity.setInstance(event.getPlayer().getInstance(), + event.getPlayer().getPosition().add(0, event.getPlayer().getEyeHeight(), 0)); + itemEntity.setVelocity(event.getPlayer().getPosition().add(0, 0.3, 0).direction().mul(6)); + itemEntity.setPickupDelay(Duration.ofMillis(500)); } @HypixelEvent(node = EventNodes.PLAYER, requireDataLoaded = false, isAsync = true) From 5615adf008e744fa14ace3872ef99509db29cb41 Mon Sep 17 00:00:00 2001 From: "Jacob Nardella (Swofty)" Date: Thu, 14 May 2026 23:59:04 +1000 Subject: [PATCH 024/113] chore(fishing): drop GUIFishingSkillExampleRemoveThis MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The filename itself was the migration note — it was an unreferenced example view from the fishing PR. Nothing in the codebase referenced it, including the freshly-extracted SeaCreatureGuidePage, so deleting is the literal instruction from the original author. --- .../GUIFishingSkillExampleRemoveThis.java | 450 ------------------ 1 file changed, 450 deletions(-) delete mode 100644 type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/gui/inventories/fishing/GUIFishingSkillExampleRemoveThis.java diff --git a/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/gui/inventories/fishing/GUIFishingSkillExampleRemoveThis.java b/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/gui/inventories/fishing/GUIFishingSkillExampleRemoveThis.java deleted file mode 100644 index b0e02bcdf..000000000 --- a/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/gui/inventories/fishing/GUIFishingSkillExampleRemoveThis.java +++ /dev/null @@ -1,450 +0,0 @@ -package net.swofty.type.skyblockgeneric.gui.inventories.fishing; - -import net.minestom.server.inventory.InventoryType; -import net.minestom.server.item.Material; -import net.swofty.type.generic.gui.inventory.ItemStackCreator; -import net.swofty.type.generic.gui.v2.Components; -import net.swofty.type.generic.gui.v2.DefaultState; -import net.swofty.type.generic.gui.v2.StatelessView; -import net.swofty.type.generic.gui.v2.ViewConfiguration; -import net.swofty.type.generic.gui.v2.ViewLayout; -import net.swofty.type.generic.gui.v2.context.ViewContext; - -public class GUIFishingSkillExampleRemoveThis extends StatelessView { - - @Override - public ViewConfiguration configuration() { - return new ViewConfiguration<>("Fishing Skill", InventoryType.CHEST_6_ROW); - } - - @Override - public void layout(ViewLayout layout, DefaultState state, ViewContext ctx) { - Components.close(layout, 49); - - layout.slot(0, ItemStackCreator.getStack( - "§aFishing Skill", - Material.FISHING_ROD, - 1, - "§7Visit your local pond to fish and", - "§7earn Fishing XP!", - "", - "§7Progress to Level XIX: §e33.1%", - "§2§l§m §f§l§m §e33,082§6/§e100k", - "", - "§eTreasure Hunter XVIII", - " §fGrants §a+1.8§f §6⛃ Treasure Chance§f.", - "", - "§8Increase your Fishing Level to", - "§8unlock Perks, statistic bonuses, and", - "§8more!" - )); - layout.slot(2, ItemStackCreator.getStack( - "§aFishing Level VIII", - Material.LIME_STAINED_GLASS_PANE, - 8, - "§7Rewards:", - " §eTreasure Hunter VIII", - " §fGrants §a+§80.7➜§a0.8§f §6⛃ Treasure Chance§f.", - " §8+§a2 §c❤ Health", - " §8+§64,000 §7Coins", - " §8+§b5 SkyBlock XP", - "", - "§a§lUNLOCKED" - )); - layout.slot(3, ItemStackCreator.getStack( - "§aFishing Level IX", - Material.LIME_STAINED_GLASS_PANE, - 9, - "§7Rewards:", - " §fScarecrow§3 Sea Creature", - " §9Tadgang§3 Sea Creature", - " §aSea Archer§3 Sea Creature", - " §eTreasure Hunter IX", - " §fGrants §a+§80.8➜§a0.9§f §6⛃ Treasure Chance§f.", - " §8+§a2 §c❤ Health", - " §8+§65,000 §7Coins", - " §8+§b5 SkyBlock XP", - "", - "§a§lUNLOCKED" - )); - layout.slot(4, ItemStackCreator.getStack( - "§aFishing Level X", - Material.PRISMARINE, - 10, - "§7Rewards:", - " §9Banshee§3 Sea Creature", - " §aOasis Sheep§3 Sea Creature", - " §9Blue Shark§3 Sea Creature", - " §9Snapping Turtle§3 Sea Creature", - " §aOasis Rabbit§3 Sea Creature", - " §eTreasure Hunter X", - " §fGrants §a+§80.9➜§a1§f §6⛃ Treasure Chance§f.", - " §8+§a2 §c❤ Health", - " §8+§67,500 §7Coins", - " §8+§b5 SkyBlock XP", - "", - "§a§lUNLOCKED" - )); - layout.slot(6, ItemStackCreator.getStack( - "§aFishing Level XVIII", - Material.LIME_STAINED_GLASS_PANE, - 18, - "§7Rewards:", - " §5Tiger Shark§3 Sea Creature", - " §5Deep Sea Protector§3 Sea Creature", - " §eTreasure Hunter XVIII", - " §fGrants §a+§81.7➜§a1.8§f §6⛃ Treasure Chance§f.", - " §8+§a3 §c❤ Health", - " §8+§665,000 §7Coins", - " §8+§b10 SkyBlock XP", - "", - "§a§lUNLOCKED" - )); - layout.slot(7, ItemStackCreator.getStack( - "§eFishing Level XIX", - Material.YELLOW_STAINED_GLASS_PANE, - 19, - "§7Rewards:", - " §6???§3 Sea Creature", - " §9???§3 Sea Creature", - " §eTreasure Hunter XIX", - " §fGrants §a+§81.8➜§a1.9§f §6⛃ Treasure Chance§f.", - " §8+§a3 §c❤ Health", - " §8+§680,000 §7Coins", - " §8+§b10 SkyBlock XP", - "", - "§7Progress: §e33.1%", - "§2§l§m §f§l§m §e33,082§6/§e100k" - )); - layout.slot(8, ItemStackCreator.getStack( - "§cFishing Level XX", - Material.RED_STAINED_GLASS_PANE, - 20, - "§7Rewards:", - " §6???§3 Sea Creature", - " §5???§3 Sea Creature", - " §6???§3 Sea Creature", - " §eTreasure Hunter XX", - " §fGrants §a+§81.9➜§a2§f §6⛃ Treasure Chance§f.", - " §8+§a4 §c❤ Health", - " §8+§6100,000 §7Coins", - " §8+§b10 SkyBlock XP" - )); - layout.slot(9, ItemStackCreator.getStack( - "§aFishing Level I", - Material.LIME_STAINED_GLASS_PANE, - 1, - "§7Rewards:", - " §fSquid§3 Sea Creature", - " §fSea Walker§3 Sea Creature", - " §eTreasure Hunter I", - " §fGrants §a+0.1§f §6⛃ Treasure Chance§f.", - " §8+§a2 §c❤ Health", - " §8+§6100 §7Coins", - " §8+§b5 SkyBlock XP", - "", - "§a§lUNLOCKED" - )); - layout.slot(11, ItemStackCreator.getStack( - "§aFishing Level VII", - Material.LIME_STAINED_GLASS_PANE, - 7, - "§7Rewards:", - " §aWetwing§3 Sea Creature", - " §aSea Witch§3 Sea Creature", - " §eTreasure Hunter VII", - " §fGrants §a+§80.6➜§a0.7§f §6⛃ Treasure Chance§f.", - " §8+§a2 §c❤ Health", - " §8+§63,000 §7Coins", - " §8+§b5 SkyBlock XP", - "", - "§a§lUNLOCKED" - )); - layout.slot(13, ItemStackCreator.getStack( - "§aFishing Level XI", - Material.LIME_STAINED_GLASS_PANE, - 11, - "§7Rewards:", - " §aRider of the Deep§3 Sea Creature", - " §eTreasure Hunter XI", - " §fGrants §a+§81➜§a1.1§f §6⛃ Treasure Chance§f.", - " §8+§a2 §c❤ Health", - " §8+§610,000 §7Coins", - " §8+§b10 SkyBlock XP", - "", - "§a§lUNLOCKED" - )); - layout.slot(15, ItemStackCreator.getStack( - "§aFishing Level XVII", - Material.LIME_STAINED_GLASS_PANE, - 17, - "§7Rewards:", - " §5Guardian Defender§3 Sea Creature", - " §5Werewolf§3 Sea Creature", - " §9Stridersurfer§3 Sea Creature", - " §9Poisoned Water Worm§3 Sea Creature", - " §eTreasure Hunter XVII", - " §fGrants §a+§81.6➜§a1.7§f §6⛃ Treasure Chance§f.", - " §8+§a3 §c❤ Health", - " §8+§650,000 §7Coins", - " §8+§b10 SkyBlock XP", - "", - "§a§lUNLOCKED" - )); - layout.slot(17, ItemStackCreator.getStack( - "§cFishing Level XXI", - Material.RED_STAINED_GLASS_PANE, - 21, - "§7Rewards:", - " §6???§3 Sea Creature", - " §eTreasure Hunter XXI", - " §fGrants §a+§82➜§a2.1§f §6⛃ Treasure Chance§f.", - " §8+§a4 §c❤ Health", - " §8+§6125,000 §7Coins", - " §8+§b10 SkyBlock XP" - )); - layout.slot(18, ItemStackCreator.getStack( - "§aFishing Level II", - Material.LIME_STAINED_GLASS_PANE, - 2, - "§7Rewards:", - " §eTreasure Hunter II", - " §fGrants §a+§80.1➜§a0.2§f §6⛃ Treasure Chance§f.", - " §8+§a2 §c❤ Health", - " §8+§6250 §7Coins", - " §8+§b5 SkyBlock XP", - "", - "§a§lUNLOCKED" - )); - layout.slot(20, ItemStackCreator.getStack( - "§aFishing Level VI", - Material.LIME_STAINED_GLASS_PANE, - 6, - "§7Rewards:", - " §aMedium Mithril Grubber§3 Sea Creature", - " §aMithril Grubber§3 Sea Creature", - " §aBloated Mithril Grubber§3 Sea Creature", - " §aLarge Mithril Grubber§3 Sea Creature", - " §fFrosty§3 Sea Creature", - " §eTreasure Hunter VI", - " §fGrants §a+§80.5➜§a0.6§f §6⛃ Treasure Chance§f.", - " §8+§a2 §c❤ Health", - " §8+§62,000 §7Coins", - " §8+§b5 SkyBlock XP", - "", - "§a§lUNLOCKED" - )); - layout.slot(22, ItemStackCreator.getStack( - "§aFishing Level XII", - Material.LIME_STAINED_GLASS_PANE, - 12, - "§7Rewards:", - " §5Ent§3 Sea Creature", - " §eTreasure Hunter XII", - " §fGrants §a+§81.1➜§a1.2§f §6⛃ Treasure Chance§f.", - " §8+§a2 §c❤ Health", - " §8+§615,000 §7Coins", - " §8+§b10 SkyBlock XP", - "", - "§a§lUNLOCKED" - )); - layout.slot(24, ItemStackCreator.getStack( - "§aFishing Level XVI", - Material.LIME_STAINED_GLASS_PANE, - 16, - "§7Rewards:", - " §9Sea Leech§3 Sea Creature", - " §9Fireproof Witch§3 Sea Creature", - " §eTreasure Hunter XVI", - " §fGrants §a+§81.5➜§a1.6§f §6⛃ Treasure Chance§f.", - " §8+§a3 §c❤ Health", - " §8+§640,000 §7Coins", - " §8+§b10 SkyBlock XP", - "", - "§a§lUNLOCKED" - )); - layout.slot(26, ItemStackCreator.getStack( - "§cFishing Level XXII", - Material.RED_STAINED_GLASS_PANE, - 22, - "§7Rewards:", - " §5???§3 Sea Creature", - " §eTreasure Hunter XXII", - " §fGrants §a+§82.1➜§a2.2§f §6⛃ Treasure Chance§f.", - " §8+§a4 §c❤ Health", - " §8+§6150,000 §7Coins", - " §8+§b10 SkyBlock XP" - )); - layout.slot(27, ItemStackCreator.getStack( - "§aFishing Level III", - Material.LIME_STAINED_GLASS_PANE, - 3, - "§7Rewards:", - " §fNight Squid§3 Sea Creature", - " §eTreasure Hunter III", - " §fGrants §a+§80.2➜§a0.3§f §6⛃ Treasure Chance§f.", - " §8+§a2 §c❤ Health", - " §8+§6500 §7Coins", - " §8+§b5 SkyBlock XP", - "", - "§a§lUNLOCKED" - )); - layout.slot(28, ItemStackCreator.getStack( - "§aFishing Level IV", - Material.LIME_STAINED_GLASS_PANE, - 4, - "§7Rewards:", - " §eTreasure Hunter IV", - " §fGrants §a+§80.3➜§a0.4§f §6⛃ Treasure Chance§f.", - " §8+§a2 §c❤ Health", - " §8+§6750 §7Coins", - " §8+§b5 SkyBlock XP", - "", - "§a§lUNLOCKED" - )); - layout.slot(29, ItemStackCreator.getStack( - "§aFishing Level V", - Material.PRISMARINE, - 5, - "§7Rewards:", - " §fSea Guardian§3 Sea Creature", - " §aDumpster Diver§3 Sea Creature", - " §fFrog Man§3 Sea Creature", - " §fTrash Gobbler§3 Sea Creature", - " §fBogged§3 Sea Creature", - " §aNurse Shark§3 Sea Creature", - " §fFrozen Steve§3 Sea Creature", - " §eTreasure Hunter V", - " §fGrants §a+§80.4➜§a0.5§f §6⛃ Treasure Chance§f.", - " §8+§a2 §c❤ Health", - " §8+§61,000 §7Coins", - " §8+§b5 SkyBlock XP", - "", - "§a§lUNLOCKED" - )); - layout.slot(31, ItemStackCreator.getStack( - "§aFishing Level XIII", - Material.LIME_STAINED_GLASS_PANE, - 13, - "§7Rewards:", - " §9Catfish§3 Sea Creature", - " §aGrinch§3 Sea Creature", - " §eTreasure Hunter XIII", - " §fGrants §a+§81.2➜§a1.3§f §6⛃ Treasure Chance§f.", - " §8+§a2 §c❤ Health", - " §8+§620,000 §7Coins", - " §8+§b10 SkyBlock XP", - "", - "§a§lUNLOCKED" - )); - layout.slot(32, ItemStackCreator.getStack( - "§aFishing Level XIV", - Material.LIME_STAINED_GLASS_PANE, - 14, - "§7Rewards:", - " §fFried Chicken§3 Sea Creature", - " §9Carrot King§3 Sea Creature", - " §9Nightmare§3 Sea Creature", - " §eTreasure Hunter XIV", - " §fGrants §a+§81.3➜§a1.4§f §6⛃ Treasure Chance§f.", - " §8+§a2 §c❤ Health", - " §8+§625,000 §7Coins", - " §8+§b10 SkyBlock XP", - "", - "§a§lUNLOCKED" - )); - layout.slot(33, ItemStackCreator.getStack( - "§aFishing Level XV", - Material.PRISMARINE, - 15, - "§7Rewards:", - " §9Agarimoo§3 Sea Creature", - " §9Water Worm§3 Sea Creature", - " §5Bayou Sludge§3 Sea Creature", - " §eTreasure Hunter XV", - " §fGrants §a+§81.4➜§a1.5§f §6⛃ Treasure Chance§f.", - " §8+§a3 §c❤ Health", - " §8+§630,000 §7Coins", - " §8+§b10 SkyBlock XP", - "", - "§a§lUNLOCKED" - )); - layout.slot(35, ItemStackCreator.getStack( - "§cFishing Level XXIII", - Material.RED_STAINED_GLASS_PANE, - 23, - "§7Rewards:", - " §eTreasure Hunter XXIII", - " §fGrants §a+§82.2➜§a2.3§f §6⛃ Treasure Chance§f.", - " §8+§a4 §c❤ Health", - " §8+§6175,000 §7Coins", - " §8+§b10 SkyBlock XP" - )); - layout.slot(39, ItemStackCreator.getStack( - "§6Bait Guide", - Material.BOOK, - 1, - "§7View §6Baits§7, their uses, and how to", - "§7obtain them! Can also be accessed", - "§7with §a/bait§7!", - "", - "§eClick to view!" - )); - layout.slot(40, ItemStackCreator.getStack( - "§aSea Creature Guide", - Material.BOOK, - 1, - "§7Your guide to the creatures of the", - "§7deep! Can also be accessed with", - "§a/scg§7!", - "", - "§7Beware, Sea Creatures spawn much", - "§7less often on your private island.", - "", - "§7Your Fishing: §aLevel XVIII", - "", - "§eClick to view!" - )); - layout.slot(41, ItemStackCreator.getStack( - "§9Rod Part Guide", - Material.BOOK, - 1, - "§7View all of the §9Rod Parts §7that can be", - "§7applied to §aFishing Rods§7! Can also be", - "§7accessed with §a/rodparts§7!", - "", - "§eClick to view!" - )); - layout.slot(44, ItemStackCreator.getStack( - "§cFishing Level XXIV", - Material.RED_STAINED_GLASS_PANE, - 24, - "§7Rewards:", - " §6???§3 Sea Creature", - " §6???§3 Sea Creature", - " §eTreasure Hunter XXIV", - " §fGrants §a+§82.3➜§a2.4§f §6⛃ Treasure Chance§f.", - " §8+§a4 §c❤ Health", - " §8+§6200,000 §7Coins", - " §8+§b10 SkyBlock XP" - )); - layout.slot(48, ItemStackCreator.getStack( - "§aGo Back", - Material.ARROW, - 1, - "§7To Your Skills" - )); - layout.slot(53, ItemStackCreator.getStack( - "§cFishing Level XXV", - Material.RED_STAINED_GLASS_PANE, - 25, - "§7Rewards:", - " §6???§3 Sea Creature", - " §eTreasure Hunter XXV", - " §fGrants §a+§82.4➜§a2.5§f §6⛃ Treasure Chance§f.", - " §8+§a4 §c❤ Health", - " §8+§6225,000 §7Coins", - " §8+§b10 SkyBlock XP" - )); - } -} From 07c1e35ce11b0e228d8151de6427455b08774e8e Mon Sep 17 00:00:00 2001 From: "Jacob Nardella (Swofty)" Date: Thu, 14 May 2026 23:59:55 +1000 Subject: [PATCH 025/113] refactor(commons): collapse FriendEvent.createDummyInstance to one reflection pass MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The previous switch was 100 lines: one case per subclass naming the exact constructor parameter types so an empty placeholder instance could be built. Adding a friend event meant adding a case here, and nothing tied the cases to the subclass list — they could (and did) drift. The replacement picks the first declared constructor and fills each parameter from a small type → default-value table. Same outcome, zero per-subclass coupling. The hot reflection call is unchanged. --- .../swofty/commons/friend/FriendEvent.java | 167 ++++++------------ 1 file changed, 57 insertions(+), 110 deletions(-) diff --git a/commons/src/main/java/net/swofty/commons/friend/FriendEvent.java b/commons/src/main/java/net/swofty/commons/friend/FriendEvent.java index af1d22f44..6b7bdbf50 100644 --- a/commons/src/main/java/net/swofty/commons/friend/FriendEvent.java +++ b/commons/src/main/java/net/swofty/commons/friend/FriendEvent.java @@ -8,7 +8,10 @@ import net.swofty.commons.friend.events.response.*; import net.swofty.commons.protocol.Serializer; +import java.lang.reflect.Constructor; +import java.lang.reflect.Parameter; import java.util.Arrays; +import java.util.Collections; import java.util.List; import java.util.UUID; @@ -28,6 +31,12 @@ @JsonSubTypes.Type(value = FriendResponseEvent.class) }) public abstract class FriendEvent { + + private static final String[] EVENT_PACKAGES = { + "net.swofty.commons.friend.events", + "net.swofty.commons.friend.events.response" + }; + public FriendEvent() { } @@ -35,127 +44,65 @@ public FriendEvent() { public abstract List getParticipants(); + /** + * Returns a placeholder instance of the named event subclass. Used by the + * Redis dispatch layer to obtain a {@link Serializer} for incoming + * payloads — the dummy itself is discarded once its serializer is held. + * + *

The dummy is built by picking the first declared constructor of the + * subclass and filling every parameter with a default of the appropriate + * type. This replaces a ~100-line switch over each event class name with + * one reflection pass; adding a new event subtype no longer requires a + * matching case here.

+ */ public static @NonNull FriendEvent findFromType(String className) { - String[] packageNames = { - "net.swofty.commons.friend.events", - "net.swofty.commons.friend.events.response" - }; - - for (String packageName : packageNames) { + for (String packageName : EVENT_PACKAGES) { try { Class clazz = Class.forName(packageName + "." + className); return createDummyInstance(clazz); + } catch (ClassNotFoundException ignored) { + // try next package } catch (Exception e) { - // Try next package + throw new RuntimeException( + "Failed to instantiate friend event class " + className, e); } } - - throw new RuntimeException("Failed to find friend event class: " + className + " in " + Arrays.toString(packageNames)); + throw new RuntimeException( + "Failed to find friend event class: " + className + + " in " + Arrays.toString(EVENT_PACKAGES)); } private static FriendEvent createDummyInstance(Class clazz) throws Exception { - String className = clazz.getSimpleName(); + Constructor[] constructors = clazz.getDeclaredConstructors(); + if (constructors.length == 0) { + throw new IllegalStateException("No constructors on " + clazz.getName()); + } - switch (className) { - // Request events - case "FriendAddRequestEvent" -> { - var constructor = clazz.getDeclaredConstructor(UUID.class, UUID.class); - return (FriendEvent) constructor.newInstance(UUID.randomUUID(), UUID.randomUUID()); - } - case "FriendAcceptRequestEvent" -> { - var constructor = clazz.getDeclaredConstructor(UUID.class, UUID.class); - return (FriendEvent) constructor.newInstance(UUID.randomUUID(), UUID.randomUUID()); - } - case "FriendDenyRequestEvent" -> { - var constructor = clazz.getDeclaredConstructor(UUID.class, UUID.class); - return (FriendEvent) constructor.newInstance(UUID.randomUUID(), UUID.randomUUID()); - } - case "FriendRemoveRequestEvent" -> { - var constructor = clazz.getDeclaredConstructor(UUID.class, UUID.class); - return (FriendEvent) constructor.newInstance(UUID.randomUUID(), UUID.randomUUID()); - } - case "FriendRemoveAllRequestEvent" -> { - var constructor = clazz.getDeclaredConstructor(UUID.class); - return (FriendEvent) constructor.newInstance(UUID.randomUUID()); - } - case "FriendToggleBestRequestEvent" -> { - var constructor = clazz.getDeclaredConstructor(UUID.class, UUID.class); - return (FriendEvent) constructor.newInstance(UUID.randomUUID(), UUID.randomUUID()); - } - case "FriendSetNicknameRequestEvent" -> { - var constructor = clazz.getDeclaredConstructor(UUID.class, UUID.class, String.class); - return (FriendEvent) constructor.newInstance(UUID.randomUUID(), UUID.randomUUID(), ""); - } - case "FriendToggleSettingRequestEvent" -> { - var constructor = clazz.getDeclaredConstructor(UUID.class, FriendSettingType.class); - return (FriendEvent) constructor.newInstance(UUID.randomUUID(), FriendSettingType.ACCEPTING_REQUESTS); - } - case "FriendListRequestEvent" -> { - var constructor = clazz.getDeclaredConstructor(UUID.class, int.class, boolean.class); - return (FriendEvent) constructor.newInstance(UUID.randomUUID(), 1, false); - } - case "FriendRequestsListEvent" -> { - var constructor = clazz.getDeclaredConstructor(UUID.class, int.class); - return (FriendEvent) constructor.newInstance(UUID.randomUUID(), 1); - } - // Response events - case "FriendRequestSentResponseEvent" -> { - var constructor = clazz.getDeclaredConstructor(UUID.class, UUID.class, String.class); - return (FriendEvent) constructor.newInstance(UUID.randomUUID(), UUID.randomUUID(), ""); - } - case "FriendRequestReceivedResponseEvent" -> { - var constructor = clazz.getDeclaredConstructor(UUID.class, UUID.class, String.class); - return (FriendEvent) constructor.newInstance(UUID.randomUUID(), UUID.randomUUID(), ""); - } - case "FriendAddedResponseEvent" -> { - var constructor = clazz.getDeclaredConstructor(UUID.class, UUID.class, String.class, String.class); - return (FriendEvent) constructor.newInstance(UUID.randomUUID(), UUID.randomUUID(), "", ""); - } - case "FriendDeniedResponseEvent" -> { - var constructor = clazz.getDeclaredConstructor(UUID.class, UUID.class, String.class); - return (FriendEvent) constructor.newInstance(UUID.randomUUID(), UUID.randomUUID(), ""); - } - case "FriendRemovedResponseEvent" -> { - var constructor = clazz.getDeclaredConstructor(UUID.class, UUID.class, String.class); - return (FriendEvent) constructor.newInstance(UUID.randomUUID(), UUID.randomUUID(), ""); - } - case "FriendRemoveAllResponseEvent" -> { - var constructor = clazz.getDeclaredConstructor(UUID.class, int.class); - return (FriendEvent) constructor.newInstance(UUID.randomUUID(), 0); - } - case "FriendBestToggledResponseEvent" -> { - var constructor = clazz.getDeclaredConstructor(UUID.class, UUID.class, String.class, boolean.class); - return (FriendEvent) constructor.newInstance(UUID.randomUUID(), UUID.randomUUID(), "", false); - } - case "FriendNicknameSetResponseEvent" -> { - var constructor = clazz.getDeclaredConstructor(UUID.class, UUID.class, String.class, String.class); - return (FriendEvent) constructor.newInstance(UUID.randomUUID(), UUID.randomUUID(), "", ""); - } - case "FriendSettingToggledResponseEvent" -> { - var constructor = clazz.getDeclaredConstructor(UUID.class, FriendSettingType.class, boolean.class); - return (FriendEvent) constructor.newInstance(UUID.randomUUID(), FriendSettingType.ACCEPTING_REQUESTS, false); - } - case "FriendJoinNotificationEvent" -> { - var constructor = clazz.getDeclaredConstructor(UUID.class, UUID.class, String.class); - return (FriendEvent) constructor.newInstance(UUID.randomUUID(), UUID.randomUUID(), ""); - } - case "FriendLeaveNotificationEvent" -> { - var constructor = clazz.getDeclaredConstructor(UUID.class, UUID.class, String.class); - return (FriendEvent) constructor.newInstance(UUID.randomUUID(), UUID.randomUUID(), ""); - } - case "FriendRequestExpiredResponseEvent" -> { - var constructor = clazz.getDeclaredConstructor(UUID.class, UUID.class, String.class, String.class); - return (FriendEvent) constructor.newInstance(UUID.randomUUID(), UUID.randomUUID(), "", ""); - } - case "FriendListResponseEvent" -> { - var constructor = clazz.getDeclaredConstructor(UUID.class, List.class, int.class, int.class, boolean.class); - return (FriendEvent) constructor.newInstance(UUID.randomUUID(), List.of(), 1, 1, false); - } - case "FriendRequestsListResponseEvent" -> { - var constructor = clazz.getDeclaredConstructor(UUID.class, List.class, int.class, int.class); - return (FriendEvent) constructor.newInstance(UUID.randomUUID(), List.of(), 1, 1); - } - default -> throw new IllegalArgumentException("Unknown friend event class: " + className); + Constructor constructor = constructors[0]; + Object[] args = Arrays.stream(constructor.getParameters()) + .map(FriendEvent::placeholderFor) + .toArray(); + constructor.setAccessible(true); + return (FriendEvent) constructor.newInstance(args); + } + + private static Object placeholderFor(Parameter parameter) { + Class type = parameter.getType(); + if (type == UUID.class) return UUID.randomUUID(); + if (type == String.class) return ""; + if (type == int.class || type == Integer.class) return 0; + if (type == long.class || type == Long.class) return 0L; + if (type == double.class || type == Double.class) return 0.0D; + if (type == float.class || type == Float.class) return 0F; + if (type == boolean.class || type == Boolean.class) return false; + if (type == byte.class || type == Byte.class) return (byte) 0; + if (type == short.class || type == Short.class) return (short) 0; + if (type == char.class || type == Character.class) return '\0'; + if (type == List.class) return Collections.emptyList(); + if (type.isEnum()) { + Object[] constants = type.getEnumConstants(); + return constants.length == 0 ? null : constants[0]; } + return null; } } From a6542afdf5d57834cd650cd9f6e564669cd9bb28 Mon Sep 17 00:00:00 2001 From: "Jacob Nardella (Swofty)" Date: Fri, 15 May 2026 00:07:10 +1000 Subject: [PATCH 026/113] chore: replace System.out / printStackTrace with proper logging MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Five callsites where production code dumped to stdout or used the default Throwable.printStackTrace path instead of going through the existing tinylog Logger: - service.bazaar OrderDatabase connect message (added tinylog deps to the bazaar build, matching the other services) - velocity.extension RedisListener and GameManager - type.skyblockgeneric ItemConfigParser parse failures (×2) - pvp EntityUtil reflection failure (uses j.u.l since pvp has no tinylog dep and isn't worth pulling one in for one callsite) Stack traces now reach the configured log appenders + Sentry rather than disappearing to the launcher console. --- pvp/src/main/java/net/swofty/pvp/utils/EntityUtil.java | 3 ++- service.bazaar/build.gradle.kts | 2 ++ .../java/net/swofty/service/bazaar/OrderDatabase.java | 3 ++- .../type/skyblockgeneric/item/ItemConfigParser.java | 6 ++---- .../java/net/swofty/velocity/gamemanager/GameManager.java | 8 ++++++-- .../java/net/swofty/velocity/redis/RedisListener.java | 3 +-- 6 files changed, 15 insertions(+), 10 deletions(-) diff --git a/pvp/src/main/java/net/swofty/pvp/utils/EntityUtil.java b/pvp/src/main/java/net/swofty/pvp/utils/EntityUtil.java index fccaebb5b..605c336c2 100644 --- a/pvp/src/main/java/net/swofty/pvp/utils/EntityUtil.java +++ b/pvp/src/main/java/net/swofty/pvp/utils/EntityUtil.java @@ -46,7 +46,8 @@ public static void setLastDamage(LivingEntity livingEntity, Damage lastDamage) { field.setAccessible(true); field.set(livingEntity, lastDamage); } catch (NoSuchFieldException | IllegalAccessException e) { - e.printStackTrace(); + java.util.logging.Logger.getLogger("PVP").log(java.util.logging.Level.SEVERE, + "Failed to set LivingEntity.lastDamage via reflection", e); Sentry.captureException(e); } } diff --git a/service.bazaar/build.gradle.kts b/service.bazaar/build.gradle.kts index 6686c0516..5476e5cbc 100644 --- a/service.bazaar/build.gradle.kts +++ b/service.bazaar/build.gradle.kts @@ -28,6 +28,8 @@ dependencies { implementation(libs.caffeine) implementation(libs.mongodb.bson) implementation(libs.mongodb.driver.sync) + implementation(libs.tinylog.api) + implementation(libs.tinylog.impl) } application { diff --git a/service.bazaar/src/main/java/net/swofty/service/bazaar/OrderDatabase.java b/service.bazaar/src/main/java/net/swofty/service/bazaar/OrderDatabase.java index 1fb6be851..f9d4137d8 100644 --- a/service.bazaar/src/main/java/net/swofty/service/bazaar/OrderDatabase.java +++ b/service.bazaar/src/main/java/net/swofty/service/bazaar/OrderDatabase.java @@ -4,6 +4,7 @@ import com.mongodb.MongoClientSettings; import com.mongodb.client.*; import org.bson.Document; +import org.tinylog.Logger; public class OrderDatabase { public static MongoClient client; @@ -20,7 +21,7 @@ public static void connect(String connectionString) { database = client.getDatabase("Minestom"); ordersCollection = database.getCollection("bazaarOrders"); - System.out.println("Connected to MongoDB for bazaar orders"); + Logger.info("Connected to MongoDB for bazaar orders"); } public static void disconnect() { diff --git a/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/item/ItemConfigParser.java b/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/item/ItemConfigParser.java index f1cef59c0..5366413bb 100644 --- a/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/item/ItemConfigParser.java +++ b/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/item/ItemConfigParser.java @@ -77,8 +77,7 @@ public static ConfigurableSkyBlockItem parseItem(Map config) { Logger.error("Failed to parse item: {}", e.getMessage()); return null; } catch (Exception e) { - Logger.error("Unexpected error parsing item: {}", e.getMessage()); - e.printStackTrace(); + Logger.error(e, "Unexpected error parsing item"); Sentry.captureException(e); return null; } @@ -678,8 +677,7 @@ yield new PetComponent( Logger.error("Failed to parse component {} for item {}: {}", id, itemId, e.getMessage()); return null; } catch (Exception e) { - Logger.error("Unexpected error parsing component {} for item {}: {}", id, itemId, e.getMessage()); - e.printStackTrace(); + Logger.error(e, "Unexpected error parsing component {} for item {}", id, itemId); return null; } } diff --git a/velocity.extension/src/main/java/net/swofty/velocity/gamemanager/GameManager.java b/velocity.extension/src/main/java/net/swofty/velocity/gamemanager/GameManager.java index 3a2b571e7..270aeb3f9 100644 --- a/velocity.extension/src/main/java/net/swofty/velocity/gamemanager/GameManager.java +++ b/velocity.extension/src/main/java/net/swofty/velocity/gamemanager/GameManager.java @@ -112,8 +112,12 @@ public static void loopServers(ProxyServer server) { server.getScheduler().buildTask(SkyBlockVelocity.getPlugin(), () -> { if (!pingSuccess.get()) { - System.out.println("Server " + givenServer.getServerInfo().getName() + " is offline! Removing from list..."); - System.out.println("Ping was sent at " + startTime + " and was not received at " + System.currentTimeMillis() + " (" + (System.currentTimeMillis() - startTime) + "ms)"); + org.tinylog.Logger.warn( + "Server {} is offline! Removing from list (ping sent at {}, deadline {}ms)", + givenServer.getServerInfo().getName(), + startTime, + System.currentTimeMillis() - startTime + ); servers.get(serverType).remove(registeredServer); TestFlowManager.handleServerDisconnect(registeredServer.internalID); diff --git a/velocity.extension/src/main/java/net/swofty/velocity/redis/RedisListener.java b/velocity.extension/src/main/java/net/swofty/velocity/redis/RedisListener.java index a382d498c..8eb50828e 100644 --- a/velocity.extension/src/main/java/net/swofty/velocity/redis/RedisListener.java +++ b/velocity.extension/src/main/java/net/swofty/velocity/redis/RedisListener.java @@ -35,8 +35,7 @@ public void onMessage(String channel, String message) { try { response = receivedMessage(typedMessage, filterID); } catch (Exception e) { - System.out.println("Error on channel " + channel + " with message " + envelope.payload()); - Logger.error(e, "Error in Redis listener"); + Logger.error(e, "Error on channel {} with message {}", channel, envelope.payload()); return; } From 24c2ba325dcc1fa856742649d2db4704a37128e5 Mon Sep 17 00:00:00 2001 From: "Jacob Nardella (Swofty)" Date: Fri, 15 May 2026 00:07:47 +1000 Subject: [PATCH 027/113] chore: turn silent-catch blocks into deliberate logs Two empty 'catch (Exception ignored) {}' sites silently swallowed failures. Replaced both with intent-bearing logs: - MinionEntityImpl.setItemInMainHand: was followed by a 'TODO: Fix this' comment, so the exception was never seen. Now logs at warn. - PlayerChannelHandler limbo replay: this one was intentional swallow (a missing cached respawn shouldn't drop the player), but it's worth a debug log so diagnostic runs can see when it fires. --- .../type/skyblockgeneric/entity/MinionEntityImpl.java | 5 +++-- .../net/swofty/velocity/packet/PlayerChannelHandler.java | 7 ++++++- 2 files changed, 9 insertions(+), 3 deletions(-) diff --git a/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/entity/MinionEntityImpl.java b/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/entity/MinionEntityImpl.java index c526851b7..0b1f21e79 100644 --- a/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/entity/MinionEntityImpl.java +++ b/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/entity/MinionEntityImpl.java @@ -76,8 +76,9 @@ public void updateMinionDisplay(IslandMinionData.IslandMinion updatedMinion) { try { setItemInMainHand(ItemStack.builder(minionTier.heldItem()).build()); - } catch (Exception e) {} - // TODO: Fix this, I have no clue why it stopped working + } catch (Exception e) { + org.tinylog.Logger.warn(e, "Failed to set held item for minion tier {}", minionTier); + } } @Override diff --git a/velocity.extension/src/main/java/net/swofty/velocity/packet/PlayerChannelHandler.java b/velocity.extension/src/main/java/net/swofty/velocity/packet/PlayerChannelHandler.java index e66912aab..7d8f8c46c 100644 --- a/velocity.extension/src/main/java/net/swofty/velocity/packet/PlayerChannelHandler.java +++ b/velocity.extension/src/main/java/net/swofty/velocity/packet/PlayerChannelHandler.java @@ -48,7 +48,12 @@ public void write(final ChannelHandlerContext ctx, final Object packet, final Ch write(ctx, respawn, ctx.newPromise()); } } - } catch (Exception ignored) {} + } catch (Exception e) { + // Limbo packet replay is best-effort: a malformed cached respawn + // shouldn't drop the player. Log at debug so it surfaces during + // diagnostic runs without spamming production logs. + org.tinylog.Logger.debug(e, "Failed to replay cached respawn during limbo transfer"); + } super.write(ctx, packet, promise); From 2487f1f78516d4349cbb8aea560a83046141a0d6 Mon Sep 17 00:00:00 2001 From: "Jacob Nardella (Swofty)" Date: Fri, 15 May 2026 00:09:37 +1000 Subject: [PATCH 028/113] test(commons): add unit tests for StringUtility pure functions MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Covers getAsRomanNumeral, capitalize, shortenNumber, commaify, roundTo, formatTimeLeft, and stripColor — twelve assertions across the boundary conditions for each (zero/single-digit/compound, null/empty input, K/M/B threshold crossings, day-hour-minute-second rollovers). The commons module previously only tested protocol serializers, so nothing protected these helpers from regressions despite being called across most of the type/service modules. --- .../net/swofty/commons/StringUtilityTest.java | 94 +++++++++++++++++++ 1 file changed, 94 insertions(+) create mode 100644 commons/src/test/java/net/swofty/commons/StringUtilityTest.java diff --git a/commons/src/test/java/net/swofty/commons/StringUtilityTest.java b/commons/src/test/java/net/swofty/commons/StringUtilityTest.java new file mode 100644 index 000000000..c5e06338a --- /dev/null +++ b/commons/src/test/java/net/swofty/commons/StringUtilityTest.java @@ -0,0 +1,94 @@ +package net.swofty.commons; + +import org.junit.jupiter.api.Test; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertNull; + +class StringUtilityTest { + + @Test + void romanNumeralZeroIsEmpty() { + assertEquals("", StringUtility.getAsRomanNumeral(0)); + } + + @Test + void romanNumeralSingleDigits() { + assertEquals("I", StringUtility.getAsRomanNumeral(1)); + assertEquals("IV", StringUtility.getAsRomanNumeral(4)); + assertEquals("V", StringUtility.getAsRomanNumeral(5)); + assertEquals("IX", StringUtility.getAsRomanNumeral(9)); + } + + @Test + void romanNumeralCompound() { + assertEquals("XLII", StringUtility.getAsRomanNumeral(42)); + assertEquals("MCMXCIX", StringUtility.getAsRomanNumeral(1999)); + assertEquals("MMXXVI", StringUtility.getAsRomanNumeral(2026)); + } + + @Test + void capitalizeNormalCase() { + assertEquals("Hello", StringUtility.capitalize("hello")); + assertEquals("World", StringUtility.capitalize("WORLD")); + } + + @Test + void capitalizeEdgeCases() { + assertEquals("", StringUtility.capitalize("")); + assertNull(StringUtility.capitalize(null)); + assertEquals("A", StringUtility.capitalize("a")); + assertEquals("A", StringUtility.capitalize("A")); + } + + @Test + void shortenNumberSmallValues() { + assertEquals("0", StringUtility.shortenNumber(0)); + assertEquals("999", StringUtility.shortenNumber(999)); + } + + @Test + void shortenNumberThousands() { + assertEquals("1.0K", StringUtility.shortenNumber(1000)); + assertEquals("1.5K", StringUtility.shortenNumber(1500)); + assertEquals("999.9K", StringUtility.shortenNumber(999_900)); + } + + @Test + void shortenNumberMillionsAndBillions() { + assertEquals("1.0M", StringUtility.shortenNumber(1_000_000)); + assertEquals("2.5M", StringUtility.shortenNumber(2_500_000)); + assertEquals("1.0B", StringUtility.shortenNumber(1_000_000_000)); + } + + @Test + void commaifyAddsThousandsSeparators() { + assertEquals("1,234", StringUtility.commaify(1234)); + assertEquals("1,000,000", StringUtility.commaify(1_000_000)); + assertEquals("0", StringUtility.commaify(0)); + } + + @Test + void roundToPrecision() { + assertEquals(3.14, StringUtility.roundTo(3.14159, 2), 1e-9); + assertEquals(3.142, StringUtility.roundTo(3.14159, 3), 1e-9); + assertEquals(3.0, StringUtility.roundTo(3.14159, 0), 1e-9); + } + + @Test + void formatTimeLeftBoundaries() { + assertEquals("0s", StringUtility.formatTimeLeft(0)); + assertEquals("59s", StringUtility.formatTimeLeft(59_000)); + assertEquals("1m", StringUtility.formatTimeLeft(60_000)); + assertEquals("1m 30s", StringUtility.formatTimeLeft(90_000)); + assertEquals("1h", StringUtility.formatTimeLeft(3_600_000)); + assertEquals("1d", StringUtility.formatTimeLeft(86_400_000)); + } + + @Test + void stripColorRemovesSectionCodes() { + assertEquals("Hello", StringUtility.stripColor("§aHello")); + assertEquals("Plain", StringUtility.stripColor("Plain")); + assertEquals("Mixed text", StringUtility.stripColor("§cMixed §btext")); + } +} From 90371127e254221a064a9baf0127f59a695c6d77 Mon Sep 17 00:00:00 2001 From: "Jacob Nardella (Swofty)" Date: Fri, 15 May 2026 00:12:40 +1000 Subject: [PATCH 029/113] chore(velocity): route test flow / redis logging through tinylog Five files in velocity.extension printed structured 'INFO/WARN/ERROR' markers inline to stdout instead of going through the configured tinylog logger that the rest of the module already uses. That fragmented logs across two sinks and lost severity routing. Replaced with Logger.info/warn/error (with templated placeholders so they don't allocate when the level is filtered out). Same messages, correctly tagged, going through one sink. --- .../swofty/velocity/redis/RedisMessage.java | 6 +-- .../listeners/ListenerRegisterTestFlow.java | 5 ++- .../ListenerTestFlowServerReady.java | 7 ++-- .../velocity/testflow/TestFlowManager.java | 41 ++++++++----------- .../handlers/SendToHubTestFlowHandler.java | 18 ++++---- 5 files changed, 38 insertions(+), 39 deletions(-) diff --git a/velocity.extension/src/main/java/net/swofty/velocity/redis/RedisMessage.java b/velocity.extension/src/main/java/net/swofty/velocity/redis/RedisMessage.java index fd8089765..b2e28910a 100644 --- a/velocity.extension/src/main/java/net/swofty/velocity/redis/RedisMessage.java +++ b/velocity.extension/src/main/java/net/swofty/velocity/redis/RedisMessage.java @@ -4,6 +4,7 @@ import net.swofty.commons.redis.RedisEnvelope; import net.swofty.redisapi.api.ChannelRegistry; import net.swofty.redisapi.api.RedisAPI; +import org.tinylog.Logger; import java.util.HashMap; import java.util.Map; @@ -41,9 +42,8 @@ public static void registerProxyToServer(ProtocolObject protocol) { callbacks.get(request).complete(rawMessage); callbacks.remove(request); } catch (Exception e) { - System.out.println("RedisMessage: Error while processing message"); - System.out.println("Channel: " + event.channel); - System.out.println("Message: " + event.message); + Logger.error(e, "RedisMessage error processing channel={} message={}", + event.channel, event.message); } }); } diff --git a/velocity.extension/src/main/java/net/swofty/velocity/redis/listeners/ListenerRegisterTestFlow.java b/velocity.extension/src/main/java/net/swofty/velocity/redis/listeners/ListenerRegisterTestFlow.java index b41dbde2a..e14e5f244 100644 --- a/velocity.extension/src/main/java/net/swofty/velocity/redis/listeners/ListenerRegisterTestFlow.java +++ b/velocity.extension/src/main/java/net/swofty/velocity/redis/listeners/ListenerRegisterTestFlow.java @@ -6,6 +6,7 @@ import net.swofty.velocity.redis.RedisListener; import net.swofty.velocity.testflow.TestFlowManager; import org.json.JSONObject; +import org.tinylog.Logger; import java.util.ArrayList; import java.util.List; @@ -37,12 +38,12 @@ public RegisterTestFlowProtocol.Response receivedMessage(RegisterTestFlowProtoco TestFlowManager.registerTestFlow(testFlowName, handler, players, serverConfigs); - System.out.println("Registered test flow '" + testFlowName + "' from server " + serverUUID); + Logger.info("Registered test flow '{}' from server {}", testFlowName, serverUUID); return new RegisterTestFlowProtocol.Response(true, "Test flow registered successfully", null); } catch (Exception e) { - System.out.println("Failed to register test flow from server " + serverUUID); + Logger.error(e, "Failed to register test flow from server {}", serverUUID); return new RegisterTestFlowProtocol.Response(false, null, e.getMessage()); } } diff --git a/velocity.extension/src/main/java/net/swofty/velocity/redis/listeners/ListenerTestFlowServerReady.java b/velocity.extension/src/main/java/net/swofty/velocity/redis/listeners/ListenerTestFlowServerReady.java index 495f31186..8f6f86ab8 100644 --- a/velocity.extension/src/main/java/net/swofty/velocity/redis/listeners/ListenerTestFlowServerReady.java +++ b/velocity.extension/src/main/java/net/swofty/velocity/redis/listeners/ListenerTestFlowServerReady.java @@ -6,6 +6,7 @@ import net.swofty.velocity.redis.ChannelListener; import net.swofty.velocity.redis.RedisListener; import net.swofty.velocity.testflow.TestFlowManager; +import org.tinylog.Logger; import java.util.UUID; @@ -28,13 +29,13 @@ public TestFlowServerReadyProtocol.Response receivedMessage(TestFlowServerReadyP TestFlowManager.markServerReady(testFlowName, serverType, serverIndex, serverUUID); - System.out.println("Server " + serverType.name() + " #" + serverIndex + - " is ready for test flow '" + testFlowName + "' (UUID: " + serverUUID + ")"); + Logger.info("Server {} #{} is ready for test flow '{}' (UUID: {})", + serverType.name(), serverIndex, testFlowName, serverUUID); return new TestFlowServerReadyProtocol.Response(true, "Server ready status recorded", null); } catch (Exception e) { - System.out.println("Failed to process test flow server ready from server " + serverUUID); + Logger.error(e, "Failed to process test flow server ready from server {}", serverUUID); return new TestFlowServerReadyProtocol.Response(false, null, e.getMessage()); } } diff --git a/velocity.extension/src/main/java/net/swofty/velocity/testflow/TestFlowManager.java b/velocity.extension/src/main/java/net/swofty/velocity/testflow/TestFlowManager.java index ccd9c2de2..a52692c70 100644 --- a/velocity.extension/src/main/java/net/swofty/velocity/testflow/TestFlowManager.java +++ b/velocity.extension/src/main/java/net/swofty/velocity/testflow/TestFlowManager.java @@ -3,6 +3,7 @@ import lombok.Getter; import net.swofty.commons.ServerType; import net.swofty.velocity.gamemanager.GameManager; +import org.tinylog.Logger; import java.lang.reflect.Constructor; import java.util.ArrayList; @@ -26,17 +27,15 @@ public class TestFlowManager { */ public static void registerTestFlow(String name, String handler, List players, List serverConfigs) { if (activeTestFlows.containsKey(name)) { - System.out.println("[WARN] Test flow " + name + " is already registered, ignoring duplicate registration"); + Logger.warn("Test flow {} is already registered, ignoring duplicate registration", name); return; } ProxyTestFlowInstance instance = new ProxyTestFlowInstance(name, handler, players, serverConfigs); activeTestFlows.put(name, instance); - System.out.println("[INFO] Registered test flow: " + name); - System.out.println("[INFO] Handler: " + handler); - System.out.println("[INFO] Players: " + players); - System.out.println("[INFO] Expected servers: " + instance.getTotalExpectedServers()); + Logger.info("Registered test flow: {} (handler={}, players={}, expectedServers={})", + name, handler, players, instance.getTotalExpectedServers()); // Try to load and instantiate the handler loadTestFlowHandler(instance); @@ -48,17 +47,17 @@ public static void registerTestFlow(String name, String handler, List pl public static void markServerReady(String testFlowName, ServerType serverType, int serverIndex, UUID serverUUID) { ProxyTestFlowInstance instance = activeTestFlows.get(testFlowName); if (instance == null) { - System.out.println("[WARN] Received server ready notification for unknown test flow: " + testFlowName); + Logger.warn("Received server ready notification for unknown test flow: {}", testFlowName); return; } instance.markServerReady(serverType, serverIndex, serverUUID); - System.out.println("[INFO] Server " + serverType.name() + " #" + serverIndex + " is ready for test flow: " + testFlowName); + Logger.info("Server {} #{} is ready for test flow: {}", serverType.name(), serverIndex, testFlowName); // Only trigger "all servers ready" once when we actually reach the total count if (instance.areAllServersReady() && !instance.isAllServersReadyTriggered()) { instance.setAllServersReadyTriggered(true); - System.out.println("[INFO] All servers are ready for test flow: " + testFlowName); + Logger.info("All servers are ready for test flow: {}", testFlowName); if (instance.getHandler() != null) { instance.getHandler().onAllServersReady(instance); } @@ -72,17 +71,15 @@ public static void markServerReady(String testFlowName, ServerType serverType, i public static void handleServerDisconnect(UUID serverUUID) { activeTestFlows.values().forEach(instance -> { if (instance.getServerUUIDs().contains(serverUUID)) { - System.out.println("[INFO] Test flow server disconnected: " + serverUUID + " from test flow: " + instance.getName()); + Logger.info("Test flow server disconnected: {} from test flow: {}", serverUUID, instance.getName()); - // Remove the server from the ready servers list instance.removeServer(serverUUID); - // Check if any servers are still online for this test flow if (instance.hasAnyServersOnline()) { - System.out.println("[INFO] Test flow " + instance.getName() + " still has " + - instance.getOnlineServerCount() + " servers online"); + Logger.info("Test flow {} still has {} servers online", + instance.getName(), instance.getOnlineServerCount()); } else { - System.out.println("[WARN] All servers for test flow " + instance.getName() + " are offline, cleaning up..."); + Logger.warn("All servers for test flow {} are offline, cleaning up...", instance.getName()); cleanupTestFlow(instance.getName()); } } @@ -96,20 +93,18 @@ public static void handleServerDisconnect(UUID serverUUID) { private static void cleanupTestFlow(String testFlowName) { ProxyTestFlowInstance instance = activeTestFlows.get(testFlowName); if (instance != null) { - System.out.println("[INFO] Cleaning up test flow: " + testFlowName); + Logger.info("Cleaning up test flow: {}", testFlowName); - // Notify handler that test flow is ending if (instance.getHandler() != null) { try { instance.getHandler().onTestFlowEnd(instance); } catch (Exception e) { - System.out.println("[ERROR] Error in test flow handler onTestFlowEnd: " + e.getMessage()); + Logger.error(e, "Error in test flow handler onTestFlowEnd"); } } - // Remove from active test flows activeTestFlows.remove(testFlowName); - System.out.println("[INFO] Test flow " + testFlowName + " has been cleaned up and removed"); + Logger.info("Test flow {} has been cleaned up and removed", testFlowName); } } @@ -157,7 +152,7 @@ public static void unregisterTestFlow(String name) { ProxyTestFlowInstance instance = activeTestFlows.remove(name); if (instance != null && instance.getHandler() != null) { instance.getHandler().onTestFlowEnd(instance); - System.out.println("[INFO] Unregistered test flow: " + name); + Logger.info("Unregistered test flow: {}", name); } } @@ -202,12 +197,12 @@ private static void loadTestFlowHandler(ProxyTestFlowInstance instance) { ProxyTestFlowHandler handler = (ProxyTestFlowHandler) constructor.newInstance(); instance.setHandler(handler); handler.onTestFlowStart(instance); - System.out.println("[INFO] Successfully loaded test flow handler: " + handlerName); + Logger.info("Successfully loaded test flow handler: {}", handlerName); } else { - System.out.println("[ERROR] Handler " + handlerName + " does not extend ProxyTestFlowHandler"); + Logger.error("Handler {} does not extend ProxyTestFlowHandler", handlerName); } } catch (Exception e) { - System.out.println("[ERROR] Failed to load test flow handler: " + instance.getHandlerClassName() + " - " + e.getMessage()); + Logger.error(e, "Failed to load test flow handler: {}", instance.getHandlerClassName()); } } diff --git a/velocity.extension/src/main/java/net/swofty/velocity/testflow/handlers/SendToHubTestFlowHandler.java b/velocity.extension/src/main/java/net/swofty/velocity/testflow/handlers/SendToHubTestFlowHandler.java index 8ec7559e3..3988cf4a7 100644 --- a/velocity.extension/src/main/java/net/swofty/velocity/testflow/handlers/SendToHubTestFlowHandler.java +++ b/velocity.extension/src/main/java/net/swofty/velocity/testflow/handlers/SendToHubTestFlowHandler.java @@ -3,6 +3,7 @@ import net.swofty.velocity.SkyBlockVelocity; import net.swofty.velocity.testflow.ProxyTestFlowHandler; import net.swofty.velocity.testflow.TestFlowManager; +import org.tinylog.Logger; public class SendToHubTestFlowHandler extends ProxyTestFlowHandler { @@ -28,19 +29,20 @@ public void onPlayerLeave(String playerName, TestFlowManager.ProxyTestFlowInstan @Override public void onTestFlowEnd(TestFlowManager.ProxyTestFlowInstance instance) { - System.out.println("Example test flow ended: " + instance.getName()); + Logger.info("Example test flow ended: {}", instance.getName()); } @Override public void onPeriodicUpdate(TestFlowManager.ProxyTestFlowInstance instance) { if (instance.getUptime() % 300000 == 0) { - System.out.println("Test flow " + instance.getName() + " status update:"); - System.out.println(" Runtime: " + (instance.getUptime() / 1000) + " seconds"); - System.out.println(" Active servers: " + instance.getGameServers().size()); - System.out.println(" Online test players: " + - instance.getPlayers().stream() - .mapToLong(name -> SkyBlockVelocity.getServer().getPlayer(name).isPresent() ? 1 : 0) - .sum()); + long onlinePlayers = instance.getPlayers().stream() + .mapToLong(name -> SkyBlockVelocity.getServer().getPlayer(name).isPresent() ? 1 : 0) + .sum(); + Logger.info("Test flow {} status — runtime: {}s, active servers: {}, online test players: {}", + instance.getName(), + instance.getUptime() / 1000, + instance.getGameServers().size(), + onlinePlayers); } } } \ No newline at end of file From 5f06714d000e4f577477b17c97f7af6c27438103 Mon Sep 17 00:00:00 2001 From: "Jacob Nardella (Swofty)" Date: Fri, 15 May 2026 00:16:01 +1000 Subject: [PATCH 030/113] fix(punishment): use jedis.expire(String, long) instead of (String, int) Newer jedis versions deprecate the int-seconds overload. The cast to int was also a silent truncation hazard for TTLs near 2^31s. --- .../java/net/swofty/commons/punishment/PunishmentRedis.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/commons/src/main/java/net/swofty/commons/punishment/PunishmentRedis.java b/commons/src/main/java/net/swofty/commons/punishment/PunishmentRedis.java index b71c84e1d..c1d1e8faf 100644 --- a/commons/src/main/java/net/swofty/commons/punishment/PunishmentRedis.java +++ b/commons/src/main/java/net/swofty/commons/punishment/PunishmentRedis.java @@ -88,7 +88,7 @@ public static void saveActivePunishment(UUID playerId, String type, String id, if (expiresAt > 0) { long ttlSeconds = (expiresAt - System.currentTimeMillis()) / 1000; if (ttlSeconds > 0) { - jedis.expire(redisKey, (int) ttlSeconds); + jedis.expire(redisKey, ttlSeconds); } } else { jedis.persist(redisKey); From 4971e0779f4df8fc15b1bcd94eaa661672e3909a Mon Sep 17 00:00:00 2001 From: "Jacob Nardella (Swofty)" Date: Fri, 15 May 2026 00:17:17 +1000 Subject: [PATCH 031/113] refactor(velocity): clean up BalanceConfigurations MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Several improvements to the load-balancer config: - Hoisted the two strategy instances (IslandCheck, LowestPlayerCount) to constants — they're stateless and the previous code allocated a fresh copy for every server type entry, which is wasteful and obscures the fact that 'lowest player count' is one logical configuration. - DEFAULT_CHAIN constant for the 24 server types that share the same one-element pipeline, replacing 24 lines of `List.of(new ...)`. - Made the map immutable + final + uppercased to match Java conventions for shared configuration; the field was technically a HashMap initialised from Map.ofEntries(), which gave a misleading 'mutable' signal even though the bridge map was immutable. - Extracted the 'is server eligible for this player' decision out of the inner loop into two named methods — easier to read and the null-check on the test-flow lookup that the previous code missed (NPE-able if getFromServerUUID returned null) is now explicit. - private constructor — class is purely static. - Routed the catch-and-rethrow log through tinylog instead of stdout. --- .../net/swofty/velocity/SkyBlockVelocity.java | 2 +- .../gamemanager/BalanceConfigurations.java | 204 +++++++----------- 2 files changed, 80 insertions(+), 126 deletions(-) diff --git a/velocity.extension/src/main/java/net/swofty/velocity/SkyBlockVelocity.java b/velocity.extension/src/main/java/net/swofty/velocity/SkyBlockVelocity.java index 1c321ed7f..139bf511c 100644 --- a/velocity.extension/src/main/java/net/swofty/velocity/SkyBlockVelocity.java +++ b/velocity.extension/src/main/java/net/swofty/velocity/SkyBlockVelocity.java @@ -359,7 +359,7 @@ public EventTask onPlayerJoin(PlayerChooseInitialServerEvent event) { return; } - List configurations = BalanceConfigurations.configurations.get(ServerType.BEDWARS_LOBBY); + List configurations = BalanceConfigurations.CONFIGURATIONS.get(ServerType.BEDWARS_LOBBY); GameManager.GameServer toSendTo = gameServers.getFirst(); for (BalanceConfiguration configuration : configurations) { diff --git a/velocity.extension/src/main/java/net/swofty/velocity/gamemanager/BalanceConfigurations.java b/velocity.extension/src/main/java/net/swofty/velocity/gamemanager/BalanceConfigurations.java index ada937516..b993b1ce1 100644 --- a/velocity.extension/src/main/java/net/swofty/velocity/gamemanager/BalanceConfigurations.java +++ b/velocity.extension/src/main/java/net/swofty/velocity/gamemanager/BalanceConfigurations.java @@ -6,143 +6,97 @@ import net.swofty.velocity.gamemanager.impl.LowestPlayerCount; import net.swofty.velocity.testflow.TestFlowManager; import org.jetbrains.annotations.Nullable; +import org.tinylog.Logger; -import java.util.HashMap; import java.util.List; import java.util.Map; -public class BalanceConfigurations { - public static HashMap> configurations = new HashMap<>(Map.ofEntries( - Map.entry(ServerType.SKYBLOCK_ISLAND, List.of( - new IslandCheck(), - new LowestPlayerCount() - )), - Map.entry(ServerType.SKYBLOCK_HUB, List.of( - new LowestPlayerCount() - )), - Map.entry(ServerType.SKYBLOCK_DUNGEON_HUB, List.of( - new LowestPlayerCount() - )), - Map.entry(ServerType.SKYBLOCK_THE_FARMING_ISLANDS, List.of( - new LowestPlayerCount() - )), - Map.entry(ServerType.SKYBLOCK_SPIDERS_DEN, List.of( - new LowestPlayerCount() - )), - Map.entry(ServerType.SKYBLOCK_THE_END, List.of( - new LowestPlayerCount() - )), - Map.entry(ServerType.SKYBLOCK_CRIMSON_ISLE, List.of( - new LowestPlayerCount() - )), - Map.entry(ServerType.SKYBLOCK_GOLD_MINE, List.of( - new LowestPlayerCount() - )), - Map.entry(ServerType.SKYBLOCK_DEEP_CAVERNS, List.of( - new LowestPlayerCount() - )), - Map.entry(ServerType.SKYBLOCK_DWARVEN_MINES, List.of( - new LowestPlayerCount() - )), - Map.entry(ServerType.SKYBLOCK_THE_PARK, List.of( - new LowestPlayerCount() - )), - Map.entry(ServerType.SKYBLOCK_GALATEA, List.of( - new LowestPlayerCount() - )), - Map.entry(ServerType.SKYBLOCK_BACKWATER_BAYOU, List.of( - new LowestPlayerCount() - )), - Map.entry(ServerType.SKYBLOCK_JERRYS_WORKSHOP, List.of( - new LowestPlayerCount() - )), - Map.entry(ServerType.PROTOTYPE_LOBBY, List.of( - new LowestPlayerCount() - )), - Map.entry(ServerType.BEDWARS_LOBBY, List.of( - new LowestPlayerCount() - )), - Map.entry(ServerType.BEDWARS_GAME, List.of( - new LowestPlayerCount() - )), - Map.entry(ServerType.SKYWARS_LOBBY, List.of( - new LowestPlayerCount() - )), - Map.entry(ServerType.SKYWARS_GAME, List.of( - new LowestPlayerCount() - )), - Map.entry(ServerType.MURDER_MYSTERY_LOBBY, List.of( - new LowestPlayerCount() - )), - Map.entry(ServerType.MURDER_MYSTERY_GAME, List.of( - new LowestPlayerCount() - )), - Map.entry(ServerType.SKYWARS_CONFIGURATOR, List.of( - new LowestPlayerCount() - )), - Map.entry(ServerType.BEDWARS_CONFIGURATOR, List.of( - new LowestPlayerCount() - )), - Map.entry(ServerType.MURDER_MYSTERY_CONFIGURATOR, List.of( - new LowestPlayerCount() - )), - Map.entry(ServerType.RAVENGARD_LOBBY, List.of( - new LowestPlayerCount() - )) - )); +public final class BalanceConfigurations { - public static @Nullable GameManager.GameServer getServerFor(Player player, ServerType type) { - if (TestFlowManager.isPlayerInTestFlow(player.getUsername())) { - player.sendPlainMessage("§eYou are currently in a network-isolated test flow, load balancing will be restricted to test flow servers!"); - player.sendPlainMessage("§8Executing test flow " + TestFlowManager.getTestFlowForPlayer(player.getUsername()).getName() + "..."); - } + // Shared singletons — the strategies are stateless, so there's no reason to + // hold 25+ separate instances when one per kind suffices. + private static final BalanceConfiguration ISLAND_CHECK = new IslandCheck(); + private static final BalanceConfiguration LOWEST_PLAYER_COUNT = new LowestPlayerCount(); + private static final List DEFAULT_CHAIN = List.of(LOWEST_PLAYER_COUNT); - try { - for (BalanceConfiguration configuration : configurations.get(type)) { - List serversToConsider = GameManager.getFromType(type); - if (TestFlowManager.isPlayerInTestFlow(player.getUsername())) { - serversToConsider.removeIf(server -> { - boolean remove = server.maxPlayers() <= server.registeredServer().getPlayersConnected().size(); + public static final Map> CONFIGURATIONS = Map.ofEntries( + Map.entry(ServerType.SKYBLOCK_ISLAND, List.of(ISLAND_CHECK, LOWEST_PLAYER_COUNT)), + Map.entry(ServerType.SKYBLOCK_HUB, DEFAULT_CHAIN), + Map.entry(ServerType.SKYBLOCK_DUNGEON_HUB, DEFAULT_CHAIN), + Map.entry(ServerType.SKYBLOCK_THE_FARMING_ISLANDS, DEFAULT_CHAIN), + Map.entry(ServerType.SKYBLOCK_SPIDERS_DEN, DEFAULT_CHAIN), + Map.entry(ServerType.SKYBLOCK_THE_END, DEFAULT_CHAIN), + Map.entry(ServerType.SKYBLOCK_CRIMSON_ISLE, DEFAULT_CHAIN), + Map.entry(ServerType.SKYBLOCK_GOLD_MINE, DEFAULT_CHAIN), + Map.entry(ServerType.SKYBLOCK_DEEP_CAVERNS, DEFAULT_CHAIN), + Map.entry(ServerType.SKYBLOCK_DWARVEN_MINES, DEFAULT_CHAIN), + Map.entry(ServerType.SKYBLOCK_THE_PARK, DEFAULT_CHAIN), + Map.entry(ServerType.SKYBLOCK_GALATEA, DEFAULT_CHAIN), + Map.entry(ServerType.SKYBLOCK_BACKWATER_BAYOU, DEFAULT_CHAIN), + Map.entry(ServerType.SKYBLOCK_JERRYS_WORKSHOP, DEFAULT_CHAIN), + Map.entry(ServerType.PROTOTYPE_LOBBY, DEFAULT_CHAIN), + Map.entry(ServerType.BEDWARS_LOBBY, DEFAULT_CHAIN), + Map.entry(ServerType.BEDWARS_GAME, DEFAULT_CHAIN), + Map.entry(ServerType.SKYWARS_LOBBY, DEFAULT_CHAIN), + Map.entry(ServerType.SKYWARS_GAME, DEFAULT_CHAIN), + Map.entry(ServerType.MURDER_MYSTERY_LOBBY, DEFAULT_CHAIN), + Map.entry(ServerType.MURDER_MYSTERY_GAME, DEFAULT_CHAIN), + Map.entry(ServerType.SKYWARS_CONFIGURATOR, DEFAULT_CHAIN), + Map.entry(ServerType.BEDWARS_CONFIGURATOR, DEFAULT_CHAIN), + Map.entry(ServerType.MURDER_MYSTERY_CONFIGURATOR, DEFAULT_CHAIN), + Map.entry(ServerType.RAVENGARD_LOBBY, DEFAULT_CHAIN) + ); - if (!TestFlowManager.isServerInTestFlow(server.internalID())) { - remove = true; - } + private BalanceConfigurations() { + } - TestFlowManager.ProxyTestFlowInstance testFlowInstance = TestFlowManager.getFromServerUUID( - server.internalID() - ); + public static @Nullable GameManager.GameServer getServerFor(Player player, ServerType type) { + final boolean inTestFlow = TestFlowManager.isPlayerInTestFlow(player.getUsername()); + if (inTestFlow) { + player.sendPlainMessage("§eYou are currently in a network-isolated test flow, load balancing will be restricted to test flow servers!"); + player.sendPlainMessage("§8Executing test flow " + + TestFlowManager.getTestFlowForPlayer(player.getUsername()).getName() + "..."); + } - if (!testFlowInstance.hasPlayer(player.getUsername())) { - remove = true; - } + try { + for (BalanceConfiguration configuration : CONFIGURATIONS.get(type)) { + List serversToConsider = GameManager.getFromType(type); + if (inTestFlow) { + serversToConsider.removeIf(server -> !isEligibleForTestFlowPlayer(server, player)); + } else { + serversToConsider.removeIf(server -> !isEligibleForRegularPlayer(server)); + } - return remove; - }); - } else { - serversToConsider.removeIf(server -> { - boolean remove = server.maxPlayers() <= server.registeredServer().getPlayersConnected().size(); + GameManager.GameServer server = configuration.getServer(player, serversToConsider); + if (server != null) { + if (inTestFlow) { + player.sendPlainMessage("§8Done overriding the server manager for your test flow."); + } + return server; + } + } + return null; + } catch (Exception e) { + Logger.error(e, "Error in trying to balance type {} for player {}", + type.name(), player.getUsername()); + throw e; + } + } - if (TestFlowManager.isServerInTestFlow(server.internalID())) { - remove = true; - } + private static boolean hasCapacity(GameManager.GameServer server) { + return server.maxPlayers() > server.registeredServer().getPlayersConnected().size(); + } - return remove; - }); - } + private static boolean isEligibleForRegularPlayer(GameManager.GameServer server) { + return hasCapacity(server) && !TestFlowManager.isServerInTestFlow(server.internalID()); + } - GameManager.GameServer server = configuration.getServer(player, serversToConsider); + private static boolean isEligibleForTestFlowPlayer(GameManager.GameServer server, Player player) { + if (!hasCapacity(server)) return false; + if (!TestFlowManager.isServerInTestFlow(server.internalID())) return false; - if (server != null) { - if (TestFlowManager.isPlayerInTestFlow(player.getUsername())) { - player.sendPlainMessage("§8Done overriding the server manager for your test flow."); - } - return server; - } - } - return null; - } catch (Exception e) { - System.out.println("Error in trying to balance type " + type.name() + " for player " + player.getUsername()); - throw e; - } - } + TestFlowManager.ProxyTestFlowInstance instance = + TestFlowManager.getFromServerUUID(server.internalID()); + return instance != null && instance.hasPlayer(player.getUsername()); + } } From 5418fe4bd4940381587085905fb78118e50e7342 Mon Sep 17 00:00:00 2001 From: "Jacob Nardella (Swofty)" Date: Fri, 15 May 2026 00:19:57 +1000 Subject: [PATCH 032/113] refactor(velocity): LowestPlayerCount uses a hoisted Comparator MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The previous min(comparator) lambda computed both player counts on every comparison and called Integer.compare manually. Comparator.comparingInt extracts the key once per element and is both shorter and idiomatic. Hoisted it to a static field since the strategy is reused via the shared instance in BalanceConfigurations. Class made final — no subclasses anywhere in the tree. --- .../gamemanager/impl/LowestPlayerCount.java | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) diff --git a/velocity.extension/src/main/java/net/swofty/velocity/gamemanager/impl/LowestPlayerCount.java b/velocity.extension/src/main/java/net/swofty/velocity/gamemanager/impl/LowestPlayerCount.java index 35a56e11c..17e4b5a92 100644 --- a/velocity.extension/src/main/java/net/swofty/velocity/gamemanager/impl/LowestPlayerCount.java +++ b/velocity.extension/src/main/java/net/swofty/velocity/gamemanager/impl/LowestPlayerCount.java @@ -4,17 +4,16 @@ import net.swofty.velocity.gamemanager.BalanceConfiguration; import net.swofty.velocity.gamemanager.GameManager; +import java.util.Comparator; import java.util.List; -public class LowestPlayerCount extends BalanceConfiguration { +public final class LowestPlayerCount extends BalanceConfiguration { + + private static final Comparator BY_PLAYER_COUNT = + Comparator.comparingInt(server -> server.registeredServer().getPlayersConnected().size()); @Override public GameManager.GameServer getServer(Player player, List servers) { - return servers.stream().min((server1, server2) -> { - int server1Players = server1.registeredServer().getPlayersConnected().size(); - int server2Players = server2.registeredServer().getPlayersConnected().size(); - - return Integer.compare(server1Players, server2Players); - }).orElse(null); + return servers.stream().min(BY_PLAYER_COUNT).orElse(null); } } From 2117647709ef36ad4f1e91b137fa0af02eaa7380 Mon Sep 17 00:00:00 2001 From: "Jacob Nardella (Swofty)" Date: Fri, 15 May 2026 00:22:16 +1000 Subject: [PATCH 033/113] refactor(commons): mark FriendEvent subclasses final Each direct subclass of FriendEvent and FriendResponseEvent is now final, codifying what the @JsonSubTypes annotation already documented: the hierarchy is closed and serialisation knows every concrete type. Tried making the parents sealed first, but sealed-class rules require permitted subtypes in the same module (or same package); the events live under .events and .events.response subpackages and the project isn't modularised. Final is the closest we get without flattening the package layout. --- .../swofty/commons/friend/events/FriendAcceptRequestEvent.java | 2 +- .../net/swofty/commons/friend/events/FriendAddRequestEvent.java | 2 +- .../swofty/commons/friend/events/FriendDenyRequestEvent.java | 2 +- .../swofty/commons/friend/events/FriendListRequestEvent.java | 2 +- .../commons/friend/events/FriendRemoveAllRequestEvent.java | 2 +- .../swofty/commons/friend/events/FriendRemoveRequestEvent.java | 2 +- .../swofty/commons/friend/events/FriendRequestsListEvent.java | 2 +- .../commons/friend/events/FriendSetNicknameRequestEvent.java | 2 +- .../commons/friend/events/FriendToggleBestRequestEvent.java | 2 +- .../commons/friend/events/FriendToggleSettingRequestEvent.java | 2 +- .../friend/events/response/FriendAddedResponseEvent.java | 2 +- .../friend/events/response/FriendBestToggledResponseEvent.java | 2 +- .../friend/events/response/FriendDeniedResponseEvent.java | 2 +- .../friend/events/response/FriendJoinNotificationEvent.java | 2 +- .../friend/events/response/FriendLeaveNotificationEvent.java | 2 +- .../commons/friend/events/response/FriendListResponseEvent.java | 2 +- .../friend/events/response/FriendNicknameSetResponseEvent.java | 2 +- .../friend/events/response/FriendRemoveAllResponseEvent.java | 2 +- .../friend/events/response/FriendRemovedResponseEvent.java | 2 +- .../events/response/FriendRequestExpiredResponseEvent.java | 2 +- .../events/response/FriendRequestReceivedResponseEvent.java | 2 +- .../friend/events/response/FriendRequestSentResponseEvent.java | 2 +- .../friend/events/response/FriendRequestsListResponseEvent.java | 2 +- .../events/response/FriendSettingToggledResponseEvent.java | 2 +- 24 files changed, 24 insertions(+), 24 deletions(-) diff --git a/commons/src/main/java/net/swofty/commons/friend/events/FriendAcceptRequestEvent.java b/commons/src/main/java/net/swofty/commons/friend/events/FriendAcceptRequestEvent.java index e3f766a09..f3227850c 100644 --- a/commons/src/main/java/net/swofty/commons/friend/events/FriendAcceptRequestEvent.java +++ b/commons/src/main/java/net/swofty/commons/friend/events/FriendAcceptRequestEvent.java @@ -11,7 +11,7 @@ import java.util.UUID; @Getter -public class FriendAcceptRequestEvent extends FriendEvent { +public final class FriendAcceptRequestEvent extends FriendEvent { private final UUID accepter; private final UUID requester; diff --git a/commons/src/main/java/net/swofty/commons/friend/events/FriendAddRequestEvent.java b/commons/src/main/java/net/swofty/commons/friend/events/FriendAddRequestEvent.java index c8b0b6499..ade32ae32 100644 --- a/commons/src/main/java/net/swofty/commons/friend/events/FriendAddRequestEvent.java +++ b/commons/src/main/java/net/swofty/commons/friend/events/FriendAddRequestEvent.java @@ -11,7 +11,7 @@ import java.util.UUID; @Getter -public class FriendAddRequestEvent extends FriendEvent { +public final class FriendAddRequestEvent extends FriendEvent { private final UUID sender; private final UUID target; diff --git a/commons/src/main/java/net/swofty/commons/friend/events/FriendDenyRequestEvent.java b/commons/src/main/java/net/swofty/commons/friend/events/FriendDenyRequestEvent.java index 1f9471b91..f8b3957d3 100644 --- a/commons/src/main/java/net/swofty/commons/friend/events/FriendDenyRequestEvent.java +++ b/commons/src/main/java/net/swofty/commons/friend/events/FriendDenyRequestEvent.java @@ -11,7 +11,7 @@ import java.util.UUID; @Getter -public class FriendDenyRequestEvent extends FriendEvent { +public final class FriendDenyRequestEvent extends FriendEvent { private final UUID denier; private final UUID requester; diff --git a/commons/src/main/java/net/swofty/commons/friend/events/FriendListRequestEvent.java b/commons/src/main/java/net/swofty/commons/friend/events/FriendListRequestEvent.java index da60bea92..bd1367cb4 100644 --- a/commons/src/main/java/net/swofty/commons/friend/events/FriendListRequestEvent.java +++ b/commons/src/main/java/net/swofty/commons/friend/events/FriendListRequestEvent.java @@ -11,7 +11,7 @@ import java.util.UUID; @Getter -public class FriendListRequestEvent extends FriendEvent { +public final class FriendListRequestEvent extends FriendEvent { private final UUID player; private final int page; private final boolean bestOnly; diff --git a/commons/src/main/java/net/swofty/commons/friend/events/FriendRemoveAllRequestEvent.java b/commons/src/main/java/net/swofty/commons/friend/events/FriendRemoveAllRequestEvent.java index ea84ad532..ceb903e3b 100644 --- a/commons/src/main/java/net/swofty/commons/friend/events/FriendRemoveAllRequestEvent.java +++ b/commons/src/main/java/net/swofty/commons/friend/events/FriendRemoveAllRequestEvent.java @@ -11,7 +11,7 @@ import java.util.UUID; @Getter -public class FriendRemoveAllRequestEvent extends FriendEvent { +public final class FriendRemoveAllRequestEvent extends FriendEvent { private final UUID player; @JsonCreator diff --git a/commons/src/main/java/net/swofty/commons/friend/events/FriendRemoveRequestEvent.java b/commons/src/main/java/net/swofty/commons/friend/events/FriendRemoveRequestEvent.java index 9806a28a3..1832af2f5 100644 --- a/commons/src/main/java/net/swofty/commons/friend/events/FriendRemoveRequestEvent.java +++ b/commons/src/main/java/net/swofty/commons/friend/events/FriendRemoveRequestEvent.java @@ -11,7 +11,7 @@ import java.util.UUID; @Getter -public class FriendRemoveRequestEvent extends FriendEvent { +public final class FriendRemoveRequestEvent extends FriendEvent { private final UUID remover; private final UUID target; diff --git a/commons/src/main/java/net/swofty/commons/friend/events/FriendRequestsListEvent.java b/commons/src/main/java/net/swofty/commons/friend/events/FriendRequestsListEvent.java index e70fd689b..07bb10d6c 100644 --- a/commons/src/main/java/net/swofty/commons/friend/events/FriendRequestsListEvent.java +++ b/commons/src/main/java/net/swofty/commons/friend/events/FriendRequestsListEvent.java @@ -11,7 +11,7 @@ import java.util.UUID; @Getter -public class FriendRequestsListEvent extends FriendEvent { +public final class FriendRequestsListEvent extends FriendEvent { private final UUID player; private final int page; diff --git a/commons/src/main/java/net/swofty/commons/friend/events/FriendSetNicknameRequestEvent.java b/commons/src/main/java/net/swofty/commons/friend/events/FriendSetNicknameRequestEvent.java index f3e301292..6c2dabd60 100644 --- a/commons/src/main/java/net/swofty/commons/friend/events/FriendSetNicknameRequestEvent.java +++ b/commons/src/main/java/net/swofty/commons/friend/events/FriendSetNicknameRequestEvent.java @@ -11,7 +11,7 @@ import java.util.UUID; @Getter -public class FriendSetNicknameRequestEvent extends FriendEvent { +public final class FriendSetNicknameRequestEvent extends FriendEvent { private final UUID player; private final UUID target; private final String nickname; diff --git a/commons/src/main/java/net/swofty/commons/friend/events/FriendToggleBestRequestEvent.java b/commons/src/main/java/net/swofty/commons/friend/events/FriendToggleBestRequestEvent.java index 9bffd85fd..fdf740649 100644 --- a/commons/src/main/java/net/swofty/commons/friend/events/FriendToggleBestRequestEvent.java +++ b/commons/src/main/java/net/swofty/commons/friend/events/FriendToggleBestRequestEvent.java @@ -11,7 +11,7 @@ import java.util.UUID; @Getter -public class FriendToggleBestRequestEvent extends FriendEvent { +public final class FriendToggleBestRequestEvent extends FriendEvent { private final UUID player; private final UUID target; diff --git a/commons/src/main/java/net/swofty/commons/friend/events/FriendToggleSettingRequestEvent.java b/commons/src/main/java/net/swofty/commons/friend/events/FriendToggleSettingRequestEvent.java index 5075a0bf3..a9fee58d1 100644 --- a/commons/src/main/java/net/swofty/commons/friend/events/FriendToggleSettingRequestEvent.java +++ b/commons/src/main/java/net/swofty/commons/friend/events/FriendToggleSettingRequestEvent.java @@ -12,7 +12,7 @@ import java.util.UUID; @Getter -public class FriendToggleSettingRequestEvent extends FriendEvent { +public final class FriendToggleSettingRequestEvent extends FriendEvent { private final UUID player; private final FriendSettingType settingType; diff --git a/commons/src/main/java/net/swofty/commons/friend/events/response/FriendAddedResponseEvent.java b/commons/src/main/java/net/swofty/commons/friend/events/response/FriendAddedResponseEvent.java index 930a0dc8e..82eebe4ef 100644 --- a/commons/src/main/java/net/swofty/commons/friend/events/response/FriendAddedResponseEvent.java +++ b/commons/src/main/java/net/swofty/commons/friend/events/response/FriendAddedResponseEvent.java @@ -11,7 +11,7 @@ import java.util.UUID; @Getter -public class FriendAddedResponseEvent extends FriendResponseEvent { +public final class FriendAddedResponseEvent extends FriendResponseEvent { private final UUID player1; private final UUID player2; private final String player1Name; diff --git a/commons/src/main/java/net/swofty/commons/friend/events/response/FriendBestToggledResponseEvent.java b/commons/src/main/java/net/swofty/commons/friend/events/response/FriendBestToggledResponseEvent.java index 43bdfe48e..fdc118a59 100644 --- a/commons/src/main/java/net/swofty/commons/friend/events/response/FriendBestToggledResponseEvent.java +++ b/commons/src/main/java/net/swofty/commons/friend/events/response/FriendBestToggledResponseEvent.java @@ -11,7 +11,7 @@ import java.util.UUID; @Getter -public class FriendBestToggledResponseEvent extends FriendResponseEvent { +public final class FriendBestToggledResponseEvent extends FriendResponseEvent { private final UUID player; private final UUID target; private final String targetName; diff --git a/commons/src/main/java/net/swofty/commons/friend/events/response/FriendDeniedResponseEvent.java b/commons/src/main/java/net/swofty/commons/friend/events/response/FriendDeniedResponseEvent.java index 3edec7a9c..b454425df 100644 --- a/commons/src/main/java/net/swofty/commons/friend/events/response/FriendDeniedResponseEvent.java +++ b/commons/src/main/java/net/swofty/commons/friend/events/response/FriendDeniedResponseEvent.java @@ -11,7 +11,7 @@ import java.util.UUID; @Getter -public class FriendDeniedResponseEvent extends FriendResponseEvent { +public final class FriendDeniedResponseEvent extends FriendResponseEvent { private final UUID denier; private final UUID requester; private final String denierName; diff --git a/commons/src/main/java/net/swofty/commons/friend/events/response/FriendJoinNotificationEvent.java b/commons/src/main/java/net/swofty/commons/friend/events/response/FriendJoinNotificationEvent.java index b02dcc2d7..b48a90348 100644 --- a/commons/src/main/java/net/swofty/commons/friend/events/response/FriendJoinNotificationEvent.java +++ b/commons/src/main/java/net/swofty/commons/friend/events/response/FriendJoinNotificationEvent.java @@ -11,7 +11,7 @@ import java.util.UUID; @Getter -public class FriendJoinNotificationEvent extends FriendResponseEvent { +public final class FriendJoinNotificationEvent extends FriendResponseEvent { private final UUID player; private final UUID friend; private final String friendName; diff --git a/commons/src/main/java/net/swofty/commons/friend/events/response/FriendLeaveNotificationEvent.java b/commons/src/main/java/net/swofty/commons/friend/events/response/FriendLeaveNotificationEvent.java index 0cd735b07..3c8c8d4c4 100644 --- a/commons/src/main/java/net/swofty/commons/friend/events/response/FriendLeaveNotificationEvent.java +++ b/commons/src/main/java/net/swofty/commons/friend/events/response/FriendLeaveNotificationEvent.java @@ -11,7 +11,7 @@ import java.util.UUID; @Getter -public class FriendLeaveNotificationEvent extends FriendResponseEvent { +public final class FriendLeaveNotificationEvent extends FriendResponseEvent { private final UUID player; private final UUID friend; private final String friendName; diff --git a/commons/src/main/java/net/swofty/commons/friend/events/response/FriendListResponseEvent.java b/commons/src/main/java/net/swofty/commons/friend/events/response/FriendListResponseEvent.java index 80a33e6c5..4b2579e4b 100644 --- a/commons/src/main/java/net/swofty/commons/friend/events/response/FriendListResponseEvent.java +++ b/commons/src/main/java/net/swofty/commons/friend/events/response/FriendListResponseEvent.java @@ -13,7 +13,7 @@ import java.util.UUID; @Getter -public class FriendListResponseEvent extends FriendResponseEvent { +public final class FriendListResponseEvent extends FriendResponseEvent { private final UUID player; private final List friends; private final int page; diff --git a/commons/src/main/java/net/swofty/commons/friend/events/response/FriendNicknameSetResponseEvent.java b/commons/src/main/java/net/swofty/commons/friend/events/response/FriendNicknameSetResponseEvent.java index 0f7bcea73..c82d07e23 100644 --- a/commons/src/main/java/net/swofty/commons/friend/events/response/FriendNicknameSetResponseEvent.java +++ b/commons/src/main/java/net/swofty/commons/friend/events/response/FriendNicknameSetResponseEvent.java @@ -11,7 +11,7 @@ import java.util.UUID; @Getter -public class FriendNicknameSetResponseEvent extends FriendResponseEvent { +public final class FriendNicknameSetResponseEvent extends FriendResponseEvent { private final UUID player; private final UUID target; private final String targetName; diff --git a/commons/src/main/java/net/swofty/commons/friend/events/response/FriendRemoveAllResponseEvent.java b/commons/src/main/java/net/swofty/commons/friend/events/response/FriendRemoveAllResponseEvent.java index 95ac65804..66b835348 100644 --- a/commons/src/main/java/net/swofty/commons/friend/events/response/FriendRemoveAllResponseEvent.java +++ b/commons/src/main/java/net/swofty/commons/friend/events/response/FriendRemoveAllResponseEvent.java @@ -11,7 +11,7 @@ import java.util.UUID; @Getter -public class FriendRemoveAllResponseEvent extends FriendResponseEvent { +public final class FriendRemoveAllResponseEvent extends FriendResponseEvent { private final UUID player; private final int removedCount; diff --git a/commons/src/main/java/net/swofty/commons/friend/events/response/FriendRemovedResponseEvent.java b/commons/src/main/java/net/swofty/commons/friend/events/response/FriendRemovedResponseEvent.java index e8ceeb569..60e8572b9 100644 --- a/commons/src/main/java/net/swofty/commons/friend/events/response/FriendRemovedResponseEvent.java +++ b/commons/src/main/java/net/swofty/commons/friend/events/response/FriendRemovedResponseEvent.java @@ -11,7 +11,7 @@ import java.util.UUID; @Getter -public class FriendRemovedResponseEvent extends FriendResponseEvent { +public final class FriendRemovedResponseEvent extends FriendResponseEvent { private final UUID remover; private final UUID removed; private final String removerName; diff --git a/commons/src/main/java/net/swofty/commons/friend/events/response/FriendRequestExpiredResponseEvent.java b/commons/src/main/java/net/swofty/commons/friend/events/response/FriendRequestExpiredResponseEvent.java index 29050cc34..33fa64bff 100644 --- a/commons/src/main/java/net/swofty/commons/friend/events/response/FriendRequestExpiredResponseEvent.java +++ b/commons/src/main/java/net/swofty/commons/friend/events/response/FriendRequestExpiredResponseEvent.java @@ -11,7 +11,7 @@ import java.util.UUID; @Getter -public class FriendRequestExpiredResponseEvent extends FriendResponseEvent { +public final class FriendRequestExpiredResponseEvent extends FriendResponseEvent { private final UUID sender; private final UUID target; private final String senderName; diff --git a/commons/src/main/java/net/swofty/commons/friend/events/response/FriendRequestReceivedResponseEvent.java b/commons/src/main/java/net/swofty/commons/friend/events/response/FriendRequestReceivedResponseEvent.java index 0c19b1962..5d7b7deee 100644 --- a/commons/src/main/java/net/swofty/commons/friend/events/response/FriendRequestReceivedResponseEvent.java +++ b/commons/src/main/java/net/swofty/commons/friend/events/response/FriendRequestReceivedResponseEvent.java @@ -11,7 +11,7 @@ import java.util.UUID; @Getter -public class FriendRequestReceivedResponseEvent extends FriendResponseEvent { +public final class FriendRequestReceivedResponseEvent extends FriendResponseEvent { private final UUID sender; private final UUID target; private final String senderName; diff --git a/commons/src/main/java/net/swofty/commons/friend/events/response/FriendRequestSentResponseEvent.java b/commons/src/main/java/net/swofty/commons/friend/events/response/FriendRequestSentResponseEvent.java index b786468d2..e04f08ae8 100644 --- a/commons/src/main/java/net/swofty/commons/friend/events/response/FriendRequestSentResponseEvent.java +++ b/commons/src/main/java/net/swofty/commons/friend/events/response/FriendRequestSentResponseEvent.java @@ -11,7 +11,7 @@ import java.util.UUID; @Getter -public class FriendRequestSentResponseEvent extends FriendResponseEvent { +public final class FriendRequestSentResponseEvent extends FriendResponseEvent { private final UUID sender; private final UUID target; private final String targetName; diff --git a/commons/src/main/java/net/swofty/commons/friend/events/response/FriendRequestsListResponseEvent.java b/commons/src/main/java/net/swofty/commons/friend/events/response/FriendRequestsListResponseEvent.java index 1d301dd1c..9bc2e8070 100644 --- a/commons/src/main/java/net/swofty/commons/friend/events/response/FriendRequestsListResponseEvent.java +++ b/commons/src/main/java/net/swofty/commons/friend/events/response/FriendRequestsListResponseEvent.java @@ -13,7 +13,7 @@ import java.util.UUID; @Getter -public class FriendRequestsListResponseEvent extends FriendResponseEvent { +public final class FriendRequestsListResponseEvent extends FriendResponseEvent { private final UUID player; private final List requests; private final int page; diff --git a/commons/src/main/java/net/swofty/commons/friend/events/response/FriendSettingToggledResponseEvent.java b/commons/src/main/java/net/swofty/commons/friend/events/response/FriendSettingToggledResponseEvent.java index a85f0f040..6653c2c66 100644 --- a/commons/src/main/java/net/swofty/commons/friend/events/response/FriendSettingToggledResponseEvent.java +++ b/commons/src/main/java/net/swofty/commons/friend/events/response/FriendSettingToggledResponseEvent.java @@ -12,7 +12,7 @@ import java.util.UUID; @Getter -public class FriendSettingToggledResponseEvent extends FriendResponseEvent { +public final class FriendSettingToggledResponseEvent extends FriendResponseEvent { private final UUID player; private final FriendSettingType settingType; private final boolean newValue; From 1e7279e8747c40e37513006a771e1be156f5eff7 Mon Sep 17 00:00:00 2001 From: "Jacob Nardella (Swofty)" Date: Fri, 15 May 2026 00:23:38 +1000 Subject: [PATCH 034/113] feat(commons): add Result sealed type for error-as-value MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Adds a Rust-style Result for code paths where failure is a normal outcome the caller is expected to handle, not an exception. Modelled as a sealed interface with Ok and Err record variants so: - switch(result) is exhaustive at the compiler — no default needed - destructuring via record patterns works (if (r instanceof Result.Ok(X v))) - both variants reject null in their canonical constructors - combinators (map / mapErr / flatMap / ifOk / ifErr / orElse) chain without unboxing Result.attempt(() -> ...) wraps a thrown exception as Err so existing try/catch boundaries can be flattened into a pipeline. Currently used by nothing in production code — that migration is best done one callsite at a time. Lands with a 11-case test suite covering each combinator plus the pattern-matching shape. --- .../main/java/net/swofty/commons/Result.java | 175 ++++++++++++++++++ .../java/net/swofty/commons/ResultTest.java | 122 ++++++++++++ 2 files changed, 297 insertions(+) create mode 100644 commons/src/main/java/net/swofty/commons/Result.java create mode 100644 commons/src/test/java/net/swofty/commons/ResultTest.java diff --git a/commons/src/main/java/net/swofty/commons/Result.java b/commons/src/main/java/net/swofty/commons/Result.java new file mode 100644 index 000000000..b7e49d5c6 --- /dev/null +++ b/commons/src/main/java/net/swofty/commons/Result.java @@ -0,0 +1,175 @@ +package net.swofty.commons; + +import java.util.NoSuchElementException; +import java.util.Objects; +import java.util.Optional; +import java.util.function.Consumer; +import java.util.function.Function; +import java.util.function.Supplier; + +/** + * Either a success value of type {@code T} or an error of type {@code E}, + * never both. Use as a return type when a method has a meaningful failure + * case that the caller is expected to handle — keeps the happy path on the + * type signature instead of forcing a try/catch. + * + *

Modelled as a sealed two-variant interface so {@code switch} over a + * Result is exhaustive at the compiler level: + *

{@code
+ * String message = switch (result) {
+ *     case Result.Ok ok    -> "got " + ok.value();
+ *     case Result.Err err  -> "failed: " + err.error();
+ * };
+ * }
+ * + *

Variants are records, so destructuring works: + *

{@code
+ * if (result instanceof Result.Ok(Integer value)) {
+ *     useValue(value);
+ * }
+ * }
+ */ +public sealed interface Result { + + static Result ok(T value) { + return new Ok<>(value); + } + + static Result err(E error) { + return new Err<>(error); + } + + /** + * Runs {@code action} and wraps a thrown exception as the {@code Err} + * variant. Useful at the boundary of a try-block to keep failure as a + * value instead of a control-flow jump. + */ + static Result attempt(Supplier action) { + try { + return ok(action.get()); + } catch (Exception e) { + return err(e); + } + } + + boolean isOk(); + + default boolean isErr() { + return !isOk(); + } + + /** Returns the success value or throws if this is an error. Prefer {@link #orElse}. */ + T unwrap(); + + /** Returns the error or throws if this is a success. */ + E unwrapErr(); + + /** Returns the success value or {@code other} if this is an error. */ + T orElse(T other); + + /** Returns the success value or applies {@code mapper} to the error to produce one. */ + T orElseGet(Function mapper); + + Optional ok(); + + Optional err(); + + /** Maps the success value, leaving an error untouched. */ + Result map(Function mapper); + + /** Maps the error, leaving the success untouched. */ + Result mapErr(Function mapper); + + /** Monadic bind: chains operations that may themselves fail. */ + Result flatMap(Function> mapper); + + /** Executes the consumer if this is a success. */ + Result ifOk(Consumer action); + + /** Executes the consumer if this is an error. */ + Result ifErr(Consumer action); + + record Ok(T value) implements Result { + public Ok { + Objects.requireNonNull(value, "Ok value must not be null; use Optional for absence"); + } + + @Override public boolean isOk() { return true; } + @Override public T unwrap() { return value; } + @Override public E unwrapErr() { throw new NoSuchElementException("Result is Ok, not Err"); } + @Override public T orElse(T other) { return value; } + @Override public T orElseGet(Function mapper) { return value; } + @Override public Optional ok() { return Optional.of(value); } + @Override public Optional err() { return Optional.empty(); } + + @Override + public Result map(Function mapper) { + return new Ok<>(mapper.apply(value)); + } + + @Override + public Result mapErr(Function mapper) { + return new Ok<>(value); + } + + @Override + public Result flatMap(Function> mapper) { + return mapper.apply(value); + } + + @Override + public Result ifOk(Consumer action) { + action.accept(value); + return this; + } + + @Override + public Result ifErr(Consumer action) { + return this; + } + } + + record Err(E error) implements Result { + public Err { + Objects.requireNonNull(error, "Err value must not be null"); + } + + @Override public boolean isOk() { return false; } + @Override public T unwrap() { + throw error instanceof Throwable t + ? new RuntimeException("Result is Err: " + error, t) + : new NoSuchElementException("Result is Err: " + error); + } + @Override public E unwrapErr() { return error; } + @Override public T orElse(T other) { return other; } + @Override public T orElseGet(Function mapper) { return mapper.apply(error); } + @Override public Optional ok() { return Optional.empty(); } + @Override public Optional err() { return Optional.of(error); } + + @Override + public Result map(Function mapper) { + return new Err<>(error); + } + + @Override + public Result mapErr(Function mapper) { + return new Err<>(mapper.apply(error)); + } + + @Override + public Result flatMap(Function> mapper) { + return new Err<>(error); + } + + @Override + public Result ifOk(Consumer action) { + return this; + } + + @Override + public Result ifErr(Consumer action) { + action.accept(error); + return this; + } + } +} diff --git a/commons/src/test/java/net/swofty/commons/ResultTest.java b/commons/src/test/java/net/swofty/commons/ResultTest.java new file mode 100644 index 000000000..7bdd381fb --- /dev/null +++ b/commons/src/test/java/net/swofty/commons/ResultTest.java @@ -0,0 +1,122 @@ +package net.swofty.commons; + +import org.junit.jupiter.api.Test; + +import java.util.NoSuchElementException; +import java.util.concurrent.atomic.AtomicInteger; +import java.util.concurrent.atomic.AtomicReference; + +import static org.junit.jupiter.api.Assertions.*; + +class ResultTest { + + @Test + void okHoldsValue() { + Result r = Result.ok(42); + assertTrue(r.isOk()); + assertFalse(r.isErr()); + assertEquals(42, r.unwrap()); + assertEquals(42, r.orElse(0)); + assertEquals(42, r.ok().orElseThrow()); + assertTrue(r.err().isEmpty()); + } + + @Test + void errHoldsError() { + Result r = Result.err("boom"); + assertTrue(r.isErr()); + assertFalse(r.isOk()); + assertEquals("boom", r.unwrapErr()); + assertEquals(99, r.orElse(99)); + assertEquals("boom", r.err().orElseThrow()); + assertTrue(r.ok().isEmpty()); + } + + @Test + void unwrapOnErrThrows() { + Result r = Result.err("nope"); + assertThrows(NoSuchElementException.class, r::unwrap); + } + + @Test + void unwrapErrOnOkThrows() { + Result r = Result.ok(1); + assertThrows(NoSuchElementException.class, r::unwrapErr); + } + + @Test + void mapTransformsSuccess() { + Result r = Result.ok(3).map(x -> x * x); + assertEquals(9, r.unwrap()); + } + + @Test + void mapPassesThroughError() { + Result r = Result.err("e").map(x -> x * x); + assertEquals("e", r.unwrapErr()); + } + + @Test + void mapErrTransformsError() { + Result r = Result.err("bad").mapErr(String::length); + assertEquals(3, r.unwrapErr()); + } + + @Test + void flatMapChainsResults() { + Result r = Result.ok(2) + .flatMap(x -> Result.ok(x + 10)); + assertEquals(12, r.unwrap()); + + Result failed = Result.ok(2) + .flatMap(x -> Result.err("downstream")); + assertEquals("downstream", failed.unwrapErr()); + } + + @Test + void ifOkAndIfErrRunOnlyOnMatchingVariant() { + AtomicReference seen = new AtomicReference<>(); + AtomicInteger errCounter = new AtomicInteger(0); + + Result.ok(7) + .ifOk(seen::set) + .ifErr(e -> errCounter.incrementAndGet()); + + assertEquals(7, seen.get()); + assertEquals(0, errCounter.get()); + + seen.set(null); + Result.err("x") + .ifOk(seen::set) + .ifErr(e -> errCounter.incrementAndGet()); + + assertNull(seen.get()); + assertEquals(1, errCounter.get()); + } + + @Test + void attemptCapturesException() { + Result ok = Result.attempt(() -> 5); + assertEquals(5, ok.unwrap()); + + Result err = Result.attempt(() -> { throw new IllegalStateException("oh no"); }); + assertTrue(err.isErr()); + assertInstanceOf(IllegalStateException.class, err.unwrapErr()); + } + + @Test + void switchPatternMatchingIsExhaustive() { + Result r = Result.ok(1); + String msg = switch (r) { + case Result.Ok ok -> "ok: " + ok.value(); + case Result.Err err -> "err: " + err.error(); + }; + assertEquals("ok: 1", msg); + } + + @Test + void nullsRejected() { + assertThrows(NullPointerException.class, () -> Result.ok(null)); + assertThrows(NullPointerException.class, () -> Result.err(null)); + } +} From 651b8613648c9efb30fdd970850a564f34d7005c Mon Sep 17 00:00:00 2001 From: "Jacob Nardella (Swofty)" Date: Fri, 15 May 2026 00:26:09 +1000 Subject: [PATCH 035/113] refactor(skywars): modernise registry getters with Stream.toList() + Comparator Both SkywarsPerkRegistry and SkywarsKitRegistry exposed query methods that collected into a mutable ArrayList via Collectors.toList(). Two sort-helper methods then mutated that returned list in place, which made the getters racy if anything else read the returned reference. Switched all eight query methods to .toList() so they return immutable lists, and rewrote the four sort variants to use Stream.sorted with a hoisted Comparator (Comparator.comparingInt / .thenComparing for the owned-first case) returning a fresh immutable list. Drop the unused Collectors import in both files. --- .../skywarslobby/kit/SkywarsKitRegistry.java | 41 ++++++++----------- .../perk/SkywarsPerkRegistry.java | 33 +++++++-------- 2 files changed, 30 insertions(+), 44 deletions(-) diff --git a/type.skywarslobby/src/main/java/net/swofty/type/skywarslobby/kit/SkywarsKitRegistry.java b/type.skywarslobby/src/main/java/net/swofty/type/skywarslobby/kit/SkywarsKitRegistry.java index 30d1d09a1..d421ad758 100644 --- a/type.skywarslobby/src/main/java/net/swofty/type/skywarslobby/kit/SkywarsKitRegistry.java +++ b/type.skywarslobby/src/main/java/net/swofty/type/skywarslobby/kit/SkywarsKitRegistry.java @@ -3,7 +3,6 @@ import org.tinylog.Logger; import java.util.*; -import java.util.stream.Collectors; /** * Registry for all SkyWars kits. @@ -62,19 +61,17 @@ public static List getKitsForMode(String mode) { ensureInitialized(); return KITS.values().stream() .filter(kit -> kit.isAvailableFor(mode)) - .collect(Collectors.toList()); + .toList(); } /** * Get all kits sorted by rarity (lowest first) */ public static List getKitsSortedByRarity(String mode, boolean lowestFirst) { - List kits = getKitsForMode(mode); - kits.sort((a, b) -> { - int comparison = Integer.compare(a.getRarity().getSortOrder(), b.getRarity().getSortOrder()); - return lowestFirst ? comparison : -comparison; - }); - return kits; + Comparator byRarity = Comparator.comparingInt(k -> k.getRarity().getSortOrder()); + return getKitsForMode(mode).stream() + .sorted(lowestFirst ? byRarity : byRarity.reversed()) + .toList(); } /** @@ -84,7 +81,7 @@ public static List getDefaultKits() { ensureInitialized(); return KITS.values().stream() .filter(SkywarsKit::isDefault) - .collect(Collectors.toList()); + .toList(); } /** @@ -94,7 +91,7 @@ public static List getSoulWellKits() { ensureInitialized(); return KITS.values().stream() .filter(SkywarsKit::isSoulWellDrop) - .collect(Collectors.toList()); + .toList(); } /** @@ -106,7 +103,7 @@ public static List getUnownedSoulWellKits(Set ownedKitIds) { return KITS.values().stream() .filter(SkywarsKit::isSoulWellDrop) .filter(kit -> !ownedKitIds.contains(kit.getId())) - .collect(Collectors.toList()); + .toList(); } /** @@ -131,19 +128,13 @@ public static SkywarsKit getRandomSoulWellKit(Set ownedKitIds) { */ public static List getKitsSortedByRarity(String mode, boolean lowestFirst, boolean ownedFirst, Set ownedKitIds) { - List kits = getKitsForMode(mode); - kits.sort((a, b) -> { - if (ownedFirst) { - boolean aOwned = ownedKitIds.contains(a.getId()); - boolean bOwned = ownedKitIds.contains(b.getId()); - if (aOwned != bOwned) { - return aOwned ? -1 : 1; - } - } - int comparison = Integer.compare(a.getRarity().getSortOrder(), b.getRarity().getSortOrder()); - return lowestFirst ? comparison : -comparison; - }); - return kits; + Comparator byRarity = Comparator.comparingInt(k -> k.getRarity().getSortOrder()); + Comparator rarityComparator = lowestFirst ? byRarity : byRarity.reversed(); + Comparator comparator = ownedFirst + ? Comparator.comparing(k -> !ownedKitIds.contains(k.getId())) + .thenComparing(rarityComparator) + : rarityComparator; + return getKitsForMode(mode).stream().sorted(comparator).toList(); } /** @@ -153,7 +144,7 @@ public static List getKitsByRarity(SkywarsKitRarity rarity) { ensureInitialized(); return KITS.values().stream() .filter(kit -> kit.getRarity() == rarity) - .collect(Collectors.toList()); + .toList(); } /** diff --git a/type.skywarslobby/src/main/java/net/swofty/type/skywarslobby/perk/SkywarsPerkRegistry.java b/type.skywarslobby/src/main/java/net/swofty/type/skywarslobby/perk/SkywarsPerkRegistry.java index e3968ae4e..496373bd4 100644 --- a/type.skywarslobby/src/main/java/net/swofty/type/skywarslobby/perk/SkywarsPerkRegistry.java +++ b/type.skywarslobby/src/main/java/net/swofty/type/skywarslobby/perk/SkywarsPerkRegistry.java @@ -3,7 +3,6 @@ import org.tinylog.Logger; import java.util.*; -import java.util.stream.Collectors; /** * Registry for all SkyWars perks. @@ -62,19 +61,17 @@ public static List getPerksForMode(String mode) { ensureInitialized(); return PERKS.values().stream() .filter(perk -> perk.isAvailableFor(mode)) - .collect(Collectors.toList()); + .toList(); } /** * Get all perks sorted by rarity (lowest first) */ public static List getPerksSortedByRarity(String mode, boolean lowestFirst) { - List perks = getPerksForMode(mode); - perks.sort((a, b) -> { - int comparison = Integer.compare(a.getRarity().getSortOrder(), b.getRarity().getSortOrder()); - return lowestFirst ? comparison : -comparison; - }); - return perks; + Comparator byRarity = Comparator.comparingInt(p -> p.getRarity().getSortOrder()); + return getPerksForMode(mode).stream() + .sorted(lowestFirst ? byRarity : byRarity.reversed()) + .toList(); } /** @@ -84,7 +81,7 @@ public static List getSoulWellPerks() { ensureInitialized(); return PERKS.values().stream() .filter(SkywarsPerk::isSoulWellDrop) - .collect(Collectors.toList()); + .toList(); } /** @@ -96,7 +93,7 @@ public static List getUnownedSoulWellPerks(Set ownedPerkIds return PERKS.values().stream() .filter(SkywarsPerk::isSoulWellDrop) .filter(perk -> !ownedPerkIds.contains(perk.getId())) - .collect(Collectors.toList()); + .toList(); } /** @@ -119,7 +116,7 @@ public static List getPerksByRarity(SkywarsPerkRarity rarity) { ensureInitialized(); return PERKS.values().stream() .filter(perk -> perk.getRarity() == rarity) - .collect(Collectors.toList()); + .toList(); } /** @@ -137,7 +134,7 @@ public static List getGlobalPerks() { ensureInitialized(); return PERKS.values().stream() .filter(SkywarsPerk::isGlobal) - .collect(Collectors.toList()); + .toList(); } /** @@ -148,19 +145,17 @@ public static List getSelectablePerksForMode(String mode) { return PERKS.values().stream() .filter(perk -> perk.isAvailableFor(mode)) .filter(SkywarsPerk::isSelectable) - .collect(Collectors.toList()); + .toList(); } /** * Get selectable perks sorted by rarity */ public static List getSelectablePerksSortedByRarity(String mode, boolean lowestFirst) { - List perks = getSelectablePerksForMode(mode); - perks.sort((a, b) -> { - int comparison = Integer.compare(a.getRarity().getSortOrder(), b.getRarity().getSortOrder()); - return lowestFirst ? comparison : -comparison; - }); - return perks; + Comparator byRarity = Comparator.comparingInt(p -> p.getRarity().getSortOrder()); + return getSelectablePerksForMode(mode).stream() + .sorted(lowestFirst ? byRarity : byRarity.reversed()) + .toList(); } private static void ensureInitialized() { From 2fa7ad6838576cec274a232fd73ad47b831ba2a9 Mon Sep 17 00:00:00 2001 From: "Jacob Nardella (Swofty)" Date: Fri, 15 May 2026 00:29:10 +1000 Subject: [PATCH 036/113] chore: clean up println-as-trace in datamutex + friend endpoints MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The two data-mutex endpoints had been instrumented with println debug breadcrumbs marked '=== ENDPOINT DEBUG ===' — 40 stdout lines per request between them. Replaced with structured Logger.debug calls that contain the same context (lockKey, requester, server set, byte counts) so it can be enabled/disabled without a recompile and won't flood stdout at info level. Also dropped two stale System.out lines in the friend FriendEventToServiceEndpoint that duplicated the same information the structured Logger.error already captured next to them. --- .../endpoints/SynchronizeDataEndpoint.java | 63 +++++-------------- .../UpdateSynchronizedDataEndpoint.java | 48 ++++---------- .../FriendEventToServiceEndpoint.java | 3 +- 3 files changed, 30 insertions(+), 84 deletions(-) diff --git a/service.datamutex/src/main/java/net/swofty/service/datamutex/endpoints/SynchronizeDataEndpoint.java b/service.datamutex/src/main/java/net/swofty/service/datamutex/endpoints/SynchronizeDataEndpoint.java index e3f113250..6b8c64abe 100644 --- a/service.datamutex/src/main/java/net/swofty/service/datamutex/endpoints/SynchronizeDataEndpoint.java +++ b/service.datamutex/src/main/java/net/swofty/service/datamutex/endpoints/SynchronizeDataEndpoint.java @@ -10,6 +10,7 @@ import net.swofty.service.generic.redis.ServiceEndpoint; import net.swofty.service.generic.redis.ServiceToServerManager; +import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.UUID; @@ -29,108 +30,76 @@ public SynchronizeDataProtocolObject.SynchronizeDataResponse onMessage( ServiceProxyRequest request, SynchronizeDataProtocolObject.SynchronizeDataRequest messageObject) { - System.out.println("=== SYNC ENDPOINT DEBUG ==="); - System.out.println("Received sync request from: " + request.getRequestServer()); - System.out.println("Player UUID: " + messageObject.playerUUID()); - System.out.println("Data Key: " + messageObject.dataKey()); - System.out.println("Server UUIDs: " + messageObject.serverUUIDs()); - List serverUUIDs = messageObject.serverUUIDs(); UUID playerUUID = messageObject.playerUUID(); String dataKey = messageObject.dataKey(); String requesterId = request.getRequestServer(); - String lockKey = playerUUID + ":" + dataKey; - System.out.println("Lock key: " + lockKey); + + Logger.debug("sync: requester={} player={} key={} servers={} lockKey={}", + requesterId, playerUUID, dataKey, serverUUIDs, lockKey); try { - // Step 1: Acquire service-level lock - System.out.println("Attempting to acquire service lock..."); if (!DataLockManager.acquireLock(lockKey, requesterId)) { - System.out.println("Failed to acquire service lock - already locked"); + Logger.debug("sync: service lock {} already held", lockKey); return new SynchronizeDataProtocolObject.SynchronizeDataResponse( false, null, "Data is currently locked by another operation"); } - System.out.println("Service lock acquired successfully"); - // Step 2: Lock data on all servers - System.out.println("Locking data on servers: " + serverUUIDs); Map lockResults = ServiceToServerManager .lockPlayerData(serverUUIDs, playerUUID, dataKey) .get(); - System.out.println("Lock results: " + lockResults); - boolean allLocked = lockResults.values().stream() .allMatch(LockPlayerDataPushProtocol.Response::success); - System.out.println("All servers locked: " + allLocked); - if (!allLocked) { - // Release service lock and any server locks we did get - System.out.println("Not all servers locked, cleaning up..."); + Logger.debug("sync: failed to lock all servers (results={}), rolling back", + lockResults); DataLockManager.releaseLock(lockKey, requesterId); ServiceToServerManager.unlockPlayerData(serverUUIDs, playerUUID, dataKey); - return new SynchronizeDataProtocolObject.SynchronizeDataResponse( false, null, "Failed to acquire locks on all servers"); } - // Step 3: Get data from all servers - System.out.println("Getting data from all servers..."); - Map> dataFutures = new java.util.HashMap<>(); + Map> dataFutures = new HashMap<>(); for (UUID serverUUID : serverUUIDs) { dataFutures.put(serverUUID, ServiceToServerManager.getPlayerData(serverUUID, playerUUID, dataKey)); } - Map allData = new java.util.HashMap<>(); + Map allData = new HashMap<>(); for (Map.Entry> entry : dataFutures.entrySet()) { allData.put(entry.getKey(), entry.getValue().get()); } - System.out.println("Received data from servers: " + allData); - GetPlayerDataPushProtocol.Response latestData = null; long latestTimestamp = 0; - for (GetPlayerDataPushProtocol.Response data : allData.values()) { - System.out.println("Processing data response: " + data); - if (data.success()) { - long timestamp = data.timestamp(); - System.out.println("Data timestamp: " + timestamp); - if (timestamp > latestTimestamp) { - latestTimestamp = timestamp; - latestData = data; - } + if (data.success() && data.timestamp() > latestTimestamp) { + latestTimestamp = data.timestamp(); + latestData = data; } } if (latestData == null) { - System.out.println("No valid data found, cleaning up..."); + Logger.debug("sync: no valid data among {} responses, rolling back", allData.size()); DataLockManager.releaseLock(lockKey, requesterId); ServiceToServerManager.unlockPlayerData(serverUUIDs, playerUUID, dataKey); - return new SynchronizeDataProtocolObject.SynchronizeDataResponse( false, null, "No valid data found on any server"); } - System.out.println("Using latest data with timestamp: " + latestTimestamp); - System.out.println("Latest data content: " + latestData.data()); - + Logger.debug("sync: settled on timestamp={}", latestTimestamp); return new SynchronizeDataProtocolObject.SynchronizeDataResponse( true, latestData.data(), null); } catch (Exception e) { - System.out.println("Exception in sync endpoint: " + e.getMessage()); - Logger.error(e, "Error occurred in data mutex endpoint"); - - // Always unlock on error + Logger.error(e, "Error occurred in data mutex endpoint (lockKey={})", lockKey); DataLockManager.releaseLock(lockKey, requesterId); ServiceToServerManager.unlockPlayerData(serverUUIDs, playerUUID, dataKey); - return new SynchronizeDataProtocolObject.SynchronizeDataResponse( false, null, "Error during synchronization: " + e.getMessage()); } } -} \ No newline at end of file +} diff --git a/service.datamutex/src/main/java/net/swofty/service/datamutex/endpoints/UpdateSynchronizedDataEndpoint.java b/service.datamutex/src/main/java/net/swofty/service/datamutex/endpoints/UpdateSynchronizedDataEndpoint.java index 74b033404..1cf27ebc6 100644 --- a/service.datamutex/src/main/java/net/swofty/service/datamutex/endpoints/UpdateSynchronizedDataEndpoint.java +++ b/service.datamutex/src/main/java/net/swofty/service/datamutex/endpoints/UpdateSynchronizedDataEndpoint.java @@ -1,4 +1,3 @@ -// Replace your UpdateSynchronizedDataEndpoint with this debug version package net.swofty.service.datamutex.endpoints; import org.tinylog.Logger; @@ -10,6 +9,7 @@ import net.swofty.service.generic.redis.ServiceEndpoint; import net.swofty.service.generic.redis.ServiceToServerManager; +import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.UUID; @@ -29,76 +29,54 @@ public UpdateSynchronizedDataProtocolObject.UpdateDataResponse onMessage( ServiceProxyRequest request, UpdateSynchronizedDataProtocolObject.UpdateDataRequest messageObject) { - System.out.println("=== UPDATE ENDPOINT DEBUG ==="); - System.out.println("Received update request from: " + request.getRequestServer()); - System.out.println("Player UUID: " + messageObject.playerUUID()); - System.out.println("Data Key: " + messageObject.dataKey()); - System.out.println("Server UUIDs: " + messageObject.serverUUIDs()); - System.out.println("New Data Length: " + messageObject.newData().length() + " chars"); - List serverUUIDs = messageObject.serverUUIDs(); UUID playerUUID = messageObject.playerUUID(); String dataKey = messageObject.dataKey(); String newData = messageObject.newData(); String requesterId = request.getRequestServer(); - String lockKey = playerUUID + ":" + dataKey; - System.out.println("Lock key: " + lockKey); + + Logger.debug("update: requester={} player={} key={} servers={} bytes={} lockKey={}", + requesterId, playerUUID, dataKey, serverUUIDs, newData.length(), lockKey); try { - // Verify we still hold the lock - System.out.println("Verifying service lock..."); DataLockManager.LockInfo lockInfo = DataLockManager.getLockInfo(lockKey); if (lockInfo == null || !lockInfo.requesterId.equals(requesterId)) { - System.out.println("Lock verification failed - lockInfo: " + lockInfo + ", requesterId: " + requesterId); + Logger.debug("update: lock check failed (held by {})", + lockInfo == null ? "" : lockInfo.requesterId); return new UpdateSynchronizedDataProtocolObject.UpdateDataResponse( false, "Lock has expired or is held by another requester"); } - System.out.println("Service lock verified successfully"); - System.out.println("Updating data on servers: " + serverUUIDs); - Map> updateFutures = new java.util.HashMap<>(); + Map> updateFutures = new HashMap<>(); for (UUID serverUUID : serverUUIDs) { - System.out.println("Sending update to server " + serverUUID); - updateFutures.put(serverUUID, ServiceToServerManager.updatePlayerData(serverUUID, playerUUID, dataKey, newData)); } - System.out.println("Waiting for update responses..."); - Map updateResults = new java.util.HashMap<>(); + Map updateResults = new HashMap<>(); for (Map.Entry> entry : updateFutures.entrySet()) { - UpdatePlayerDataPushProtocol.Response result = entry.getValue().get(); - updateResults.put(entry.getKey(), result); - System.out.println("Update result from " + entry.getKey() + ": " + result); + updateResults.put(entry.getKey(), entry.getValue().get()); } boolean allUpdated = updateResults.values().stream() .allMatch(UpdatePlayerDataPushProtocol.Response::success); - System.out.println("All servers updated successfully: " + allUpdated); - if (!allUpdated) { - System.out.println("Some updates failed, returning error"); + Logger.warn("update: partial failure (results={})", updateResults); return new UpdateSynchronizedDataProtocolObject.UpdateDataResponse( false, "Failed to update data on all servers"); } - System.out.println("All updates successful!"); - return new UpdateSynchronizedDataProtocolObject.UpdateDataResponse( - true, null); + return new UpdateSynchronizedDataProtocolObject.UpdateDataResponse(true, null); } catch (Exception e) { - System.out.println("Exception in update endpoint: " + e.getMessage()); - Logger.error(e, "Error occurred in data mutex endpoint"); - + Logger.error(e, "Error occurred in data mutex update endpoint (lockKey={})", lockKey); return new UpdateSynchronizedDataProtocolObject.UpdateDataResponse( false, "Error during data update: " + e.getMessage()); } finally { - // Always release locks when done - System.out.println("Releasing locks in finally block..."); DataLockManager.releaseLock(lockKey, requesterId); ServiceToServerManager.unlockPlayerData(serverUUIDs, playerUUID, dataKey); } } -} \ No newline at end of file +} diff --git a/service.friend/src/main/java/net/swofty/service/friend/endpoints/FriendEventToServiceEndpoint.java b/service.friend/src/main/java/net/swofty/service/friend/endpoints/FriendEventToServiceEndpoint.java index 1fb50037e..1b95dfd01 100644 --- a/service.friend/src/main/java/net/swofty/service/friend/endpoints/FriendEventToServiceEndpoint.java +++ b/service.friend/src/main/java/net/swofty/service/friend/endpoints/FriendEventToServiceEndpoint.java @@ -25,7 +25,7 @@ public SendFriendEventToServiceProtocolObject.SendFriendEventToServiceResponse o try { FriendEvent event = messageObject.event(); - System.out.println("Received friend event: " + event.getClass().getSimpleName()); + Logger.debug("Received friend event: {}", event.getClass().getSimpleName()); switch (event) { case FriendAddRequestEvent e -> FriendCache.handleAddRequest( e, @@ -63,7 +63,6 @@ public SendFriendEventToServiceProtocolObject.SendFriendEventToServiceResponse o return new SendFriendEventToServiceProtocolObject.SendFriendEventToServiceResponse(true, null); } catch (Exception e) { - System.out.println("Failed to process friend event: " + e.getMessage()); Logger.error(e, "Failed to process friend event in service endpoint"); return new SendFriendEventToServiceProtocolObject.SendFriendEventToServiceResponse(false, "Event processing failed"); } From 3c3498707dad2e2e6e1ff5af085e0fc76692ae87 Mon Sep 17 00:00:00 2001 From: "Jacob Nardella (Swofty)" Date: Fri, 15 May 2026 00:30:24 +1000 Subject: [PATCH 037/113] chore(bazaar): route propagator logs through tinylog MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Eight System.out / System.err callsites in BazaarPropagator described real workflow events (which actor wasn't handled, where the transaction got stored as pending) at log-worthy severities — info for the 'storing as pending' case, debug for the running tally. Routed through the existing tinylog dependency the module already declares. --- .../service/bazaar/BazaarPropagator.java | 25 +++++++++---------- 1 file changed, 12 insertions(+), 13 deletions(-) diff --git a/service.bazaar/src/main/java/net/swofty/service/bazaar/BazaarPropagator.java b/service.bazaar/src/main/java/net/swofty/service/bazaar/BazaarPropagator.java index 5a1129861..b5e3dc20c 100644 --- a/service.bazaar/src/main/java/net/swofty/service/bazaar/BazaarPropagator.java +++ b/service.bazaar/src/main/java/net/swofty/service/bazaar/BazaarPropagator.java @@ -6,6 +6,7 @@ import net.swofty.commons.skyblock.bazaar.SuccessfulBazaarTransaction; import net.swofty.commons.skyblock.bazaar.OrderExpiredBazaarTransaction; import net.swofty.service.generic.redis.ServiceToServerManager; +import org.tinylog.Logger; import java.util.Map; import java.util.UUID; @@ -15,7 +16,7 @@ public class BazaarPropagator { private static final BazaarTransactionPushProtocol PROTOCOL = new BazaarTransactionPushProtocol(); public void propagate(BazaarTransaction tx) { - System.out.println("Propagating transaction " + tx.getClass().getSimpleName()); + Logger.debug("Propagating transaction {}", tx.getClass().getSimpleName()); var request = new BazaarTransactionPushProtocol.Request( tx.getClass().getSimpleName(), @@ -25,7 +26,7 @@ public void propagate(BazaarTransaction tx) { ServiceToServerManager.sendToAllServers(PROTOCOL, request, 5000) .thenAccept(responses -> handleServerResponses(tx, responses)) .exceptionally(throwable -> { - System.err.println("Failed to get responses from servers for transaction: " + throwable.getMessage()); + Logger.error(throwable, "Failed to get responses from servers for transaction"); return null; }); } @@ -34,7 +35,7 @@ private void handleServerResponses(BazaarTransaction tx, Map res switch (tx) { case SuccessfulBazaarTransaction success -> handleSuccessfulTransactionResponses(success, responses); case OrderExpiredBazaarTransaction expired -> handleExpiredTransactionResponses(expired, responses); - default -> System.err.println("Unknown transaction type for response handling: " + tx.getClass().getSimpleName()); + default -> Logger.warn("Unknown transaction type for response handling: {}", tx.getClass().getSimpleName()); } } @@ -42,8 +43,7 @@ private void handleSuccessfulTransactionResponses(SuccessfulBazaarTransaction tx boolean buyerHandled = false; boolean sellerHandled = false; - for (Map.Entry entry : responses.entrySet()) { - Response response = entry.getValue(); + for (Response response : responses.values()) { if (response != null && response.success()) { buyerHandled |= response.buyerHandled(); sellerHandled |= response.sellerHandled(); @@ -51,33 +51,32 @@ private void handleSuccessfulTransactionResponses(SuccessfulBazaarTransaction tx } if (!buyerHandled) { - System.out.println("Buyer " + tx.buyer() + " not handled by any server - storing as pending"); + Logger.info("Buyer {} not handled by any server — storing as pending", tx.buyer()); PendingTransactionsDatabase.storePendingTransaction(tx.buyer(), tx.buyerProfile(), tx); } if (!sellerHandled) { - System.out.println("Seller " + tx.seller() + " not handled by any server - storing as pending"); + Logger.info("Seller {} not handled by any server — storing as pending", tx.seller()); PendingTransactionsDatabase.storePendingTransaction(tx.seller(), tx.sellerProfile(), tx); } - System.out.println("Transaction handled - Buyer: " + buyerHandled + ", Seller: " + sellerHandled); + Logger.debug("Transaction handled — buyer={}, seller={}", buyerHandled, sellerHandled); } private void handleExpiredTransactionResponses(OrderExpiredBazaarTransaction tx, Map responses) { boolean ownerHandled = false; - for (Map.Entry entry : responses.entrySet()) { - Response response = entry.getValue(); + for (Response response : responses.values()) { if (response != null && response.success()) { ownerHandled |= response.buyerHandled(); } } if (!ownerHandled) { - System.out.println("Owner " + tx.owner() + " not handled by any server - storing as pending"); + Logger.info("Owner {} not handled by any server — storing as pending", tx.owner()); PendingTransactionsDatabase.storePendingTransaction(tx.owner(), tx.ownerProfile(), tx); } - System.out.println("Expired order handled - Owner: " + ownerHandled); + Logger.debug("Expired order handled — owner={}", ownerHandled); } -} \ No newline at end of file +} From be627ed42b8222c7aadb53685a386157af7c9556 Mon Sep 17 00:00:00 2001 From: "Jacob Nardella (Swofty)" Date: Fri, 15 May 2026 00:33:07 +1000 Subject: [PATCH 038/113] chore(bazaar): finish routing service logs through tinylog MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Six more callsites converted across the bazaar service: - BazaarMarket match-price trace (debug) - PendingTransactionsDatabase store/parse error paths - EndpointBazaarBuyOrder + EndpointBazaarSellOrder order-submitted logs - EndpointProcessPendingTransactions per-id success/failure - EndpointCancelBazaarOrder + EndpointGetPendingTransactions Same severity choices as before — info for state changes a human would want to see at runtime, debug for per-iteration breadcrumbs, error for catch-blocks. Drops Collectors.toList in one spot in favour of Stream.toList(). --- .../java/net/swofty/service/bazaar/BazaarMarket.java | 6 +++--- .../service/bazaar/PendingTransactionsDatabase.java | 9 +++++---- .../bazaar/endpoints/EndpointBazaarBuyOrder.java | 7 ++++--- .../bazaar/endpoints/EndpointBazaarSellOrder.java | 7 ++++--- .../bazaar/endpoints/EndpointCancelBazaarOrder.java | 4 +++- .../endpoints/EndpointGetPendingTransactions.java | 9 ++++----- .../endpoints/EndpointProcessPendingTransactions.java | 11 ++++++----- 7 files changed, 29 insertions(+), 24 deletions(-) diff --git a/service.bazaar/src/main/java/net/swofty/service/bazaar/BazaarMarket.java b/service.bazaar/src/main/java/net/swofty/service/bazaar/BazaarMarket.java index f441520f7..7028df3a7 100644 --- a/service.bazaar/src/main/java/net/swofty/service/bazaar/BazaarMarket.java +++ b/service.bazaar/src/main/java/net/swofty/service/bazaar/BazaarMarket.java @@ -3,6 +3,7 @@ import net.swofty.commons.skyblock.bazaar.BuyOrderRefundTransaction; import net.swofty.commons.skyblock.bazaar.OrderExpiredBazaarTransaction; import net.swofty.commons.skyblock.bazaar.SuccessfulBazaarTransaction; +import org.tinylog.Logger; import java.time.Instant; import java.time.temporal.ChronoUnit; @@ -213,9 +214,8 @@ private void match(String item, tracker.recordPartialFill(qty, actualPrice); } - System.out.println("Buy price was: " + b.originalPrice); - System.out.println("Sell price was: " + s.originalPrice); - System.out.println("Actual price was: " + actualPrice); + Logger.debug("Match — buyPrice={} sellPrice={} actualPrice={}", + b.originalPrice, s.originalPrice, actualPrice); double priceImprovement = (b.originalPrice - actualPrice) * qty; var tx = new SuccessfulBazaarTransaction( item, diff --git a/service.bazaar/src/main/java/net/swofty/service/bazaar/PendingTransactionsDatabase.java b/service.bazaar/src/main/java/net/swofty/service/bazaar/PendingTransactionsDatabase.java index 08f95d1f1..876648d4d 100644 --- a/service.bazaar/src/main/java/net/swofty/service/bazaar/PendingTransactionsDatabase.java +++ b/service.bazaar/src/main/java/net/swofty/service/bazaar/PendingTransactionsDatabase.java @@ -6,6 +6,7 @@ import net.swofty.commons.skyblock.bazaar.OrderExpiredBazaarTransaction; import net.swofty.commons.skyblock.bazaar.SuccessfulBazaarTransaction; import org.bson.Document; +import org.tinylog.Logger; import java.time.Instant; import java.util.ArrayList; @@ -30,7 +31,7 @@ public static void storePendingTransaction(UUID playerUuid, UUID profileUuid, Ba .append("processed", false); OrderDatabase.database.getCollection("pendingTransactions").insertOne(doc); - System.out.println("Stored pending transaction for player " + playerUuid + " on profile " + profileUuid); + Logger.info("Stored pending transaction for player {} on profile {}", playerUuid, profileUuid); } /** @@ -63,7 +64,7 @@ public static List getPendingTransactions(UUID playerUuid, U )); } } catch (Exception e) { - System.err.println("Failed to parse pending transaction: " + e.getMessage()); + Logger.error(e, "Failed to parse pending transaction"); } } @@ -105,12 +106,12 @@ private static BazaarTransaction parseTransactionFromDocument(String type, Docum null, null, null, null, null, 0, 0, null ).fromJSON(jsonData); default -> { - System.err.println("Unknown pending transaction type: " + type); + Logger.warn("Unknown pending transaction type: {}", type); yield null; } }; } catch (Exception e) { - System.err.println("Error parsing pending transaction: " + e.getMessage()); + Logger.error(e, "Error parsing pending transaction"); return null; } } diff --git a/service.bazaar/src/main/java/net/swofty/service/bazaar/endpoints/EndpointBazaarBuyOrder.java b/service.bazaar/src/main/java/net/swofty/service/bazaar/endpoints/EndpointBazaarBuyOrder.java index b672e7e06..ef5b3e594 100644 --- a/service.bazaar/src/main/java/net/swofty/service/bazaar/endpoints/EndpointBazaarBuyOrder.java +++ b/service.bazaar/src/main/java/net/swofty/service/bazaar/endpoints/EndpointBazaarBuyOrder.java @@ -4,6 +4,7 @@ import net.swofty.commons.protocol.objects.bazaar.BazaarBuyProtocolObject; import net.swofty.service.bazaar.BazaarMarket; import net.swofty.service.generic.redis.ServiceEndpoint; +import org.tinylog.Logger; import java.util.UUID; @@ -29,11 +30,11 @@ public BazaarBuyProtocolObject.BazaarBuyResponse onMessage( try { BazaarMarket.get().submitBuy(itemName, playerUUID, profileUUID, price, amount); - System.out.println("Buy order submitted for " + itemName + " by " + playerUUID - + " (profile: " + profileUUID + ") - Price: " + price + ", Amount: " + amount); + Logger.info("Buy order submitted for {} by {} (profile: {}) — price={}, amount={}", + itemName, playerUUID, profileUUID, price, amount); return new BazaarBuyProtocolObject.BazaarBuyResponse(true, null); } catch (Exception e) { - System.err.println("Failed to submit buy order: " + e.getMessage()); + Logger.error(e, "Failed to submit buy order for {} by {}", itemName, playerUUID); return new BazaarBuyProtocolObject.BazaarBuyResponse(false, "Buy order failed"); } } diff --git a/service.bazaar/src/main/java/net/swofty/service/bazaar/endpoints/EndpointBazaarSellOrder.java b/service.bazaar/src/main/java/net/swofty/service/bazaar/endpoints/EndpointBazaarSellOrder.java index 5323923ef..afc2decac 100644 --- a/service.bazaar/src/main/java/net/swofty/service/bazaar/endpoints/EndpointBazaarSellOrder.java +++ b/service.bazaar/src/main/java/net/swofty/service/bazaar/endpoints/EndpointBazaarSellOrder.java @@ -5,6 +5,7 @@ import net.swofty.commons.protocol.objects.bazaar.BazaarSellProtocolObject; import net.swofty.service.bazaar.BazaarMarket; import net.swofty.service.generic.redis.ServiceEndpoint; +import org.tinylog.Logger; import java.util.UUID; @@ -30,11 +31,11 @@ public BazaarSellProtocolObject.BazaarSellResponse onMessage( try { BazaarMarket.get().submitSell(itemName, playerUUID, profileUUID, price, amount); - System.out.println("Sell order submitted for " + itemName + " by " + playerUUID - + " (profile: " + profileUUID + ") - Price: " + price + ", Amount: " + amount); + Logger.info("Sell order submitted for {} by {} (profile: {}) — price={}, amount={}", + itemName, playerUUID, profileUUID, price, amount); return new BazaarSellProtocolObject.BazaarSellResponse(true, null); } catch (Exception e) { - System.err.println("Failed to submit sell order: " + e.getMessage()); + Logger.error(e, "Failed to submit sell order for {} by {}", itemName, playerUUID); return new BazaarSellProtocolObject.BazaarSellResponse(false, "Sell order failed"); } } diff --git a/service.bazaar/src/main/java/net/swofty/service/bazaar/endpoints/EndpointCancelBazaarOrder.java b/service.bazaar/src/main/java/net/swofty/service/bazaar/endpoints/EndpointCancelBazaarOrder.java index 84b9e2fde..ed9c201bb 100644 --- a/service.bazaar/src/main/java/net/swofty/service/bazaar/endpoints/EndpointCancelBazaarOrder.java +++ b/service.bazaar/src/main/java/net/swofty/service/bazaar/endpoints/EndpointCancelBazaarOrder.java @@ -8,6 +8,7 @@ import net.swofty.service.bazaar.BazaarMarket; import net.swofty.service.bazaar.OrderDatabase; import net.swofty.service.generic.redis.ServiceEndpoint; +import org.tinylog.Logger; public class EndpointCancelBazaarOrder implements ServiceEndpoint< CancelMessage, CancelResponse> { @@ -27,7 +28,8 @@ public CancelResponse onMessage(ServiceProxyRequest _msg, CancelMessage msg) { ) ); BazaarMarket.get().submitDelete(msg.orderId(), msg.playerUuid(), msg.profileUuid()); - System.out.println("Deleted order " + msg.orderId() + " for player " + msg.playerUuid() + " and profile " + msg.profileUuid()); + Logger.info("Deleted order {} for player {} and profile {}", + msg.orderId(), msg.playerUuid(), msg.profileUuid()); boolean success = result.getDeletedCount() > 0; return new CancelResponse(success, success ? null : "Cancel failed"); diff --git a/service.bazaar/src/main/java/net/swofty/service/bazaar/endpoints/EndpointGetPendingTransactions.java b/service.bazaar/src/main/java/net/swofty/service/bazaar/endpoints/EndpointGetPendingTransactions.java index 2242beb45..9e227226d 100644 --- a/service.bazaar/src/main/java/net/swofty/service/bazaar/endpoints/EndpointGetPendingTransactions.java +++ b/service.bazaar/src/main/java/net/swofty/service/bazaar/endpoints/EndpointGetPendingTransactions.java @@ -7,9 +7,9 @@ import net.swofty.commons.protocol.objects.bazaar.BazaarGetPendingTransactionsProtocolObject.PendingTransactionInfo; import net.swofty.service.bazaar.PendingTransactionsDatabase; import net.swofty.service.generic.redis.ServiceEndpoint; +import org.tinylog.Logger; import java.util.List; -import java.util.stream.Collectors; public class EndpointGetPendingTransactions implements ServiceEndpoint< BazaarGetPendingTransactionsMessage, @@ -35,11 +35,10 @@ public BazaarGetPendingTransactionsResponse onMessage( pt.getTransaction().toJSON().toMap(), pt.getCreatedAt() )) - .collect(Collectors.toList()); + .toList(); - System.out.println("Retrieved " + transactionInfos.size() + - " pending transactions for player " + msg.playerUUID() + - " on profile " + msg.profileUUID()); + Logger.debug("Retrieved {} pending transactions for player {} on profile {}", + transactionInfos.size(), msg.playerUUID(), msg.profileUUID()); return new BazaarGetPendingTransactionsResponse(transactionInfos, true, null); } diff --git a/service.bazaar/src/main/java/net/swofty/service/bazaar/endpoints/EndpointProcessPendingTransactions.java b/service.bazaar/src/main/java/net/swofty/service/bazaar/endpoints/EndpointProcessPendingTransactions.java index 1f78b46e6..1d2ab15ac 100644 --- a/service.bazaar/src/main/java/net/swofty/service/bazaar/endpoints/EndpointProcessPendingTransactions.java +++ b/service.bazaar/src/main/java/net/swofty/service/bazaar/endpoints/EndpointProcessPendingTransactions.java @@ -6,6 +6,7 @@ import net.swofty.commons.protocol.objects.bazaar.BazaarProcessPendingTransactionsProtocolObject.BazaarProcessPendingTransactionsResponse; import net.swofty.service.bazaar.PendingTransactionsDatabase; import net.swofty.service.generic.redis.ServiceEndpoint; +import org.tinylog.Logger; import java.util.ArrayList; import java.util.List; @@ -27,17 +28,17 @@ public BazaarProcessPendingTransactionsResponse onMessage( List successfulIds = new ArrayList<>(); List failedIds = new ArrayList<>(); - System.out.println("Processing " + msg.transactionIds().size() + - " pending transactions for player " + msg.playerUUID()); + Logger.info("Processing {} pending transactions for player {}", + msg.transactionIds().size(), msg.playerUUID()); for (String transactionId : msg.transactionIds()) { try { PendingTransactionsDatabase.markTransactionProcessed(transactionId); successfulIds.add(transactionId); - System.out.println("Successfully processed pending transaction: " + transactionId); + Logger.debug("Successfully processed pending transaction: {}", transactionId); } catch (Exception e) { failedIds.add(transactionId); - System.err.println("Failed to process pending transaction " + transactionId + ": " + e.getMessage()); + Logger.error(e, "Failed to process pending transaction {}", transactionId); } } @@ -45,7 +46,7 @@ public BazaarProcessPendingTransactionsResponse onMessage( try { PendingTransactionsDatabase.cleanupProcessedTransactions(); } catch (Exception e) { - System.err.println("Failed to cleanup processed transactions: " + e.getMessage()); + Logger.error(e, "Failed to cleanup processed transactions"); } } From 533f9f8c388db6178b16faff0de73dbff9814667 Mon Sep 17 00:00:00 2001 From: "Jacob Nardella (Swofty)" Date: Fri, 15 May 2026 00:34:15 +1000 Subject: [PATCH 039/113] chore(bazaar): route BazaarAwarder process-* error paths through tinylog Six catch-block stderr lines in BazaarAwarder lost their stack traces to System.err and only captured e.getMessage(). Replaced with Logger.error(e, ...) so the stack traces reach the configured sinks (file, sentry) and the message stays template-formatted. --- .../type/skyblockgeneric/bazaar/BazaarAwarder.java | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/bazaar/BazaarAwarder.java b/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/bazaar/BazaarAwarder.java index e42c5a2b0..72539da1e 100644 --- a/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/bazaar/BazaarAwarder.java +++ b/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/bazaar/BazaarAwarder.java @@ -9,6 +9,7 @@ import net.swofty.type.skyblockgeneric.item.SkyBlockItem; import net.swofty.type.skyblockgeneric.user.SkyBlockPlayer; import org.json.JSONObject; +import org.tinylog.Logger; import java.text.DecimalFormat; import java.util.UUID; @@ -93,12 +94,12 @@ public static boolean processPendingTransaction(SkyBlockPlayer player, String tr return processExpiredOrder(player, transaction); } default -> { - System.err.println("Unknown pending transaction type: " + transactionType); + Logger.warn("Unknown pending transaction type: {}", transactionType); return false; } } } catch (Exception e) { - System.err.println("Failed to process pending transaction: " + e.getMessage()); + Logger.error(e, "Failed to process pending transaction"); return false; } } @@ -138,7 +139,7 @@ private static boolean processBuyer(SkyBlockPlayer player, SuccessfulBazaarTrans return true; } catch (Exception e) { - System.err.println("Failed to process buyer transaction: " + e.getMessage()); + Logger.error(e, "Failed to process buyer transaction"); return false; } } @@ -174,7 +175,7 @@ private static boolean processRefund(SkyBlockPlayer player, BuyOrderRefundTransa return true; } catch (Exception e) { - System.err.println("Failed to process refund transaction: " + e.getMessage()); + Logger.error(e, "Failed to process refund transaction"); return false; } } @@ -214,7 +215,7 @@ private static boolean processSeller(SkyBlockPlayer player, SuccessfulBazaarTran return true; } catch (Exception e) { - System.err.println("Failed to process seller transaction: " + e.getMessage()); + Logger.error(e, "Failed to process seller transaction"); return false; } } @@ -263,7 +264,7 @@ private static boolean processExpiredOrderOwner(SkyBlockPlayer player, OrderExpi return true; } catch (Exception e) { - System.err.println("Failed to process expired order: " + e.getMessage()); + Logger.error(e, "Failed to process expired order"); return false; } } From 6d32fa9f711344e07941e2455fbfd723c15158a2 Mon Sep 17 00:00:00 2001 From: "Jacob Nardella (Swofty)" Date: Fri, 15 May 2026 00:36:22 +1000 Subject: [PATCH 040/113] chore: route remaining reforge/level-reward loader output through tinylog MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit LevelRewardRegistry and ReforgeLoader both already imported tinylog elsewhere; the startup/parse-error paths still printed to stdout/stderr. Now consistent throughout — stack traces reach Logger.error, missing-config falls to Logger.warn, the 'Loaded N rewards' / 'Reloading' banners go to Logger.info. --- .../commons/skyblock/item/reforge/ReforgeLoader.java | 10 +++++----- .../type/generic/experience/LevelRewardRegistry.java | 11 ++++++----- 2 files changed, 11 insertions(+), 10 deletions(-) diff --git a/commons/src/main/java/net/swofty/commons/skyblock/item/reforge/ReforgeLoader.java b/commons/src/main/java/net/swofty/commons/skyblock/item/reforge/ReforgeLoader.java index 40f377c12..79ce87419 100644 --- a/commons/src/main/java/net/swofty/commons/skyblock/item/reforge/ReforgeLoader.java +++ b/commons/src/main/java/net/swofty/commons/skyblock/item/reforge/ReforgeLoader.java @@ -52,7 +52,7 @@ public static void loadAllReforges() { File[] reforgeFiles = REFORGES_DIR.listFiles((dir, name) -> name.toLowerCase().endsWith(".yml")); if (reforgeFiles == null) { - System.out.println("No reforge files found in " + REFORGES_DIR.getPath()); + Logger.info("No reforge files found in {}", REFORGES_DIR.getPath()); return; } @@ -77,7 +77,7 @@ private static Reforge loadFromFile(File file) { ReforgeConfig config = yaml.loadAs(new FileReader(file), ReforgeConfig.class); if (config == null) { - System.err.println("Failed to parse reforge config from: " + file.getName()); + Logger.error("Failed to parse reforge config from: {}", file.getName()); return null; } @@ -97,7 +97,7 @@ private static Reforge parseReforge(ReforgeConfig config) { ReforgeType type = ReforgeType.valueOf(typeStr.toUpperCase()); applicableTypes.add(type); } catch (IllegalArgumentException e) { - System.err.println("Unknown reforge type: " + typeStr + " for reforge: " + config.name); + Logger.warn("Unknown reforge type: {} for reforge: {}", typeStr, config.name); } } } @@ -123,7 +123,7 @@ private static BiFunction createCalcula double value = calculateStatisticValue(data, level); result = result.addBase(statistic, value); } catch (IllegalArgumentException e) { - System.err.println("Unknown statistic: " + entry.getKey()); + Logger.warn("Unknown statistic: {}", entry.getKey()); } } } @@ -227,7 +227,7 @@ public static boolean isReforgeApplicable(String reforgeName, ReforgeType type) // Utility method to reload all reforges public static void reloadReforges() { - System.out.println("Reloading all reforges..."); + Logger.info("Reloading all reforges..."); loadAllReforges(); } } \ No newline at end of file diff --git a/type.generic/src/main/java/net/swofty/type/generic/experience/LevelRewardRegistry.java b/type.generic/src/main/java/net/swofty/type/generic/experience/LevelRewardRegistry.java index 3b7668067..4bddd91aa 100644 --- a/type.generic/src/main/java/net/swofty/type/generic/experience/LevelRewardRegistry.java +++ b/type.generic/src/main/java/net/swofty/type/generic/experience/LevelRewardRegistry.java @@ -1,6 +1,7 @@ package net.swofty.type.generic.experience; import net.swofty.commons.YamlFileUtils; +import org.tinylog.Logger; import java.io.File; import java.util.*; @@ -14,7 +15,7 @@ public static void initialize(File configRoot) { File rewardsFile = new File(configRoot, "leveling/rewards.yml"); if (!rewardsFile.exists()) { - System.out.println("[LevelRewardRegistry] rewards.yml not found at: " + rewardsFile.getAbsolutePath()); + Logger.warn("rewards.yml not found at: {}", rewardsFile.getAbsolutePath()); initialized = true; return; } @@ -23,19 +24,19 @@ public static void initialize(File configRoot) { try { yaml = YamlFileUtils.loadYaml(rewardsFile); } catch (java.io.IOException e) { - System.out.println("[LevelRewardRegistry] Failed to load rewards.yml: " + e.getMessage()); + Logger.error(e, "Failed to load rewards.yml"); initialized = true; return; } if (yaml == null) { - System.out.println("[LevelRewardRegistry] Failed to load rewards.yml"); + Logger.warn("rewards.yml parsed to null — empty file?"); initialized = true; return; } loadRewards(yaml); initialized = true; - System.out.println("[LevelRewardRegistry] Loaded " + REWARDS.size() + " level rewards"); + Logger.info("Loaded {} level rewards", REWARDS.size()); } @SuppressWarnings("unchecked") @@ -66,7 +67,7 @@ private static void loadRewards(Map yaml) { LevelReward reward = builder.build(); REWARDS.put(level, reward); } catch (Exception e) { - System.err.println("[LevelRewardRegistry] Error loading reward: " + e.getMessage()); + Logger.error(e, "Error loading level reward entry"); } } } From e4e12157c9b438a15a5aa243f45811618d6d679c Mon Sep 17 00:00:00 2001 From: "Jacob Nardella (Swofty)" Date: Fri, 15 May 2026 00:37:55 +1000 Subject: [PATCH 041/113] chore(minion): clean up IslandMinionData println in error paths MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The deserialize() path logged 'Invalid item format' / 'Failed to parse amount' to stderr then immediately threw — the stderr writes were strictly redundant with the exception message. Kept them through tinylog as a structured log for the dataloader to see, then the throw. Folded the NullPointerException trace string into the exception message instead of printing the type first. --- .../type/skyblockgeneric/minion/IslandMinionData.java | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/minion/IslandMinionData.java b/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/minion/IslandMinionData.java index 9c0ed6c15..178bd400d 100644 --- a/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/minion/IslandMinionData.java +++ b/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/minion/IslandMinionData.java @@ -16,6 +16,7 @@ import net.swofty.type.skyblockgeneric.minion.extension.MinionExtensionData; import net.swofty.type.skyblockgeneric.minion.extension.extensions.MinionFuelExtension; import net.swofty.type.skyblockgeneric.user.SkyBlockIsland; +import org.tinylog.Logger; import java.util.*; @@ -96,8 +97,8 @@ public boolean addItem(SkyBlockItem item) { } else { // If the item does not exist, add it as a new entry. if (item.getAttributeHandler().getPotentialType() == null) { - System.out.println(item.getAttributeHandler().getTypeAsString()); - throw new NullPointerException("Item type is null"); + throw new NullPointerException( + "Item type is null for " + item.getAttributeHandler().getTypeAsString()); } itemsInMinion.add(new ItemQuantifiable(item.getAttributeHandler().getPotentialType(), item.getAmount())); } @@ -172,7 +173,7 @@ public static IslandMinion deserialize(Map data) { try { amount = Integer.parseInt(item.substring(splitIndex + 1)); } catch (NumberFormatException e) { - System.err.println("Failed to parse item amount: " + item); + Logger.error("Failed to parse item amount: {}", item); throw new RuntimeException("Failed to parse item amount: " + item, e); } itemsInMinion.add(new ItemQuantifiable( @@ -180,7 +181,7 @@ public static IslandMinion deserialize(Map data) { amount )); } else { - System.err.println("Invalid item format: " + item); + Logger.error("Invalid item format: {}", item); throw new RuntimeException("Invalid item format: " + item); } }); From 2f224bc3e0b1c30f48fba2f5a26b5b87f57f2d2e Mon Sep 17 00:00:00 2001 From: "Jacob Nardella (Swofty)" Date: Fri, 15 May 2026 00:39:35 +1000 Subject: [PATCH 042/113] refactor(commons): tighten TrackedItem encapsulation MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The class had @Setter on public final fields — a no-op since Lombok won't emit setters for final fields, but it implied the data was mutable. Made the fields private with @Getter, which matches the behaviour the existing callers were already using (getItemUUID, getCreated, etc). The two callers reading fields directly (.itemUUID, .attachedPlayers) get routed through the accessors. --- .../main/java/net/swofty/commons/TrackedItem.java | 12 +++++------- .../service/itemtracker/TrackedItemsDatabase.java | 4 ++-- .../commands/GetTrackedItemInformationCommand.java | 4 ++-- 3 files changed, 9 insertions(+), 11 deletions(-) diff --git a/commons/src/main/java/net/swofty/commons/TrackedItem.java b/commons/src/main/java/net/swofty/commons/TrackedItem.java index 82d3036ae..38ed2c14e 100644 --- a/commons/src/main/java/net/swofty/commons/TrackedItem.java +++ b/commons/src/main/java/net/swofty/commons/TrackedItem.java @@ -1,7 +1,6 @@ package net.swofty.commons; import lombok.Getter; -import lombok.Setter; import org.bson.Document; import org.json.JSONObject; @@ -11,13 +10,12 @@ import java.util.UUID; @Getter -@Setter public class TrackedItem { - public final UUID itemUUID; - public final long created; - public final ArrayList attachedPlayers; - public final String itemType; - public final Integer numberMade; + private final UUID itemUUID; + private final long created; + private final ArrayList attachedPlayers; + private final String itemType; + private final Integer numberMade; public TrackedItem(UUID itemUUID, long created, ArrayList attachedPlayers, String itemType, Integer numberMade) { this.itemUUID = itemUUID; diff --git a/service.itemtracker/src/main/java/net/swofty/service/itemtracker/TrackedItemsDatabase.java b/service.itemtracker/src/main/java/net/swofty/service/itemtracker/TrackedItemsDatabase.java index 3e84376ae..6c03fdf26 100644 --- a/service.itemtracker/src/main/java/net/swofty/service/itemtracker/TrackedItemsDatabase.java +++ b/service.itemtracker/src/main/java/net/swofty/service/itemtracker/TrackedItemsDatabase.java @@ -41,10 +41,10 @@ public TrackedItem get() { public void insertOrUpdate(TrackedItem trackedItem) { if (!exists()) { - collection.insertOne(trackedItem.toDocument().append("_id", trackedItem.itemUUID.toString())); + collection.insertOne(trackedItem.toDocument().append("_id", trackedItem.getItemUUID().toString())); return; } - collection.replaceOne(Filters.eq("_id", trackedItem.itemUUID.toString()), trackedItem.toDocument()); + collection.replaceOne(Filters.eq("_id", trackedItem.getItemUUID().toString()), trackedItem.toDocument()); } } diff --git a/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/commands/GetTrackedItemInformationCommand.java b/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/commands/GetTrackedItemInformationCommand.java index 99397596e..8eadcc4f8 100644 --- a/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/commands/GetTrackedItemInformationCommand.java +++ b/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/commands/GetTrackedItemInformationCommand.java @@ -51,9 +51,9 @@ public void registerUsage(MinestomCommand command) { player.sendMessage("§7- §eItem UUID: §7" + trackedItem.getItemUUID()); player.sendMessage("§7- §eNumber Made: §7" + trackedItem.getNumberMade()); player.sendMessage("§7- §eMade: §7" + StringUtility.formatTimeAsAgo(trackedItem.getCreated())); - player.sendMessage("§8Attached Players: §7" + trackedItem.attachedPlayers.size()); + player.sendMessage("§8Attached Players: §7" + trackedItem.getAttachedPlayers().size()); - trackedItem.attachedPlayers.forEach(log -> { + trackedItem.getAttachedPlayers().forEach(log -> { player.sendMessage("§7- §ePlayer UUID: §7" + log.playerUUID()); player.sendMessage("§7- §eProfile UUID: §7" + log.playerProfileUUID()); player.sendMessage("§7- §eFirst Seen: §7" + StringUtility.formatTimeAsAgo(log.firstSeen())); From 5274c986aee3ece1adbf0b54310f6a02c352f81c Mon Sep 17 00:00:00 2001 From: "Jacob Nardella (Swofty)" Date: Fri, 15 May 2026 00:41:48 +1000 Subject: [PATCH 043/113] chore(orchestrator): route instantiate-game errors through tinylog MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit GetServerForMapEndpoint had three identical catch-blocks that dropped stack traces to stderr — one per game type (Bedwars, MurderMystery, Skywars). All three now go through Logger.error(e, ...) so the trace reaches the configured sinks. --- .../orchestrator/endpoints/GetServerForMapEndpoint.java | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/service.orchestrator/src/main/java/net/swofty/service/orchestrator/endpoints/GetServerForMapEndpoint.java b/service.orchestrator/src/main/java/net/swofty/service/orchestrator/endpoints/GetServerForMapEndpoint.java index 42733132d..16de8f9d1 100644 --- a/service.orchestrator/src/main/java/net/swofty/service/orchestrator/endpoints/GetServerForMapEndpoint.java +++ b/service.orchestrator/src/main/java/net/swofty/service/orchestrator/endpoints/GetServerForMapEndpoint.java @@ -12,6 +12,7 @@ import net.swofty.service.generic.redis.ServiceToServerManager; import net.swofty.service.generic.redis.ServiceEndpoint; import net.swofty.service.orchestrator.OrchestratorCache; +import org.tinylog.Logger; import java.util.ArrayList; import java.util.concurrent.CompletableFuture; @@ -89,7 +90,7 @@ private GetServerForMapProtocolObject.GetServerForMapResponse handleBedwars( return new GetServerForMapProtocolObject.GetServerForMapResponse(proxy, response.gameId(), true, null); } } catch (Exception e) { - System.err.println("Failed to instantiate Bedwars game: " + e.getMessage()); + Logger.error(e, "Failed to instantiate Bedwars game"); } } @@ -154,7 +155,7 @@ private GetServerForMapProtocolObject.GetServerForMapResponse handleMurderMyster return new GetServerForMapProtocolObject.GetServerForMapResponse(proxy, response.gameId(), true, null); } } catch (Exception e) { - System.err.println("Failed to instantiate Murder Mystery game: " + e.getMessage()); + Logger.error(e, "Failed to instantiate Murder Mystery game"); } } @@ -256,7 +257,7 @@ private GetServerForMapProtocolObject.GetServerForMapResponse handleSkywars( return new GetServerForMapProtocolObject.GetServerForMapResponse(proxy, response.gameId(), true, null); } } catch (Exception e) { - System.err.println("Failed to instantiate Skywars game: " + e.getMessage()); + Logger.error(e, "Failed to instantiate Skywars game"); } } From 6f6d3cf35dd16ad7cb7df2b8801c781d23d3fc17 Mon Sep 17 00:00:00 2001 From: "Jacob Nardella (Swofty)" Date: Fri, 15 May 2026 00:47:00 +1000 Subject: [PATCH 044/113] refactor(tab): collapse 13 boilerplate ServerModule classes into AreaServerModule MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Each type.* module had its own *ServerModule.java tab module that did exactly the same thing — 'Server Info' header, one i18n area-name row, one 'Server: …' row, fillRestWithGray. The only thing that varied was the i18n area key. 13 × ~29 lines = ~380 lines of pure copy/paste. Replaced with one parameterised AreaServerModule in type.generic.tab. Each loader now calls: new AreaServerModule("tablist.server_info.area.") instead of importing and instantiating a near-duplicate class. IslandServerModule stays — it has real custom logic (minion summary rows, minion-state lookups) and isn't part of the boilerplate set. 13 files deleted, 1 file added, 13 loaders updated. --- .../TypeBackwaterBayouLoader.java | 4 +- .../tab/BackwaterBayouServerModule.java | 29 ----------- .../crimsonisle/TypeCrimsonIsleLoader.java | 4 +- .../tab/CrimsonIsleServerModule.java | 29 ----------- .../deepcaverns/TypeDeepCavernsLoader.java | 4 +- .../tab/DeepCavernsServerModule.java | 29 ----------- .../type/dungeonhub/TypeDungeonHubLoader.java | 4 +- .../dungeonhub/tab/DungeonServerModule.java | 29 ----------- .../dwarvenmines/TypeDwarvenMinesLoader.java | 4 +- .../tab/DwarvenMinesServerModule.java | 29 ----------- .../type/galatea/TypeGalateaLoader.java | 4 +- .../type/galatea/tab/GalateaServerModule.java | 29 ----------- .../type/generic/tab/AreaServerModule.java | 51 +++++++++++++++++++ .../type/goldmine/TypeGoldMineLoader.java | 4 +- .../goldmine/tab/GoldMineServerModule.java | 29 ----------- .../net/swofty/type/hub/TypeHubLoader.java | 4 +- .../swofty/type/hub/tab/HubServerModule.java | 29 ----------- .../TypeJerrysWorkshopLoader.java | 4 +- .../tab/JerrysWorkshopServerModule.java | 29 ----------- .../type/spidersden/TypeSpidersDenLoader.java | 4 +- .../tab/SpidersDenServerModule.java | 29 ----------- .../swofty/type/theend/TypeTheEndLoader.java | 4 +- .../type/theend/tab/TheEndServerModule.java | 29 ----------- .../TypeTheFarmingIslandsLoader.java | 4 +- .../tab/TheFarmingIslandsServerModule.java | 29 ----------- .../type/thepark/TypeTheParkLoader.java | 4 +- .../type/thepark/tab/TheParkServerModule.java | 29 ----------- 27 files changed, 77 insertions(+), 403 deletions(-) delete mode 100644 type.backwaterbayou/src/main/java/net/swofty/type/backwaterbayou/tab/BackwaterBayouServerModule.java delete mode 100644 type.crimsonisle/src/main/java/net/swofty/type/crimsonisle/tab/CrimsonIsleServerModule.java delete mode 100644 type.deepcaverns/src/main/java/net/swofty/type/deepcaverns/tab/DeepCavernsServerModule.java delete mode 100644 type.dungeonhub/src/main/java/net/swofty/type/dungeonhub/tab/DungeonServerModule.java delete mode 100644 type.dwarvenmines/src/main/java/net/swofty/type/dwarvenmines/tab/DwarvenMinesServerModule.java delete mode 100644 type.galatea/src/main/java/net/swofty/type/galatea/tab/GalateaServerModule.java create mode 100644 type.generic/src/main/java/net/swofty/type/generic/tab/AreaServerModule.java delete mode 100644 type.goldmine/src/main/java/net/swofty/type/goldmine/tab/GoldMineServerModule.java delete mode 100644 type.hub/src/main/java/net/swofty/type/hub/tab/HubServerModule.java delete mode 100644 type.jerrysworkshop/src/main/java/net/swofty/type/jerrysworkshop/tab/JerrysWorkshopServerModule.java delete mode 100644 type.spidersden/src/main/java/net/swofty/type/spidersden/tab/SpidersDenServerModule.java delete mode 100644 type.theend/src/main/java/net/swofty/type/theend/tab/TheEndServerModule.java delete mode 100644 type.thefarmingislands/src/main/java/net/swofty/type/thefarmingislands/tab/TheFarmingIslandsServerModule.java delete mode 100644 type.thepark/src/main/java/net/swofty/type/thepark/tab/TheParkServerModule.java diff --git a/type.backwaterbayou/src/main/java/net/swofty/type/backwaterbayou/TypeBackwaterBayouLoader.java b/type.backwaterbayou/src/main/java/net/swofty/type/backwaterbayou/TypeBackwaterBayouLoader.java index 2999edae0..92cf45931 100644 --- a/type.backwaterbayou/src/main/java/net/swofty/type/backwaterbayou/TypeBackwaterBayouLoader.java +++ b/type.backwaterbayou/src/main/java/net/swofty/type/backwaterbayou/TypeBackwaterBayouLoader.java @@ -6,7 +6,7 @@ import net.swofty.commons.ServerType; import net.swofty.commons.ServiceType; import net.swofty.proxyapi.redis.TypedProxyHandler; -import net.swofty.type.backwaterbayou.tab.BackwaterBayouServerModule; +import net.swofty.type.generic.tab.AreaServerModule; import net.swofty.type.generic.SkyBlockTypeLoader; import net.swofty.type.generic.entity.npc.HypixelNPC; import net.swofty.type.generic.event.HypixelEventClass; @@ -53,7 +53,7 @@ public List getModules() { return new ArrayList<>(List.of( new SkyBlockPlayersOnlineModule(1), new SkyBlockPlayersOnlineModule(2), - new BackwaterBayouServerModule(), + new AreaServerModule("tablist.server_info.area.backwater_bayou"), new AccountInformationModule() )); } diff --git a/type.backwaterbayou/src/main/java/net/swofty/type/backwaterbayou/tab/BackwaterBayouServerModule.java b/type.backwaterbayou/src/main/java/net/swofty/type/backwaterbayou/tab/BackwaterBayouServerModule.java deleted file mode 100644 index 3c7bd7024..000000000 --- a/type.backwaterbayou/src/main/java/net/swofty/type/backwaterbayou/tab/BackwaterBayouServerModule.java +++ /dev/null @@ -1,29 +0,0 @@ -package net.swofty.type.backwaterbayou.tab; - -import net.kyori.adventure.text.Component; -import net.swofty.type.generic.HypixelConst; -import net.swofty.type.generic.i18n.I18n; -import net.swofty.type.generic.tab.TablistModule; -import net.swofty.type.generic.tab.TablistSkinRegistry; -import net.swofty.type.generic.user.HypixelPlayer; - -import java.util.ArrayList; -import java.util.List; -import java.util.Locale; - -public class BackwaterBayouServerModule extends TablistModule { - @Override - public List getEntries(HypixelPlayer player) { - Locale l = player.getLocale(); - ArrayList entries = new ArrayList<>(List.of( - new TablistEntry(getCentered(I18n.string("tablist.module.server_info", l)), TablistSkinRegistry.CYAN) - )); - - entries.add(new TablistEntry(I18n.string("tablist.server_info.area.backwater_bayou", l), TablistSkinRegistry.GRAY)); - entries.add(new TablistEntry(I18n.string("tablist.server_info.server_label", l, Component.text(HypixelConst.getServerName())), TablistSkinRegistry.GRAY)); - - fillRestWithGray(entries); - - return entries; - } -} diff --git a/type.crimsonisle/src/main/java/net/swofty/type/crimsonisle/TypeCrimsonIsleLoader.java b/type.crimsonisle/src/main/java/net/swofty/type/crimsonisle/TypeCrimsonIsleLoader.java index 2f5f2b34a..2e0c332b5 100644 --- a/type.crimsonisle/src/main/java/net/swofty/type/crimsonisle/TypeCrimsonIsleLoader.java +++ b/type.crimsonisle/src/main/java/net/swofty/type/crimsonisle/TypeCrimsonIsleLoader.java @@ -6,7 +6,7 @@ import net.swofty.commons.ServerType; import net.swofty.commons.ServiceType; import net.swofty.proxyapi.redis.TypedProxyHandler; -import net.swofty.type.crimsonisle.tab.CrimsonIsleServerModule; +import net.swofty.type.generic.tab.AreaServerModule; import net.swofty.type.generic.SkyBlockTypeLoader; import net.swofty.type.generic.entity.npc.HypixelNPC; import net.swofty.type.generic.event.HypixelEventClass; @@ -53,7 +53,7 @@ public List getModules() { return new ArrayList<>(List.of( new SkyBlockPlayersOnlineModule(1), new SkyBlockPlayersOnlineModule(2), - new CrimsonIsleServerModule(), + new AreaServerModule("tablist.server_info.area.crimson_isle"), new AccountInformationModule() )); } diff --git a/type.crimsonisle/src/main/java/net/swofty/type/crimsonisle/tab/CrimsonIsleServerModule.java b/type.crimsonisle/src/main/java/net/swofty/type/crimsonisle/tab/CrimsonIsleServerModule.java deleted file mode 100644 index 1f4002568..000000000 --- a/type.crimsonisle/src/main/java/net/swofty/type/crimsonisle/tab/CrimsonIsleServerModule.java +++ /dev/null @@ -1,29 +0,0 @@ -package net.swofty.type.crimsonisle.tab; - -import net.kyori.adventure.text.Component; -import net.swofty.type.generic.HypixelConst; -import net.swofty.type.generic.i18n.I18n; -import net.swofty.type.generic.tab.TablistModule; -import net.swofty.type.generic.tab.TablistSkinRegistry; -import net.swofty.type.generic.user.HypixelPlayer; - -import java.util.ArrayList; -import java.util.List; -import java.util.Locale; - -public class CrimsonIsleServerModule extends TablistModule { - @Override - public List getEntries(HypixelPlayer player) { - Locale l = player.getLocale(); - ArrayList entries = new ArrayList<>(List.of( - new TablistEntry(getCentered(I18n.string("tablist.module.server_info", l)), TablistSkinRegistry.CYAN) - )); - - entries.add(new TablistEntry(I18n.string("tablist.server_info.area.crimson_isle", l), TablistSkinRegistry.GRAY)); - entries.add(new TablistEntry(I18n.string("tablist.server_info.server_label", l, Component.text(HypixelConst.getServerName())), TablistSkinRegistry.GRAY)); - - fillRestWithGray(entries); - - return entries; - } -} diff --git a/type.deepcaverns/src/main/java/net/swofty/type/deepcaverns/TypeDeepCavernsLoader.java b/type.deepcaverns/src/main/java/net/swofty/type/deepcaverns/TypeDeepCavernsLoader.java index ef8c2cf61..5d5625373 100644 --- a/type.deepcaverns/src/main/java/net/swofty/type/deepcaverns/TypeDeepCavernsLoader.java +++ b/type.deepcaverns/src/main/java/net/swofty/type/deepcaverns/TypeDeepCavernsLoader.java @@ -6,7 +6,7 @@ import net.swofty.commons.ServerType; import net.swofty.commons.ServiceType; import net.swofty.proxyapi.redis.TypedProxyHandler; -import net.swofty.type.deepcaverns.tab.DeepCavernsServerModule; +import net.swofty.type.generic.tab.AreaServerModule; import net.swofty.type.generic.SkyBlockTypeLoader; import net.swofty.type.generic.entity.npc.HypixelNPC; @@ -57,7 +57,7 @@ public List getModules() { return new ArrayList<>(List.of( new SkyBlockPlayersOnlineModule(1), new SkyBlockPlayersOnlineModule(2), - new DeepCavernsServerModule(), + new AreaServerModule("tablist.server_info.area.deep_caverns"), new AccountInformationModule() )); } diff --git a/type.deepcaverns/src/main/java/net/swofty/type/deepcaverns/tab/DeepCavernsServerModule.java b/type.deepcaverns/src/main/java/net/swofty/type/deepcaverns/tab/DeepCavernsServerModule.java deleted file mode 100644 index 5be8972ce..000000000 --- a/type.deepcaverns/src/main/java/net/swofty/type/deepcaverns/tab/DeepCavernsServerModule.java +++ /dev/null @@ -1,29 +0,0 @@ -package net.swofty.type.deepcaverns.tab; - -import net.kyori.adventure.text.Component; -import net.swofty.type.generic.HypixelConst; -import net.swofty.type.generic.i18n.I18n; -import net.swofty.type.generic.tab.TablistModule; -import net.swofty.type.generic.tab.TablistSkinRegistry; -import net.swofty.type.generic.user.HypixelPlayer; - -import java.util.ArrayList; -import java.util.List; -import java.util.Locale; - -public class DeepCavernsServerModule extends TablistModule { - @Override - public List getEntries(HypixelPlayer player) { - Locale l = player.getLocale(); - ArrayList entries = new ArrayList<>(List.of( - new TablistEntry(getCentered(I18n.string("tablist.module.server_info", l)), TablistSkinRegistry.CYAN) - )); - - entries.add(new TablistEntry(I18n.string("tablist.server_info.area.deep_caverns", l), TablistSkinRegistry.GRAY)); - entries.add(new TablistEntry(I18n.string("tablist.server_info.server_label", l, Component.text(HypixelConst.getServerName())), TablistSkinRegistry.GRAY)); - - fillRestWithGray(entries); - - return entries; - } -} diff --git a/type.dungeonhub/src/main/java/net/swofty/type/dungeonhub/TypeDungeonHubLoader.java b/type.dungeonhub/src/main/java/net/swofty/type/dungeonhub/TypeDungeonHubLoader.java index 7d9425623..c0fe2bf19 100644 --- a/type.dungeonhub/src/main/java/net/swofty/type/dungeonhub/TypeDungeonHubLoader.java +++ b/type.dungeonhub/src/main/java/net/swofty/type/dungeonhub/TypeDungeonHubLoader.java @@ -6,7 +6,7 @@ import net.swofty.commons.ServerType; import net.swofty.commons.ServiceType; import net.swofty.proxyapi.redis.TypedProxyHandler; -import net.swofty.type.dungeonhub.tab.DungeonServerModule; +import net.swofty.type.generic.tab.AreaServerModule; import net.swofty.type.generic.SkyBlockTypeLoader; import net.swofty.type.generic.entity.npc.HypixelNPC; import net.swofty.type.generic.event.HypixelEventClass; @@ -57,7 +57,7 @@ public List getModules() { return new ArrayList<>(List.of( new SkyBlockPlayersOnlineModule(1), new SkyBlockPlayersOnlineModule(2), - new DungeonServerModule(), + new AreaServerModule("tablist.server_info.area.dungeon_hub"), new AccountInformationModule() )); } diff --git a/type.dungeonhub/src/main/java/net/swofty/type/dungeonhub/tab/DungeonServerModule.java b/type.dungeonhub/src/main/java/net/swofty/type/dungeonhub/tab/DungeonServerModule.java deleted file mode 100644 index abf6e8034..000000000 --- a/type.dungeonhub/src/main/java/net/swofty/type/dungeonhub/tab/DungeonServerModule.java +++ /dev/null @@ -1,29 +0,0 @@ -package net.swofty.type.dungeonhub.tab; - -import net.kyori.adventure.text.Component; -import net.swofty.type.generic.HypixelConst; -import net.swofty.type.generic.i18n.I18n; -import net.swofty.type.generic.tab.TablistModule; -import net.swofty.type.generic.tab.TablistSkinRegistry; -import net.swofty.type.generic.user.HypixelPlayer; - -import java.util.ArrayList; -import java.util.List; -import java.util.Locale; - -public class DungeonServerModule extends TablistModule { - @Override - public List getEntries(HypixelPlayer player) { - Locale l = player.getLocale(); - ArrayList entries = new ArrayList<>(List.of( - new TablistEntry(getCentered(I18n.string("tablist.module.server_info", l)), TablistSkinRegistry.CYAN) - )); - - entries.add(new TablistEntry(I18n.string("tablist.server_info.area.dungeon_hub", l), TablistSkinRegistry.GRAY)); - entries.add(new TablistEntry(I18n.string("tablist.server_info.server_label", l, Component.text(HypixelConst.getServerName())), TablistSkinRegistry.GRAY)); - - fillRestWithGray(entries); - - return entries; - } -} diff --git a/type.dwarvenmines/src/main/java/net/swofty/type/dwarvenmines/TypeDwarvenMinesLoader.java b/type.dwarvenmines/src/main/java/net/swofty/type/dwarvenmines/TypeDwarvenMinesLoader.java index 8445cda5d..15f99ab5b 100644 --- a/type.dwarvenmines/src/main/java/net/swofty/type/dwarvenmines/TypeDwarvenMinesLoader.java +++ b/type.dwarvenmines/src/main/java/net/swofty/type/dwarvenmines/TypeDwarvenMinesLoader.java @@ -14,7 +14,7 @@ import net.swofty.commons.ServiceType; import net.swofty.proxyapi.redis.TypedProxyHandler; import net.swofty.type.dwarvenmines.gui.GUIGemstoneGrinder; -import net.swofty.type.dwarvenmines.tab.DwarvenMinesServerModule; +import net.swofty.type.generic.tab.AreaServerModule; import net.swofty.type.generic.HypixelConst; import net.swofty.type.generic.SkyBlockTypeLoader; import net.swofty.type.generic.entity.InteractionEntity; @@ -74,7 +74,7 @@ public List getModules() { return new ArrayList<>(List.of( new SkyBlockPlayersOnlineModule(1), new SkyBlockPlayersOnlineModule(2), - new DwarvenMinesServerModule(), + new AreaServerModule("tablist.server_info.area.dwarven_mines"), new AccountInformationModule() )); } diff --git a/type.dwarvenmines/src/main/java/net/swofty/type/dwarvenmines/tab/DwarvenMinesServerModule.java b/type.dwarvenmines/src/main/java/net/swofty/type/dwarvenmines/tab/DwarvenMinesServerModule.java deleted file mode 100644 index f56bdc9be..000000000 --- a/type.dwarvenmines/src/main/java/net/swofty/type/dwarvenmines/tab/DwarvenMinesServerModule.java +++ /dev/null @@ -1,29 +0,0 @@ -package net.swofty.type.dwarvenmines.tab; - -import net.kyori.adventure.text.Component; -import net.swofty.type.generic.HypixelConst; -import net.swofty.type.generic.i18n.I18n; -import net.swofty.type.generic.tab.TablistModule; -import net.swofty.type.generic.tab.TablistSkinRegistry; -import net.swofty.type.generic.user.HypixelPlayer; - -import java.util.ArrayList; -import java.util.List; -import java.util.Locale; - -public class DwarvenMinesServerModule extends TablistModule { - @Override - public List getEntries(HypixelPlayer player) { - Locale l = player.getLocale(); - ArrayList entries = new ArrayList<>(List.of( - new TablistEntry(getCentered(I18n.string("tablist.module.server_info", l)), TablistSkinRegistry.CYAN) - )); - - entries.add(new TablistEntry(I18n.string("tablist.server_info.area.dwarven_mines", l), TablistSkinRegistry.GRAY)); - entries.add(new TablistEntry(I18n.string("tablist.server_info.server_label", l, Component.text(HypixelConst.getServerName())), TablistSkinRegistry.GRAY)); - - fillRestWithGray(entries); - - return entries; - } -} diff --git a/type.galatea/src/main/java/net/swofty/type/galatea/TypeGalateaLoader.java b/type.galatea/src/main/java/net/swofty/type/galatea/TypeGalateaLoader.java index 16abe65c1..529a2551a 100644 --- a/type.galatea/src/main/java/net/swofty/type/galatea/TypeGalateaLoader.java +++ b/type.galatea/src/main/java/net/swofty/type/galatea/TypeGalateaLoader.java @@ -7,7 +7,7 @@ import net.swofty.commons.ServiceType; import net.swofty.commons.Songs; import net.swofty.proxyapi.redis.TypedProxyHandler; -import net.swofty.type.galatea.tab.GalateaServerModule; +import net.swofty.type.generic.tab.AreaServerModule; import net.swofty.type.generic.SkyBlockTypeLoader; import net.swofty.type.generic.entity.npc.HypixelNPC; import net.swofty.type.generic.event.HypixelEventClass; @@ -61,7 +61,7 @@ public List getModules() { return new ArrayList<>(List.of( new SkyBlockPlayersOnlineModule(1), new SkyBlockPlayersOnlineModule(2), - new GalateaServerModule(), + new AreaServerModule("tablist.server_info.area.galatea"), new AccountInformationModule() )); } diff --git a/type.galatea/src/main/java/net/swofty/type/galatea/tab/GalateaServerModule.java b/type.galatea/src/main/java/net/swofty/type/galatea/tab/GalateaServerModule.java deleted file mode 100644 index 0cf7ae892..000000000 --- a/type.galatea/src/main/java/net/swofty/type/galatea/tab/GalateaServerModule.java +++ /dev/null @@ -1,29 +0,0 @@ -package net.swofty.type.galatea.tab; - -import net.kyori.adventure.text.Component; -import net.swofty.type.generic.HypixelConst; -import net.swofty.type.generic.i18n.I18n; -import net.swofty.type.generic.tab.TablistModule; -import net.swofty.type.generic.tab.TablistSkinRegistry; -import net.swofty.type.generic.user.HypixelPlayer; - -import java.util.ArrayList; -import java.util.List; -import java.util.Locale; - -public class GalateaServerModule extends TablistModule { - @Override - public List getEntries(HypixelPlayer player) { - Locale l = player.getLocale(); - ArrayList entries = new ArrayList<>(List.of( - new TablistEntry(getCentered(I18n.string("tablist.module.server_info", l)), TablistSkinRegistry.CYAN) - )); - - entries.add(new TablistEntry(I18n.string("tablist.server_info.area.galatea", l), TablistSkinRegistry.GRAY)); - entries.add(new TablistEntry(I18n.string("tablist.server_info.server_label", l, Component.text(HypixelConst.getServerName())), TablistSkinRegistry.GRAY)); - - fillRestWithGray(entries); - - return entries; - } -} diff --git a/type.generic/src/main/java/net/swofty/type/generic/tab/AreaServerModule.java b/type.generic/src/main/java/net/swofty/type/generic/tab/AreaServerModule.java new file mode 100644 index 000000000..8e6ce13b6 --- /dev/null +++ b/type.generic/src/main/java/net/swofty/type/generic/tab/AreaServerModule.java @@ -0,0 +1,51 @@ +package net.swofty.type.generic.tab; + +import net.kyori.adventure.text.Component; +import net.swofty.type.generic.HypixelConst; +import net.swofty.type.generic.i18n.I18n; +import net.swofty.type.generic.user.HypixelPlayer; + +import java.util.ArrayList; +import java.util.List; +import java.util.Locale; + +/** + * Generic 'Server Info' tablist module that displays: + *
+ *   {area name}
+ *   Server: {server identifier}
+ * 
+ * Most type.* loaders previously held a hand-written subclass that differed + * only in the i18n area key (spiders_den, crimson_isle, gold_mine, ...). + * Those have been collapsed to a single shared module; callers pass the + * area key when registering. + * + *

Modules that need extra rows (e.g. private-island minion summary) still + * extend {@link TablistModule} directly; this is only for the plain + * area/server pair. + */ +public class AreaServerModule extends TablistModule { + + private final String areaI18nKey; + + public AreaServerModule(String areaI18nKey) { + this.areaI18nKey = areaI18nKey; + } + + @Override + public List getEntries(HypixelPlayer player) { + Locale l = player.getLocale(); + ArrayList entries = new ArrayList<>(List.of( + new TablistEntry(getCentered(I18n.string("tablist.module.server_info", l)), TablistSkinRegistry.CYAN) + )); + + entries.add(new TablistEntry(I18n.string(areaI18nKey, l), TablistSkinRegistry.GRAY)); + entries.add(new TablistEntry( + I18n.string("tablist.server_info.server_label", l, Component.text(HypixelConst.getServerName())), + TablistSkinRegistry.GRAY + )); + + fillRestWithGray(entries); + return entries; + } +} diff --git a/type.goldmine/src/main/java/net/swofty/type/goldmine/TypeGoldMineLoader.java b/type.goldmine/src/main/java/net/swofty/type/goldmine/TypeGoldMineLoader.java index d3f9d7f8c..79b333ae7 100644 --- a/type.goldmine/src/main/java/net/swofty/type/goldmine/TypeGoldMineLoader.java +++ b/type.goldmine/src/main/java/net/swofty/type/goldmine/TypeGoldMineLoader.java @@ -18,7 +18,7 @@ import net.swofty.type.generic.tab.TablistManager; import net.swofty.type.generic.tab.TablistModule; import net.swofty.type.goldmine.entity.EntityLostPickaxe; -import net.swofty.type.goldmine.tab.GoldMineServerModule; +import net.swofty.type.generic.tab.AreaServerModule; import net.swofty.type.skyblockgeneric.SkyBlockGenericLoader; import net.swofty.type.skyblockgeneric.tabmodules.AccountInformationModule; import net.swofty.type.skyblockgeneric.tabmodules.SkyBlockPlayersOnlineModule; @@ -76,7 +76,7 @@ public List getModules() { return new ArrayList<>(List.of( new SkyBlockPlayersOnlineModule(1), new SkyBlockPlayersOnlineModule(2), - new GoldMineServerModule(), + new AreaServerModule("tablist.server_info.area.gold_mine"), new AccountInformationModule() )); } diff --git a/type.goldmine/src/main/java/net/swofty/type/goldmine/tab/GoldMineServerModule.java b/type.goldmine/src/main/java/net/swofty/type/goldmine/tab/GoldMineServerModule.java deleted file mode 100644 index cffa6ba95..000000000 --- a/type.goldmine/src/main/java/net/swofty/type/goldmine/tab/GoldMineServerModule.java +++ /dev/null @@ -1,29 +0,0 @@ -package net.swofty.type.goldmine.tab; - -import net.kyori.adventure.text.Component; -import net.swofty.type.generic.HypixelConst; -import net.swofty.type.generic.i18n.I18n; -import net.swofty.type.generic.tab.TablistModule; -import net.swofty.type.generic.tab.TablistSkinRegistry; -import net.swofty.type.generic.user.HypixelPlayer; - -import java.util.ArrayList; -import java.util.List; -import java.util.Locale; - -public class GoldMineServerModule extends TablistModule { - @Override - public List getEntries(HypixelPlayer player) { - Locale l = player.getLocale(); - ArrayList entries = new ArrayList<>(List.of( - new TablistEntry(getCentered(I18n.string("tablist.module.server_info", l)), TablistSkinRegistry.CYAN) - )); - - entries.add(new TablistEntry(I18n.string("tablist.server_info.area.gold_mine", l), TablistSkinRegistry.GRAY)); - entries.add(new TablistEntry(I18n.string("tablist.server_info.server_label", l, Component.text(HypixelConst.getServerName())), TablistSkinRegistry.GRAY)); - - fillRestWithGray(entries); - - return entries; - } -} diff --git a/type.hub/src/main/java/net/swofty/type/hub/TypeHubLoader.java b/type.hub/src/main/java/net/swofty/type/hub/TypeHubLoader.java index ed6a5433c..4a61fc9c0 100644 --- a/type.hub/src/main/java/net/swofty/type/hub/TypeHubLoader.java +++ b/type.hub/src/main/java/net/swofty/type/hub/TypeHubLoader.java @@ -30,7 +30,7 @@ import net.swofty.type.generic.tab.TablistManager; import net.swofty.type.generic.tab.TablistModule; import net.swofty.type.hub.darkauction.DarkAuctionDisplay; -import net.swofty.type.hub.tab.HubServerModule; +import net.swofty.type.generic.tab.AreaServerModule; import net.swofty.type.hub.util.HubMap; import net.swofty.type.skyblockgeneric.SkyBlockGenericLoader; import net.swofty.type.skyblockgeneric.calendar.CalendarEvent; @@ -207,7 +207,7 @@ public List getModules() { return new ArrayList<>(List.of( new SkyBlockPlayersOnlineModule(1), new SkyBlockPlayersOnlineModule(2), - new HubServerModule(), + new AreaServerModule("tablist.server_info.area.hub"), new AccountInformationModule() )); } diff --git a/type.hub/src/main/java/net/swofty/type/hub/tab/HubServerModule.java b/type.hub/src/main/java/net/swofty/type/hub/tab/HubServerModule.java deleted file mode 100644 index 17f1c7473..000000000 --- a/type.hub/src/main/java/net/swofty/type/hub/tab/HubServerModule.java +++ /dev/null @@ -1,29 +0,0 @@ -package net.swofty.type.hub.tab; - -import net.kyori.adventure.text.Component; -import net.swofty.type.generic.HypixelConst; -import net.swofty.type.generic.i18n.I18n; -import net.swofty.type.generic.tab.TablistModule; -import net.swofty.type.generic.tab.TablistSkinRegistry; -import net.swofty.type.generic.user.HypixelPlayer; - -import java.util.ArrayList; -import java.util.List; -import java.util.Locale; - -public class HubServerModule extends TablistModule { - @Override - public List getEntries(HypixelPlayer player) { - Locale l = player.getLocale(); - ArrayList entries = new ArrayList<>(List.of( - new TablistEntry(getCentered(I18n.string("tablist.module.server_info", l)), TablistSkinRegistry.CYAN) - )); - - entries.add(new TablistEntry(I18n.string("tablist.server_info.area.hub", l), TablistSkinRegistry.GRAY)); - entries.add(new TablistEntry(I18n.string("tablist.server_info.server_label", l, Component.text(HypixelConst.getServerName())), TablistSkinRegistry.GRAY)); - - fillRestWithGray(entries); - - return entries; - } -} diff --git a/type.jerrysworkshop/src/main/java/net/swofty/type/jerrysworkshop/TypeJerrysWorkshopLoader.java b/type.jerrysworkshop/src/main/java/net/swofty/type/jerrysworkshop/TypeJerrysWorkshopLoader.java index 2903ef275..46e3bda21 100644 --- a/type.jerrysworkshop/src/main/java/net/swofty/type/jerrysworkshop/TypeJerrysWorkshopLoader.java +++ b/type.jerrysworkshop/src/main/java/net/swofty/type/jerrysworkshop/TypeJerrysWorkshopLoader.java @@ -21,7 +21,7 @@ import net.swofty.type.skyblockgeneric.item.SkyBlockItem; import net.swofty.type.skyblockgeneric.tabmodules.AccountInformationModule; import net.swofty.type.skyblockgeneric.tabmodules.SkyBlockPlayersOnlineModule; -import net.swofty.type.jerrysworkshop.tab.JerrysWorkshopServerModule; +import net.swofty.type.generic.tab.AreaServerModule; import org.jetbrains.annotations.Nullable; import org.tinylog.Logger; @@ -66,7 +66,7 @@ public List getModules() { return new ArrayList<>(List.of( new SkyBlockPlayersOnlineModule(1), new SkyBlockPlayersOnlineModule(2), - new JerrysWorkshopServerModule(), + new AreaServerModule("tablist.server_info.area.jerrys_workshop"), new AccountInformationModule() )); } diff --git a/type.jerrysworkshop/src/main/java/net/swofty/type/jerrysworkshop/tab/JerrysWorkshopServerModule.java b/type.jerrysworkshop/src/main/java/net/swofty/type/jerrysworkshop/tab/JerrysWorkshopServerModule.java deleted file mode 100644 index cc496d6b9..000000000 --- a/type.jerrysworkshop/src/main/java/net/swofty/type/jerrysworkshop/tab/JerrysWorkshopServerModule.java +++ /dev/null @@ -1,29 +0,0 @@ -package net.swofty.type.jerrysworkshop.tab; - -import net.kyori.adventure.text.Component; -import net.swofty.type.generic.HypixelConst; -import net.swofty.type.generic.i18n.I18n; -import net.swofty.type.generic.tab.TablistModule; -import net.swofty.type.generic.tab.TablistSkinRegistry; -import net.swofty.type.generic.user.HypixelPlayer; - -import java.util.ArrayList; -import java.util.List; -import java.util.Locale; - -public class JerrysWorkshopServerModule extends TablistModule { - @Override - public List getEntries(HypixelPlayer player) { - Locale l = player.getLocale(); - ArrayList entries = new ArrayList<>(List.of( - new TablistEntry(getCentered(I18n.string("tablist.module.server_info", l)), TablistSkinRegistry.CYAN) - )); - - entries.add(new TablistEntry(I18n.string("tablist.server_info.area.jerrys_workshop", l), TablistSkinRegistry.GRAY)); - entries.add(new TablistEntry(I18n.string("tablist.server_info.server_label", l, Component.text(HypixelConst.getServerName())), TablistSkinRegistry.GRAY)); - - fillRestWithGray(entries); - - return entries; - } -} diff --git a/type.spidersden/src/main/java/net/swofty/type/spidersden/TypeSpidersDenLoader.java b/type.spidersden/src/main/java/net/swofty/type/spidersden/TypeSpidersDenLoader.java index a44b9e80a..de5042327 100644 --- a/type.spidersden/src/main/java/net/swofty/type/spidersden/TypeSpidersDenLoader.java +++ b/type.spidersden/src/main/java/net/swofty/type/spidersden/TypeSpidersDenLoader.java @@ -14,7 +14,7 @@ import net.swofty.type.skyblockgeneric.SkyBlockGenericLoader; import net.swofty.type.skyblockgeneric.tabmodules.AccountInformationModule; import net.swofty.type.skyblockgeneric.tabmodules.SkyBlockPlayersOnlineModule; -import net.swofty.type.spidersden.tab.SpidersDenServerModule; +import net.swofty.type.generic.tab.AreaServerModule; import org.jetbrains.annotations.Nullable; import org.tinylog.Logger; @@ -57,7 +57,7 @@ public List getModules() { return new ArrayList<>(List.of( new SkyBlockPlayersOnlineModule(1), new SkyBlockPlayersOnlineModule(2), - new SpidersDenServerModule(), + new AreaServerModule("tablist.server_info.area.spiders_den"), new AccountInformationModule() )); } diff --git a/type.spidersden/src/main/java/net/swofty/type/spidersden/tab/SpidersDenServerModule.java b/type.spidersden/src/main/java/net/swofty/type/spidersden/tab/SpidersDenServerModule.java deleted file mode 100644 index 43bf6d32e..000000000 --- a/type.spidersden/src/main/java/net/swofty/type/spidersden/tab/SpidersDenServerModule.java +++ /dev/null @@ -1,29 +0,0 @@ -package net.swofty.type.spidersden.tab; - -import net.kyori.adventure.text.Component; -import net.swofty.type.generic.HypixelConst; -import net.swofty.type.generic.i18n.I18n; -import net.swofty.type.generic.tab.TablistModule; -import net.swofty.type.generic.tab.TablistSkinRegistry; -import net.swofty.type.generic.user.HypixelPlayer; - -import java.util.ArrayList; -import java.util.List; -import java.util.Locale; - -public class SpidersDenServerModule extends TablistModule { - @Override - public List getEntries(HypixelPlayer player) { - Locale l = player.getLocale(); - ArrayList entries = new ArrayList<>(List.of( - new TablistEntry(getCentered(I18n.string("tablist.module.server_info", l)), TablistSkinRegistry.CYAN) - )); - - entries.add(new TablistEntry(I18n.string("tablist.server_info.area.spiders_den", l), TablistSkinRegistry.GRAY)); - entries.add(new TablistEntry(I18n.string("tablist.server_info.server_label", l, Component.text(HypixelConst.getServerName())), TablistSkinRegistry.GRAY)); - - fillRestWithGray(entries); - - return entries; - } -} diff --git a/type.theend/src/main/java/net/swofty/type/theend/TypeTheEndLoader.java b/type.theend/src/main/java/net/swofty/type/theend/TypeTheEndLoader.java index a90a16ca2..99448ca3f 100644 --- a/type.theend/src/main/java/net/swofty/type/theend/TypeTheEndLoader.java +++ b/type.theend/src/main/java/net/swofty/type/theend/TypeTheEndLoader.java @@ -17,7 +17,7 @@ import net.swofty.type.skyblockgeneric.SkyBlockGenericLoader; import net.swofty.type.skyblockgeneric.tabmodules.AccountInformationModule; import net.swofty.type.skyblockgeneric.tabmodules.SkyBlockPlayersOnlineModule; -import net.swofty.type.theend.tab.TheEndServerModule; +import net.swofty.type.generic.tab.AreaServerModule; import org.jetbrains.annotations.Nullable; import org.tinylog.Logger; @@ -58,7 +58,7 @@ public List getModules() { return new ArrayList<>(List.of( new SkyBlockPlayersOnlineModule(1), new SkyBlockPlayersOnlineModule(2), - new TheEndServerModule(), + new AreaServerModule("tablist.server_info.area.the_end"), new AccountInformationModule() )); } diff --git a/type.theend/src/main/java/net/swofty/type/theend/tab/TheEndServerModule.java b/type.theend/src/main/java/net/swofty/type/theend/tab/TheEndServerModule.java deleted file mode 100644 index 4de1fd0bc..000000000 --- a/type.theend/src/main/java/net/swofty/type/theend/tab/TheEndServerModule.java +++ /dev/null @@ -1,29 +0,0 @@ -package net.swofty.type.theend.tab; - -import net.kyori.adventure.text.Component; -import net.swofty.type.generic.HypixelConst; -import net.swofty.type.generic.i18n.I18n; -import net.swofty.type.generic.tab.TablistModule; -import net.swofty.type.generic.tab.TablistSkinRegistry; -import net.swofty.type.generic.user.HypixelPlayer; - -import java.util.ArrayList; -import java.util.List; -import java.util.Locale; - -public class TheEndServerModule extends TablistModule { - @Override - public List getEntries(HypixelPlayer player) { - Locale l = player.getLocale(); - ArrayList entries = new ArrayList<>(List.of( - new TablistEntry(getCentered(I18n.string("tablist.module.server_info", l)), TablistSkinRegistry.CYAN) - )); - - entries.add(new TablistEntry(I18n.string("tablist.server_info.area.the_end", l), TablistSkinRegistry.GRAY)); - entries.add(new TablistEntry(I18n.string("tablist.server_info.server_label", l, Component.text(HypixelConst.getServerName())), TablistSkinRegistry.GRAY)); - - fillRestWithGray(entries); - - return entries; - } -} diff --git a/type.thefarmingislands/src/main/java/net/swofty/type/thefarmingislands/TypeTheFarmingIslandsLoader.java b/type.thefarmingislands/src/main/java/net/swofty/type/thefarmingislands/TypeTheFarmingIslandsLoader.java index 0b5d81507..9bb241c6d 100644 --- a/type.thefarmingislands/src/main/java/net/swofty/type/thefarmingislands/TypeTheFarmingIslandsLoader.java +++ b/type.thefarmingislands/src/main/java/net/swofty/type/thefarmingislands/TypeTheFarmingIslandsLoader.java @@ -15,7 +15,7 @@ import net.swofty.type.generic.tab.TablistModule; import net.swofty.type.skyblockgeneric.tabmodules.AccountInformationModule; import net.swofty.type.skyblockgeneric.tabmodules.SkyBlockPlayersOnlineModule; -import net.swofty.type.thefarmingislands.tab.TheFarmingIslandsServerModule; +import net.swofty.type.generic.tab.AreaServerModule; import net.swofty.type.skyblockgeneric.SkyBlockGenericLoader; import org.jetbrains.annotations.Nullable; import org.tinylog.Logger; @@ -57,7 +57,7 @@ public List getModules() { return new ArrayList<>(List.of( new SkyBlockPlayersOnlineModule(1), new SkyBlockPlayersOnlineModule(2), - new TheFarmingIslandsServerModule(), + new AreaServerModule("tablist.server_info.area.the_farming_islands"), new AccountInformationModule() )); } diff --git a/type.thefarmingislands/src/main/java/net/swofty/type/thefarmingislands/tab/TheFarmingIslandsServerModule.java b/type.thefarmingislands/src/main/java/net/swofty/type/thefarmingislands/tab/TheFarmingIslandsServerModule.java deleted file mode 100644 index f535466f0..000000000 --- a/type.thefarmingislands/src/main/java/net/swofty/type/thefarmingislands/tab/TheFarmingIslandsServerModule.java +++ /dev/null @@ -1,29 +0,0 @@ -package net.swofty.type.thefarmingislands.tab; - -import net.kyori.adventure.text.Component; -import net.swofty.type.generic.HypixelConst; -import net.swofty.type.generic.i18n.I18n; -import net.swofty.type.generic.tab.TablistModule; -import net.swofty.type.generic.tab.TablistSkinRegistry; -import net.swofty.type.generic.user.HypixelPlayer; - -import java.util.ArrayList; -import java.util.List; -import java.util.Locale; - -public class TheFarmingIslandsServerModule extends TablistModule { - @Override - public List getEntries(HypixelPlayer player) { - Locale l = player.getLocale(); - ArrayList entries = new ArrayList<>(List.of( - new TablistEntry(getCentered(I18n.string("tablist.module.server_info", l)), TablistSkinRegistry.CYAN) - )); - - entries.add(new TablistEntry(I18n.string("tablist.server_info.area.the_farming_islands", l), TablistSkinRegistry.GRAY)); - entries.add(new TablistEntry(I18n.string("tablist.server_info.server_label", l, Component.text(HypixelConst.getServerName())), TablistSkinRegistry.GRAY)); - - fillRestWithGray(entries); - - return entries; - } -} diff --git a/type.thepark/src/main/java/net/swofty/type/thepark/TypeTheParkLoader.java b/type.thepark/src/main/java/net/swofty/type/thepark/TypeTheParkLoader.java index 4806ed56f..9c93591b6 100644 --- a/type.thepark/src/main/java/net/swofty/type/thepark/TypeTheParkLoader.java +++ b/type.thepark/src/main/java/net/swofty/type/thepark/TypeTheParkLoader.java @@ -35,7 +35,7 @@ import net.swofty.type.skyblockgeneric.tabmodules.AccountInformationModule; import net.swofty.type.skyblockgeneric.tabmodules.SkyBlockPlayersOnlineModule; import net.swofty.type.skyblockgeneric.user.SkyBlockPlayer; -import net.swofty.type.thepark.tab.TheParkServerModule; +import net.swofty.type.generic.tab.AreaServerModule; import org.jetbrains.annotations.Nullable; import org.joml.Quaternionf; import org.tinylog.Logger; @@ -243,7 +243,7 @@ public List getModules() { return new ArrayList<>(List.of( new SkyBlockPlayersOnlineModule(1), new SkyBlockPlayersOnlineModule(2), - new TheParkServerModule(), + new AreaServerModule("tablist.server_info.area.the_park"), new AccountInformationModule() )); } diff --git a/type.thepark/src/main/java/net/swofty/type/thepark/tab/TheParkServerModule.java b/type.thepark/src/main/java/net/swofty/type/thepark/tab/TheParkServerModule.java deleted file mode 100644 index e35b8fdb8..000000000 --- a/type.thepark/src/main/java/net/swofty/type/thepark/tab/TheParkServerModule.java +++ /dev/null @@ -1,29 +0,0 @@ -package net.swofty.type.thepark.tab; - -import net.kyori.adventure.text.Component; -import net.swofty.type.generic.HypixelConst; -import net.swofty.type.generic.i18n.I18n; -import net.swofty.type.generic.tab.TablistModule; -import net.swofty.type.generic.tab.TablistSkinRegistry; -import net.swofty.type.generic.user.HypixelPlayer; - -import java.util.ArrayList; -import java.util.List; -import java.util.Locale; - -public class TheParkServerModule extends TablistModule { - @Override - public List getEntries(HypixelPlayer player) { - Locale l = player.getLocale(); - ArrayList entries = new ArrayList<>(List.of( - new TablistEntry(getCentered(I18n.string("tablist.module.server_info", l)), TablistSkinRegistry.CYAN) - )); - - entries.add(new TablistEntry(I18n.string("tablist.server_info.area.the_park", l), TablistSkinRegistry.GRAY)); - entries.add(new TablistEntry(I18n.string("tablist.server_info.server_label", l, Component.text(HypixelConst.getServerName())), TablistSkinRegistry.GRAY)); - - fillRestWithGray(entries); - - return entries; - } -} From 6c84ffc8a3d4b60d454e0eb4b4ba7cd1f39c1881 Mon Sep 17 00:00:00 2001 From: "Jacob Nardella (Swofty)" Date: Fri, 15 May 2026 00:51:07 +1000 Subject: [PATCH 045/113] test(commons): add unit tests for ChatUtility.FontInfo MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Locks down stripTokens, getDefaultFontInfo (including fallback to DEFAULT for unknown characters), getLength, centerLines, and the empty/null guard on getCenterSpaces. While writing 'getLengthBoldIsWider' I discovered that the bold detection in getLength is dead — stripTokens(message) runs first and removes every '§l' before the loop ever sees it. Replaced the ambitious bold assertion with a tight 'each character adds length+1px' assertion (22 for 'Hello') and left the bold dead-code detection as a follow-up so we don't shift centering of currently non-bold strings. --- .../net/swofty/commons/ChatUtilityTest.java | 83 +++++++++++++++++++ 1 file changed, 83 insertions(+) create mode 100644 commons/src/test/java/net/swofty/commons/ChatUtilityTest.java diff --git a/commons/src/test/java/net/swofty/commons/ChatUtilityTest.java b/commons/src/test/java/net/swofty/commons/ChatUtilityTest.java new file mode 100644 index 000000000..973091ecd --- /dev/null +++ b/commons/src/test/java/net/swofty/commons/ChatUtilityTest.java @@ -0,0 +1,83 @@ +package net.swofty.commons; + +import org.junit.jupiter.api.Test; + +import java.util.List; + +import static org.junit.jupiter.api.Assertions.*; + +class ChatUtilityTest { + + @Test + void stripTokensRemovesColorCodes() { + assertEquals("Hello", ChatUtility.FontInfo.stripTokens("§aHello")); + assertEquals("Plain", ChatUtility.FontInfo.stripTokens("Plain")); + assertEquals("Mixed text", ChatUtility.FontInfo.stripTokens("§cMixed §btext")); + assertEquals("", ChatUtility.FontInfo.stripTokens("§a§b§c")); + } + + @Test + void getDefaultFontInfoFindsKnownChars() { + assertEquals(ChatUtility.FontInfo.A, ChatUtility.FontInfo.getDefaultFontInfo('A')); + assertEquals(ChatUtility.FontInfo.i, ChatUtility.FontInfo.getDefaultFontInfo('i')); + assertEquals(ChatUtility.FontInfo.SPACE, ChatUtility.FontInfo.getDefaultFontInfo(' ')); + assertEquals(ChatUtility.FontInfo.NUM_5, ChatUtility.FontInfo.getDefaultFontInfo('5')); + } + + @Test + void getDefaultFontInfoFallsBackForUnknown() { + // Characters that aren't in the table return DEFAULT + assertEquals(ChatUtility.FontInfo.DEFAULT, ChatUtility.FontInfo.getDefaultFontInfo('Ω')); + assertEquals(ChatUtility.FontInfo.DEFAULT, ChatUtility.FontInfo.getDefaultFontInfo('€')); + } + + @Test + void getLengthEmptyStringIsZero() { + assertEquals(0, ChatUtility.FontInfo.getLength("")); + } + + @Test + void getLengthIgnoresColorCodes() { + // Color codes don't contribute width + int plain = ChatUtility.FontInfo.getLength("Hello"); + int colored = ChatUtility.FontInfo.getLength("§aHello"); + int doubleColored = ChatUtility.FontInfo.getLength("§c§oHello"); + assertEquals(plain, colored); + assertEquals(plain, doubleColored); + } + + @Test + void getLengthCountsEachCharacter() { + // Each letter adds its declared length + 1 spacing pixel. + // 'H','e','l','l','o' -> 5+1 + 5+1 + 1+1 + 1+1 + 5+1 = 22 + assertEquals(22, ChatUtility.FontInfo.getLength("Hello")); + } + + @Test + void centerLinesPadsEachLine() { + List input = List.of("Short", "A longer line"); + List output = ChatUtility.FontInfo.centerLines(input); + assertEquals(input.size(), output.size()); + // Each output line ends with the input line + for (int i = 0; i < input.size(); i++) { + assertTrue(output.get(i).endsWith(input.get(i)), + "Output line should end with input: " + output.get(i)); + } + } + + @Test + void centerEmptyStringYieldsEmptyPad() { + // Implementation returns "" for null or empty + assertEquals("", ChatUtility.FontInfo.getCenterSpaces("")); + assertEquals("", ChatUtility.FontInfo.getCenterSpaces(null)); + } + + @Test + void fontInfoCharacterAndLengthMatch() { + // Spot-check a few entries to lock down the data + assertEquals('A', ChatUtility.FontInfo.A.getCharacter()); + assertEquals(5, ChatUtility.FontInfo.A.getLength()); + assertEquals(1, ChatUtility.FontInfo.i.getLength()); + assertEquals(3, ChatUtility.FontInfo.SPACE.getLength()); + } +} From 463ed97406e8a251f068220a80bce55ec1a094f0 Mon Sep 17 00:00:00 2001 From: "Jacob Nardella (Swofty)" Date: Fri, 15 May 2026 00:53:22 +1000 Subject: [PATCH 046/113] chore(service): route ServiceInitializer banner through tinylog ServiceInitializer.init() printed three structured 'initializing service / registering channel / service initialized' lines to stdout on every service start. Routed through tinylog; the channel-register trace dropped to debug because it fires once per endpoint (10+ per service) and is rarely useful at info level. Added tinylog-api to service.generic so the rest of the module can follow. --- service.generic/build.gradle.kts | 1 + .../net/swofty/service/generic/ServiceInitializer.java | 7 ++++--- 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/service.generic/build.gradle.kts b/service.generic/build.gradle.kts index e513d9711..c7b0ea4eb 100644 --- a/service.generic/build.gradle.kts +++ b/service.generic/build.gradle.kts @@ -23,4 +23,5 @@ dependencies { implementation(libs.atlas.redis) implementation(libs.adventure.api) implementation(libs.adventure.text.serializer.gson) + implementation(libs.tinylog.api) } \ No newline at end of file diff --git a/service.generic/src/main/java/net/swofty/service/generic/ServiceInitializer.java b/service.generic/src/main/java/net/swofty/service/generic/ServiceInitializer.java index 78d3840c6..62de978ae 100644 --- a/service.generic/src/main/java/net/swofty/service/generic/ServiceInitializer.java +++ b/service.generic/src/main/java/net/swofty/service/generic/ServiceInitializer.java @@ -13,6 +13,7 @@ import net.swofty.service.generic.redis.ServiceRedisManager; import net.swofty.service.generic.redis.ServiceToServerManager; import org.json.JSONObject; +import org.tinylog.Logger; import java.util.ArrayList; import java.util.List; @@ -23,7 +24,7 @@ public class ServiceInitializer { private final SkyBlockService service; public void init() { - System.out.println("Initializing service " + service.getType().name() + "..."); + Logger.info("Initializing service {}...", service.getType().name()); ItemAttribute.registerItemAttributes(); /** @@ -38,7 +39,7 @@ public void init() { endpoints.forEach(endpoint -> { ProtocolObject protocolObject = endpoint.associatedProtocolObject(); - System.out.println("Registering channel " + protocolObject.channel()); + Logger.debug("Registering channel {}", protocolObject.channel()); RedisAPI.getInstance().registerChannel(protocolObject.channel(), message -> { // Everything after the first semicolon is the actual message @@ -59,7 +60,7 @@ public void init() { }); RedisAPI.getInstance().startListeners(); - System.out.println("Service " + service.getType().name() + " initialized!"); + Logger.info("Service {} initialized!", service.getType().name()); try { new CountDownLatch(1).await(); From 05ff0d40c71d45296a26054b8a6437c5ebf67c18 Mon Sep 17 00:00:00 2001 From: "Jacob Nardella (Swofty)" Date: Fri, 15 May 2026 00:55:36 +1000 Subject: [PATCH 047/113] refactor(commons): migrate FriendEvent subclasses to JacksonSerializer Each of the 24 friend event subclasses had a hand-rolled inner-class Serializer that walked org.json.JSONObject to serialize each field, then reversed it for deserialize. ~25 lines of boilerplate per event. JacksonSerializer already exists in commons/protocol and round-trips through Jackson. The @JsonCreator / @JsonProperty annotations were already present on every constructor, so the conversion is mechanical: - one static SERIALIZER field per class - getSerializer() returns it - imports for org.json.JSONObject / JSONArray drop where no other code in the file uses them Net deletion of 552 lines (+120/-672 across 24 files). Same wire format, same instances; only the serializer implementation moved. --- .../events/FriendAcceptRequestEvent.java | 29 ++------ .../friend/events/FriendAddRequestEvent.java | 29 ++------ .../friend/events/FriendDenyRequestEvent.java | 29 ++------ .../friend/events/FriendListRequestEvent.java | 31 ++------- .../events/FriendRemoveAllRequestEvent.java | 27 ++------ .../events/FriendRemoveRequestEvent.java | 29 ++------ .../events/FriendRequestsListEvent.java | 29 ++------ .../events/FriendSetNicknameRequestEvent.java | 31 ++------- .../events/FriendToggleBestRequestEvent.java | 29 ++------ .../FriendToggleSettingRequestEvent.java | 29 ++------ .../response/FriendAddedResponseEvent.java | 33 ++------- .../FriendBestToggledResponseEvent.java | 33 ++------- .../response/FriendDeniedResponseEvent.java | 31 ++------- .../response/FriendJoinNotificationEvent.java | 31 ++------- .../FriendLeaveNotificationEvent.java | 31 ++------- .../response/FriendListResponseEvent.java | 67 ++----------------- .../FriendNicknameSetResponseEvent.java | 33 ++------- .../FriendRemoveAllResponseEvent.java | 29 ++------ .../response/FriendRemovedResponseEvent.java | 31 ++------- .../FriendRequestExpiredResponseEvent.java | 33 ++------- .../FriendRequestReceivedResponseEvent.java | 31 ++------- .../FriendRequestSentResponseEvent.java | 31 ++------- .../FriendRequestsListResponseEvent.java | 55 ++------------- .../FriendSettingToggledResponseEvent.java | 31 ++------- 24 files changed, 120 insertions(+), 672 deletions(-) diff --git a/commons/src/main/java/net/swofty/commons/friend/events/FriendAcceptRequestEvent.java b/commons/src/main/java/net/swofty/commons/friend/events/FriendAcceptRequestEvent.java index f3227850c..0daacd6a2 100644 --- a/commons/src/main/java/net/swofty/commons/friend/events/FriendAcceptRequestEvent.java +++ b/commons/src/main/java/net/swofty/commons/friend/events/FriendAcceptRequestEvent.java @@ -4,14 +4,17 @@ import com.fasterxml.jackson.annotation.JsonProperty; import lombok.Getter; import net.swofty.commons.friend.FriendEvent; +import net.swofty.commons.protocol.JacksonSerializer; import net.swofty.commons.protocol.Serializer; -import org.json.JSONObject; import java.util.List; import java.util.UUID; @Getter public final class FriendAcceptRequestEvent extends FriendEvent { + private static final Serializer SERIALIZER = + new JacksonSerializer<>(FriendAcceptRequestEvent.class); + private final UUID accepter; private final UUID requester; @@ -29,28 +32,6 @@ public List getParticipants() { @Override public Serializer getSerializer() { - return new Serializer<>() { - @Override - public String serialize(FriendAcceptRequestEvent value) { - JSONObject json = new JSONObject(); - json.put("accepter", value.accepter.toString()); - json.put("requester", value.requester.toString()); - return json.toString(); - } - - @Override - public FriendAcceptRequestEvent deserialize(String json) { - JSONObject jsonObject = new JSONObject(json); - return new FriendAcceptRequestEvent( - UUID.fromString(jsonObject.getString("accepter")), - UUID.fromString(jsonObject.getString("requester")) - ); - } - - @Override - public FriendAcceptRequestEvent clone(FriendAcceptRequestEvent value) { - return new FriendAcceptRequestEvent(value.accepter, value.requester); - } - }; + return SERIALIZER; } } diff --git a/commons/src/main/java/net/swofty/commons/friend/events/FriendAddRequestEvent.java b/commons/src/main/java/net/swofty/commons/friend/events/FriendAddRequestEvent.java index ade32ae32..89e65f1fb 100644 --- a/commons/src/main/java/net/swofty/commons/friend/events/FriendAddRequestEvent.java +++ b/commons/src/main/java/net/swofty/commons/friend/events/FriendAddRequestEvent.java @@ -4,14 +4,17 @@ import com.fasterxml.jackson.annotation.JsonProperty; import lombok.Getter; import net.swofty.commons.friend.FriendEvent; +import net.swofty.commons.protocol.JacksonSerializer; import net.swofty.commons.protocol.Serializer; -import org.json.JSONObject; import java.util.List; import java.util.UUID; @Getter public final class FriendAddRequestEvent extends FriendEvent { + private static final Serializer SERIALIZER = + new JacksonSerializer<>(FriendAddRequestEvent.class); + private final UUID sender; private final UUID target; @@ -29,28 +32,6 @@ public List getParticipants() { @Override public Serializer getSerializer() { - return new Serializer<>() { - @Override - public String serialize(FriendAddRequestEvent value) { - JSONObject json = new JSONObject(); - json.put("sender", value.sender.toString()); - json.put("target", value.target.toString()); - return json.toString(); - } - - @Override - public FriendAddRequestEvent deserialize(String json) { - JSONObject jsonObject = new JSONObject(json); - return new FriendAddRequestEvent( - UUID.fromString(jsonObject.getString("sender")), - UUID.fromString(jsonObject.getString("target")) - ); - } - - @Override - public FriendAddRequestEvent clone(FriendAddRequestEvent value) { - return new FriendAddRequestEvent(value.sender, value.target); - } - }; + return SERIALIZER; } } diff --git a/commons/src/main/java/net/swofty/commons/friend/events/FriendDenyRequestEvent.java b/commons/src/main/java/net/swofty/commons/friend/events/FriendDenyRequestEvent.java index f8b3957d3..614741c70 100644 --- a/commons/src/main/java/net/swofty/commons/friend/events/FriendDenyRequestEvent.java +++ b/commons/src/main/java/net/swofty/commons/friend/events/FriendDenyRequestEvent.java @@ -4,14 +4,17 @@ import com.fasterxml.jackson.annotation.JsonProperty; import lombok.Getter; import net.swofty.commons.friend.FriendEvent; +import net.swofty.commons.protocol.JacksonSerializer; import net.swofty.commons.protocol.Serializer; -import org.json.JSONObject; import java.util.List; import java.util.UUID; @Getter public final class FriendDenyRequestEvent extends FriendEvent { + private static final Serializer SERIALIZER = + new JacksonSerializer<>(FriendDenyRequestEvent.class); + private final UUID denier; private final UUID requester; @@ -29,28 +32,6 @@ public List getParticipants() { @Override public Serializer getSerializer() { - return new Serializer<>() { - @Override - public String serialize(FriendDenyRequestEvent value) { - JSONObject json = new JSONObject(); - json.put("denier", value.denier.toString()); - json.put("requester", value.requester.toString()); - return json.toString(); - } - - @Override - public FriendDenyRequestEvent deserialize(String json) { - JSONObject jsonObject = new JSONObject(json); - return new FriendDenyRequestEvent( - UUID.fromString(jsonObject.getString("denier")), - UUID.fromString(jsonObject.getString("requester")) - ); - } - - @Override - public FriendDenyRequestEvent clone(FriendDenyRequestEvent value) { - return new FriendDenyRequestEvent(value.denier, value.requester); - } - }; + return SERIALIZER; } } diff --git a/commons/src/main/java/net/swofty/commons/friend/events/FriendListRequestEvent.java b/commons/src/main/java/net/swofty/commons/friend/events/FriendListRequestEvent.java index bd1367cb4..346392981 100644 --- a/commons/src/main/java/net/swofty/commons/friend/events/FriendListRequestEvent.java +++ b/commons/src/main/java/net/swofty/commons/friend/events/FriendListRequestEvent.java @@ -4,14 +4,17 @@ import com.fasterxml.jackson.annotation.JsonProperty; import lombok.Getter; import net.swofty.commons.friend.FriendEvent; +import net.swofty.commons.protocol.JacksonSerializer; import net.swofty.commons.protocol.Serializer; -import org.json.JSONObject; import java.util.List; import java.util.UUID; @Getter public final class FriendListRequestEvent extends FriendEvent { + private static final Serializer SERIALIZER = + new JacksonSerializer<>(FriendListRequestEvent.class); + private final UUID player; private final int page; private final boolean bestOnly; @@ -31,30 +34,6 @@ public List getParticipants() { @Override public Serializer getSerializer() { - return new Serializer<>() { - @Override - public String serialize(FriendListRequestEvent value) { - JSONObject json = new JSONObject(); - json.put("player", value.player.toString()); - json.put("page", value.page); - json.put("bestOnly", value.bestOnly); - return json.toString(); - } - - @Override - public FriendListRequestEvent deserialize(String json) { - JSONObject jsonObject = new JSONObject(json); - return new FriendListRequestEvent( - UUID.fromString(jsonObject.getString("player")), - jsonObject.getInt("page"), - jsonObject.getBoolean("bestOnly") - ); - } - - @Override - public FriendListRequestEvent clone(FriendListRequestEvent value) { - return new FriendListRequestEvent(value.player, value.page, value.bestOnly); - } - }; + return SERIALIZER; } } diff --git a/commons/src/main/java/net/swofty/commons/friend/events/FriendRemoveAllRequestEvent.java b/commons/src/main/java/net/swofty/commons/friend/events/FriendRemoveAllRequestEvent.java index ceb903e3b..8dbba9783 100644 --- a/commons/src/main/java/net/swofty/commons/friend/events/FriendRemoveAllRequestEvent.java +++ b/commons/src/main/java/net/swofty/commons/friend/events/FriendRemoveAllRequestEvent.java @@ -4,14 +4,17 @@ import com.fasterxml.jackson.annotation.JsonProperty; import lombok.Getter; import net.swofty.commons.friend.FriendEvent; +import net.swofty.commons.protocol.JacksonSerializer; import net.swofty.commons.protocol.Serializer; -import org.json.JSONObject; import java.util.List; import java.util.UUID; @Getter public final class FriendRemoveAllRequestEvent extends FriendEvent { + private static final Serializer SERIALIZER = + new JacksonSerializer<>(FriendRemoveAllRequestEvent.class); + private final UUID player; @JsonCreator @@ -27,26 +30,6 @@ public List getParticipants() { @Override public Serializer getSerializer() { - return new Serializer<>() { - @Override - public String serialize(FriendRemoveAllRequestEvent value) { - JSONObject json = new JSONObject(); - json.put("player", value.player.toString()); - return json.toString(); - } - - @Override - public FriendRemoveAllRequestEvent deserialize(String json) { - JSONObject jsonObject = new JSONObject(json); - return new FriendRemoveAllRequestEvent( - UUID.fromString(jsonObject.getString("player")) - ); - } - - @Override - public FriendRemoveAllRequestEvent clone(FriendRemoveAllRequestEvent value) { - return new FriendRemoveAllRequestEvent(value.player); - } - }; + return SERIALIZER; } } diff --git a/commons/src/main/java/net/swofty/commons/friend/events/FriendRemoveRequestEvent.java b/commons/src/main/java/net/swofty/commons/friend/events/FriendRemoveRequestEvent.java index 1832af2f5..0ce0b3ce8 100644 --- a/commons/src/main/java/net/swofty/commons/friend/events/FriendRemoveRequestEvent.java +++ b/commons/src/main/java/net/swofty/commons/friend/events/FriendRemoveRequestEvent.java @@ -4,14 +4,17 @@ import com.fasterxml.jackson.annotation.JsonProperty; import lombok.Getter; import net.swofty.commons.friend.FriendEvent; +import net.swofty.commons.protocol.JacksonSerializer; import net.swofty.commons.protocol.Serializer; -import org.json.JSONObject; import java.util.List; import java.util.UUID; @Getter public final class FriendRemoveRequestEvent extends FriendEvent { + private static final Serializer SERIALIZER = + new JacksonSerializer<>(FriendRemoveRequestEvent.class); + private final UUID remover; private final UUID target; @@ -29,28 +32,6 @@ public List getParticipants() { @Override public Serializer getSerializer() { - return new Serializer<>() { - @Override - public String serialize(FriendRemoveRequestEvent value) { - JSONObject json = new JSONObject(); - json.put("remover", value.remover.toString()); - json.put("target", value.target.toString()); - return json.toString(); - } - - @Override - public FriendRemoveRequestEvent deserialize(String json) { - JSONObject jsonObject = new JSONObject(json); - return new FriendRemoveRequestEvent( - UUID.fromString(jsonObject.getString("remover")), - UUID.fromString(jsonObject.getString("target")) - ); - } - - @Override - public FriendRemoveRequestEvent clone(FriendRemoveRequestEvent value) { - return new FriendRemoveRequestEvent(value.remover, value.target); - } - }; + return SERIALIZER; } } diff --git a/commons/src/main/java/net/swofty/commons/friend/events/FriendRequestsListEvent.java b/commons/src/main/java/net/swofty/commons/friend/events/FriendRequestsListEvent.java index 07bb10d6c..af44773f3 100644 --- a/commons/src/main/java/net/swofty/commons/friend/events/FriendRequestsListEvent.java +++ b/commons/src/main/java/net/swofty/commons/friend/events/FriendRequestsListEvent.java @@ -4,14 +4,17 @@ import com.fasterxml.jackson.annotation.JsonProperty; import lombok.Getter; import net.swofty.commons.friend.FriendEvent; +import net.swofty.commons.protocol.JacksonSerializer; import net.swofty.commons.protocol.Serializer; -import org.json.JSONObject; import java.util.List; import java.util.UUID; @Getter public final class FriendRequestsListEvent extends FriendEvent { + private static final Serializer SERIALIZER = + new JacksonSerializer<>(FriendRequestsListEvent.class); + private final UUID player; private final int page; @@ -29,28 +32,6 @@ public List getParticipants() { @Override public Serializer getSerializer() { - return new Serializer<>() { - @Override - public String serialize(FriendRequestsListEvent value) { - JSONObject json = new JSONObject(); - json.put("player", value.player.toString()); - json.put("page", value.page); - return json.toString(); - } - - @Override - public FriendRequestsListEvent deserialize(String json) { - JSONObject jsonObject = new JSONObject(json); - return new FriendRequestsListEvent( - UUID.fromString(jsonObject.getString("player")), - jsonObject.getInt("page") - ); - } - - @Override - public FriendRequestsListEvent clone(FriendRequestsListEvent value) { - return new FriendRequestsListEvent(value.player, value.page); - } - }; + return SERIALIZER; } } diff --git a/commons/src/main/java/net/swofty/commons/friend/events/FriendSetNicknameRequestEvent.java b/commons/src/main/java/net/swofty/commons/friend/events/FriendSetNicknameRequestEvent.java index 6c2dabd60..b9a37ee5c 100644 --- a/commons/src/main/java/net/swofty/commons/friend/events/FriendSetNicknameRequestEvent.java +++ b/commons/src/main/java/net/swofty/commons/friend/events/FriendSetNicknameRequestEvent.java @@ -4,14 +4,17 @@ import com.fasterxml.jackson.annotation.JsonProperty; import lombok.Getter; import net.swofty.commons.friend.FriendEvent; +import net.swofty.commons.protocol.JacksonSerializer; import net.swofty.commons.protocol.Serializer; -import org.json.JSONObject; import java.util.List; import java.util.UUID; @Getter public final class FriendSetNicknameRequestEvent extends FriendEvent { + private static final Serializer SERIALIZER = + new JacksonSerializer<>(FriendSetNicknameRequestEvent.class); + private final UUID player; private final UUID target; private final String nickname; @@ -31,30 +34,6 @@ public List getParticipants() { @Override public Serializer getSerializer() { - return new Serializer<>() { - @Override - public String serialize(FriendSetNicknameRequestEvent value) { - JSONObject json = new JSONObject(); - json.put("player", value.player.toString()); - json.put("target", value.target.toString()); - json.put("nickname", value.nickname != null ? value.nickname : JSONObject.NULL); - return json.toString(); - } - - @Override - public FriendSetNicknameRequestEvent deserialize(String json) { - JSONObject jsonObject = new JSONObject(json); - return new FriendSetNicknameRequestEvent( - UUID.fromString(jsonObject.getString("player")), - UUID.fromString(jsonObject.getString("target")), - jsonObject.isNull("nickname") ? null : jsonObject.getString("nickname") - ); - } - - @Override - public FriendSetNicknameRequestEvent clone(FriendSetNicknameRequestEvent value) { - return new FriendSetNicknameRequestEvent(value.player, value.target, value.nickname); - } - }; + return SERIALIZER; } } diff --git a/commons/src/main/java/net/swofty/commons/friend/events/FriendToggleBestRequestEvent.java b/commons/src/main/java/net/swofty/commons/friend/events/FriendToggleBestRequestEvent.java index fdf740649..8a1043819 100644 --- a/commons/src/main/java/net/swofty/commons/friend/events/FriendToggleBestRequestEvent.java +++ b/commons/src/main/java/net/swofty/commons/friend/events/FriendToggleBestRequestEvent.java @@ -4,14 +4,17 @@ import com.fasterxml.jackson.annotation.JsonProperty; import lombok.Getter; import net.swofty.commons.friend.FriendEvent; +import net.swofty.commons.protocol.JacksonSerializer; import net.swofty.commons.protocol.Serializer; -import org.json.JSONObject; import java.util.List; import java.util.UUID; @Getter public final class FriendToggleBestRequestEvent extends FriendEvent { + private static final Serializer SERIALIZER = + new JacksonSerializer<>(FriendToggleBestRequestEvent.class); + private final UUID player; private final UUID target; @@ -29,28 +32,6 @@ public List getParticipants() { @Override public Serializer getSerializer() { - return new Serializer<>() { - @Override - public String serialize(FriendToggleBestRequestEvent value) { - JSONObject json = new JSONObject(); - json.put("player", value.player.toString()); - json.put("target", value.target.toString()); - return json.toString(); - } - - @Override - public FriendToggleBestRequestEvent deserialize(String json) { - JSONObject jsonObject = new JSONObject(json); - return new FriendToggleBestRequestEvent( - UUID.fromString(jsonObject.getString("player")), - UUID.fromString(jsonObject.getString("target")) - ); - } - - @Override - public FriendToggleBestRequestEvent clone(FriendToggleBestRequestEvent value) { - return new FriendToggleBestRequestEvent(value.player, value.target); - } - }; + return SERIALIZER; } } diff --git a/commons/src/main/java/net/swofty/commons/friend/events/FriendToggleSettingRequestEvent.java b/commons/src/main/java/net/swofty/commons/friend/events/FriendToggleSettingRequestEvent.java index a9fee58d1..e48c64081 100644 --- a/commons/src/main/java/net/swofty/commons/friend/events/FriendToggleSettingRequestEvent.java +++ b/commons/src/main/java/net/swofty/commons/friend/events/FriendToggleSettingRequestEvent.java @@ -5,14 +5,17 @@ import lombok.Getter; import net.swofty.commons.friend.FriendEvent; import net.swofty.commons.friend.FriendSettingType; +import net.swofty.commons.protocol.JacksonSerializer; import net.swofty.commons.protocol.Serializer; -import org.json.JSONObject; import java.util.List; import java.util.UUID; @Getter public final class FriendToggleSettingRequestEvent extends FriendEvent { + private static final Serializer SERIALIZER = + new JacksonSerializer<>(FriendToggleSettingRequestEvent.class); + private final UUID player; private final FriendSettingType settingType; @@ -30,28 +33,6 @@ public List getParticipants() { @Override public Serializer getSerializer() { - return new Serializer<>() { - @Override - public String serialize(FriendToggleSettingRequestEvent value) { - JSONObject json = new JSONObject(); - json.put("player", value.player.toString()); - json.put("settingType", value.settingType.name()); - return json.toString(); - } - - @Override - public FriendToggleSettingRequestEvent deserialize(String json) { - JSONObject jsonObject = new JSONObject(json); - return new FriendToggleSettingRequestEvent( - UUID.fromString(jsonObject.getString("player")), - FriendSettingType.valueOf(jsonObject.getString("settingType")) - ); - } - - @Override - public FriendToggleSettingRequestEvent clone(FriendToggleSettingRequestEvent value) { - return new FriendToggleSettingRequestEvent(value.player, value.settingType); - } - }; + return SERIALIZER; } } diff --git a/commons/src/main/java/net/swofty/commons/friend/events/response/FriendAddedResponseEvent.java b/commons/src/main/java/net/swofty/commons/friend/events/response/FriendAddedResponseEvent.java index 82eebe4ef..421c43aa5 100644 --- a/commons/src/main/java/net/swofty/commons/friend/events/response/FriendAddedResponseEvent.java +++ b/commons/src/main/java/net/swofty/commons/friend/events/response/FriendAddedResponseEvent.java @@ -4,14 +4,17 @@ import com.fasterxml.jackson.annotation.JsonProperty; import lombok.Getter; import net.swofty.commons.friend.FriendResponseEvent; +import net.swofty.commons.protocol.JacksonSerializer; import net.swofty.commons.protocol.Serializer; -import org.json.JSONObject; import java.util.List; import java.util.UUID; @Getter public final class FriendAddedResponseEvent extends FriendResponseEvent { + private static final Serializer SERIALIZER = + new JacksonSerializer<>(FriendAddedResponseEvent.class); + private final UUID player1; private final UUID player2; private final String player1Name; @@ -33,32 +36,6 @@ public List getParticipants() { @Override public Serializer getSerializer() { - return new Serializer<>() { - @Override - public String serialize(FriendAddedResponseEvent value) { - JSONObject json = new JSONObject(); - json.put("player1", value.player1.toString()); - json.put("player2", value.player2.toString()); - json.put("player1Name", value.player1Name); - json.put("player2Name", value.player2Name); - return json.toString(); - } - - @Override - public FriendAddedResponseEvent deserialize(String json) { - JSONObject jsonObject = new JSONObject(json); - return new FriendAddedResponseEvent( - UUID.fromString(jsonObject.getString("player1")), - UUID.fromString(jsonObject.getString("player2")), - jsonObject.getString("player1Name"), - jsonObject.getString("player2Name") - ); - } - - @Override - public FriendAddedResponseEvent clone(FriendAddedResponseEvent value) { - return new FriendAddedResponseEvent(value.player1, value.player2, value.player1Name, value.player2Name); - } - }; + return SERIALIZER; } } diff --git a/commons/src/main/java/net/swofty/commons/friend/events/response/FriendBestToggledResponseEvent.java b/commons/src/main/java/net/swofty/commons/friend/events/response/FriendBestToggledResponseEvent.java index fdc118a59..5274e4b6c 100644 --- a/commons/src/main/java/net/swofty/commons/friend/events/response/FriendBestToggledResponseEvent.java +++ b/commons/src/main/java/net/swofty/commons/friend/events/response/FriendBestToggledResponseEvent.java @@ -4,14 +4,17 @@ import com.fasterxml.jackson.annotation.JsonProperty; import lombok.Getter; import net.swofty.commons.friend.FriendResponseEvent; +import net.swofty.commons.protocol.JacksonSerializer; import net.swofty.commons.protocol.Serializer; -import org.json.JSONObject; import java.util.List; import java.util.UUID; @Getter public final class FriendBestToggledResponseEvent extends FriendResponseEvent { + private static final Serializer SERIALIZER = + new JacksonSerializer<>(FriendBestToggledResponseEvent.class); + private final UUID player; private final UUID target; private final String targetName; @@ -33,32 +36,6 @@ public List getParticipants() { @Override public Serializer getSerializer() { - return new Serializer<>() { - @Override - public String serialize(FriendBestToggledResponseEvent value) { - JSONObject json = new JSONObject(); - json.put("player", value.player.toString()); - json.put("target", value.target.toString()); - json.put("targetName", value.targetName); - json.put("isBest", value.isBest); - return json.toString(); - } - - @Override - public FriendBestToggledResponseEvent deserialize(String json) { - JSONObject jsonObject = new JSONObject(json); - return new FriendBestToggledResponseEvent( - UUID.fromString(jsonObject.getString("player")), - UUID.fromString(jsonObject.getString("target")), - jsonObject.getString("targetName"), - jsonObject.getBoolean("isBest") - ); - } - - @Override - public FriendBestToggledResponseEvent clone(FriendBestToggledResponseEvent value) { - return new FriendBestToggledResponseEvent(value.player, value.target, value.targetName, value.isBest); - } - }; + return SERIALIZER; } } diff --git a/commons/src/main/java/net/swofty/commons/friend/events/response/FriendDeniedResponseEvent.java b/commons/src/main/java/net/swofty/commons/friend/events/response/FriendDeniedResponseEvent.java index b454425df..acb3f873c 100644 --- a/commons/src/main/java/net/swofty/commons/friend/events/response/FriendDeniedResponseEvent.java +++ b/commons/src/main/java/net/swofty/commons/friend/events/response/FriendDeniedResponseEvent.java @@ -4,14 +4,17 @@ import com.fasterxml.jackson.annotation.JsonProperty; import lombok.Getter; import net.swofty.commons.friend.FriendResponseEvent; +import net.swofty.commons.protocol.JacksonSerializer; import net.swofty.commons.protocol.Serializer; -import org.json.JSONObject; import java.util.List; import java.util.UUID; @Getter public final class FriendDeniedResponseEvent extends FriendResponseEvent { + private static final Serializer SERIALIZER = + new JacksonSerializer<>(FriendDeniedResponseEvent.class); + private final UUID denier; private final UUID requester; private final String denierName; @@ -31,30 +34,6 @@ public List getParticipants() { @Override public Serializer getSerializer() { - return new Serializer<>() { - @Override - public String serialize(FriendDeniedResponseEvent value) { - JSONObject json = new JSONObject(); - json.put("denier", value.denier.toString()); - json.put("requester", value.requester.toString()); - json.put("denierName", value.denierName); - return json.toString(); - } - - @Override - public FriendDeniedResponseEvent deserialize(String json) { - JSONObject jsonObject = new JSONObject(json); - return new FriendDeniedResponseEvent( - UUID.fromString(jsonObject.getString("denier")), - UUID.fromString(jsonObject.getString("requester")), - jsonObject.getString("denierName") - ); - } - - @Override - public FriendDeniedResponseEvent clone(FriendDeniedResponseEvent value) { - return new FriendDeniedResponseEvent(value.denier, value.requester, value.denierName); - } - }; + return SERIALIZER; } } diff --git a/commons/src/main/java/net/swofty/commons/friend/events/response/FriendJoinNotificationEvent.java b/commons/src/main/java/net/swofty/commons/friend/events/response/FriendJoinNotificationEvent.java index b48a90348..ccf9f0727 100644 --- a/commons/src/main/java/net/swofty/commons/friend/events/response/FriendJoinNotificationEvent.java +++ b/commons/src/main/java/net/swofty/commons/friend/events/response/FriendJoinNotificationEvent.java @@ -4,14 +4,17 @@ import com.fasterxml.jackson.annotation.JsonProperty; import lombok.Getter; import net.swofty.commons.friend.FriendResponseEvent; +import net.swofty.commons.protocol.JacksonSerializer; import net.swofty.commons.protocol.Serializer; -import org.json.JSONObject; import java.util.List; import java.util.UUID; @Getter public final class FriendJoinNotificationEvent extends FriendResponseEvent { + private static final Serializer SERIALIZER = + new JacksonSerializer<>(FriendJoinNotificationEvent.class); + private final UUID player; private final UUID friend; private final String friendName; @@ -31,30 +34,6 @@ public List getParticipants() { @Override public Serializer getSerializer() { - return new Serializer<>() { - @Override - public String serialize(FriendJoinNotificationEvent value) { - JSONObject json = new JSONObject(); - json.put("player", value.player.toString()); - json.put("friend", value.friend.toString()); - json.put("friendName", value.friendName); - return json.toString(); - } - - @Override - public FriendJoinNotificationEvent deserialize(String json) { - JSONObject jsonObject = new JSONObject(json); - return new FriendJoinNotificationEvent( - UUID.fromString(jsonObject.getString("player")), - UUID.fromString(jsonObject.getString("friend")), - jsonObject.getString("friendName") - ); - } - - @Override - public FriendJoinNotificationEvent clone(FriendJoinNotificationEvent value) { - return new FriendJoinNotificationEvent(value.player, value.friend, value.friendName); - } - }; + return SERIALIZER; } } diff --git a/commons/src/main/java/net/swofty/commons/friend/events/response/FriendLeaveNotificationEvent.java b/commons/src/main/java/net/swofty/commons/friend/events/response/FriendLeaveNotificationEvent.java index 3c8c8d4c4..0957cb0c9 100644 --- a/commons/src/main/java/net/swofty/commons/friend/events/response/FriendLeaveNotificationEvent.java +++ b/commons/src/main/java/net/swofty/commons/friend/events/response/FriendLeaveNotificationEvent.java @@ -4,14 +4,17 @@ import com.fasterxml.jackson.annotation.JsonProperty; import lombok.Getter; import net.swofty.commons.friend.FriendResponseEvent; +import net.swofty.commons.protocol.JacksonSerializer; import net.swofty.commons.protocol.Serializer; -import org.json.JSONObject; import java.util.List; import java.util.UUID; @Getter public final class FriendLeaveNotificationEvent extends FriendResponseEvent { + private static final Serializer SERIALIZER = + new JacksonSerializer<>(FriendLeaveNotificationEvent.class); + private final UUID player; private final UUID friend; private final String friendName; @@ -31,30 +34,6 @@ public List getParticipants() { @Override public Serializer getSerializer() { - return new Serializer<>() { - @Override - public String serialize(FriendLeaveNotificationEvent value) { - JSONObject json = new JSONObject(); - json.put("player", value.player.toString()); - json.put("friend", value.friend.toString()); - json.put("friendName", value.friendName); - return json.toString(); - } - - @Override - public FriendLeaveNotificationEvent deserialize(String json) { - JSONObject jsonObject = new JSONObject(json); - return new FriendLeaveNotificationEvent( - UUID.fromString(jsonObject.getString("player")), - UUID.fromString(jsonObject.getString("friend")), - jsonObject.getString("friendName") - ); - } - - @Override - public FriendLeaveNotificationEvent clone(FriendLeaveNotificationEvent value) { - return new FriendLeaveNotificationEvent(value.player, value.friend, value.friendName); - } - }; + return SERIALIZER; } } diff --git a/commons/src/main/java/net/swofty/commons/friend/events/response/FriendListResponseEvent.java b/commons/src/main/java/net/swofty/commons/friend/events/response/FriendListResponseEvent.java index 4b2579e4b..ca949421b 100644 --- a/commons/src/main/java/net/swofty/commons/friend/events/response/FriendListResponseEvent.java +++ b/commons/src/main/java/net/swofty/commons/friend/events/response/FriendListResponseEvent.java @@ -4,9 +4,9 @@ import com.fasterxml.jackson.annotation.JsonProperty; import lombok.Getter; import net.swofty.commons.friend.FriendResponseEvent; +import net.swofty.commons.protocol.JacksonSerializer; import net.swofty.commons.protocol.Serializer; import org.json.JSONArray; -import org.json.JSONObject; import java.util.ArrayList; import java.util.List; @@ -14,6 +14,9 @@ @Getter public final class FriendListResponseEvent extends FriendResponseEvent { + private static final Serializer SERIALIZER = + new JacksonSerializer<>(FriendListResponseEvent.class); + private final UUID player; private final List friends; private final int page; @@ -37,67 +40,7 @@ public List getParticipants() { @Override public Serializer getSerializer() { - return new Serializer<>() { - @Override - public String serialize(FriendListResponseEvent value) { - JSONObject json = new JSONObject(); - json.put("player", value.player.toString()); - - JSONArray friendsArray = new JSONArray(); - for (FriendListEntry entry : value.friends) { - JSONObject entryJson = new JSONObject(); - entryJson.put("uuid", entry.uuid.toString()); - entryJson.put("name", entry.name); - entryJson.put("nickname", entry.nickname != null ? entry.nickname : JSONObject.NULL); - entryJson.put("isBest", entry.isBest); - entryJson.put("isOnline", entry.isOnline); - entryJson.put("lastSeen", entry.lastSeen); - entryJson.put("friendSince", entry.friendSince); - entryJson.put("server", entry.server != null ? entry.server : JSONObject.NULL); - friendsArray.put(entryJson); - } - json.put("friends", friendsArray); - - json.put("page", value.page); - json.put("totalPages", value.totalPages); - json.put("bestOnly", value.bestOnly); - return json.toString(); - } - - @Override - public FriendListResponseEvent deserialize(String json) { - JSONObject jsonObject = new JSONObject(json); - - List friends = new ArrayList<>(); - JSONArray friendsArray = jsonObject.getJSONArray("friends"); - for (int i = 0; i < friendsArray.length(); i++) { - JSONObject entryJson = friendsArray.getJSONObject(i); - friends.add(new FriendListEntry( - UUID.fromString(entryJson.getString("uuid")), - entryJson.getString("name"), - entryJson.isNull("nickname") ? null : entryJson.getString("nickname"), - entryJson.getBoolean("isBest"), - entryJson.getBoolean("isOnline"), - entryJson.optLong("lastSeen", 0L), - entryJson.optLong("friendSince", 0L), - entryJson.isNull("server") ? null : entryJson.getString("server") - )); - } - - return new FriendListResponseEvent( - UUID.fromString(jsonObject.getString("player")), - friends, - jsonObject.getInt("page"), - jsonObject.getInt("totalPages"), - jsonObject.getBoolean("bestOnly") - ); - } - - @Override - public FriendListResponseEvent clone(FriendListResponseEvent value) { - return new FriendListResponseEvent(value.player, new ArrayList<>(value.friends), value.page, value.totalPages, value.bestOnly); - } - }; + return SERIALIZER; } @Getter diff --git a/commons/src/main/java/net/swofty/commons/friend/events/response/FriendNicknameSetResponseEvent.java b/commons/src/main/java/net/swofty/commons/friend/events/response/FriendNicknameSetResponseEvent.java index c82d07e23..b71f5c33b 100644 --- a/commons/src/main/java/net/swofty/commons/friend/events/response/FriendNicknameSetResponseEvent.java +++ b/commons/src/main/java/net/swofty/commons/friend/events/response/FriendNicknameSetResponseEvent.java @@ -4,14 +4,17 @@ import com.fasterxml.jackson.annotation.JsonProperty; import lombok.Getter; import net.swofty.commons.friend.FriendResponseEvent; +import net.swofty.commons.protocol.JacksonSerializer; import net.swofty.commons.protocol.Serializer; -import org.json.JSONObject; import java.util.List; import java.util.UUID; @Getter public final class FriendNicknameSetResponseEvent extends FriendResponseEvent { + private static final Serializer SERIALIZER = + new JacksonSerializer<>(FriendNicknameSetResponseEvent.class); + private final UUID player; private final UUID target; private final String targetName; @@ -33,32 +36,6 @@ public List getParticipants() { @Override public Serializer getSerializer() { - return new Serializer<>() { - @Override - public String serialize(FriendNicknameSetResponseEvent value) { - JSONObject json = new JSONObject(); - json.put("player", value.player.toString()); - json.put("target", value.target.toString()); - json.put("targetName", value.targetName); - json.put("nickname", value.nickname != null ? value.nickname : JSONObject.NULL); - return json.toString(); - } - - @Override - public FriendNicknameSetResponseEvent deserialize(String json) { - JSONObject jsonObject = new JSONObject(json); - return new FriendNicknameSetResponseEvent( - UUID.fromString(jsonObject.getString("player")), - UUID.fromString(jsonObject.getString("target")), - jsonObject.getString("targetName"), - jsonObject.isNull("nickname") ? null : jsonObject.getString("nickname") - ); - } - - @Override - public FriendNicknameSetResponseEvent clone(FriendNicknameSetResponseEvent value) { - return new FriendNicknameSetResponseEvent(value.player, value.target, value.targetName, value.nickname); - } - }; + return SERIALIZER; } } diff --git a/commons/src/main/java/net/swofty/commons/friend/events/response/FriendRemoveAllResponseEvent.java b/commons/src/main/java/net/swofty/commons/friend/events/response/FriendRemoveAllResponseEvent.java index 66b835348..ec49cf23b 100644 --- a/commons/src/main/java/net/swofty/commons/friend/events/response/FriendRemoveAllResponseEvent.java +++ b/commons/src/main/java/net/swofty/commons/friend/events/response/FriendRemoveAllResponseEvent.java @@ -4,14 +4,17 @@ import com.fasterxml.jackson.annotation.JsonProperty; import lombok.Getter; import net.swofty.commons.friend.FriendResponseEvent; +import net.swofty.commons.protocol.JacksonSerializer; import net.swofty.commons.protocol.Serializer; -import org.json.JSONObject; import java.util.List; import java.util.UUID; @Getter public final class FriendRemoveAllResponseEvent extends FriendResponseEvent { + private static final Serializer SERIALIZER = + new JacksonSerializer<>(FriendRemoveAllResponseEvent.class); + private final UUID player; private final int removedCount; @@ -29,28 +32,6 @@ public List getParticipants() { @Override public Serializer getSerializer() { - return new Serializer<>() { - @Override - public String serialize(FriendRemoveAllResponseEvent value) { - JSONObject json = new JSONObject(); - json.put("player", value.player.toString()); - json.put("removedCount", value.removedCount); - return json.toString(); - } - - @Override - public FriendRemoveAllResponseEvent deserialize(String json) { - JSONObject jsonObject = new JSONObject(json); - return new FriendRemoveAllResponseEvent( - UUID.fromString(jsonObject.getString("player")), - jsonObject.getInt("removedCount") - ); - } - - @Override - public FriendRemoveAllResponseEvent clone(FriendRemoveAllResponseEvent value) { - return new FriendRemoveAllResponseEvent(value.player, value.removedCount); - } - }; + return SERIALIZER; } } diff --git a/commons/src/main/java/net/swofty/commons/friend/events/response/FriendRemovedResponseEvent.java b/commons/src/main/java/net/swofty/commons/friend/events/response/FriendRemovedResponseEvent.java index 60e8572b9..f2be032f5 100644 --- a/commons/src/main/java/net/swofty/commons/friend/events/response/FriendRemovedResponseEvent.java +++ b/commons/src/main/java/net/swofty/commons/friend/events/response/FriendRemovedResponseEvent.java @@ -4,14 +4,17 @@ import com.fasterxml.jackson.annotation.JsonProperty; import lombok.Getter; import net.swofty.commons.friend.FriendResponseEvent; +import net.swofty.commons.protocol.JacksonSerializer; import net.swofty.commons.protocol.Serializer; -import org.json.JSONObject; import java.util.List; import java.util.UUID; @Getter public final class FriendRemovedResponseEvent extends FriendResponseEvent { + private static final Serializer SERIALIZER = + new JacksonSerializer<>(FriendRemovedResponseEvent.class); + private final UUID remover; private final UUID removed; private final String removerName; @@ -31,30 +34,6 @@ public List getParticipants() { @Override public Serializer getSerializer() { - return new Serializer<>() { - @Override - public String serialize(FriendRemovedResponseEvent value) { - JSONObject json = new JSONObject(); - json.put("remover", value.remover.toString()); - json.put("removed", value.removed.toString()); - json.put("removerName", value.removerName); - return json.toString(); - } - - @Override - public FriendRemovedResponseEvent deserialize(String json) { - JSONObject jsonObject = new JSONObject(json); - return new FriendRemovedResponseEvent( - UUID.fromString(jsonObject.getString("remover")), - UUID.fromString(jsonObject.getString("removed")), - jsonObject.getString("removerName") - ); - } - - @Override - public FriendRemovedResponseEvent clone(FriendRemovedResponseEvent value) { - return new FriendRemovedResponseEvent(value.remover, value.removed, value.removerName); - } - }; + return SERIALIZER; } } diff --git a/commons/src/main/java/net/swofty/commons/friend/events/response/FriendRequestExpiredResponseEvent.java b/commons/src/main/java/net/swofty/commons/friend/events/response/FriendRequestExpiredResponseEvent.java index 33fa64bff..40d7d2755 100644 --- a/commons/src/main/java/net/swofty/commons/friend/events/response/FriendRequestExpiredResponseEvent.java +++ b/commons/src/main/java/net/swofty/commons/friend/events/response/FriendRequestExpiredResponseEvent.java @@ -4,14 +4,17 @@ import com.fasterxml.jackson.annotation.JsonProperty; import lombok.Getter; import net.swofty.commons.friend.FriendResponseEvent; +import net.swofty.commons.protocol.JacksonSerializer; import net.swofty.commons.protocol.Serializer; -import org.json.JSONObject; import java.util.List; import java.util.UUID; @Getter public final class FriendRequestExpiredResponseEvent extends FriendResponseEvent { + private static final Serializer SERIALIZER = + new JacksonSerializer<>(FriendRequestExpiredResponseEvent.class); + private final UUID sender; private final UUID target; private final String senderName; @@ -33,32 +36,6 @@ public List getParticipants() { @Override public Serializer getSerializer() { - return new Serializer<>() { - @Override - public String serialize(FriendRequestExpiredResponseEvent value) { - JSONObject json = new JSONObject(); - json.put("sender", value.sender.toString()); - json.put("target", value.target.toString()); - json.put("senderName", value.senderName); - json.put("targetName", value.targetName); - return json.toString(); - } - - @Override - public FriendRequestExpiredResponseEvent deserialize(String json) { - JSONObject jsonObject = new JSONObject(json); - return new FriendRequestExpiredResponseEvent( - UUID.fromString(jsonObject.getString("sender")), - UUID.fromString(jsonObject.getString("target")), - jsonObject.getString("senderName"), - jsonObject.getString("targetName") - ); - } - - @Override - public FriendRequestExpiredResponseEvent clone(FriendRequestExpiredResponseEvent value) { - return new FriendRequestExpiredResponseEvent(value.sender, value.target, value.senderName, value.targetName); - } - }; + return SERIALIZER; } } diff --git a/commons/src/main/java/net/swofty/commons/friend/events/response/FriendRequestReceivedResponseEvent.java b/commons/src/main/java/net/swofty/commons/friend/events/response/FriendRequestReceivedResponseEvent.java index 5d7b7deee..67d736661 100644 --- a/commons/src/main/java/net/swofty/commons/friend/events/response/FriendRequestReceivedResponseEvent.java +++ b/commons/src/main/java/net/swofty/commons/friend/events/response/FriendRequestReceivedResponseEvent.java @@ -4,14 +4,17 @@ import com.fasterxml.jackson.annotation.JsonProperty; import lombok.Getter; import net.swofty.commons.friend.FriendResponseEvent; +import net.swofty.commons.protocol.JacksonSerializer; import net.swofty.commons.protocol.Serializer; -import org.json.JSONObject; import java.util.List; import java.util.UUID; @Getter public final class FriendRequestReceivedResponseEvent extends FriendResponseEvent { + private static final Serializer SERIALIZER = + new JacksonSerializer<>(FriendRequestReceivedResponseEvent.class); + private final UUID sender; private final UUID target; private final String senderName; @@ -31,30 +34,6 @@ public List getParticipants() { @Override public Serializer getSerializer() { - return new Serializer<>() { - @Override - public String serialize(FriendRequestReceivedResponseEvent value) { - JSONObject json = new JSONObject(); - json.put("sender", value.sender.toString()); - json.put("target", value.target.toString()); - json.put("senderName", value.senderName); - return json.toString(); - } - - @Override - public FriendRequestReceivedResponseEvent deserialize(String json) { - JSONObject jsonObject = new JSONObject(json); - return new FriendRequestReceivedResponseEvent( - UUID.fromString(jsonObject.getString("sender")), - UUID.fromString(jsonObject.getString("target")), - jsonObject.getString("senderName") - ); - } - - @Override - public FriendRequestReceivedResponseEvent clone(FriendRequestReceivedResponseEvent value) { - return new FriendRequestReceivedResponseEvent(value.sender, value.target, value.senderName); - } - }; + return SERIALIZER; } } diff --git a/commons/src/main/java/net/swofty/commons/friend/events/response/FriendRequestSentResponseEvent.java b/commons/src/main/java/net/swofty/commons/friend/events/response/FriendRequestSentResponseEvent.java index e04f08ae8..1259fd9e6 100644 --- a/commons/src/main/java/net/swofty/commons/friend/events/response/FriendRequestSentResponseEvent.java +++ b/commons/src/main/java/net/swofty/commons/friend/events/response/FriendRequestSentResponseEvent.java @@ -4,14 +4,17 @@ import com.fasterxml.jackson.annotation.JsonProperty; import lombok.Getter; import net.swofty.commons.friend.FriendResponseEvent; +import net.swofty.commons.protocol.JacksonSerializer; import net.swofty.commons.protocol.Serializer; -import org.json.JSONObject; import java.util.List; import java.util.UUID; @Getter public final class FriendRequestSentResponseEvent extends FriendResponseEvent { + private static final Serializer SERIALIZER = + new JacksonSerializer<>(FriendRequestSentResponseEvent.class); + private final UUID sender; private final UUID target; private final String targetName; @@ -31,30 +34,6 @@ public List getParticipants() { @Override public Serializer getSerializer() { - return new Serializer<>() { - @Override - public String serialize(FriendRequestSentResponseEvent value) { - JSONObject json = new JSONObject(); - json.put("sender", value.sender.toString()); - json.put("target", value.target.toString()); - json.put("targetName", value.targetName); - return json.toString(); - } - - @Override - public FriendRequestSentResponseEvent deserialize(String json) { - JSONObject jsonObject = new JSONObject(json); - return new FriendRequestSentResponseEvent( - UUID.fromString(jsonObject.getString("sender")), - UUID.fromString(jsonObject.getString("target")), - jsonObject.getString("targetName") - ); - } - - @Override - public FriendRequestSentResponseEvent clone(FriendRequestSentResponseEvent value) { - return new FriendRequestSentResponseEvent(value.sender, value.target, value.targetName); - } - }; + return SERIALIZER; } } diff --git a/commons/src/main/java/net/swofty/commons/friend/events/response/FriendRequestsListResponseEvent.java b/commons/src/main/java/net/swofty/commons/friend/events/response/FriendRequestsListResponseEvent.java index 9bc2e8070..2689bd5a6 100644 --- a/commons/src/main/java/net/swofty/commons/friend/events/response/FriendRequestsListResponseEvent.java +++ b/commons/src/main/java/net/swofty/commons/friend/events/response/FriendRequestsListResponseEvent.java @@ -4,9 +4,9 @@ import com.fasterxml.jackson.annotation.JsonProperty; import lombok.Getter; import net.swofty.commons.friend.FriendResponseEvent; +import net.swofty.commons.protocol.JacksonSerializer; import net.swofty.commons.protocol.Serializer; import org.json.JSONArray; -import org.json.JSONObject; import java.util.ArrayList; import java.util.List; @@ -14,6 +14,9 @@ @Getter public final class FriendRequestsListResponseEvent extends FriendResponseEvent { + private static final Serializer SERIALIZER = + new JacksonSerializer<>(FriendRequestsListResponseEvent.class); + private final UUID player; private final List requests; private final int page; @@ -35,55 +38,7 @@ public List getParticipants() { @Override public Serializer getSerializer() { - return new Serializer<>() { - @Override - public String serialize(FriendRequestsListResponseEvent value) { - JSONObject json = new JSONObject(); - json.put("player", value.player.toString()); - - JSONArray requestsArray = new JSONArray(); - for (FriendRequestEntry entry : value.requests) { - JSONObject entryJson = new JSONObject(); - entryJson.put("senderUuid", entry.senderUuid.toString()); - entryJson.put("senderName", entry.senderName); - entryJson.put("timestamp", entry.timestamp); - requestsArray.put(entryJson); - } - json.put("requests", requestsArray); - - json.put("page", value.page); - json.put("totalPages", value.totalPages); - return json.toString(); - } - - @Override - public FriendRequestsListResponseEvent deserialize(String json) { - JSONObject jsonObject = new JSONObject(json); - - List requests = new ArrayList<>(); - JSONArray requestsArray = jsonObject.getJSONArray("requests"); - for (int i = 0; i < requestsArray.length(); i++) { - JSONObject entryJson = requestsArray.getJSONObject(i); - requests.add(new FriendRequestEntry( - UUID.fromString(entryJson.getString("senderUuid")), - entryJson.getString("senderName"), - entryJson.getLong("timestamp") - )); - } - - return new FriendRequestsListResponseEvent( - UUID.fromString(jsonObject.getString("player")), - requests, - jsonObject.getInt("page"), - jsonObject.getInt("totalPages") - ); - } - - @Override - public FriendRequestsListResponseEvent clone(FriendRequestsListResponseEvent value) { - return new FriendRequestsListResponseEvent(value.player, new ArrayList<>(value.requests), value.page, value.totalPages); - } - }; + return SERIALIZER; } @Getter diff --git a/commons/src/main/java/net/swofty/commons/friend/events/response/FriendSettingToggledResponseEvent.java b/commons/src/main/java/net/swofty/commons/friend/events/response/FriendSettingToggledResponseEvent.java index 6653c2c66..1a189515d 100644 --- a/commons/src/main/java/net/swofty/commons/friend/events/response/FriendSettingToggledResponseEvent.java +++ b/commons/src/main/java/net/swofty/commons/friend/events/response/FriendSettingToggledResponseEvent.java @@ -5,14 +5,17 @@ import lombok.Getter; import net.swofty.commons.friend.FriendResponseEvent; import net.swofty.commons.friend.FriendSettingType; +import net.swofty.commons.protocol.JacksonSerializer; import net.swofty.commons.protocol.Serializer; -import org.json.JSONObject; import java.util.List; import java.util.UUID; @Getter public final class FriendSettingToggledResponseEvent extends FriendResponseEvent { + private static final Serializer SERIALIZER = + new JacksonSerializer<>(FriendSettingToggledResponseEvent.class); + private final UUID player; private final FriendSettingType settingType; private final boolean newValue; @@ -32,30 +35,6 @@ public List getParticipants() { @Override public Serializer getSerializer() { - return new Serializer<>() { - @Override - public String serialize(FriendSettingToggledResponseEvent value) { - JSONObject json = new JSONObject(); - json.put("player", value.player.toString()); - json.put("settingType", value.settingType.name()); - json.put("newValue", value.newValue); - return json.toString(); - } - - @Override - public FriendSettingToggledResponseEvent deserialize(String json) { - JSONObject jsonObject = new JSONObject(json); - return new FriendSettingToggledResponseEvent( - UUID.fromString(jsonObject.getString("player")), - FriendSettingType.valueOf(jsonObject.getString("settingType")), - jsonObject.getBoolean("newValue") - ); - } - - @Override - public FriendSettingToggledResponseEvent clone(FriendSettingToggledResponseEvent value) { - return new FriendSettingToggledResponseEvent(value.player, value.settingType, value.newValue); - } - }; + return SERIALIZER; } } From aafc34566c73fd972a9df2bc1db740669f87bf93 Mon Sep 17 00:00:00 2001 From: "Jacob Nardella (Swofty)" Date: Fri, 15 May 2026 00:57:04 +1000 Subject: [PATCH 048/113] chore(velocity): route SkyBlockVersionProvider warnings through tinylog Two stdout writes describing protocol-lookup failures (reflection failure, no-registered-protocol fallback) now log at warn level so they surface in the configured sink instead of disappearing into the launcher stdout. --- .../viaversion/provider/SkyBlockVersionProvider.java | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/velocity.extension/src/main/java/net/swofty/velocity/viaversion/provider/SkyBlockVersionProvider.java b/velocity.extension/src/main/java/net/swofty/velocity/viaversion/provider/SkyBlockVersionProvider.java index c0cfa65c2..bdd644ea5 100644 --- a/velocity.extension/src/main/java/net/swofty/velocity/viaversion/provider/SkyBlockVersionProvider.java +++ b/velocity.extension/src/main/java/net/swofty/velocity/viaversion/provider/SkyBlockVersionProvider.java @@ -10,6 +10,7 @@ import net.swofty.velocity.SkyBlockVelocity; import net.swofty.velocity.viaversion.injector.SkyBlockViaInjector; import org.jetbrains.annotations.Nullable; +import org.tinylog.Logger; public class SkyBlockVersionProvider implements VersionProvider { private static final Method GET_ASSOCIATION = getAssociationMethod(); @@ -18,7 +19,7 @@ public class SkyBlockVersionProvider implements VersionProvider { try { return Class.forName("com.velocitypowered.proxy.connection.MinecraftConnection").getMethod("getAssociation"); } catch (NoSuchMethodException | ClassNotFoundException e) { - System.out.println("Failed to get association method from Velocity"); + Logger.warn(e, "Failed to get association method from Velocity"); return null; } } @@ -61,7 +62,7 @@ private ProtocolVersion getFrontProtocol(UserConnection user) throws Exception { } } - System.out.println("Panic, no protocol id found for " + playerVersion); + Logger.warn("No registered protocol id found for {}, falling back to player version", playerVersion); return playerVersion; } } From 1f2636b7b08434dfaa50c070f53a4578dc2ff71f Mon Sep 17 00:00:00 2001 From: "Jacob Nardella (Swofty)" Date: Fri, 15 May 2026 00:57:56 +1000 Subject: [PATCH 049/113] chore(skyblock): route SkyBlockLevelLoader warnings through tinylog Two stderr writes for 'unknown statistic' / 'unknown custom award' go through the Logger that the file already imports. --- .../type/skyblockgeneric/levels/SkyBlockLevelLoader.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/levels/SkyBlockLevelLoader.java b/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/levels/SkyBlockLevelLoader.java index 20dd3c5c8..205d2b647 100644 --- a/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/levels/SkyBlockLevelLoader.java +++ b/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/levels/SkyBlockLevelLoader.java @@ -154,7 +154,7 @@ private static SkyBlockLevelStatisticUnlock parseStatisticUnlock(LevelUnlockData builder.withMultiplicativePercentage(stat, value.multiplicativePercentage); } } catch (IllegalArgumentException e) { - System.err.println("Unknown statistic: " + entry.getKey()); + Logger.warn("Unknown statistic: {}", entry.getKey()); } } } @@ -167,7 +167,7 @@ private static CustomLevelUnlock parseCustomUnlock(LevelUnlockData data) { CustomLevelAward award = CustomLevelAward.valueOf(data.customAward.toUpperCase()); return new CustomLevelUnlock(award); } catch (IllegalArgumentException e) { - System.err.println("Unknown custom award: " + data.customAward); + Logger.error("Unknown custom award: {}", data.customAward); throw new RuntimeException("Unknown custom award: " + data.customAward); } } From a5ac4ac736fa7ae754ad17c78476477671c98330 Mon Sep 17 00:00:00 2001 From: "Jacob Nardella (Swofty)" Date: Fri, 15 May 2026 00:58:47 +1000 Subject: [PATCH 050/113] chore(datamutex): route UnlockDataEndpoint errors through tinylog MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Same pattern as the other two datamutex endpoints — stderr writes for per-server unlock failures + the CompletableFuture exception handler now go through Logger. Collapsed the .thenAccept lambda body since we no longer need the surrounding block for the single println. --- .../datamutex/endpoints/UnlockDataEndpoint.java | 17 ++++++++--------- 1 file changed, 8 insertions(+), 9 deletions(-) diff --git a/service.datamutex/src/main/java/net/swofty/service/datamutex/endpoints/UnlockDataEndpoint.java b/service.datamutex/src/main/java/net/swofty/service/datamutex/endpoints/UnlockDataEndpoint.java index 527623380..082f1df6d 100644 --- a/service.datamutex/src/main/java/net/swofty/service/datamutex/endpoints/UnlockDataEndpoint.java +++ b/service.datamutex/src/main/java/net/swofty/service/datamutex/endpoints/UnlockDataEndpoint.java @@ -5,6 +5,7 @@ import net.swofty.service.datamutex.DataLockManager; import net.swofty.service.generic.redis.ServiceEndpoint; import net.swofty.service.generic.redis.ServiceToServerManager; +import org.tinylog.Logger; import java.util.List; import java.util.UUID; @@ -35,16 +36,14 @@ public UnlockDataProtocolObject.UnlockDataResponse onMessage( DataLockManager.releaseLock(lockKey, requesterId); ServiceToServerManager.unlockPlayerData(serverUUIDs, playerUUID, dataKey) - .thenAccept(results -> { - results.forEach((serverUUID, response) -> { - if (!response.success()) { - System.err.println("Failed to unlock data on server " + serverUUID + - " for player " + playerUUID + ", dataKey: " + dataKey); - } - }); - }) + .thenAccept(results -> results.forEach((serverUUID, response) -> { + if (!response.success()) { + Logger.warn("Failed to unlock data on server {} for player {}, dataKey: {}", + serverUUID, playerUUID, dataKey); + } + })) .exceptionally(throwable -> { - System.err.println("Error unlocking data on servers: " + throwable.getMessage()); + Logger.error(throwable, "Error unlocking data on servers"); return null; }); From 2ffb0f53d6a81662e2f8073a630143db296d07ce Mon Sep 17 00:00:00 2001 From: "Jacob Nardella (Swofty)" Date: Fri, 15 May 2026 01:00:05 +1000 Subject: [PATCH 051/113] chore(bazaar): route GUIBazaar fetch failures through tinylog --- .../skyblockgeneric/gui/inventories/bazaar/GUIBazaar.java | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/gui/inventories/bazaar/GUIBazaar.java b/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/gui/inventories/bazaar/GUIBazaar.java index a2cd9c0bb..3e270ced1 100644 --- a/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/gui/inventories/bazaar/GUIBazaar.java +++ b/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/gui/inventories/bazaar/GUIBazaar.java @@ -20,6 +20,7 @@ import net.swofty.type.skyblockgeneric.bazaar.BazaarCategories; import net.swofty.type.skyblockgeneric.bazaar.BazaarItemSet; import net.swofty.type.skyblockgeneric.user.SkyBlockPlayer; +import org.tinylog.Logger; import java.util.ArrayList; import java.util.List; @@ -158,8 +159,7 @@ private void rebuildCacheAndRender(SkyBlockPlayer player) { )); }) .exceptionally(throwable -> { - System.err.println("Failed to fetch bazaar data for " + type.name() + ": " + throwable.getMessage()); - // Store empty data on failure + Logger.error(throwable, "Failed to fetch bazaar data for {}", type.name()); setDataMap.get(set).put(type, new PriceData(type, 0, 0)); return null; }); @@ -207,7 +207,7 @@ private void rebuildCacheAndRender(SkyBlockPlayer player) { }, 1); }) .exceptionally(throwable -> { - System.err.println("Failed to rebuild bazaar cache: " + throwable.getMessage()); + Logger.error(throwable, "Failed to rebuild bazaar cache"); // Fallback: render with "Error loading" placeholders MathUtility.delay(() -> { From 2b199a5f7cec1dd0e36d4a318c38aa76ec771edc Mon Sep 17 00:00:00 2001 From: "Jacob Nardella (Swofty)" Date: Fri, 15 May 2026 01:01:09 +1000 Subject: [PATCH 052/113] chore(commands): route SignGUICommand debug output through tinylog MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit It's a staff-only debug command (/signgui) so the two trace lines are genuinely for developers, not user-facing — moved them to Logger.debug so they're filtered out by default but available with debug logging on. --- .../swofty/type/generic/command/commands/SignGUICommand.java | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/type.generic/src/main/java/net/swofty/type/generic/command/commands/SignGUICommand.java b/type.generic/src/main/java/net/swofty/type/generic/command/commands/SignGUICommand.java index 3aad2fc4b..aaac19079 100644 --- a/type.generic/src/main/java/net/swofty/type/generic/command/commands/SignGUICommand.java +++ b/type.generic/src/main/java/net/swofty/type/generic/command/commands/SignGUICommand.java @@ -7,6 +7,7 @@ import net.swofty.type.generic.gui.HypixelSignGUI; import net.swofty.type.generic.user.HypixelPlayer; import net.swofty.type.generic.user.categories.Rank; +import org.tinylog.Logger; @CommandParameters(aliases = "signgraphicaluserinterface", description = "Opens a graphical user interface", @@ -26,12 +27,12 @@ public void registerUsage(MinestomCommand command) { new HypixelSignGUI(player).open(new String[]{"Test1", "Test2"}).thenAccept(line -> { if (line == null) { - System.out.println(player.getDisplayName().toString() + " left server while GUI was open"); + Logger.debug("{} left server while sign GUI was open", player.getDisplayName()); return; } player.sendMessage("§7You wrote: §a" + line); - System.out.println(line); + Logger.debug("Sign GUI input: {}", line); }); }, text); } From d388d1fa346248c2847b16afdf88fb9f0880adf7 Mon Sep 17 00:00:00 2001 From: "Jacob Nardella (Swofty)" Date: Fri, 15 May 2026 01:02:50 +1000 Subject: [PATCH 053/113] chore: route remaining datamutex/orchestrator/reforge errors through tinylog Three more catch-block stderr lines converted: - LockCleanupTask cleanup-loop exception (was silently dropping stack) - RejoinGameEndpoint rejoin-check failure - ItemAttributeReforge unknown-reforge warning (loadFromString) All cases benefit from getting stack traces into the configured log sinks; the rest of the file already imported Logger or had reasonable dependencies for it. --- .../item/attribute/attributes/ItemAttributeReforge.java | 3 ++- .../java/net/swofty/service/datamutex/LockCleanupTask.java | 4 +++- .../service/orchestrator/endpoints/RejoinGameEndpoint.java | 3 ++- 3 files changed, 7 insertions(+), 3 deletions(-) diff --git a/commons/src/main/java/net/swofty/commons/skyblock/item/attribute/attributes/ItemAttributeReforge.java b/commons/src/main/java/net/swofty/commons/skyblock/item/attribute/attributes/ItemAttributeReforge.java index 7bcd08999..4a42f7695 100644 --- a/commons/src/main/java/net/swofty/commons/skyblock/item/attribute/attributes/ItemAttributeReforge.java +++ b/commons/src/main/java/net/swofty/commons/skyblock/item/attribute/attributes/ItemAttributeReforge.java @@ -4,6 +4,7 @@ import net.swofty.commons.skyblock.item.reforge.ReforgeLoader; import net.swofty.commons.skyblock.statistics.ItemStatistics; import org.jetbrains.annotations.Nullable; +import org.tinylog.Logger; public class ItemAttributeReforge extends ItemAttribute { @Override @@ -26,7 +27,7 @@ public String loadFromString(String string) { return string; } - System.err.println("Unknown reforge: " + string); + Logger.warn("Unknown reforge: {}", string); return null; } diff --git a/service.datamutex/src/main/java/net/swofty/service/datamutex/LockCleanupTask.java b/service.datamutex/src/main/java/net/swofty/service/datamutex/LockCleanupTask.java index 9ada9d40c..e7c0f73a1 100644 --- a/service.datamutex/src/main/java/net/swofty/service/datamutex/LockCleanupTask.java +++ b/service.datamutex/src/main/java/net/swofty/service/datamutex/LockCleanupTask.java @@ -1,5 +1,7 @@ package net.swofty.service.datamutex; +import org.tinylog.Logger; + import java.util.concurrent.Executors; import java.util.concurrent.ScheduledExecutorService; import java.util.concurrent.TimeUnit; @@ -13,7 +15,7 @@ public static void startCleanupTask() { try { DataLockManager.cleanupExpiredLocks(); } catch (Exception e) { - System.err.println("Error during lock cleanup: " + e.getMessage()); + Logger.error(e, "Error during lock cleanup"); } }, 10, 10, TimeUnit.SECONDS); } diff --git a/service.orchestrator/src/main/java/net/swofty/service/orchestrator/endpoints/RejoinGameEndpoint.java b/service.orchestrator/src/main/java/net/swofty/service/orchestrator/endpoints/RejoinGameEndpoint.java index a2c987a5e..b5170e0b8 100644 --- a/service.orchestrator/src/main/java/net/swofty/service/orchestrator/endpoints/RejoinGameEndpoint.java +++ b/service.orchestrator/src/main/java/net/swofty/service/orchestrator/endpoints/RejoinGameEndpoint.java @@ -7,6 +7,7 @@ import net.swofty.commons.protocol.objects.orchestrator.RejoinGameProtocolObject; import net.swofty.service.generic.redis.ServiceEndpoint; import net.swofty.service.orchestrator.OrchestratorCache; +import org.tinylog.Logger; import java.util.ArrayList; @@ -71,7 +72,7 @@ public RejoinGameProtocolObject.RejoinGameResponse onMessage(ServiceProxyRequest null ); } catch (Exception e) { - System.err.println("Failed to check rejoin: " + e.getMessage()); + Logger.error(e, "Failed to check rejoin"); return new RejoinGameProtocolObject.RejoinGameResponse(false, null, null, null, null, false, true, null); } } From 38575dffcf924434d85c7c0cf1dbd089a5825b24 Mon Sep 17 00:00:00 2001 From: "Jacob Nardella (Swofty)" Date: Fri, 15 May 2026 01:04:14 +1000 Subject: [PATCH 054/113] chore: route remaining commons + service.generic stderr through tinylog Three more deserialisation/parse stderr writes now go through Logger: - UnderstandableSkyBlockItemSerializer: invalid itemKey on deserialize - ReforgeExpressionEvaluator: unknown variable substitution - ServiceToServerManager: failed push response deserialisation All three were silently dropping stack traces and lacked the templated arg style. Same severity choices (warn for malformed input, error for unhandled exceptions). --- .../serializers/UnderstandableSkyBlockItemSerializer.java | 4 ++-- .../skyblock/item/reforge/ReforgeExpressionEvaluator.java | 2 +- .../swofty/service/generic/redis/ServiceToServerManager.java | 3 ++- 3 files changed, 5 insertions(+), 4 deletions(-) diff --git a/commons/src/main/java/net/swofty/commons/protocol/serializers/UnderstandableSkyBlockItemSerializer.java b/commons/src/main/java/net/swofty/commons/protocol/serializers/UnderstandableSkyBlockItemSerializer.java index 0307f32fb..84b84b0f0 100644 --- a/commons/src/main/java/net/swofty/commons/protocol/serializers/UnderstandableSkyBlockItemSerializer.java +++ b/commons/src/main/java/net/swofty/commons/protocol/serializers/UnderstandableSkyBlockItemSerializer.java @@ -6,6 +6,7 @@ import net.swofty.commons.skyblock.item.attribute.ItemAttribute; import net.swofty.commons.protocol.Serializer; import org.json.JSONObject; +import org.tinylog.Logger; import java.util.ArrayList; import java.util.List; @@ -37,8 +38,7 @@ public UnderstandableSkyBlockItem deserialize(String json) { try { itemKey = ItemType.valueOf(jsonObject.getString("itemKey")); } catch (IllegalArgumentException e) { - // Handle invalid itemKey - System.err.println("Invalid itemKey: " + jsonObject.getString("itemKey")); + Logger.warn("Invalid itemKey: {}", jsonObject.getString("itemKey")); } } diff --git a/commons/src/main/java/net/swofty/commons/skyblock/item/reforge/ReforgeExpressionEvaluator.java b/commons/src/main/java/net/swofty/commons/skyblock/item/reforge/ReforgeExpressionEvaluator.java index 312f3472b..17b58680e 100644 --- a/commons/src/main/java/net/swofty/commons/skyblock/item/reforge/ReforgeExpressionEvaluator.java +++ b/commons/src/main/java/net/swofty/commons/skyblock/item/reforge/ReforgeExpressionEvaluator.java @@ -34,7 +34,7 @@ private static String replaceVariables(String expression, Map va if (value != null) { matcher.appendReplacement(result, value.toString()); } else { - System.err.println("Variable not found: " + varName); + Logger.warn("Variable not found: {}", varName); matcher.appendReplacement(result, "0"); } } diff --git a/service.generic/src/main/java/net/swofty/service/generic/redis/ServiceToServerManager.java b/service.generic/src/main/java/net/swofty/service/generic/redis/ServiceToServerManager.java index 1c690599d..d8a2f6456 100644 --- a/service.generic/src/main/java/net/swofty/service/generic/redis/ServiceToServerManager.java +++ b/service.generic/src/main/java/net/swofty/service/generic/redis/ServiceToServerManager.java @@ -12,6 +12,7 @@ import net.swofty.redisapi.api.ChannelRegistry; import net.swofty.redisapi.api.RedisAPI; import org.json.JSONObject; +import org.tinylog.Logger; import java.util.List; import java.util.Map; @@ -133,7 +134,7 @@ public static CompletableFuture> sendToAllServers( try { typedMap.put(uuid, protocol.translateReturnFromString(json.toString())); } catch (Exception e) { - System.err.println("Failed to deserialize push response from " + uuid + ": " + e.getMessage()); + Logger.error(e, "Failed to deserialize push response from {}", uuid); } }); typedFuture.complete(typedMap); From fe5dec8ea372f184edf7ff88f71f6eade0a8f001 Mon Sep 17 00:00:00 2001 From: "Jacob Nardella (Swofty)" Date: Fri, 15 May 2026 01:04:56 +1000 Subject: [PATCH 055/113] fix(api): stop leaking session IDs to stdout in LogoutEndpoint MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit handle() printed the user's session cookie to stdout on every /logout call — that's a credential heading into shared log infrastructure. Dropped the line entirely (it was a leftover debug print, not load-bearing). The actual error path stays unchanged. --- .../net/swofty/service/api/http/endpoints/LogoutEndpoint.java | 1 - 1 file changed, 1 deletion(-) diff --git a/service.api/src/main/java/net/swofty/service/api/http/endpoints/LogoutEndpoint.java b/service.api/src/main/java/net/swofty/service/api/http/endpoints/LogoutEndpoint.java index 8f0f9d96d..b99ef39a4 100644 --- a/service.api/src/main/java/net/swofty/service/api/http/endpoints/LogoutEndpoint.java +++ b/service.api/src/main/java/net/swofty/service/api/http/endpoints/LogoutEndpoint.java @@ -27,7 +27,6 @@ public String getPath() { @Override public @Nullable APIResponse handle(Map headers, Request req, Response res) { String sessionId = req.cookie("sessionId"); - System.out.println("Session ID: " + sessionId); if (sessionId == null) { return APIResponse.error("Missing required headers"); From 703aab2166538be19bc41cf6955971eccb1a94e6 Mon Sep 17 00:00:00 2001 From: "Jacob Nardella (Swofty)" Date: Fri, 15 May 2026 01:05:39 +1000 Subject: [PATCH 056/113] chore(util): route MathUtility.getBlocksInRadius failure through tinylog MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The inner catch in getBlocksInRadius printed to stdout for every block read that threw — usually a chunk that wasn't loaded yet. Now logs at debug with the coordinates and the exception cause so chunk-load timing issues are debuggable without spamming stdout in production. Also dropped the unnecessary 'continue' (it was the last statement in the loop body). --- .../java/net/swofty/type/generic/utility/MathUtility.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/type.generic/src/main/java/net/swofty/type/generic/utility/MathUtility.java b/type.generic/src/main/java/net/swofty/type/generic/utility/MathUtility.java index 106cbfe53..16ca4240d 100644 --- a/type.generic/src/main/java/net/swofty/type/generic/utility/MathUtility.java +++ b/type.generic/src/main/java/net/swofty/type/generic/utility/MathUtility.java @@ -7,6 +7,7 @@ import net.minestom.server.inventory.InventoryType; import net.minestom.server.timer.TaskSchedule; import net.minestom.server.utils.Direction; +import org.tinylog.Logger; import java.util.ArrayList; import java.util.List; @@ -108,8 +109,7 @@ public static List getNearbyBlocks(Instance instance, Pos pos, int range, B blocks.add(new Pos(x, y, z)); } } catch (Exception e) { - System.out.println("Threw an error for " + x + " " + y + " " + z); - continue; + Logger.debug(e, "Block read failed at {} {} {} during getBlocksInRadius", x, y, z); } } } From a21a8cd0904aaef7666d159eaf537bf13da7069d Mon Sep 17 00:00:00 2001 From: "Jacob Nardella (Swofty)" Date: Fri, 15 May 2026 01:06:05 +1000 Subject: [PATCH 057/113] chore(velocity): route via-injector reflection failure through tinylog --- .../velocity/viaversion/injector/SkyBlockViaInjector.java | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/velocity.extension/src/main/java/net/swofty/velocity/viaversion/injector/SkyBlockViaInjector.java b/velocity.extension/src/main/java/net/swofty/velocity/viaversion/injector/SkyBlockViaInjector.java index c171274c7..c3f19eb9b 100644 --- a/velocity.extension/src/main/java/net/swofty/velocity/viaversion/injector/SkyBlockViaInjector.java +++ b/velocity.extension/src/main/java/net/swofty/velocity/viaversion/injector/SkyBlockViaInjector.java @@ -10,6 +10,7 @@ import net.swofty.velocity.SkyBlockVelocity; import net.swofty.velocity.packet.PlayerChannelInitializer; import org.jetbrains.annotations.Nullable; +import org.tinylog.Logger; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; @@ -22,7 +23,7 @@ public class SkyBlockViaInjector implements ViaInjector { try { return Class.forName("com.velocitypowered.proxy.config.VelocityConfiguration").getMethod("getPlayerInfoForwardingMode"); } catch (NoSuchMethodException | ClassNotFoundException e) { - System.out.println("Failed to get getPlayerInfoForwardingMode method from Velocity"); + Logger.warn(e, "Failed to get getPlayerInfoForwardingMode method from Velocity"); return null; } } From 9e3cc3d8423c26e26441a4a9f2859cc64bfb33e5 Mon Sep 17 00:00:00 2001 From: "Jacob Nardella (Swofty)" Date: Fri, 15 May 2026 01:06:53 +1000 Subject: [PATCH 058/113] chore(commons): delete unused MethodLister debug utility MethodLister was a reflection-driven println-the-methods helper that no production code calls. Looks like leftover scaffolding from diagnosing a Lombok/reflection issue. Dead code, gone. --- .../java/net/swofty/commons/MethodLister.java | 46 ------------------- 1 file changed, 46 deletions(-) delete mode 100644 commons/src/main/java/net/swofty/commons/MethodLister.java diff --git a/commons/src/main/java/net/swofty/commons/MethodLister.java b/commons/src/main/java/net/swofty/commons/MethodLister.java deleted file mode 100644 index d2f699ffe..000000000 --- a/commons/src/main/java/net/swofty/commons/MethodLister.java +++ /dev/null @@ -1,46 +0,0 @@ -package net.swofty.commons; - -import java.lang.reflect.Method; -import java.lang.reflect.Modifier; - -public class MethodLister { - - public static void listMethods(Class clazz) { - // Get all declared methods including public, protected, default (package) access, - // and private methods, but excluding inherited methods. - Method[] methods = clazz.getDeclaredMethods(); - - System.out.println("Methods of " + clazz.getName() + ":"); - - for (Method method : methods) { - // Get the method name - String methodName = method.getName(); - - // Get the method modifiers - String modifier = Modifier.toString(method.getModifiers()); - - // Get the return type - Class returnType = method.getReturnType(); - String returnTypeName = returnType.getSimpleName(); - - // Get the parameter types - Class[] parameterTypes = method.getParameterTypes(); - String parameters = getParameterString(parameterTypes); - - // Print method signature - System.out.println(modifier + " " + returnTypeName + " " + methodName + "(" + parameters + ")"); - } - } - - private static String getParameterString(Class[] parameterTypes) { - StringBuilder parameters = new StringBuilder(); - for (int i = 0; i < parameterTypes.length; i++) { - Class paramType = parameterTypes[i]; - parameters.append(paramType.getSimpleName()); - if (i < parameterTypes.length - 1) { - parameters.append(", "); - } - } - return parameters.toString(); - } -} From 7cf89717f01cd0c440939a9c17d2910ea363b161 Mon Sep 17 00:00:00 2001 From: "Jacob Nardella (Swofty)" Date: Fri, 15 May 2026 01:08:44 +1000 Subject: [PATCH 059/113] chore(velocity): drop commented-out debug print in PlayerChannelHandler --- .../java/net/swofty/velocity/packet/PlayerChannelHandler.java | 1 - 1 file changed, 1 deletion(-) diff --git a/velocity.extension/src/main/java/net/swofty/velocity/packet/PlayerChannelHandler.java b/velocity.extension/src/main/java/net/swofty/velocity/packet/PlayerChannelHandler.java index 7d8f8c46c..2635b8ef8 100644 --- a/velocity.extension/src/main/java/net/swofty/velocity/packet/PlayerChannelHandler.java +++ b/velocity.extension/src/main/java/net/swofty/velocity/packet/PlayerChannelHandler.java @@ -37,7 +37,6 @@ public void write(final ChannelHandlerContext ctx, final Object packet, final Ch && packet.getClass() != KnownPacksPacket.class && packet.getClass() != TagsUpdatePacket.class ) { - //System.out.println("Blocked packet " + packet.getClass().getSimpleName() + " from being sent to " + player.getUsername() + " because they are in limbo."); return; } if (respawn == null && packet.getClass() == RespawnPacket.class) { From 0ed6b4a5e2547b03e2666c53154085e64671d483 Mon Sep 17 00:00:00 2001 From: "Jacob Nardella (Swofty)" Date: Fri, 15 May 2026 01:11:18 +1000 Subject: [PATCH 060/113] fix(murdermystery): cap gold spawn points at one coin each MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Closes #673. The 5-second spawn task picked a random spawn point and called spawnGoldCoin() without checking whether that point already held a coin. With few players and slow pickup the same point kept being rolled, stacking up to MAX_GOLD_SPAWNED (50) coins at one spot. Added isSpawnPointOccupied() which scans the live spawnedGold list for an existing entity within SPAWN_POINT_OCCUPIED_DISTANCE (1 block) of the candidate position. If occupied, the tick skips this round and tries a fresh roll on the next interval — preserves the randomised spawn cadence without the stacking artefact. Also flattened the spawn-task body so the no-op branches early-return instead of nesting the spawn call inside an if. --- .../murdermysterygame/gold/GoldManager.java | 25 ++++++++++++++++--- 1 file changed, 22 insertions(+), 3 deletions(-) diff --git a/type.murdermysterygame/src/main/java/net/swofty/type/murdermysterygame/gold/GoldManager.java b/type.murdermysterygame/src/main/java/net/swofty/type/murdermysterygame/gold/GoldManager.java index 5e41e1908..01971372f 100644 --- a/type.murdermysterygame/src/main/java/net/swofty/type/murdermysterygame/gold/GoldManager.java +++ b/type.murdermysterygame/src/main/java/net/swofty/type/murdermysterygame/gold/GoldManager.java @@ -27,6 +27,8 @@ public class GoldManager { private static final int SPAWN_INTERVAL_SECONDS = 5; private static final int MAX_GOLD_SPAWNED = 50; private static final double PICKUP_DISTANCE = 1.5; + /** Closer than this and we count a spawn point as 'already occupied' — see #673. */ + private static final double SPAWN_POINT_OCCUPIED_DISTANCE = 1.0; private final Game game; private final List spawnedGold = new ArrayList<>(); @@ -46,10 +48,17 @@ public void startSpawning() { List spawnLocations = config.getGoldSpawns(); spawnTask = MinecraftServer.getSchedulerManager().buildTask(() -> { - if (spawnedGold.size() < MAX_GOLD_SPAWNED && !spawnLocations.isEmpty()) { - MurderMysteryMapsConfig.Position randomSpawn = spawnLocations.get(new Random().nextInt(spawnLocations.size())); - spawnGoldCoin(new Pos(randomSpawn.x(), randomSpawn.y(), randomSpawn.z())); + if (spawnedGold.size() >= MAX_GOLD_SPAWNED || spawnLocations.isEmpty()) { + return; } + MurderMysteryMapsConfig.Position randomSpawn = spawnLocations.get(new Random().nextInt(spawnLocations.size())); + Pos spawnPos = new Pos(randomSpawn.x(), randomSpawn.y(), randomSpawn.z()); + // Issue #673: cap each spawn point at one gold coin. The previous loop + // rolled the same point repeatedly and stacked up to five coins there. + if (isSpawnPointOccupied(spawnPos)) { + return; + } + spawnGoldCoin(spawnPos); }).delay(TaskSchedule.seconds(3)).repeat(TaskSchedule.seconds(SPAWN_INTERVAL_SECONDS)).schedule(); pickupCheckTask = MinecraftServer.getSchedulerManager().buildTask(() -> { @@ -113,6 +122,16 @@ private void spawnGoldCoin(Pos position) { spawnedGold.add(goldEntity); } + private boolean isSpawnPointOccupied(Pos position) { + for (Entity existing : spawnedGold) { + if (existing.isRemoved()) continue; + if (existing.getPosition().distance(position) <= SPAWN_POINT_OCCUPIED_DISTANCE) { + return true; + } + } + return false; + } + public boolean collectGold(MurderMysteryPlayer player, Entity goldEntity) { if (!spawnedGold.contains(goldEntity)) return false; From 344f1b02f08f831e786d0a1b72ef39ea11604380 Mon Sep 17 00:00:00 2001 From: "Jacob Nardella (Swofty)" Date: Fri, 15 May 2026 01:14:18 +1000 Subject: [PATCH 061/113] chore(skyblock): route remaining stderr/stdout in bazaar+player+particle through tinylog Five more callsites converted across skyblockgeneric: - SkyBlockPlayer invalid-sack-name warning - BazaarConnector pending-transaction failure - DatapointCompletedBazaarTransactions deserialise failure - GUIBazaarOrderCompletedOptions claim-rewards failure - ParticleEngine offsets-overridden warning Also dropped a debug println of upgradeItem.getPotentialType() in AnvilCombineRegistry that fired every time someone considered an anvil combine. --- .../net/swofty/type/skyblockgeneric/bazaar/BazaarConnector.java | 2 +- .../data/datapoints/DatapointCompletedBazaarTransactions.java | 2 +- .../gui/inventories/bazaar/GUIBazaarOrderCompletedOptions.java | 2 +- .../item/handlers/anvilcombine/AnvilCombineRegistry.java | 2 -- .../swofty/type/skyblockgeneric/particle/ParticleEngine.java | 2 +- .../net/swofty/type/skyblockgeneric/user/SkyBlockPlayer.java | 2 +- 6 files changed, 5 insertions(+), 7 deletions(-) diff --git a/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/bazaar/BazaarConnector.java b/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/bazaar/BazaarConnector.java index a784a15f3..0af787a8f 100644 --- a/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/bazaar/BazaarConnector.java +++ b/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/bazaar/BazaarConnector.java @@ -279,7 +279,7 @@ private CompletableFuture processTransactions(List()); } diff --git a/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/gui/inventories/bazaar/GUIBazaarOrderCompletedOptions.java b/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/gui/inventories/bazaar/GUIBazaarOrderCompletedOptions.java index b078293e0..e97bbde04 100644 --- a/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/gui/inventories/bazaar/GUIBazaarOrderCompletedOptions.java +++ b/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/gui/inventories/bazaar/GUIBazaarOrderCompletedOptions.java @@ -276,7 +276,7 @@ private void claimRewards(SkyBlockPlayer player) { } catch (Exception e) { player.sendMessage(I18n.string("gui_bazaar.order_completed.claim_failed", l, Component.text(e.getMessage()))); - System.err.println("Failed to claim bazaar rewards: " + e.getMessage()); + org.tinylog.Logger.error(e, "Failed to claim bazaar rewards"); } } diff --git a/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/item/handlers/anvilcombine/AnvilCombineRegistry.java b/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/item/handlers/anvilcombine/AnvilCombineRegistry.java index 772304067..934b5cafe 100644 --- a/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/item/handlers/anvilcombine/AnvilCombineRegistry.java +++ b/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/item/handlers/anvilcombine/AnvilCombineRegistry.java @@ -34,8 +34,6 @@ public class AnvilCombineRegistry { }, (player, upgradeItem, sacrificeItem) -> { if (upgradeItem.hasComponent(HotPotatoableComponent.class)) { - System.out.println(upgradeItem.getAttributeHandler().getPotentialType()); - var type = sacrificeItem.getAttributeHandler().getPotentialType(); HotPotatoableComponent hotPotatoable = upgradeItem.getComponent(HotPotatoableComponent.class); diff --git a/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/particle/ParticleEngine.java b/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/particle/ParticleEngine.java index c78b7a2a0..a532fbb09 100644 --- a/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/particle/ParticleEngine.java +++ b/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/particle/ParticleEngine.java @@ -59,7 +59,7 @@ public ParticleEngine offsets(Vec offsets) { public ParticleEngine shape(ParticleShape shape) { if (offsets != Vec.ZERO) - System.out.println("[WARNING] Particle offsets overridden by shape preset."); + org.tinylog.Logger.warn("Particle offsets overridden by shape preset."); this.shape = shape; return this; diff --git a/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/user/SkyBlockPlayer.java b/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/user/SkyBlockPlayer.java index 467189e91..e24f2c905 100644 --- a/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/user/SkyBlockPlayer.java +++ b/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/user/SkyBlockPlayer.java @@ -677,7 +677,7 @@ public int getMaxSackStorage(ItemType sack) { if (matcher.find()) { sackCategory = matcher.group(2); } else { - System.out.println("Invalid sack name: " + sack.name()); + org.tinylog.Logger.warn("Invalid sack name: {}", sack.name()); return 0; } From 8889f146bfe0f443be093e0ca2a05fb25ee81a3f Mon Sep 17 00:00:00 2001 From: "Jacob Nardella (Swofty)" Date: Fri, 15 May 2026 01:15:18 +1000 Subject: [PATCH 062/113] chore(minion): replace commented-out minion-loop debug with Logger.debug The 'every other week I need this' comment block of stdout prints made commenting/uncommenting code the only way to enable diagnostics. Folded into a single Logger.debug call guarded by isDebugEnabled() so the trace ships with the build and is toggled by log config instead. --- .../type/skyblockgeneric/minion/MinionHandler.java | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) diff --git a/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/minion/MinionHandler.java b/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/minion/MinionHandler.java index 34af4a329..2ea0d3299 100644 --- a/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/minion/MinionHandler.java +++ b/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/minion/MinionHandler.java @@ -53,13 +53,12 @@ private void minionLoop() { if (!instance.isChunkLoaded(minionEntity.getPosition().chunkX(), minionEntity.getPosition().chunkZ())) return; - /** seems like I need this debug every other week, so keep it here for now - System.out.println("Minion loop"); - System.out.println("Time between actions: " + timeBetweenActions); - System.out.println("Current time diff: " + (System.currentTimeMillis() - lastAction)); - System.out.println("Tier: " + islandMinion.getTier()); - System.out.println("State: " + tags.getState()); - System.out.println("Step: " + tags.getCurrentStep());*/ + // Diagnostic trace — enable via tinylog debug level instead of uncommenting prints. + if (Logger.isDebugEnabled()) { + Logger.debug("Minion loop tier={} state={} step={} timeBetween={}ms timeSince={}ms", + islandMinion.getTier(), tags.getState(), tags.getCurrentStep(), + timeBetweenActions, System.currentTimeMillis() - lastAction); + } //Get the extra minion range granted from minion expanders int extraMinionRange = islandMinion.getBonusRange(); From eb2844dd770dbe2d3e285d92f1bebc7184805b44 Mon Sep 17 00:00:00 2001 From: "Jacob Nardella (Swofty)" Date: Fri, 15 May 2026 01:17:06 +1000 Subject: [PATCH 063/113] refactor(achievement): dedupe toRoman across the achievement subsystem MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Same six-arm switch lived in three places — AchievementTier (instance), PlayerAchievementHandler (private helper), and GUITieredAchievements (private helper). Hoisted the switch into AchievementTier.toRomanNumeral(int) and pointed the two private helpers at it. Kept tier-specific semantics (decimal fallback for 6+) since the shared StringUtility.getAsRomanNumeral returns '' for 0, which is wrong here. Added a Javadoc note on the new method explaining why the two converters aren't merged. --- .../type/generic/achievement/AchievementTier.java | 11 +++++++++++ .../generic/achievement/PlayerAchievementHandler.java | 9 +-------- .../swofty/type/lobby/gui/GUITieredAchievements.java | 9 +-------- 3 files changed, 13 insertions(+), 16 deletions(-) diff --git a/type.generic/src/main/java/net/swofty/type/generic/achievement/AchievementTier.java b/type.generic/src/main/java/net/swofty/type/generic/achievement/AchievementTier.java index f7ab403ac..c6bd06db0 100644 --- a/type.generic/src/main/java/net/swofty/type/generic/achievement/AchievementTier.java +++ b/type.generic/src/main/java/net/swofty/type/generic/achievement/AchievementTier.java @@ -2,6 +2,17 @@ public record AchievementTier(int tier, int goal, int points) { public String getRomanNumeral() { + return toRomanNumeral(tier); + } + + /** + * Tier-friendly Roman numeral converter. Tiers in this codebase don't + * exceed V in practice, so the higher-order rules of + * {@link net.swofty.commons.StringUtility#getAsRomanNumeral} aren't + * needed — and a value outside 1-5 should fall back to its decimal form + * (which the StringUtility variant doesn't do). + */ + public static String toRomanNumeral(int tier) { return switch (tier) { case 1 -> "I"; case 2 -> "II"; diff --git a/type.generic/src/main/java/net/swofty/type/generic/achievement/PlayerAchievementHandler.java b/type.generic/src/main/java/net/swofty/type/generic/achievement/PlayerAchievementHandler.java index 2d64055b4..2c507be65 100644 --- a/type.generic/src/main/java/net/swofty/type/generic/achievement/PlayerAchievementHandler.java +++ b/type.generic/src/main/java/net/swofty/type/generic/achievement/PlayerAchievementHandler.java @@ -182,13 +182,6 @@ private void onAchievementUnlocked(AchievementDefinition def, AchievementData.Ac } private String toRoman(int tier) { - return switch (tier) { - case 1 -> "I"; - case 2 -> "II"; - case 3 -> "III"; - case 4 -> "IV"; - case 5 -> "V"; - default -> String.valueOf(tier); - }; + return AchievementTier.toRomanNumeral(tier); } } diff --git a/type.lobby/src/main/java/net/swofty/type/lobby/gui/GUITieredAchievements.java b/type.lobby/src/main/java/net/swofty/type/lobby/gui/GUITieredAchievements.java index b8918abb2..a3ae3f25d 100644 --- a/type.lobby/src/main/java/net/swofty/type/lobby/gui/GUITieredAchievements.java +++ b/type.lobby/src/main/java/net/swofty/type/lobby/gui/GUITieredAchievements.java @@ -317,14 +317,7 @@ public void run(InventoryPreClickEvent e, HypixelPlayer player) { } private String toRoman(int num) { - return switch (num) { - case 1 -> "I"; - case 2 -> "II"; - case 3 -> "III"; - case 4 -> "IV"; - case 5 -> "V"; - default -> String.valueOf(num); - }; + return AchievementTier.toRomanNumeral(num); } private int getMaxPages(int totalAchievements) { From b382e44dc90c236222503b70c02cab52e1fcff71 Mon Sep 17 00:00:00 2001 From: "Jacob Nardella (Swofty)" Date: Fri, 15 May 2026 01:18:33 +1000 Subject: [PATCH 064/113] perf(skywars): use ThreadLocalRandom in random-pick helpers The two getRandom*Drop methods in SkywarsPerkRegistry and SkywarsKitRegistry instantiated a new Random for every call. ThreadLocalRandom.current() avoids the allocation and skips the internal AtomicLong CAS that bare Random uses for seed updates. --- .../net/swofty/type/skywarslobby/kit/SkywarsKitRegistry.java | 2 +- .../net/swofty/type/skywarslobby/perk/SkywarsPerkRegistry.java | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/type.skywarslobby/src/main/java/net/swofty/type/skywarslobby/kit/SkywarsKitRegistry.java b/type.skywarslobby/src/main/java/net/swofty/type/skywarslobby/kit/SkywarsKitRegistry.java index d421ad758..84eba5b0a 100644 --- a/type.skywarslobby/src/main/java/net/swofty/type/skywarslobby/kit/SkywarsKitRegistry.java +++ b/type.skywarslobby/src/main/java/net/swofty/type/skywarslobby/kit/SkywarsKitRegistry.java @@ -116,7 +116,7 @@ public static SkywarsKit getRandomSoulWellKit(Set ownedKitIds) { if (unownedKits.isEmpty()) { return null; } - return unownedKits.get(new Random().nextInt(unownedKits.size())); + return unownedKits.get(java.util.concurrent.ThreadLocalRandom.current().nextInt(unownedKits.size())); } /** diff --git a/type.skywarslobby/src/main/java/net/swofty/type/skywarslobby/perk/SkywarsPerkRegistry.java b/type.skywarslobby/src/main/java/net/swofty/type/skywarslobby/perk/SkywarsPerkRegistry.java index 496373bd4..635da9b3f 100644 --- a/type.skywarslobby/src/main/java/net/swofty/type/skywarslobby/perk/SkywarsPerkRegistry.java +++ b/type.skywarslobby/src/main/java/net/swofty/type/skywarslobby/perk/SkywarsPerkRegistry.java @@ -106,7 +106,7 @@ public static SkywarsPerk getRandomSoulWellPerk(Set ownedPerkIds) { if (unownedPerks.isEmpty()) { return null; } - return unownedPerks.get(new Random().nextInt(unownedPerks.size())); + return unownedPerks.get(java.util.concurrent.ThreadLocalRandom.current().nextInt(unownedPerks.size())); } /** From f09e934943ac1faf752286eb271dfcd797cf26c5 Mon Sep 17 00:00:00 2001 From: "Jacob Nardella (Swofty)" Date: Fri, 15 May 2026 01:19:10 +1000 Subject: [PATCH 065/113] perf(skywars): ThreadLocalRandom + Set.add return value in ChestManager.fillChest MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Two cleanups in one method: - Replaced the per-call new Random() with ThreadLocalRandom.current() - usedSlots.contains then add was redundant — Set.add already returns true iff the value was inserted, so one map probe instead of two per loot item. --- .../net/swofty/type/skywarsgame/manager/ChestManager.java | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/type.skywarsgame/src/main/java/net/swofty/type/skywarsgame/manager/ChestManager.java b/type.skywarsgame/src/main/java/net/swofty/type/skywarsgame/manager/ChestManager.java index 1e0b62776..cc7f6bfc0 100644 --- a/type.skywarsgame/src/main/java/net/swofty/type/skywarsgame/manager/ChestManager.java +++ b/type.skywarsgame/src/main/java/net/swofty/type/skywarsgame/manager/ChestManager.java @@ -50,7 +50,7 @@ private void fillChest(Inventory chest, LootTier tier) { chest.clear(); List loot = ChestLootTable.generateLoot(tier, gameType.isInsane(), gameType); - Random random = new Random(); + java.util.concurrent.ThreadLocalRandom random = java.util.concurrent.ThreadLocalRandom.current(); Set usedSlots = new HashSet<>(); for (ItemStack item : loot) { @@ -61,8 +61,7 @@ private void fillChest(Inventory chest, LootTier tier) { attempts++; } while (usedSlots.contains(slot) && attempts < 50); - if (!usedSlots.contains(slot)) { - usedSlots.add(slot); + if (usedSlots.add(slot)) { chest.setItemStack(slot, item); } } From 09d3b7d512e32e7b654a5f92c740898693d5e9b9 Mon Sep 17 00:00:00 2001 From: "Jacob Nardella (Swofty)" Date: Fri, 15 May 2026 01:20:36 +1000 Subject: [PATCH 066/113] refactor(datamutex): convert LockInfo from inner class to record MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit LockInfo was a 14-line nested class with three public final fields, a generated constructor, and one method (isExpired). It's a perfect record fit — same shape, same accessors, less boilerplate. Updated the one external field access (lockInfo.requesterId → .requesterId()) in UpdateSynchronizedDataEndpoint. --- .../service/datamutex/DataLockManager.java | 36 ++++++------------- .../UpdateSynchronizedDataEndpoint.java | 4 +-- 2 files changed, 13 insertions(+), 27 deletions(-) diff --git a/service.datamutex/src/main/java/net/swofty/service/datamutex/DataLockManager.java b/service.datamutex/src/main/java/net/swofty/service/datamutex/DataLockManager.java index 1d02c7e51..841fb67d4 100644 --- a/service.datamutex/src/main/java/net/swofty/service/datamutex/DataLockManager.java +++ b/service.datamutex/src/main/java/net/swofty/service/datamutex/DataLockManager.java @@ -6,59 +6,45 @@ public class DataLockManager { private static final Map activeLocks = new ConcurrentHashMap<>(); - private static final long LOCK_TIMEOUT = 30000; // 30 seconds - - public static class LockInfo { - public final UUID lockId; - public final long timestamp; - public final String requesterId; - - public LockInfo(UUID lockId, long timestamp, String requesterId) { - this.lockId = lockId; - this.timestamp = timestamp; - this.requesterId = requesterId; - } + private static final long LOCK_TIMEOUT = 30_000; // 30 seconds + public record LockInfo(UUID lockId, long timestamp, String requesterId) { public boolean isExpired() { return (System.currentTimeMillis() - timestamp) > LOCK_TIMEOUT; } } /** - * Attempts to acquire a lock for the given key + * Attempts to acquire a lock for the given key. */ public static boolean acquireLock(String lockKey, String requesterId) { LockInfo existingLock = activeLocks.get(lockKey); - // Clean up expired locks if (existingLock != null && existingLock.isExpired()) { activeLocks.remove(lockKey); existingLock = null; } - // Check if already locked by someone else - if (existingLock != null && !existingLock.requesterId.equals(requesterId)) { + if (existingLock != null && !existingLock.requesterId().equals(requesterId)) { return false; } - // Acquire or renew lock - UUID lockId = UUID.randomUUID(); - activeLocks.put(lockKey, new LockInfo(lockId, System.currentTimeMillis(), requesterId)); + activeLocks.put(lockKey, new LockInfo(UUID.randomUUID(), System.currentTimeMillis(), requesterId)); return true; } /** - * Releases a lock for the given key + * Releases a lock for the given key. */ public static void releaseLock(String lockKey, String requesterId) { LockInfo lock = activeLocks.get(lockKey); - if (lock != null && lock.requesterId.equals(requesterId)) { + if (lock != null && lock.requesterId().equals(requesterId)) { activeLocks.remove(lockKey); } } /** - * Checks if a key is currently locked + * Checks if a key is currently locked. */ public static boolean isLocked(String lockKey) { LockInfo lock = activeLocks.get(lockKey); @@ -73,7 +59,7 @@ public static boolean isLocked(String lockKey) { } /** - * Gets the lock info for a key (or null if not locked) + * Gets the lock info for a key, or null if not locked. */ public static LockInfo getLockInfo(String lockKey) { LockInfo lock = activeLocks.get(lockKey); @@ -85,9 +71,9 @@ public static LockInfo getLockInfo(String lockKey) { } /** - * Cleans up all expired locks + * Cleans up all expired locks. */ public static void cleanupExpiredLocks() { activeLocks.entrySet().removeIf(entry -> entry.getValue().isExpired()); } -} \ No newline at end of file +} diff --git a/service.datamutex/src/main/java/net/swofty/service/datamutex/endpoints/UpdateSynchronizedDataEndpoint.java b/service.datamutex/src/main/java/net/swofty/service/datamutex/endpoints/UpdateSynchronizedDataEndpoint.java index 1cf27ebc6..8a5f32fd3 100644 --- a/service.datamutex/src/main/java/net/swofty/service/datamutex/endpoints/UpdateSynchronizedDataEndpoint.java +++ b/service.datamutex/src/main/java/net/swofty/service/datamutex/endpoints/UpdateSynchronizedDataEndpoint.java @@ -41,9 +41,9 @@ public UpdateSynchronizedDataProtocolObject.UpdateDataResponse onMessage( try { DataLockManager.LockInfo lockInfo = DataLockManager.getLockInfo(lockKey); - if (lockInfo == null || !lockInfo.requesterId.equals(requesterId)) { + if (lockInfo == null || !lockInfo.requesterId().equals(requesterId)) { Logger.debug("update: lock check failed (held by {})", - lockInfo == null ? "" : lockInfo.requesterId); + lockInfo == null ? "" : lockInfo.requesterId()); return new UpdateSynchronizedDataProtocolObject.UpdateDataResponse( false, "Lock has expired or is held by another requester"); } From 2058bb8ad4ed9ff93ba28d6eed31972bbe516ce5 Mon Sep 17 00:00:00 2001 From: "Jacob Nardella (Swofty)" Date: Fri, 15 May 2026 01:22:48 +1000 Subject: [PATCH 067/113] perf: ThreadLocalRandom for remaining inline new Random() callsites MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Seven more inline 'new Random().nextInt(...)' calls converted to ThreadLocalRandom.current().nextInt(...) — one allocation skipped per call and no AtomicLong CAS contention on hot paths: - GameManager.addServer (per-server name letter) - GUICageKitSelector (random unowned kit pick) - SwoftyPlayer anticheat (random id) - SkyBlockPlayerProfiles (random profile name) - bedwarsgame Game (random game id substring) - MurderMysteryGameGoldManager (random spawn point) - ServerOrbRegistry (random flower material) All seven were one-shot calls that allocated a brand-new Random per invocation, which is both wasteful and a tiny bit contended. --- .../src/main/java/net/swofty/anticheat/engine/SwoftyPlayer.java | 2 +- .../net/swofty/commons/skyblock/SkyBlockPlayerProfiles.java | 2 +- .../src/main/java/net/swofty/type/bedwarsgame/game/Game.java | 2 +- .../net/swofty/type/murdermysterygame/gold/GoldManager.java | 2 +- .../skyblockgeneric/item/handlers/orbs/ServerOrbRegistry.java | 2 +- .../net/swofty/type/skywarsgame/gui/GUICageKitSelector.java | 2 +- .../main/java/net/swofty/velocity/gamemanager/GameManager.java | 2 +- 7 files changed, 7 insertions(+), 7 deletions(-) diff --git a/anticheat/src/main/java/net/swofty/anticheat/engine/SwoftyPlayer.java b/anticheat/src/main/java/net/swofty/anticheat/engine/SwoftyPlayer.java index 113d3eef5..d8c3cee73 100644 --- a/anticheat/src/main/java/net/swofty/anticheat/engine/SwoftyPlayer.java +++ b/anticheat/src/main/java/net/swofty/anticheat/engine/SwoftyPlayer.java @@ -87,7 +87,7 @@ public int ticksSinceLastPingResponse() { public void sendPingRequest() { // Between 1 and 50000000 - int randomId = new Random().nextInt(50000000) + 1; + int randomId = java.util.concurrent.ThreadLocalRandom.current().nextInt(50000000) + 1; PingRequest request = new PingRequest(randomId); pingRequests.offerLast(request); diff --git a/commons/src/main/java/net/swofty/commons/skyblock/SkyBlockPlayerProfiles.java b/commons/src/main/java/net/swofty/commons/skyblock/SkyBlockPlayerProfiles.java index 85fcc7701..7044e2a0e 100644 --- a/commons/src/main/java/net/swofty/commons/skyblock/SkyBlockPlayerProfiles.java +++ b/commons/src/main/java/net/swofty/commons/skyblock/SkyBlockPlayerProfiles.java @@ -62,7 +62,7 @@ public static SkyBlockPlayerProfiles deserialize(Map map) { } public static String getRandomName() { - return PROFILE_NAMES[new Random().nextInt(PROFILE_NAMES.length)]; + return PROFILE_NAMES[java.util.concurrent.ThreadLocalRandom.current().nextInt(PROFILE_NAMES.length)]; } public static SkyBlockPlayerProfiles get(UUID uuid) { diff --git a/type.bedwarsgame/src/main/java/net/swofty/type/bedwarsgame/game/Game.java b/type.bedwarsgame/src/main/java/net/swofty/type/bedwarsgame/game/Game.java index 30a1209cf..ff1cdd874 100644 --- a/type.bedwarsgame/src/main/java/net/swofty/type/bedwarsgame/game/Game.java +++ b/type.bedwarsgame/src/main/java/net/swofty/type/bedwarsgame/game/Game.java @@ -110,7 +110,7 @@ public void join(BedWarsPlayer player) { int maxPlayers = getMaxPlayers(); String randomLetters = UUID.randomUUID().toString().replaceAll("-", "") - .substring(0, new Random().nextInt(10) + 4); + .substring(0, java.util.concurrent.ThreadLocalRandom.current().nextInt(10) + 4); for (BedWarsPlayer p : players) { String name = p.getUuid().compareTo(player.getUuid()) == 0 ? player.getUsername() : "§k" + randomLetters; p.sendMessage(name + " §ehas joined (§b" + players.size() + "§e/§b" + maxPlayers + "§e)"); diff --git a/type.murdermysterygame/src/main/java/net/swofty/type/murdermysterygame/gold/GoldManager.java b/type.murdermysterygame/src/main/java/net/swofty/type/murdermysterygame/gold/GoldManager.java index 01971372f..abad6d03e 100644 --- a/type.murdermysterygame/src/main/java/net/swofty/type/murdermysterygame/gold/GoldManager.java +++ b/type.murdermysterygame/src/main/java/net/swofty/type/murdermysterygame/gold/GoldManager.java @@ -51,7 +51,7 @@ public void startSpawning() { if (spawnedGold.size() >= MAX_GOLD_SPAWNED || spawnLocations.isEmpty()) { return; } - MurderMysteryMapsConfig.Position randomSpawn = spawnLocations.get(new Random().nextInt(spawnLocations.size())); + MurderMysteryMapsConfig.Position randomSpawn = spawnLocations.get(java.util.concurrent.ThreadLocalRandom.current().nextInt(spawnLocations.size())); Pos spawnPos = new Pos(randomSpawn.x(), randomSpawn.y(), randomSpawn.z()); // Issue #673: cap each spawn point at one gold coin. The previous loop // rolled the same point repeatedly and stacked up to five coins there. diff --git a/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/item/handlers/orbs/ServerOrbRegistry.java b/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/item/handlers/orbs/ServerOrbRegistry.java index 270c51078..64ab5b670 100644 --- a/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/item/handlers/orbs/ServerOrbRegistry.java +++ b/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/item/handlers/orbs/ServerOrbRegistry.java @@ -16,7 +16,7 @@ public class ServerOrbRegistry { registerHandler("WHEAT_CRYSTAL_ORB_HANDLER", new ServerOrbHandler(crystalImpl -> Block.WHEAT)); registerHandler("FLOWER_CRYSTAL_ORB_HANDLER", new ServerOrbHandler(crystalImpl -> { List flowers = Groups.FLOWERS; - Material randomMaterial = flowers.get(new Random().nextInt(flowers.size())); + Material randomMaterial = flowers.get(java.util.concurrent.ThreadLocalRandom.current().nextInt(flowers.size())); return randomMaterial.block(); })); registerHandler("PUMPKIN_AND_MELON_CRYSTAL_ORB_HANDLER", new ServerOrbHandler(crystalImpl -> { diff --git a/type.skywarsgame/src/main/java/net/swofty/type/skywarsgame/gui/GUICageKitSelector.java b/type.skywarsgame/src/main/java/net/swofty/type/skywarsgame/gui/GUICageKitSelector.java index 0905bf272..331db2185 100644 --- a/type.skywarsgame/src/main/java/net/swofty/type/skywarsgame/gui/GUICageKitSelector.java +++ b/type.skywarsgame/src/main/java/net/swofty/type/skywarsgame/gui/GUICageKitSelector.java @@ -209,7 +209,7 @@ public void run(InventoryPreClickEvent e, HypixelPlayer player) { return; } - SkywarsKit randomKit = ownedKits.get(new Random().nextInt(ownedKits.size())); + SkywarsKit randomKit = ownedKits.get(java.util.concurrent.ThreadLocalRandom.current().nextInt(ownedKits.size())); currentUnlocks.selectKitForMode(mode, randomKit.getId()); player.sendMessage("§aRandomly selected the §e" + randomKit.getName() + " §akit!"); diff --git a/velocity.extension/src/main/java/net/swofty/velocity/gamemanager/GameManager.java b/velocity.extension/src/main/java/net/swofty/velocity/gamemanager/GameManager.java index 270aeb3f9..5a9cbfbd0 100644 --- a/velocity.extension/src/main/java/net/swofty/velocity/gamemanager/GameManager.java +++ b/velocity.extension/src/main/java/net/swofty/velocity/gamemanager/GameManager.java @@ -33,7 +33,7 @@ public static GameServer addServer(ServerType type, UUID serverID, String host, String rootName = isLobby ? "L" : (maxPlayers <= 20 ? "mini" : "mega"); String shortenedRootName = isLobby ? "L" : (maxPlayers <= 20 ? "m" : "M"); - char letter = (char) (new Random().nextInt(26) + (isLobby ? 'a' : 'A')); + char letter = (char) (java.util.concurrent.ThreadLocalRandom.current().nextInt(26) + (isLobby ? 'a' : 'A')); String displayName = getNextAvailableDisplayName() + "" + letter; GameServer server = new GameServer( From 65d402e3e2fd7d11cda0792884e1b2abea0e2d15 Mon Sep 17 00:00:00 2001 From: "Jacob Nardella (Swofty)" Date: Fri, 15 May 2026 01:25:33 +1000 Subject: [PATCH 068/113] refactor(commons): collapse TestFlow.TestFlowInstance to a record MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The nested class held two final fields + a Lombok @Getter + an explicit constructor + one method. Records carve out the same shape in two lines. No external callers — nobody references the type or its accessors outside this file. --- .../java/net/swofty/commons/TestFlow.java | 37 ++++--------------- 1 file changed, 7 insertions(+), 30 deletions(-) diff --git a/commons/src/main/java/net/swofty/commons/TestFlow.java b/commons/src/main/java/net/swofty/commons/TestFlow.java index 4b0e7ee50..474998106 100644 --- a/commons/src/main/java/net/swofty/commons/TestFlow.java +++ b/commons/src/main/java/net/swofty/commons/TestFlow.java @@ -15,25 +15,21 @@ public class TestFlow { private static List currentTestPlayers; /** - * Checks if any test flow is currently active on this server - * @return true if a test flow is active + * Checks if any test flow is currently active on this server. */ public static boolean isTestFlowActive() { return currentTestFlow != null; } /** - * Checks if a specific test flow is active - * @param testFlowName the name of the test flow - * @return true if the specified test flow is active + * Checks if a specific test flow is active. */ public static boolean isTestFlowActive(String testFlowName) { return currentTestFlow != null && currentTestFlow.equals(testFlowName); } /** - * Gets the current test flow instance - * @return a simple TestFlowInstance or null if no test flow is active + * Gets the current test flow instance, or {@code null} if no test flow is active. */ public static TestFlowInstance getTestFlowInstance() { if (currentTestFlow == null) return null; @@ -41,9 +37,7 @@ public static TestFlowInstance getTestFlowInstance() { } /** - * Sets the current test flow for this server - * @param testFlowName the name of the test flow - * @param players the list of test flow players + * Sets the current test flow for this server. */ public static void setCurrentTestFlow(String testFlowName, List players) { currentTestFlow = testFlowName; @@ -51,33 +45,16 @@ public static void setCurrentTestFlow(String testFlowName, List players) } /** - * Clears the current test flow + * Clears the current test flow. */ public static void clearTestFlow() { currentTestFlow = null; currentTestPlayers = null; } - /** - * Simple test flow instance for server-side usage - */ - @Getter - public static class TestFlowInstance { - private final String name; - private final List players; - - public TestFlowInstance(String name, List players) { - this.name = name; - this.players = players; - } - - /** - * Checks if a player is part of this test flow - * @param playerName the player name to check - * @return true if the player is in this test flow - */ + public record TestFlowInstance(String name, List players) { public boolean hasPlayer(String playerName) { return players != null && players.contains(playerName); } } -} \ No newline at end of file +} From f760431c042ce70f09dfceb0273b4399f049c013 Mon Sep 17 00:00:00 2001 From: "Jacob Nardella (Swofty)" Date: Fri, 15 May 2026 01:27:03 +1000 Subject: [PATCH 069/113] chore: drop unused java.util.Random imports after ThreadLocalRandom migration The three files where the only Random usage was a 'new Random().nextInt' that's now ThreadLocalRandom now have a dangling import. Removed. --- .../java/net/swofty/commons/skyblock/SkyBlockPlayerProfiles.java | 1 - .../src/main/java/net/swofty/type/bedwarsgame/game/Game.java | 1 - .../java/net/swofty/type/skywarsgame/gui/GUICageKitSelector.java | 1 - 3 files changed, 3 deletions(-) diff --git a/commons/src/main/java/net/swofty/commons/skyblock/SkyBlockPlayerProfiles.java b/commons/src/main/java/net/swofty/commons/skyblock/SkyBlockPlayerProfiles.java index 7044e2a0e..72d51eeba 100644 --- a/commons/src/main/java/net/swofty/commons/skyblock/SkyBlockPlayerProfiles.java +++ b/commons/src/main/java/net/swofty/commons/skyblock/SkyBlockPlayerProfiles.java @@ -6,7 +6,6 @@ import java.util.ArrayList; import java.util.List; import java.util.Map; -import java.util.Random; import java.util.UUID; import java.util.concurrent.ConcurrentHashMap; diff --git a/type.bedwarsgame/src/main/java/net/swofty/type/bedwarsgame/game/Game.java b/type.bedwarsgame/src/main/java/net/swofty/type/bedwarsgame/game/Game.java index ff1cdd874..9ad0cb975 100644 --- a/type.bedwarsgame/src/main/java/net/swofty/type/bedwarsgame/game/Game.java +++ b/type.bedwarsgame/src/main/java/net/swofty/type/bedwarsgame/game/Game.java @@ -40,7 +40,6 @@ import java.util.HashMap; import java.util.List; import java.util.Map; -import java.util.Random; import java.util.UUID; import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.atomic.AtomicInteger; diff --git a/type.skywarsgame/src/main/java/net/swofty/type/skywarsgame/gui/GUICageKitSelector.java b/type.skywarsgame/src/main/java/net/swofty/type/skywarsgame/gui/GUICageKitSelector.java index 331db2185..378dfd266 100644 --- a/type.skywarsgame/src/main/java/net/swofty/type/skywarsgame/gui/GUICageKitSelector.java +++ b/type.skywarsgame/src/main/java/net/swofty/type/skywarsgame/gui/GUICageKitSelector.java @@ -22,7 +22,6 @@ import java.util.ArrayList; import java.util.List; -import java.util.Random; public class GUICageKitSelector extends HypixelInventoryGUI { private static final int[] KIT_SLOTS = { From 4ae3569a2fbc89878e12af91674a6bb8a68994df Mon Sep 17 00:00:00 2001 From: "Jacob Nardella (Swofty)" Date: Fri, 15 May 2026 01:30:44 +1000 Subject: [PATCH 070/113] refactor(commons): convert ServiceProxyRequest from @Setter class to record MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The class had @Setter generated but no caller actually set anything after construction — the static fromJSON factory built a fresh instance each time. The setters were dead surface. Made it a record (canonical constructor + auto-equals/hashCode/toString) and kept four getXxx() wrappers so external code that used the Lombok-generated getters keeps compiling unchanged. --- .../commons/impl/ServiceProxyRequest.java | 19 ++++++++----------- 1 file changed, 8 insertions(+), 11 deletions(-) diff --git a/commons/src/main/java/net/swofty/commons/impl/ServiceProxyRequest.java b/commons/src/main/java/net/swofty/commons/impl/ServiceProxyRequest.java index d87a4cc67..5db536e68 100644 --- a/commons/src/main/java/net/swofty/commons/impl/ServiceProxyRequest.java +++ b/commons/src/main/java/net/swofty/commons/impl/ServiceProxyRequest.java @@ -1,20 +1,10 @@ package net.swofty.commons.impl; -import lombok.AllArgsConstructor; -import lombok.Getter; -import lombok.Setter; import org.json.JSONObject; import java.util.UUID; -@AllArgsConstructor -@Getter -@Setter -public class ServiceProxyRequest { - private UUID requestId; - private String requestServer; - private String endpoint; - private String message; +public record ServiceProxyRequest(UUID requestId, String requestServer, String endpoint, String message) { public JSONObject toJSON() { return new JSONObject() @@ -32,4 +22,11 @@ public static ServiceProxyRequest fromJSON(JSONObject json) { json.getString("message") ); } + + // Compatibility accessors so existing call sites that used Lombok-generated + // getters keep compiling — records expose component(), not getComponent(). + public UUID getRequestId() { return requestId; } + public String getRequestServer() { return requestServer; } + public String getEndpoint() { return endpoint; } + public String getMessage() { return message; } } From 058e03898315e93e44e83bfe65712c16275cec77 Mon Sep 17 00:00:00 2001 From: "Jacob Nardella (Swofty)" Date: Fri, 15 May 2026 01:32:17 +1000 Subject: [PATCH 071/113] refactor(friend): migrate Friend.getSerializer to JacksonSerializer MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Same migration as the FriendEvent subclasses — the hand-rolled inner-class Serializer just round-tripped the four fields through org.json.JSONObject. Replaced with a static JacksonSerializer field that the existing @JsonCreator/@JsonProperty annotations already support. --- .../net/swofty/commons/friend/Friend.java | 34 +++---------------- 1 file changed, 5 insertions(+), 29 deletions(-) diff --git a/commons/src/main/java/net/swofty/commons/friend/Friend.java b/commons/src/main/java/net/swofty/commons/friend/Friend.java index 43b00fc5d..97ec70dd1 100644 --- a/commons/src/main/java/net/swofty/commons/friend/Friend.java +++ b/commons/src/main/java/net/swofty/commons/friend/Friend.java @@ -4,13 +4,15 @@ import com.fasterxml.jackson.annotation.JsonProperty; import lombok.Getter; import lombok.Setter; +import net.swofty.commons.protocol.JacksonSerializer; import net.swofty.commons.protocol.Serializer; -import org.json.JSONObject; import java.util.UUID; @Getter public class Friend { + private static final Serializer SERIALIZER = new JacksonSerializer<>(Friend.class); + private final UUID uuid; @Setter private String nickname; @@ -35,36 +37,10 @@ public static Friend create(UUID uuid) { } public static Serializer getStaticSerializer() { - return new Friend(UUID.randomUUID(), null, false, 0).getSerializer(); + return SERIALIZER; } public Serializer getSerializer() { - return new Serializer<>() { - @Override - public String serialize(Friend value) { - JSONObject json = new JSONObject(); - json.put("uuid", value.uuid.toString()); - json.put("nickname", value.nickname != null ? value.nickname : JSONObject.NULL); - json.put("bestFriend", value.bestFriend); - json.put("addedTimestamp", value.addedTimestamp); - return json.toString(); - } - - @Override - public Friend deserialize(String json) { - JSONObject jsonObject = new JSONObject(json); - return new Friend( - UUID.fromString(jsonObject.getString("uuid")), - jsonObject.isNull("nickname") ? null : jsonObject.getString("nickname"), - jsonObject.getBoolean("bestFriend"), - jsonObject.getLong("addedTimestamp") - ); - } - - @Override - public Friend clone(Friend value) { - return new Friend(value.uuid, value.nickname, value.bestFriend, value.addedTimestamp); - } - }; + return SERIALIZER; } } From 95444972dd1cc674928e8c4d08083af5a4eed9ec Mon Sep 17 00:00:00 2001 From: "Jacob Nardella (Swofty)" Date: Fri, 15 May 2026 01:32:52 +1000 Subject: [PATCH 072/113] refactor(friend): migrate PendingFriendRequest to JacksonSerializer MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Mirrors the Friend.java migration — drops the hand-rolled inner-class Serializer and routes through JacksonSerializer<>(PendingFriendRequest.class). Same wire format, much less code. --- .../commons/friend/PendingFriendRequest.java | 37 +++---------------- 1 file changed, 6 insertions(+), 31 deletions(-) diff --git a/commons/src/main/java/net/swofty/commons/friend/PendingFriendRequest.java b/commons/src/main/java/net/swofty/commons/friend/PendingFriendRequest.java index af8a042d9..be034c917 100644 --- a/commons/src/main/java/net/swofty/commons/friend/PendingFriendRequest.java +++ b/commons/src/main/java/net/swofty/commons/friend/PendingFriendRequest.java @@ -3,14 +3,17 @@ import com.fasterxml.jackson.annotation.JsonCreator; import com.fasterxml.jackson.annotation.JsonProperty; import lombok.Getter; +import net.swofty.commons.protocol.JacksonSerializer; import net.swofty.commons.protocol.Serializer; -import org.json.JSONObject; import java.util.List; import java.util.UUID; @Getter public class PendingFriendRequest { + private static final Serializer SERIALIZER = + new JacksonSerializer<>(PendingFriendRequest.class); + private final UUID from; private final UUID to; private final String fromName; @@ -40,38 +43,10 @@ public List getParticipants() { } public static Serializer getStaticSerializer() { - return create(UUID.randomUUID(), UUID.randomUUID(), "", "").getSerializer(); + return SERIALIZER; } public Serializer getSerializer() { - return new Serializer<>() { - @Override - public String serialize(PendingFriendRequest value) { - JSONObject json = new JSONObject(); - json.put("from", value.from.toString()); - json.put("to", value.to.toString()); - json.put("fromName", value.fromName); - json.put("toName", value.toName); - json.put("timestamp", value.timestamp); - return json.toString(); - } - - @Override - public PendingFriendRequest deserialize(String json) { - JSONObject jsonObject = new JSONObject(json); - return new PendingFriendRequest( - UUID.fromString(jsonObject.getString("from")), - UUID.fromString(jsonObject.getString("to")), - jsonObject.optString("fromName", "Unknown"), - jsonObject.optString("toName", "Unknown"), - jsonObject.getLong("timestamp") - ); - } - - @Override - public PendingFriendRequest clone(PendingFriendRequest value) { - return new PendingFriendRequest(value.from, value.to, value.fromName, value.toName, value.timestamp); - } - }; + return SERIALIZER; } } From 65d6cff334b0072ce0ef6593e843136d7b4d09ba Mon Sep 17 00:00:00 2001 From: "Jacob Nardella (Swofty)" Date: Fri, 15 May 2026 01:34:10 +1000 Subject: [PATCH 073/113] refactor(friend): migrate FriendSettings + FriendData to JacksonSerializer MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Same shape as the Friend / PendingFriendRequest / *Event migrations: swap the hand-rolled inner Serializer for a static JacksonSerializer field. FriendData's serializer had a nested JSONArray walk that built JSON via friend.getSerializer() — Jackson handles the recursive case for free. --- .../net/swofty/commons/friend/FriendData.java | 56 ++----------------- .../swofty/commons/friend/FriendSettings.java | 30 ++-------- 2 files changed, 10 insertions(+), 76 deletions(-) diff --git a/commons/src/main/java/net/swofty/commons/friend/FriendData.java b/commons/src/main/java/net/swofty/commons/friend/FriendData.java index 2cdc228d2..a7ad30d43 100644 --- a/commons/src/main/java/net/swofty/commons/friend/FriendData.java +++ b/commons/src/main/java/net/swofty/commons/friend/FriendData.java @@ -4,9 +4,8 @@ import com.fasterxml.jackson.annotation.JsonProperty; import lombok.Getter; import lombok.Setter; +import net.swofty.commons.protocol.JacksonSerializer; import net.swofty.commons.protocol.Serializer; -import org.json.JSONArray; -import org.json.JSONObject; import java.util.ArrayList; import java.util.List; @@ -14,6 +13,8 @@ @Getter public class FriendData { + private static final Serializer SERIALIZER = new JacksonSerializer<>(FriendData.class); + private final UUID playerUuid; private final List friends; @Setter @@ -71,57 +72,10 @@ public void removeAllNonBestFriends() { } public static Serializer getStaticSerializer() { - return createEmpty(UUID.randomUUID()).getSerializer(); + return SERIALIZER; } public Serializer getSerializer() { - return new Serializer<>() { - @Override - public String serialize(FriendData value) { - JSONObject json = new JSONObject(); - json.put("playerUuid", value.playerUuid.toString()); - - JSONArray friendsArray = new JSONArray(); - for (Friend friend : value.friends) { - friendsArray.put(new JSONObject(friend.getSerializer().serialize(friend))); - } - json.put("friends", friendsArray); - - json.put("settings", new JSONObject(value.settings.getSerializer().serialize(value.settings))); - return json.toString(); - } - - @Override - public FriendData deserialize(String json) { - JSONObject jsonObject = new JSONObject(json); - UUID playerUuid = UUID.fromString(jsonObject.getString("playerUuid")); - - List friends = new ArrayList<>(); - JSONArray friendsArray = jsonObject.getJSONArray("friends"); - Serializer friendSerializer = Friend.getStaticSerializer(); - for (int i = 0; i < friendsArray.length(); i++) { - friends.add(friendSerializer.deserialize(friendsArray.getJSONObject(i).toString())); - } - - FriendSettings settings = FriendSettings.getStaticSerializer() - .deserialize(jsonObject.getJSONObject("settings").toString()); - - return new FriendData(playerUuid, friends, settings); - } - - @Override - public FriendData clone(FriendData value) { - List clonedFriends = new ArrayList<>(); - Serializer friendSerializer = Friend.getStaticSerializer(); - for (Friend friend : value.friends) { - clonedFriends.add(friendSerializer.clone(friend)); - } - return new FriendData( - value.playerUuid, - clonedFriends, - value.settings.getSerializer().clone(value.settings) - ); - } - }; + return SERIALIZER; } } diff --git a/commons/src/main/java/net/swofty/commons/friend/FriendSettings.java b/commons/src/main/java/net/swofty/commons/friend/FriendSettings.java index 3e96e150a..8e12b2dad 100644 --- a/commons/src/main/java/net/swofty/commons/friend/FriendSettings.java +++ b/commons/src/main/java/net/swofty/commons/friend/FriendSettings.java @@ -4,12 +4,14 @@ import com.fasterxml.jackson.annotation.JsonProperty; import lombok.Getter; import lombok.Setter; +import net.swofty.commons.protocol.JacksonSerializer; import net.swofty.commons.protocol.Serializer; -import org.json.JSONObject; @Getter @Setter public class FriendSettings { + private static final Serializer SERIALIZER = new JacksonSerializer<>(FriendSettings.class); + private boolean acceptingRequests; private boolean joinLeaveNotifications; @@ -26,32 +28,10 @@ public static FriendSettings createDefault() { } public static Serializer getStaticSerializer() { - return createDefault().getSerializer(); + return SERIALIZER; } public Serializer getSerializer() { - return new Serializer<>() { - @Override - public String serialize(FriendSettings value) { - JSONObject json = new JSONObject(); - json.put("acceptingRequests", value.acceptingRequests); - json.put("joinLeaveNotifications", value.joinLeaveNotifications); - return json.toString(); - } - - @Override - public FriendSettings deserialize(String json) { - JSONObject jsonObject = new JSONObject(json); - return new FriendSettings( - jsonObject.getBoolean("acceptingRequests"), - jsonObject.getBoolean("joinLeaveNotifications") - ); - } - - @Override - public FriendSettings clone(FriendSettings value) { - return new FriendSettings(value.acceptingRequests, value.joinLeaveNotifications); - } - }; + return SERIALIZER; } } From bcc2f2aacd4dc02a3d3c63055040dc4df353b622 Mon Sep 17 00:00:00 2001 From: "Jacob Nardella (Swofty)" Date: Fri, 15 May 2026 01:35:01 +1000 Subject: [PATCH 074/113] refactor(presence): migrate PresenceInfo to JacksonSerializer --- .../swofty/commons/presence/PresenceInfo.java | 34 +++---------------- 1 file changed, 4 insertions(+), 30 deletions(-) diff --git a/commons/src/main/java/net/swofty/commons/presence/PresenceInfo.java b/commons/src/main/java/net/swofty/commons/presence/PresenceInfo.java index cacacd1f0..522972cea 100644 --- a/commons/src/main/java/net/swofty/commons/presence/PresenceInfo.java +++ b/commons/src/main/java/net/swofty/commons/presence/PresenceInfo.java @@ -3,13 +3,15 @@ import com.fasterxml.jackson.annotation.JsonCreator; import com.fasterxml.jackson.annotation.JsonProperty; import lombok.Getter; +import net.swofty.commons.protocol.JacksonSerializer; import net.swofty.commons.protocol.Serializer; -import org.json.JSONObject; import java.util.UUID; @Getter public class PresenceInfo { + private static final Serializer SERIALIZER = new JacksonSerializer<>(PresenceInfo.class); + private final UUID uuid; private final boolean online; private final String serverType; @@ -31,34 +33,6 @@ public PresenceInfo( } public static Serializer getSerializer() { - return new Serializer<>() { - @Override - public String serialize(PresenceInfo value) { - JSONObject json = new JSONObject(); - json.put("uuid", value.uuid.toString()); - json.put("online", value.online); - json.put("serverType", value.serverType != null ? value.serverType : JSONObject.NULL); - json.put("serverId", value.serverId != null ? value.serverId : JSONObject.NULL); - json.put("lastSeen", value.lastSeen); - return json.toString(); - } - - @Override - public PresenceInfo deserialize(String json) { - JSONObject jsonObject = new JSONObject(json); - return new PresenceInfo( - UUID.fromString(jsonObject.getString("uuid")), - jsonObject.getBoolean("online"), - jsonObject.isNull("serverType") ? null : jsonObject.getString("serverType"), - jsonObject.isNull("serverId") ? null : jsonObject.getString("serverId"), - jsonObject.getLong("lastSeen") - ); - } - - @Override - public PresenceInfo clone(PresenceInfo value) { - return new PresenceInfo(value.uuid, value.online, value.serverType, value.serverId, value.lastSeen); - } - }; + return SERIALIZER; } } From 7346d750d2c94c123db2445064a4f3e089504ba0 Mon Sep 17 00:00:00 2001 From: "Jacob Nardella (Swofty)" Date: Fri, 15 May 2026 01:37:19 +1000 Subject: [PATCH 075/113] refactor(darkauction): migrate 5 protocol objects to JacksonSerializer MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Same migration pattern as the friend module — every protocol object had hand-rolled inner Serializers that walked org.json.JSONObject field-by-field for both Message and Response. With records as the payload types, JacksonSerializer<>(T.class) round-trips by the canonical constructor for free. Migrated: - PlayerLeftAuctionProtocol - PlaceBidProtocol - TriggerDarkAuctionProtocol - GetAuctionStateProtocol - DarkAuctionEventProtocol Net deletion across the five files is ~330 lines of boilerplate. --- .../darkauction/DarkAuctionEventProtocol.java | 108 ++---------------- .../darkauction/GetAuctionStateProtocol.java | 98 ++-------------- .../objects/darkauction/PlaceBidProtocol.java | 63 ++-------- .../PlayerLeftAuctionProtocol.java | 67 ++--------- .../TriggerDarkAuctionProtocol.java | 56 ++------- 5 files changed, 46 insertions(+), 346 deletions(-) diff --git a/commons/src/main/java/net/swofty/commons/protocol/objects/darkauction/DarkAuctionEventProtocol.java b/commons/src/main/java/net/swofty/commons/protocol/objects/darkauction/DarkAuctionEventProtocol.java index cbddc1e1d..3152da4fc 100644 --- a/commons/src/main/java/net/swofty/commons/protocol/objects/darkauction/DarkAuctionEventProtocol.java +++ b/commons/src/main/java/net/swofty/commons/protocol/objects/darkauction/DarkAuctionEventProtocol.java @@ -1,15 +1,13 @@ package net.swofty.commons.protocol.objects.darkauction; -import net.swofty.commons.skyblock.auctions.DarkAuctionPhase; +import net.swofty.commons.protocol.JacksonSerializer; import net.swofty.commons.protocol.ProtocolObject; import net.swofty.commons.protocol.Serializer; -import org.json.JSONArray; -import org.json.JSONObject; +import net.swofty.commons.skyblock.auctions.DarkAuctionPhase; +import org.jetbrains.annotations.Nullable; -import java.util.ArrayList; import java.util.List; import java.util.UUID; -import org.jetbrains.annotations.Nullable; public class DarkAuctionEventProtocol extends ProtocolObject< DarkAuctionEventProtocol.DarkAuctionMessage, @@ -24,105 +22,19 @@ public enum EventType { AUCTION_END // Auction complete, cleanup } + private static final Serializer MESSAGE_SERIALIZER = + new JacksonSerializer<>(DarkAuctionMessage.class); + private static final Serializer RESPONSE_SERIALIZER = + new JacksonSerializer<>(DarkAuctionResponse.class); + @Override public Serializer getSerializer() { - return new Serializer<>() { - @Override - public String serialize(DarkAuctionMessage value) { - JSONObject json = new JSONObject(); - json.put("eventType", value.eventType.name()); - json.put("auctionId", value.auctionId.toString()); - json.put("phase", value.phase.name()); - json.put("currentRound", value.currentRound); - json.put("currentItemType", value.currentItemType); - json.put("currentBid", value.currentBid); - json.put("highestBidderId", value.highestBidderId != null ? value.highestBidderId.toString() : null); - json.put("highestBidderName", value.highestBidderName); - json.put("countdown", value.countdown); - - JSONArray itemsArray = new JSONArray(); - for (String item : value.roundItems) { - itemsArray.put(item); - } - json.put("roundItems", itemsArray); - - // Refund info for BID_PLACED events - json.put("refundPlayerId", value.refundPlayerId != null ? value.refundPlayerId.toString() : null); - json.put("refundAmount", value.refundAmount); - - return json.toString(); - } - - @Override - public DarkAuctionMessage deserialize(String json) { - JSONObject jsonObject = new JSONObject(json); - - EventType eventType = EventType.valueOf(jsonObject.getString("eventType")); - UUID auctionId = UUID.fromString(jsonObject.getString("auctionId")); - DarkAuctionPhase phase = DarkAuctionPhase.valueOf(jsonObject.getString("phase")); - int currentRound = jsonObject.getInt("currentRound"); - String currentItemType = jsonObject.optString("currentItemType", null); - long currentBid = jsonObject.getLong("currentBid"); - - String bidderIdStr = jsonObject.optString("highestBidderId", null); - UUID highestBidderId = bidderIdStr != null && !bidderIdStr.equals("null") ? UUID.fromString(bidderIdStr) : null; - String highestBidderName = jsonObject.optString("highestBidderName", null); - int countdown = jsonObject.getInt("countdown"); - - List roundItems = new ArrayList<>(); - JSONArray itemsArray = jsonObject.optJSONArray("roundItems"); - if (itemsArray != null) { - for (int i = 0; i < itemsArray.length(); i++) { - roundItems.add(itemsArray.getString(i)); - } - } - - String refundPlayerIdStr = jsonObject.optString("refundPlayerId", null); - UUID refundPlayerId = refundPlayerIdStr != null && !refundPlayerIdStr.equals("null") ? UUID.fromString(refundPlayerIdStr) : null; - long refundAmount = jsonObject.optLong("refundAmount", 0); - - return new DarkAuctionMessage(eventType, auctionId, phase, currentRound, currentItemType, - currentBid, highestBidderId, highestBidderName, countdown, roundItems, - refundPlayerId, refundAmount); - } - - @Override - public DarkAuctionMessage clone(DarkAuctionMessage value) { - return new DarkAuctionMessage(value.eventType, value.auctionId, value.phase, value.currentRound, - value.currentItemType, value.currentBid, value.highestBidderId, - value.highestBidderName, value.countdown, new ArrayList<>(value.roundItems), - value.refundPlayerId, value.refundAmount); - } - }; + return MESSAGE_SERIALIZER; } @Override public Serializer getReturnSerializer() { - return new Serializer<>() { - @Override - public String serialize(DarkAuctionResponse value) { - JSONObject json = new JSONObject(); - json.put("success", value.success); - json.put("playersInAuction", value.playersInAuction); - json.put("error", value.error); - return json.toString(); - } - - @Override - public DarkAuctionResponse deserialize(String json) { - JSONObject jsonObject = new JSONObject(json); - return new DarkAuctionResponse( - jsonObject.getBoolean("success"), - jsonObject.getInt("playersInAuction"), - jsonObject.optString("error", null) - ); - } - - @Override - public DarkAuctionResponse clone(DarkAuctionResponse value) { - return new DarkAuctionResponse(value.success, value.playersInAuction, value.error); - } - }; + return RESPONSE_SERIALIZER; } public record DarkAuctionMessage( diff --git a/commons/src/main/java/net/swofty/commons/protocol/objects/darkauction/GetAuctionStateProtocol.java b/commons/src/main/java/net/swofty/commons/protocol/objects/darkauction/GetAuctionStateProtocol.java index 410055545..6ecb8a7fd 100644 --- a/commons/src/main/java/net/swofty/commons/protocol/objects/darkauction/GetAuctionStateProtocol.java +++ b/commons/src/main/java/net/swofty/commons/protocol/objects/darkauction/GetAuctionStateProtocol.java @@ -1,109 +1,31 @@ package net.swofty.commons.protocol.objects.darkauction; -import net.swofty.commons.skyblock.auctions.DarkAuctionPhase; +import net.swofty.commons.protocol.JacksonSerializer; import net.swofty.commons.protocol.ProtocolObject; import net.swofty.commons.protocol.Serializer; -import org.json.JSONArray; -import org.json.JSONObject; +import net.swofty.commons.skyblock.auctions.DarkAuctionPhase; +import org.jetbrains.annotations.Nullable; -import java.util.ArrayList; import java.util.List; import java.util.UUID; -import org.jetbrains.annotations.Nullable; public class GetAuctionStateProtocol extends ProtocolObject< GetAuctionStateProtocol.GetAuctionStateMessage, GetAuctionStateProtocol.GetAuctionStateResponse> { + private static final Serializer MESSAGE_SERIALIZER = + new JacksonSerializer<>(GetAuctionStateMessage.class); + private static final Serializer RESPONSE_SERIALIZER = + new JacksonSerializer<>(GetAuctionStateResponse.class); + @Override public Serializer getSerializer() { - return new Serializer<>() { - @Override - public String serialize(GetAuctionStateMessage value) { - return ""; - } - - @Override - public GetAuctionStateMessage deserialize(String json) { - return new GetAuctionStateMessage(); - } - - @Override - public GetAuctionStateMessage clone(GetAuctionStateMessage value) { - return new GetAuctionStateMessage(); - } - }; + return MESSAGE_SERIALIZER; } @Override public Serializer getReturnSerializer() { - return new Serializer<>() { - @Override - public String serialize(GetAuctionStateResponse value) { - JSONObject json = new JSONObject(); - json.put("auctionActive", value.auctionActive); - json.put("success", value.success); - json.put("error", value.error); - if (value.auctionActive) { - json.put("auctionId", value.auctionId.toString()); - json.put("phase", value.phase.toString()); - json.put("currentRound", value.currentRound); - json.put("currentItemType", value.currentItemType); - json.put("currentBid", value.currentBid); - json.put("highestBidderId", value.highestBidderId != null ? value.highestBidderId.toString() : null); - json.put("highestBidderName", value.highestBidderName); - - JSONArray itemsArray = new JSONArray(); - for (String item : value.roundItems) { - itemsArray.put(item); - } - json.put("roundItems", itemsArray); - } - return json.toString(); - } - - @Override - public GetAuctionStateResponse deserialize(String json) { - JSONObject jsonObject = new JSONObject(json); - boolean auctionActive = jsonObject.getBoolean("auctionActive"); - boolean success = jsonObject.optBoolean("success", true); - String error = jsonObject.optString("error", null); - if ("null".equals(error)) error = null; - - if (!auctionActive) { - return new GetAuctionStateResponse(false, null, null, 0, null, 0, null, null, List.of(), success, error); - } - - UUID auctionId = UUID.fromString(jsonObject.getString("auctionId")); - String phase = jsonObject.getString("phase"); - int currentRound = jsonObject.getInt("currentRound"); - String currentItemType = jsonObject.optString("currentItemType", null); - long currentBid = jsonObject.getLong("currentBid"); - - String bidderIdStr = jsonObject.optString("highestBidderId", null); - UUID highestBidderId = bidderIdStr != null && !bidderIdStr.equals("null") ? UUID.fromString(bidderIdStr) : null; - String highestBidderName = jsonObject.optString("highestBidderName", null); - - List roundItems = new ArrayList<>(); - JSONArray itemsArray = jsonObject.optJSONArray("roundItems"); - if (itemsArray != null) { - for (int i = 0; i < itemsArray.length(); i++) { - roundItems.add(itemsArray.getString(i)); - } - } - - return new GetAuctionStateResponse(true, auctionId, DarkAuctionPhase.valueOf(phase), currentRound, currentItemType, - currentBid, highestBidderId, highestBidderName, roundItems, success, error); - } - - @Override - public GetAuctionStateResponse clone(GetAuctionStateResponse value) { - return new GetAuctionStateResponse(value.auctionActive, value.auctionId, value.phase, - value.currentRound, value.currentItemType, value.currentBid, - value.highestBidderId, value.highestBidderName, new ArrayList<>(value.roundItems), - value.success, value.error); - } - }; + return RESPONSE_SERIALIZER; } public record GetAuctionStateMessage() {} diff --git a/commons/src/main/java/net/swofty/commons/protocol/objects/darkauction/PlaceBidProtocol.java b/commons/src/main/java/net/swofty/commons/protocol/objects/darkauction/PlaceBidProtocol.java index d5d3245b2..22fbc9386 100644 --- a/commons/src/main/java/net/swofty/commons/protocol/objects/darkauction/PlaceBidProtocol.java +++ b/commons/src/main/java/net/swofty/commons/protocol/objects/darkauction/PlaceBidProtocol.java @@ -1,74 +1,29 @@ package net.swofty.commons.protocol.objects.darkauction; +import net.swofty.commons.protocol.JacksonSerializer; import net.swofty.commons.protocol.ProtocolObject; import net.swofty.commons.protocol.Serializer; -import org.json.JSONObject; +import org.jetbrains.annotations.Nullable; import java.util.UUID; -import org.jetbrains.annotations.Nullable; public class PlaceBidProtocol extends ProtocolObject< PlaceBidProtocol.PlaceBidMessage, PlaceBidProtocol.PlaceBidResponse> { + private static final Serializer MESSAGE_SERIALIZER = + new JacksonSerializer<>(PlaceBidMessage.class); + private static final Serializer RESPONSE_SERIALIZER = + new JacksonSerializer<>(PlaceBidResponse.class); + @Override public Serializer getSerializer() { - return new Serializer<>() { - @Override - public String serialize(PlaceBidMessage value) { - JSONObject json = new JSONObject(); - json.put("auctionId", value.auctionId.toString()); - json.put("playerId", value.playerId.toString()); - json.put("playerName", value.playerName); - json.put("bidAmount", value.bidAmount); - return json.toString(); - } - - @Override - public PlaceBidMessage deserialize(String json) { - JSONObject jsonObject = new JSONObject(json); - return new PlaceBidMessage( - UUID.fromString(jsonObject.getString("auctionId")), - UUID.fromString(jsonObject.getString("playerId")), - jsonObject.getString("playerName"), - jsonObject.getLong("bidAmount") - ); - } - - @Override - public PlaceBidMessage clone(PlaceBidMessage value) { - return new PlaceBidMessage(value.auctionId, value.playerId, value.playerName, value.bidAmount); - } - }; + return MESSAGE_SERIALIZER; } @Override public Serializer getReturnSerializer() { - return new Serializer<>() { - @Override - public String serialize(PlaceBidResponse value) { - JSONObject json = new JSONObject(); - json.put("success", value.success); - json.put("message", value.message); - json.put("error", value.error); - return json.toString(); - } - - @Override - public PlaceBidResponse deserialize(String json) { - JSONObject jsonObject = new JSONObject(json); - return new PlaceBidResponse( - jsonObject.getBoolean("success"), - jsonObject.getString("message"), - jsonObject.optString("error", null) - ); - } - - @Override - public PlaceBidResponse clone(PlaceBidResponse value) { - return new PlaceBidResponse(value.success, value.message, value.error); - } - }; + return RESPONSE_SERIALIZER; } public record PlaceBidMessage( diff --git a/commons/src/main/java/net/swofty/commons/protocol/objects/darkauction/PlayerLeftAuctionProtocol.java b/commons/src/main/java/net/swofty/commons/protocol/objects/darkauction/PlayerLeftAuctionProtocol.java index c6cb6c604..15b250d00 100644 --- a/commons/src/main/java/net/swofty/commons/protocol/objects/darkauction/PlayerLeftAuctionProtocol.java +++ b/commons/src/main/java/net/swofty/commons/protocol/objects/darkauction/PlayerLeftAuctionProtocol.java @@ -1,78 +1,29 @@ package net.swofty.commons.protocol.objects.darkauction; +import net.swofty.commons.protocol.JacksonSerializer; import net.swofty.commons.protocol.ProtocolObject; import net.swofty.commons.protocol.Serializer; -import org.json.JSONObject; +import org.jetbrains.annotations.Nullable; import java.util.UUID; -import org.jetbrains.annotations.Nullable; public class PlayerLeftAuctionProtocol extends ProtocolObject< PlayerLeftAuctionProtocol.PlayerLeftMessage, PlayerLeftAuctionProtocol.PlayerLeftResponse> { + private static final Serializer MESSAGE_SERIALIZER = + new JacksonSerializer<>(PlayerLeftMessage.class); + private static final Serializer RESPONSE_SERIALIZER = + new JacksonSerializer<>(PlayerLeftResponse.class); + @Override public Serializer getSerializer() { - return new Serializer<>() { - @Override - public String serialize(PlayerLeftMessage value) { - JSONObject json = new JSONObject(); - json.put("playerId", value.playerId.toString()); - json.put("playerName", value.playerName); - if (value.auctionId != null) { - json.put("auctionId", value.auctionId.toString()); - } - return json.toString(); - } - - @Override - public PlayerLeftMessage deserialize(String json) { - JSONObject jsonObject = new JSONObject(json); - UUID auctionId = null; - if (jsonObject.has("auctionId") && !jsonObject.isNull("auctionId")) { - auctionId = UUID.fromString(jsonObject.getString("auctionId")); - } - return new PlayerLeftMessage( - UUID.fromString(jsonObject.getString("playerId")), - jsonObject.getString("playerName"), - auctionId - ); - } - - @Override - public PlayerLeftMessage clone(PlayerLeftMessage value) { - return new PlayerLeftMessage(value.playerId, value.playerName, value.auctionId); - } - }; + return MESSAGE_SERIALIZER; } @Override public Serializer getReturnSerializer() { - return new Serializer<>() { - @Override - public String serialize(PlayerLeftResponse value) { - JSONObject json = new JSONObject(); - json.put("success", value.success); - json.put("refundAmount", value.refundAmount); - json.put("error", value.error); - return json.toString(); - } - - @Override - public PlayerLeftResponse deserialize(String json) { - JSONObject jsonObject = new JSONObject(json); - return new PlayerLeftResponse( - jsonObject.getBoolean("success"), - jsonObject.getLong("refundAmount"), - jsonObject.optString("error", null) - ); - } - - @Override - public PlayerLeftResponse clone(PlayerLeftResponse value) { - return new PlayerLeftResponse(value.success, value.refundAmount, value.error); - } - }; + return RESPONSE_SERIALIZER; } public record PlayerLeftMessage( diff --git a/commons/src/main/java/net/swofty/commons/protocol/objects/darkauction/TriggerDarkAuctionProtocol.java b/commons/src/main/java/net/swofty/commons/protocol/objects/darkauction/TriggerDarkAuctionProtocol.java index 78abaaee1..7318f40d9 100644 --- a/commons/src/main/java/net/swofty/commons/protocol/objects/darkauction/TriggerDarkAuctionProtocol.java +++ b/commons/src/main/java/net/swofty/commons/protocol/objects/darkauction/TriggerDarkAuctionProtocol.java @@ -1,67 +1,27 @@ package net.swofty.commons.protocol.objects.darkauction; +import net.swofty.commons.protocol.JacksonSerializer; import net.swofty.commons.protocol.ProtocolObject; import net.swofty.commons.protocol.Serializer; -import org.json.JSONObject; import org.jetbrains.annotations.Nullable; public class TriggerDarkAuctionProtocol extends ProtocolObject< TriggerDarkAuctionProtocol.TriggerMessage, TriggerDarkAuctionProtocol.TriggerResponse> { + private static final Serializer MESSAGE_SERIALIZER = + new JacksonSerializer<>(TriggerMessage.class); + private static final Serializer RESPONSE_SERIALIZER = + new JacksonSerializer<>(TriggerResponse.class); + @Override public Serializer getSerializer() { - return new Serializer<>() { - @Override - public String serialize(TriggerMessage value) { - JSONObject json = new JSONObject(); - json.put("calendarTime", value.calendarTime); - json.put("forced", value.forced); - return json.toString(); - } - - @Override - public TriggerMessage deserialize(String json) { - JSONObject jsonObject = new JSONObject(json); - long calendarTime = jsonObject.optLong("calendarTime", 0); - boolean forced = jsonObject.optBoolean("forced", false); - return new TriggerMessage(calendarTime, forced); - } - - @Override - public TriggerMessage clone(TriggerMessage value) { - return new TriggerMessage(value.calendarTime, value.forced); - } - }; + return MESSAGE_SERIALIZER; } @Override public Serializer getReturnSerializer() { - return new Serializer<>() { - @Override - public String serialize(TriggerResponse value) { - JSONObject json = new JSONObject(); - json.put("success", value.success); - json.put("message", value.message); - json.put("error", value.error); - return json.toString(); - } - - @Override - public TriggerResponse deserialize(String json) { - JSONObject jsonObject = new JSONObject(json); - boolean success = jsonObject.getBoolean("success"); - String message = jsonObject.optString("message", ""); - String error = jsonObject.optString("error", null); - if ("null".equals(error)) error = null; - return new TriggerResponse(success, message, error); - } - - @Override - public TriggerResponse clone(TriggerResponse value) { - return new TriggerResponse(value.success, value.message, value.error); - } - }; + return RESPONSE_SERIALIZER; } public record TriggerMessage(long calendarTime, boolean forced) { From ba0d358640e0f70a9195fb30e231a8f40265e825 Mon Sep 17 00:00:00 2001 From: "Jacob Nardella (Swofty)" Date: Fri, 15 May 2026 01:40:27 +1000 Subject: [PATCH 076/113] perf(protocol): hoist JacksonSerializer instances to static fields MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 45 ProtocolObject subclasses created a brand-new JacksonSerializer on every getSerializer() / getReturnSerializer() call. Each allocation builds a fresh ObjectMapper view internally — wasteful for serializers that are stateless after construction. Lifted them to static final fields named SERIALIZER and RETURN_SERIALIZER per ProtocolObject. The instance methods now just return the field. Same wire format, one allocation amortised across all calls. --- .../commons/protocol/objects/PingProtocolObject.java | 8 ++++++-- .../objects/auctions/AuctionFetchItemProtocolObject.java | 8 ++++++-- .../objects/auctions/AuctionFetchItemsProtocolObject.java | 8 ++++++-- .../objects/bazaar/BazaarCancelProtocolObject.java | 8 ++++++-- .../objects/bazaar/BazaarGetItemProtocolObject.java | 8 ++++++-- .../bazaar/BazaarGetPendingOrdersProtocolObject.java | 8 ++++++-- .../BazaarGetPendingTransactionsProtocolObject.java | 8 ++++++-- .../BazaarProcessPendingTransactionsProtocolObject.java | 8 ++++++-- .../protocol/objects/bazaar/BazaarSellProtocolObject.java | 8 ++++++-- .../objects/datamutex/SynchronizeDataProtocolObject.java | 8 ++++++-- .../objects/datamutex/UnlockDataProtocolObject.java | 8 ++++++-- .../datamutex/UpdateSynchronizedDataProtocolObject.java | 8 ++++++-- .../protocol/objects/election/CastVoteProtocolObject.java | 8 ++++++-- .../objects/election/GetCandidatesProtocolObject.java | 8 ++++++-- .../objects/election/GetElectionDataProtocolObject.java | 8 ++++++-- .../objects/election/GetPlayerVoteProtocolObject.java | 8 ++++++-- .../objects/election/ResolveElectionProtocolObject.java | 8 ++++++-- .../objects/election/StartElectionProtocolObject.java | 8 ++++++-- .../itemtracker/TrackedItemUpdateProtocolObject.java | 8 ++++++-- .../objects/orchestrator/RejoinGameProtocolObject.java | 8 ++++++-- .../objects/party/SendPartyActionProtocolObject.java | 8 ++++++-- .../objects/presence/GetPresenceBulkProtocolObject.java | 8 ++++++-- .../objects/presence/UpdatePresenceProtocolObject.java | 8 ++++++-- .../objects/proxy/from/BroadcastStaffChatProtocol.java | 8 ++++++-- .../objects/proxy/from/DoesServerHaveIslandProtocol.java | 8 ++++++-- .../objects/proxy/from/GivePlayersOriginTypeProtocol.java | 8 ++++++-- .../protocol/objects/proxy/from/PingServerProtocol.java | 8 ++++++-- .../objects/proxy/from/PlayerSwitchedProtocol.java | 8 ++++++-- .../objects/proxy/from/RefreshCoopDataProtocol.java | 8 ++++++-- .../protocol/objects/proxy/from/RunEventProtocol.java | 8 ++++++-- .../protocol/objects/proxy/from/TeleportProtocol.java | 8 ++++++-- .../objects/proxy/to/FinishedWithPlayerProtocol.java | 8 ++++++-- .../protocol/objects/proxy/to/PlayerCountProtocol.java | 8 ++++++-- .../protocol/objects/proxy/to/PlayerHandlerProtocol.java | 8 ++++++-- .../protocol/objects/proxy/to/ProxyIsOnlineProtocol.java | 8 ++++++-- .../protocol/objects/proxy/to/PunishPlayerProtocol.java | 8 ++++++-- .../protocol/objects/proxy/to/RegisterServerProtocol.java | 8 ++++++-- .../objects/proxy/to/RegisterTestFlowProtocol.java | 8 ++++++-- .../objects/proxy/to/RequestServerNameProtocol.java | 8 ++++++-- .../protocol/objects/proxy/to/RequestServersProtocol.java | 8 ++++++-- .../protocol/objects/proxy/to/StaffChatProtocol.java | 8 ++++++-- .../objects/proxy/to/TestFlowServerReadyProtocol.java | 8 ++++++-- .../punishment/GetActivePunishmentProtocolObject.java | 8 ++++++-- .../objects/punishment/PunishPlayerProtocolObject.java | 8 ++++++-- .../objects/punishment/UnpunishPlayerProtocolObject.java | 8 ++++++-- 45 files changed, 270 insertions(+), 90 deletions(-) diff --git a/commons/src/main/java/net/swofty/commons/protocol/objects/PingProtocolObject.java b/commons/src/main/java/net/swofty/commons/protocol/objects/PingProtocolObject.java index 59f8645d4..968108879 100644 --- a/commons/src/main/java/net/swofty/commons/protocol/objects/PingProtocolObject.java +++ b/commons/src/main/java/net/swofty/commons/protocol/objects/PingProtocolObject.java @@ -7,15 +7,19 @@ public class PingProtocolObject extends ProtocolObject< PingProtocolObject.EmptyMessage, PingProtocolObject.EmptyMessage> { + private static final Serializer SERIALIZER = + new JacksonSerializer<>(EmptyMessage.class); + private static final Serializer RETURN_SERIALIZER = + new JacksonSerializer<>(EmptyMessage.class); @Override public Serializer getSerializer() { - return new JacksonSerializer<>(EmptyMessage.class); + return SERIALIZER; } @Override public Serializer getReturnSerializer() { - return new JacksonSerializer<>(EmptyMessage.class); + return RETURN_SERIALIZER; } public record EmptyMessage() {} diff --git a/commons/src/main/java/net/swofty/commons/protocol/objects/auctions/AuctionFetchItemProtocolObject.java b/commons/src/main/java/net/swofty/commons/protocol/objects/auctions/AuctionFetchItemProtocolObject.java index aee64d73f..61e99acbf 100644 --- a/commons/src/main/java/net/swofty/commons/protocol/objects/auctions/AuctionFetchItemProtocolObject.java +++ b/commons/src/main/java/net/swofty/commons/protocol/objects/auctions/AuctionFetchItemProtocolObject.java @@ -11,15 +11,19 @@ public class AuctionFetchItemProtocolObject extends ProtocolObject< AuctionFetchItemProtocolObject.AuctionFetchItemMessage, AuctionFetchItemProtocolObject.AuctionFetchItemResponse> { + private static final Serializer SERIALIZER = + new JacksonSerializer<>(AuctionFetchItemMessage.class); + private static final Serializer RETURN_SERIALIZER = + new JacksonSerializer<>(AuctionFetchItemResponse.class); @Override public Serializer getSerializer() { - return new JacksonSerializer<>(AuctionFetchItemMessage.class); + return SERIALIZER; } @Override public Serializer getReturnSerializer() { - return new JacksonSerializer<>(AuctionFetchItemResponse.class); + return RETURN_SERIALIZER; } public record AuctionFetchItemMessage(UUID uuid) {} diff --git a/commons/src/main/java/net/swofty/commons/protocol/objects/auctions/AuctionFetchItemsProtocolObject.java b/commons/src/main/java/net/swofty/commons/protocol/objects/auctions/AuctionFetchItemsProtocolObject.java index 4376c6d33..95593a691 100644 --- a/commons/src/main/java/net/swofty/commons/protocol/objects/auctions/AuctionFetchItemsProtocolObject.java +++ b/commons/src/main/java/net/swofty/commons/protocol/objects/auctions/AuctionFetchItemsProtocolObject.java @@ -14,15 +14,19 @@ public class AuctionFetchItemsProtocolObject extends ProtocolObject< AuctionFetchItemsProtocolObject.AuctionFetchItemsMessage, AuctionFetchItemsProtocolObject.AuctionFetchItemsResponse> { + private static final Serializer SERIALIZER = + new JacksonSerializer<>(AuctionFetchItemsMessage.class); + private static final Serializer RETURN_SERIALIZER = + new JacksonSerializer<>(AuctionFetchItemsResponse.class); @Override public Serializer getSerializer() { - return new JacksonSerializer<>(AuctionFetchItemsMessage.class); + return SERIALIZER; } @Override public Serializer getReturnSerializer() { - return new JacksonSerializer<>(AuctionFetchItemsResponse.class); + return RETURN_SERIALIZER; } public record AuctionFetchItemsMessage( diff --git a/commons/src/main/java/net/swofty/commons/protocol/objects/bazaar/BazaarCancelProtocolObject.java b/commons/src/main/java/net/swofty/commons/protocol/objects/bazaar/BazaarCancelProtocolObject.java index 1f3fe2252..3a514efa0 100644 --- a/commons/src/main/java/net/swofty/commons/protocol/objects/bazaar/BazaarCancelProtocolObject.java +++ b/commons/src/main/java/net/swofty/commons/protocol/objects/bazaar/BazaarCancelProtocolObject.java @@ -10,15 +10,19 @@ public class BazaarCancelProtocolObject extends ProtocolObject< BazaarCancelProtocolObject.CancelMessage, BazaarCancelProtocolObject.CancelResponse> { + private static final Serializer SERIALIZER = + new JacksonSerializer<>(CancelMessage.class); + private static final Serializer RETURN_SERIALIZER = + new JacksonSerializer<>(CancelResponse.class); @Override public Serializer getSerializer() { - return new JacksonSerializer<>(CancelMessage.class); + return SERIALIZER; } @Override public Serializer getReturnSerializer() { - return new JacksonSerializer<>(CancelResponse.class); + return RETURN_SERIALIZER; } public record CancelMessage(UUID orderId, UUID playerUuid, UUID profileUuid) {} diff --git a/commons/src/main/java/net/swofty/commons/protocol/objects/bazaar/BazaarGetItemProtocolObject.java b/commons/src/main/java/net/swofty/commons/protocol/objects/bazaar/BazaarGetItemProtocolObject.java index 6eef19f80..03b0964a2 100644 --- a/commons/src/main/java/net/swofty/commons/protocol/objects/bazaar/BazaarGetItemProtocolObject.java +++ b/commons/src/main/java/net/swofty/commons/protocol/objects/bazaar/BazaarGetItemProtocolObject.java @@ -11,15 +11,19 @@ public class BazaarGetItemProtocolObject extends ProtocolObject< BazaarGetItemProtocolObject.BazaarGetItemMessage, BazaarGetItemProtocolObject.BazaarGetItemResponse> { + private static final Serializer SERIALIZER = + new JacksonSerializer<>(BazaarGetItemMessage.class); + private static final Serializer RETURN_SERIALIZER = + new JacksonSerializer<>(BazaarGetItemResponse.class); @Override public Serializer getSerializer() { - return new JacksonSerializer<>(BazaarGetItemMessage.class); + return SERIALIZER; } @Override public Serializer getReturnSerializer() { - return new JacksonSerializer<>(BazaarGetItemResponse.class); + return RETURN_SERIALIZER; } public record BazaarGetItemMessage(String itemName) {} diff --git a/commons/src/main/java/net/swofty/commons/protocol/objects/bazaar/BazaarGetPendingOrdersProtocolObject.java b/commons/src/main/java/net/swofty/commons/protocol/objects/bazaar/BazaarGetPendingOrdersProtocolObject.java index c3c12b2c7..74113dda2 100644 --- a/commons/src/main/java/net/swofty/commons/protocol/objects/bazaar/BazaarGetPendingOrdersProtocolObject.java +++ b/commons/src/main/java/net/swofty/commons/protocol/objects/bazaar/BazaarGetPendingOrdersProtocolObject.java @@ -12,15 +12,19 @@ public class BazaarGetPendingOrdersProtocolObject extends ProtocolObject< BazaarGetPendingOrdersProtocolObject.BazaarGetPendingOrdersMessage, BazaarGetPendingOrdersProtocolObject.BazaarGetPendingOrdersResponse> { + private static final Serializer SERIALIZER = + new JacksonSerializer<>(BazaarGetPendingOrdersMessage.class); + private static final Serializer RETURN_SERIALIZER = + new JacksonSerializer<>(BazaarGetPendingOrdersResponse.class); @Override public Serializer getSerializer() { - return new JacksonSerializer<>(BazaarGetPendingOrdersMessage.class); + return SERIALIZER; } @Override public Serializer getReturnSerializer() { - return new JacksonSerializer<>(BazaarGetPendingOrdersResponse.class); + return RETURN_SERIALIZER; } public record BazaarGetPendingOrdersMessage(UUID playerUUID, UUID profileUUID) {} diff --git a/commons/src/main/java/net/swofty/commons/protocol/objects/bazaar/BazaarGetPendingTransactionsProtocolObject.java b/commons/src/main/java/net/swofty/commons/protocol/objects/bazaar/BazaarGetPendingTransactionsProtocolObject.java index 4d06f9150..b2faa28e4 100644 --- a/commons/src/main/java/net/swofty/commons/protocol/objects/bazaar/BazaarGetPendingTransactionsProtocolObject.java +++ b/commons/src/main/java/net/swofty/commons/protocol/objects/bazaar/BazaarGetPendingTransactionsProtocolObject.java @@ -13,15 +13,19 @@ public class BazaarGetPendingTransactionsProtocolObject extends ProtocolObject< BazaarGetPendingTransactionsProtocolObject.BazaarGetPendingTransactionsMessage, BazaarGetPendingTransactionsProtocolObject.BazaarGetPendingTransactionsResponse> { + private static final Serializer SERIALIZER = + new JacksonSerializer<>(BazaarGetPendingTransactionsMessage.class); + private static final Serializer RETURN_SERIALIZER = + new JacksonSerializer<>(BazaarGetPendingTransactionsResponse.class); @Override public Serializer getSerializer() { - return new JacksonSerializer<>(BazaarGetPendingTransactionsMessage.class); + return SERIALIZER; } @Override public Serializer getReturnSerializer() { - return new JacksonSerializer<>(BazaarGetPendingTransactionsResponse.class); + return RETURN_SERIALIZER; } public record BazaarGetPendingTransactionsMessage(UUID playerUUID, UUID profileUUID) {} diff --git a/commons/src/main/java/net/swofty/commons/protocol/objects/bazaar/BazaarProcessPendingTransactionsProtocolObject.java b/commons/src/main/java/net/swofty/commons/protocol/objects/bazaar/BazaarProcessPendingTransactionsProtocolObject.java index fc4380784..26f686970 100644 --- a/commons/src/main/java/net/swofty/commons/protocol/objects/bazaar/BazaarProcessPendingTransactionsProtocolObject.java +++ b/commons/src/main/java/net/swofty/commons/protocol/objects/bazaar/BazaarProcessPendingTransactionsProtocolObject.java @@ -11,15 +11,19 @@ public class BazaarProcessPendingTransactionsProtocolObject extends ProtocolObject< BazaarProcessPendingTransactionsProtocolObject.BazaarProcessPendingTransactionsMessage, BazaarProcessPendingTransactionsProtocolObject.BazaarProcessPendingTransactionsResponse> { + private static final Serializer SERIALIZER = + new JacksonSerializer<>(BazaarProcessPendingTransactionsMessage.class); + private static final Serializer RETURN_SERIALIZER = + new JacksonSerializer<>(BazaarProcessPendingTransactionsResponse.class); @Override public Serializer getSerializer() { - return new JacksonSerializer<>(BazaarProcessPendingTransactionsMessage.class); + return SERIALIZER; } @Override public Serializer getReturnSerializer() { - return new JacksonSerializer<>(BazaarProcessPendingTransactionsResponse.class); + return RETURN_SERIALIZER; } public record BazaarProcessPendingTransactionsMessage(UUID playerUUID, UUID profileUUID, List transactionIds) {} diff --git a/commons/src/main/java/net/swofty/commons/protocol/objects/bazaar/BazaarSellProtocolObject.java b/commons/src/main/java/net/swofty/commons/protocol/objects/bazaar/BazaarSellProtocolObject.java index 193f14844..4f4485aeb 100644 --- a/commons/src/main/java/net/swofty/commons/protocol/objects/bazaar/BazaarSellProtocolObject.java +++ b/commons/src/main/java/net/swofty/commons/protocol/objects/bazaar/BazaarSellProtocolObject.java @@ -10,15 +10,19 @@ public class BazaarSellProtocolObject extends ProtocolObject< BazaarSellProtocolObject.BazaarSellMessage, BazaarSellProtocolObject.BazaarSellResponse> { + private static final Serializer SERIALIZER = + new JacksonSerializer<>(BazaarSellMessage.class); + private static final Serializer RETURN_SERIALIZER = + new JacksonSerializer<>(BazaarSellResponse.class); @Override public Serializer getSerializer() { - return new JacksonSerializer<>(BazaarSellMessage.class); + return SERIALIZER; } @Override public Serializer getReturnSerializer() { - return new JacksonSerializer<>(BazaarSellResponse.class); + return RETURN_SERIALIZER; } public record BazaarSellMessage(String itemName, UUID playerUUID, UUID profileUUID, Double price, int amount) {} diff --git a/commons/src/main/java/net/swofty/commons/protocol/objects/datamutex/SynchronizeDataProtocolObject.java b/commons/src/main/java/net/swofty/commons/protocol/objects/datamutex/SynchronizeDataProtocolObject.java index 0d335acfd..bf279a39e 100644 --- a/commons/src/main/java/net/swofty/commons/protocol/objects/datamutex/SynchronizeDataProtocolObject.java +++ b/commons/src/main/java/net/swofty/commons/protocol/objects/datamutex/SynchronizeDataProtocolObject.java @@ -11,15 +11,19 @@ public class SynchronizeDataProtocolObject extends ProtocolObject< SynchronizeDataProtocolObject.SynchronizeDataRequest, SynchronizeDataProtocolObject.SynchronizeDataResponse> { + private static final Serializer SERIALIZER = + new JacksonSerializer<>(SynchronizeDataRequest.class); + private static final Serializer RETURN_SERIALIZER = + new JacksonSerializer<>(SynchronizeDataResponse.class); @Override public Serializer getSerializer() { - return new JacksonSerializer<>(SynchronizeDataRequest.class); + return SERIALIZER; } @Override public Serializer getReturnSerializer() { - return new JacksonSerializer<>(SynchronizeDataResponse.class); + return RETURN_SERIALIZER; } public record SynchronizeDataRequest( diff --git a/commons/src/main/java/net/swofty/commons/protocol/objects/datamutex/UnlockDataProtocolObject.java b/commons/src/main/java/net/swofty/commons/protocol/objects/datamutex/UnlockDataProtocolObject.java index c29edf17e..56d67791e 100644 --- a/commons/src/main/java/net/swofty/commons/protocol/objects/datamutex/UnlockDataProtocolObject.java +++ b/commons/src/main/java/net/swofty/commons/protocol/objects/datamutex/UnlockDataProtocolObject.java @@ -11,15 +11,19 @@ public class UnlockDataProtocolObject extends ProtocolObject< UnlockDataProtocolObject.UnlockDataRequest, UnlockDataProtocolObject.UnlockDataResponse> { + private static final Serializer SERIALIZER = + new JacksonSerializer<>(UnlockDataRequest.class); + private static final Serializer RETURN_SERIALIZER = + new JacksonSerializer<>(UnlockDataResponse.class); @Override public Serializer getSerializer() { - return new JacksonSerializer<>(UnlockDataRequest.class); + return SERIALIZER; } @Override public Serializer getReturnSerializer() { - return new JacksonSerializer<>(UnlockDataResponse.class); + return RETURN_SERIALIZER; } public record UnlockDataRequest( diff --git a/commons/src/main/java/net/swofty/commons/protocol/objects/datamutex/UpdateSynchronizedDataProtocolObject.java b/commons/src/main/java/net/swofty/commons/protocol/objects/datamutex/UpdateSynchronizedDataProtocolObject.java index bf5f19c89..a5408d645 100644 --- a/commons/src/main/java/net/swofty/commons/protocol/objects/datamutex/UpdateSynchronizedDataProtocolObject.java +++ b/commons/src/main/java/net/swofty/commons/protocol/objects/datamutex/UpdateSynchronizedDataProtocolObject.java @@ -11,15 +11,19 @@ public class UpdateSynchronizedDataProtocolObject extends ProtocolObject< UpdateSynchronizedDataProtocolObject.UpdateDataRequest, UpdateSynchronizedDataProtocolObject.UpdateDataResponse> { + private static final Serializer SERIALIZER = + new JacksonSerializer<>(UpdateDataRequest.class); + private static final Serializer RETURN_SERIALIZER = + new JacksonSerializer<>(UpdateDataResponse.class); @Override public Serializer getSerializer() { - return new JacksonSerializer<>(UpdateDataRequest.class); + return SERIALIZER; } @Override public Serializer getReturnSerializer() { - return new JacksonSerializer<>(UpdateDataResponse.class); + return RETURN_SERIALIZER; } public record UpdateDataRequest( diff --git a/commons/src/main/java/net/swofty/commons/protocol/objects/election/CastVoteProtocolObject.java b/commons/src/main/java/net/swofty/commons/protocol/objects/election/CastVoteProtocolObject.java index 02446ccd7..54503347e 100644 --- a/commons/src/main/java/net/swofty/commons/protocol/objects/election/CastVoteProtocolObject.java +++ b/commons/src/main/java/net/swofty/commons/protocol/objects/election/CastVoteProtocolObject.java @@ -11,15 +11,19 @@ public class CastVoteProtocolObject extends ProtocolObject { + private static final Serializer SERIALIZER = + new JacksonSerializer<>(CastVoteMessage.class); + private static final Serializer RETURN_SERIALIZER = + new JacksonSerializer<>(CastVoteResponse.class); @Override public Serializer getSerializer() { - return new JacksonSerializer<>(CastVoteMessage.class); + return SERIALIZER; } @Override public Serializer getReturnSerializer() { - return new JacksonSerializer<>(CastVoteResponse.class); + return RETURN_SERIALIZER; } public record CastVoteMessage(UUID accountId, String candidateName) {} diff --git a/commons/src/main/java/net/swofty/commons/protocol/objects/election/GetCandidatesProtocolObject.java b/commons/src/main/java/net/swofty/commons/protocol/objects/election/GetCandidatesProtocolObject.java index 4d6857b15..03e322c06 100644 --- a/commons/src/main/java/net/swofty/commons/protocol/objects/election/GetCandidatesProtocolObject.java +++ b/commons/src/main/java/net/swofty/commons/protocol/objects/election/GetCandidatesProtocolObject.java @@ -10,15 +10,19 @@ public class GetCandidatesProtocolObject extends ProtocolObject { + private static final Serializer SERIALIZER = + new JacksonSerializer<>(GetCandidatesMessage.class); + private static final Serializer RETURN_SERIALIZER = + new JacksonSerializer<>(GetCandidatesResponse.class); @Override public Serializer getSerializer() { - return new JacksonSerializer<>(GetCandidatesMessage.class); + return SERIALIZER; } @Override public Serializer getReturnSerializer() { - return new JacksonSerializer<>(GetCandidatesResponse.class); + return RETURN_SERIALIZER; } public record GetCandidatesMessage() {} diff --git a/commons/src/main/java/net/swofty/commons/protocol/objects/election/GetElectionDataProtocolObject.java b/commons/src/main/java/net/swofty/commons/protocol/objects/election/GetElectionDataProtocolObject.java index c185e54a3..1fcc8af61 100644 --- a/commons/src/main/java/net/swofty/commons/protocol/objects/election/GetElectionDataProtocolObject.java +++ b/commons/src/main/java/net/swofty/commons/protocol/objects/election/GetElectionDataProtocolObject.java @@ -8,15 +8,19 @@ public class GetElectionDataProtocolObject extends ProtocolObject { + private static final Serializer SERIALIZER = + new JacksonSerializer<>(GetElectionDataMessage.class); + private static final Serializer RETURN_SERIALIZER = + new JacksonSerializer<>(GetElectionDataResponse.class); @Override public Serializer getSerializer() { - return new JacksonSerializer<>(GetElectionDataMessage.class); + return SERIALIZER; } @Override public Serializer getReturnSerializer() { - return new JacksonSerializer<>(GetElectionDataResponse.class); + return RETURN_SERIALIZER; } public record GetElectionDataMessage() {} diff --git a/commons/src/main/java/net/swofty/commons/protocol/objects/election/GetPlayerVoteProtocolObject.java b/commons/src/main/java/net/swofty/commons/protocol/objects/election/GetPlayerVoteProtocolObject.java index a8e8ef013..0dc04afd1 100644 --- a/commons/src/main/java/net/swofty/commons/protocol/objects/election/GetPlayerVoteProtocolObject.java +++ b/commons/src/main/java/net/swofty/commons/protocol/objects/election/GetPlayerVoteProtocolObject.java @@ -10,15 +10,19 @@ public class GetPlayerVoteProtocolObject extends ProtocolObject { + private static final Serializer SERIALIZER = + new JacksonSerializer<>(GetPlayerVoteMessage.class); + private static final Serializer RETURN_SERIALIZER = + new JacksonSerializer<>(GetPlayerVoteResponse.class); @Override public Serializer getSerializer() { - return new JacksonSerializer<>(GetPlayerVoteMessage.class); + return SERIALIZER; } @Override public Serializer getReturnSerializer() { - return new JacksonSerializer<>(GetPlayerVoteResponse.class); + return RETURN_SERIALIZER; } public record GetPlayerVoteMessage(UUID accountId) {} diff --git a/commons/src/main/java/net/swofty/commons/protocol/objects/election/ResolveElectionProtocolObject.java b/commons/src/main/java/net/swofty/commons/protocol/objects/election/ResolveElectionProtocolObject.java index 03a6bd3a4..6ad01b750 100644 --- a/commons/src/main/java/net/swofty/commons/protocol/objects/election/ResolveElectionProtocolObject.java +++ b/commons/src/main/java/net/swofty/commons/protocol/objects/election/ResolveElectionProtocolObject.java @@ -8,15 +8,19 @@ public class ResolveElectionProtocolObject extends ProtocolObject { + private static final Serializer SERIALIZER = + new JacksonSerializer<>(ResolveElectionMessage.class); + private static final Serializer RETURN_SERIALIZER = + new JacksonSerializer<>(ResolveElectionResponse.class); @Override public Serializer getSerializer() { - return new JacksonSerializer<>(ResolveElectionMessage.class); + return SERIALIZER; } @Override public Serializer getReturnSerializer() { - return new JacksonSerializer<>(ResolveElectionResponse.class); + return RETURN_SERIALIZER; } public record ResolveElectionMessage(int year) {} diff --git a/commons/src/main/java/net/swofty/commons/protocol/objects/election/StartElectionProtocolObject.java b/commons/src/main/java/net/swofty/commons/protocol/objects/election/StartElectionProtocolObject.java index 7df2d2d04..d6ed27009 100644 --- a/commons/src/main/java/net/swofty/commons/protocol/objects/election/StartElectionProtocolObject.java +++ b/commons/src/main/java/net/swofty/commons/protocol/objects/election/StartElectionProtocolObject.java @@ -8,15 +8,19 @@ public class StartElectionProtocolObject extends ProtocolObject { + private static final Serializer SERIALIZER = + new JacksonSerializer<>(StartElectionMessage.class); + private static final Serializer RETURN_SERIALIZER = + new JacksonSerializer<>(StartElectionResponse.class); @Override public Serializer getSerializer() { - return new JacksonSerializer<>(StartElectionMessage.class); + return SERIALIZER; } @Override public Serializer getReturnSerializer() { - return new JacksonSerializer<>(StartElectionResponse.class); + return RETURN_SERIALIZER; } public record StartElectionMessage(int year, String candidatesJson) {} diff --git a/commons/src/main/java/net/swofty/commons/protocol/objects/itemtracker/TrackedItemUpdateProtocolObject.java b/commons/src/main/java/net/swofty/commons/protocol/objects/itemtracker/TrackedItemUpdateProtocolObject.java index 2068bed1f..739acc36f 100644 --- a/commons/src/main/java/net/swofty/commons/protocol/objects/itemtracker/TrackedItemUpdateProtocolObject.java +++ b/commons/src/main/java/net/swofty/commons/protocol/objects/itemtracker/TrackedItemUpdateProtocolObject.java @@ -9,15 +9,19 @@ public class TrackedItemUpdateProtocolObject extends ProtocolObject< TrackedItemUpdateProtocolObject.TrackedItemUpdateMessage, TrackedItemUpdateProtocolObject.TrackedItemUpdateResponse> { + private static final Serializer SERIALIZER = + new JacksonSerializer<>(TrackedItemUpdateMessage.class); + private static final Serializer RETURN_SERIALIZER = + new JacksonSerializer<>(TrackedItemUpdateResponse.class); @Override public Serializer getSerializer() { - return new JacksonSerializer<>(TrackedItemUpdateMessage.class); + return SERIALIZER; } @Override public Serializer getReturnSerializer() { - return new JacksonSerializer<>(TrackedItemUpdateResponse.class); + return RETURN_SERIALIZER; } public record TrackedItemUpdateMessage( diff --git a/commons/src/main/java/net/swofty/commons/protocol/objects/orchestrator/RejoinGameProtocolObject.java b/commons/src/main/java/net/swofty/commons/protocol/objects/orchestrator/RejoinGameProtocolObject.java index 5ce367f73..0bee52952 100644 --- a/commons/src/main/java/net/swofty/commons/protocol/objects/orchestrator/RejoinGameProtocolObject.java +++ b/commons/src/main/java/net/swofty/commons/protocol/objects/orchestrator/RejoinGameProtocolObject.java @@ -11,15 +11,19 @@ public class RejoinGameProtocolObject extends ProtocolObject< RejoinGameProtocolObject.RejoinGameRequest, RejoinGameProtocolObject.RejoinGameResponse> { + private static final Serializer SERIALIZER = + new JacksonSerializer<>(RejoinGameRequest.class); + private static final Serializer RETURN_SERIALIZER = + new JacksonSerializer<>(RejoinGameResponse.class); @Override public Serializer getSerializer() { - return new JacksonSerializer<>(RejoinGameRequest.class); + return SERIALIZER; } @Override public Serializer getReturnSerializer() { - return new JacksonSerializer<>(RejoinGameResponse.class); + return RETURN_SERIALIZER; } public record RejoinGameRequest(UUID playerUuid) { diff --git a/commons/src/main/java/net/swofty/commons/protocol/objects/party/SendPartyActionProtocolObject.java b/commons/src/main/java/net/swofty/commons/protocol/objects/party/SendPartyActionProtocolObject.java index e5ba6aa84..49243bdee 100644 --- a/commons/src/main/java/net/swofty/commons/protocol/objects/party/SendPartyActionProtocolObject.java +++ b/commons/src/main/java/net/swofty/commons/protocol/objects/party/SendPartyActionProtocolObject.java @@ -9,15 +9,19 @@ public class SendPartyActionProtocolObject extends ProtocolObject< SendPartyActionProtocolObject.Request, SendPartyActionProtocolObject.Response> { + private static final Serializer SERIALIZER = + new JacksonSerializer<>(Request.class); + private static final Serializer RETURN_SERIALIZER = + new JacksonSerializer<>(Response.class); @Override public Serializer getSerializer() { - return new JacksonSerializer<>(Request.class); + return SERIALIZER; } @Override public Serializer getReturnSerializer() { - return new JacksonSerializer<>(Response.class); + return RETURN_SERIALIZER; } public record Request(PartyAction action) {} diff --git a/commons/src/main/java/net/swofty/commons/protocol/objects/presence/GetPresenceBulkProtocolObject.java b/commons/src/main/java/net/swofty/commons/protocol/objects/presence/GetPresenceBulkProtocolObject.java index 9bc062307..c6a18e376 100644 --- a/commons/src/main/java/net/swofty/commons/protocol/objects/presence/GetPresenceBulkProtocolObject.java +++ b/commons/src/main/java/net/swofty/commons/protocol/objects/presence/GetPresenceBulkProtocolObject.java @@ -12,15 +12,19 @@ public class GetPresenceBulkProtocolObject extends ProtocolObject< GetPresenceBulkProtocolObject.GetPresenceBulkMessage, GetPresenceBulkProtocolObject.GetPresenceBulkResponse> { + private static final Serializer SERIALIZER = + new JacksonSerializer<>(GetPresenceBulkMessage.class); + private static final Serializer RETURN_SERIALIZER = + new JacksonSerializer<>(GetPresenceBulkResponse.class); @Override public Serializer getSerializer() { - return new JacksonSerializer<>(GetPresenceBulkMessage.class); + return SERIALIZER; } @Override public Serializer getReturnSerializer() { - return new JacksonSerializer<>(GetPresenceBulkResponse.class); + return RETURN_SERIALIZER; } public record GetPresenceBulkMessage(List uuids) {} diff --git a/commons/src/main/java/net/swofty/commons/protocol/objects/presence/UpdatePresenceProtocolObject.java b/commons/src/main/java/net/swofty/commons/protocol/objects/presence/UpdatePresenceProtocolObject.java index 2b7191cb7..c1555daf0 100644 --- a/commons/src/main/java/net/swofty/commons/protocol/objects/presence/UpdatePresenceProtocolObject.java +++ b/commons/src/main/java/net/swofty/commons/protocol/objects/presence/UpdatePresenceProtocolObject.java @@ -9,15 +9,19 @@ public class UpdatePresenceProtocolObject extends ProtocolObject< UpdatePresenceProtocolObject.UpdatePresenceMessage, UpdatePresenceProtocolObject.UpdatePresenceResponse> { + private static final Serializer SERIALIZER = + new JacksonSerializer<>(UpdatePresenceMessage.class); + private static final Serializer RETURN_SERIALIZER = + new JacksonSerializer<>(UpdatePresenceResponse.class); @Override public Serializer getSerializer() { - return new JacksonSerializer<>(UpdatePresenceMessage.class); + return SERIALIZER; } @Override public Serializer getReturnSerializer() { - return new JacksonSerializer<>(UpdatePresenceResponse.class); + return RETURN_SERIALIZER; } public record UpdatePresenceMessage(PresenceInfo presence) {} diff --git a/commons/src/main/java/net/swofty/commons/protocol/objects/proxy/from/BroadcastStaffChatProtocol.java b/commons/src/main/java/net/swofty/commons/protocol/objects/proxy/from/BroadcastStaffChatProtocol.java index effcbfd0a..26e70b0bc 100644 --- a/commons/src/main/java/net/swofty/commons/protocol/objects/proxy/from/BroadcastStaffChatProtocol.java +++ b/commons/src/main/java/net/swofty/commons/protocol/objects/proxy/from/BroadcastStaffChatProtocol.java @@ -7,15 +7,19 @@ public class BroadcastStaffChatProtocol extends ProtocolObject< BroadcastStaffChatProtocol.Request, BroadcastStaffChatProtocol.Response> { + private static final Serializer SERIALIZER = + new JacksonSerializer<>(Request.class); + private static final Serializer RETURN_SERIALIZER = + new JacksonSerializer<>(Response.class); @Override public Serializer getSerializer() { - return new JacksonSerializer<>(Request.class); + return SERIALIZER; } @Override public Serializer getReturnSerializer() { - return new JacksonSerializer<>(Response.class); + return RETURN_SERIALIZER; } public record Request(String type, String formattedMessage, String uuid) {} diff --git a/commons/src/main/java/net/swofty/commons/protocol/objects/proxy/from/DoesServerHaveIslandProtocol.java b/commons/src/main/java/net/swofty/commons/protocol/objects/proxy/from/DoesServerHaveIslandProtocol.java index 152e90a17..e67ef28bf 100644 --- a/commons/src/main/java/net/swofty/commons/protocol/objects/proxy/from/DoesServerHaveIslandProtocol.java +++ b/commons/src/main/java/net/swofty/commons/protocol/objects/proxy/from/DoesServerHaveIslandProtocol.java @@ -8,15 +8,19 @@ public class DoesServerHaveIslandProtocol extends ProtocolObject< DoesServerHaveIslandProtocol.Request, DoesServerHaveIslandProtocol.Response> { + private static final Serializer SERIALIZER = + new JacksonSerializer<>(Request.class); + private static final Serializer RETURN_SERIALIZER = + new JacksonSerializer<>(Response.class); @Override public Serializer getSerializer() { - return new JacksonSerializer<>(Request.class); + return SERIALIZER; } @Override public Serializer getReturnSerializer() { - return new JacksonSerializer<>(Response.class); + return RETURN_SERIALIZER; } public record Request(String islandUuid) {} diff --git a/commons/src/main/java/net/swofty/commons/protocol/objects/proxy/from/GivePlayersOriginTypeProtocol.java b/commons/src/main/java/net/swofty/commons/protocol/objects/proxy/from/GivePlayersOriginTypeProtocol.java index 59f4cce0c..4683b21e6 100644 --- a/commons/src/main/java/net/swofty/commons/protocol/objects/proxy/from/GivePlayersOriginTypeProtocol.java +++ b/commons/src/main/java/net/swofty/commons/protocol/objects/proxy/from/GivePlayersOriginTypeProtocol.java @@ -7,15 +7,19 @@ public class GivePlayersOriginTypeProtocol extends ProtocolObject< GivePlayersOriginTypeProtocol.Request, GivePlayersOriginTypeProtocol.Response> { + private static final Serializer SERIALIZER = + new JacksonSerializer<>(Request.class); + private static final Serializer RETURN_SERIALIZER = + new JacksonSerializer<>(Response.class); @Override public Serializer getSerializer() { - return new JacksonSerializer<>(Request.class); + return SERIALIZER; } @Override public Serializer getReturnSerializer() { - return new JacksonSerializer<>(Response.class); + return RETURN_SERIALIZER; } public record Request(String uuid, String originType) {} diff --git a/commons/src/main/java/net/swofty/commons/protocol/objects/proxy/from/PingServerProtocol.java b/commons/src/main/java/net/swofty/commons/protocol/objects/proxy/from/PingServerProtocol.java index 13aa9b350..67662c0c2 100644 --- a/commons/src/main/java/net/swofty/commons/protocol/objects/proxy/from/PingServerProtocol.java +++ b/commons/src/main/java/net/swofty/commons/protocol/objects/proxy/from/PingServerProtocol.java @@ -7,15 +7,19 @@ public class PingServerProtocol extends ProtocolObject< PingServerProtocol.Request, PingServerProtocol.Response> { + private static final Serializer SERIALIZER = + new JacksonSerializer<>(Request.class); + private static final Serializer RETURN_SERIALIZER = + new JacksonSerializer<>(Response.class); @Override public Serializer getSerializer() { - return new JacksonSerializer<>(Request.class); + return SERIALIZER; } @Override public Serializer getReturnSerializer() { - return new JacksonSerializer<>(Response.class); + return RETURN_SERIALIZER; } public record Request() {} diff --git a/commons/src/main/java/net/swofty/commons/protocol/objects/proxy/from/PlayerSwitchedProtocol.java b/commons/src/main/java/net/swofty/commons/protocol/objects/proxy/from/PlayerSwitchedProtocol.java index e29f00e49..75d9527a5 100644 --- a/commons/src/main/java/net/swofty/commons/protocol/objects/proxy/from/PlayerSwitchedProtocol.java +++ b/commons/src/main/java/net/swofty/commons/protocol/objects/proxy/from/PlayerSwitchedProtocol.java @@ -7,15 +7,19 @@ public class PlayerSwitchedProtocol extends ProtocolObject< PlayerSwitchedProtocol.Request, PlayerSwitchedProtocol.Response> { + private static final Serializer SERIALIZER = + new JacksonSerializer<>(Request.class); + private static final Serializer RETURN_SERIALIZER = + new JacksonSerializer<>(Response.class); @Override public Serializer getSerializer() { - return new JacksonSerializer<>(Request.class); + return SERIALIZER; } @Override public Serializer getReturnSerializer() { - return new JacksonSerializer<>(Response.class); + return RETURN_SERIALIZER; } public record Request(String uuid) {} diff --git a/commons/src/main/java/net/swofty/commons/protocol/objects/proxy/from/RefreshCoopDataProtocol.java b/commons/src/main/java/net/swofty/commons/protocol/objects/proxy/from/RefreshCoopDataProtocol.java index eb682642c..c7d3de5d8 100644 --- a/commons/src/main/java/net/swofty/commons/protocol/objects/proxy/from/RefreshCoopDataProtocol.java +++ b/commons/src/main/java/net/swofty/commons/protocol/objects/proxy/from/RefreshCoopDataProtocol.java @@ -7,15 +7,19 @@ public class RefreshCoopDataProtocol extends ProtocolObject< RefreshCoopDataProtocol.Request, RefreshCoopDataProtocol.Response> { + private static final Serializer SERIALIZER = + new JacksonSerializer<>(Request.class); + private static final Serializer RETURN_SERIALIZER = + new JacksonSerializer<>(Response.class); @Override public Serializer getSerializer() { - return new JacksonSerializer<>(Request.class); + return SERIALIZER; } @Override public Serializer getReturnSerializer() { - return new JacksonSerializer<>(Response.class); + return RETURN_SERIALIZER; } public record Request(String uuid, String datapoint) {} diff --git a/commons/src/main/java/net/swofty/commons/protocol/objects/proxy/from/RunEventProtocol.java b/commons/src/main/java/net/swofty/commons/protocol/objects/proxy/from/RunEventProtocol.java index 2554f4545..8aa8f61e1 100644 --- a/commons/src/main/java/net/swofty/commons/protocol/objects/proxy/from/RunEventProtocol.java +++ b/commons/src/main/java/net/swofty/commons/protocol/objects/proxy/from/RunEventProtocol.java @@ -7,15 +7,19 @@ public class RunEventProtocol extends ProtocolObject< RunEventProtocol.Request, RunEventProtocol.Response> { + private static final Serializer SERIALIZER = + new JacksonSerializer<>(Request.class); + private static final Serializer RETURN_SERIALIZER = + new JacksonSerializer<>(Response.class); @Override public Serializer getSerializer() { - return new JacksonSerializer<>(Request.class); + return SERIALIZER; } @Override public Serializer getReturnSerializer() { - return new JacksonSerializer<>(Response.class); + return RETURN_SERIALIZER; } public record Request(String uuid, String event, String data) {} diff --git a/commons/src/main/java/net/swofty/commons/protocol/objects/proxy/from/TeleportProtocol.java b/commons/src/main/java/net/swofty/commons/protocol/objects/proxy/from/TeleportProtocol.java index df9fcbff9..a6c22e620 100644 --- a/commons/src/main/java/net/swofty/commons/protocol/objects/proxy/from/TeleportProtocol.java +++ b/commons/src/main/java/net/swofty/commons/protocol/objects/proxy/from/TeleportProtocol.java @@ -7,15 +7,19 @@ public class TeleportProtocol extends ProtocolObject< TeleportProtocol.Request, TeleportProtocol.Response> { + private static final Serializer SERIALIZER = + new JacksonSerializer<>(Request.class); + private static final Serializer RETURN_SERIALIZER = + new JacksonSerializer<>(Response.class); @Override public Serializer getSerializer() { - return new JacksonSerializer<>(Request.class); + return SERIALIZER; } @Override public Serializer getReturnSerializer() { - return new JacksonSerializer<>(Response.class); + return RETURN_SERIALIZER; } public record Request(String uuid, double x, double y, double z, float yaw, float pitch) {} diff --git a/commons/src/main/java/net/swofty/commons/protocol/objects/proxy/to/FinishedWithPlayerProtocol.java b/commons/src/main/java/net/swofty/commons/protocol/objects/proxy/to/FinishedWithPlayerProtocol.java index 006291036..754e0325b 100644 --- a/commons/src/main/java/net/swofty/commons/protocol/objects/proxy/to/FinishedWithPlayerProtocol.java +++ b/commons/src/main/java/net/swofty/commons/protocol/objects/proxy/to/FinishedWithPlayerProtocol.java @@ -7,15 +7,19 @@ public class FinishedWithPlayerProtocol extends ProtocolObject< FinishedWithPlayerProtocol.Request, FinishedWithPlayerProtocol.Response> { + private static final Serializer SERIALIZER = + new JacksonSerializer<>(Request.class); + private static final Serializer RETURN_SERIALIZER = + new JacksonSerializer<>(Response.class); @Override public Serializer getSerializer() { - return new JacksonSerializer<>(Request.class); + return SERIALIZER; } @Override public Serializer getReturnSerializer() { - return new JacksonSerializer<>(Response.class); + return RETURN_SERIALIZER; } public record Request(String uuid) {} diff --git a/commons/src/main/java/net/swofty/commons/protocol/objects/proxy/to/PlayerCountProtocol.java b/commons/src/main/java/net/swofty/commons/protocol/objects/proxy/to/PlayerCountProtocol.java index faed156c8..33a372983 100644 --- a/commons/src/main/java/net/swofty/commons/protocol/objects/proxy/to/PlayerCountProtocol.java +++ b/commons/src/main/java/net/swofty/commons/protocol/objects/proxy/to/PlayerCountProtocol.java @@ -8,15 +8,19 @@ public class PlayerCountProtocol extends ProtocolObject< PlayerCountProtocol.Request, PlayerCountProtocol.Response> { + private static final Serializer SERIALIZER = + new JacksonSerializer<>(Request.class); + private static final Serializer RETURN_SERIALIZER = + new JacksonSerializer<>(Response.class); @Override public Serializer getSerializer() { - return new JacksonSerializer<>(Request.class); + return SERIALIZER; } @Override public Serializer getReturnSerializer() { - return new JacksonSerializer<>(Response.class); + return RETURN_SERIALIZER; } public enum LookupType { ALL, TYPE, UUID } diff --git a/commons/src/main/java/net/swofty/commons/protocol/objects/proxy/to/PlayerHandlerProtocol.java b/commons/src/main/java/net/swofty/commons/protocol/objects/proxy/to/PlayerHandlerProtocol.java index e23cab32c..082b8de7e 100644 --- a/commons/src/main/java/net/swofty/commons/protocol/objects/proxy/to/PlayerHandlerProtocol.java +++ b/commons/src/main/java/net/swofty/commons/protocol/objects/proxy/to/PlayerHandlerProtocol.java @@ -10,15 +10,19 @@ public class PlayerHandlerProtocol extends ProtocolObject< PlayerHandlerProtocol.Request, PlayerHandlerProtocol.Response> { + private static final Serializer SERIALIZER = + new JacksonSerializer<>(Request.class); + private static final Serializer RETURN_SERIALIZER = + new JacksonSerializer<>(Response.class); @Override public Serializer getSerializer() { - return new JacksonSerializer<>(Request.class); + return SERIALIZER; } @Override public Serializer getReturnSerializer() { - return new JacksonSerializer<>(Response.class); + return RETURN_SERIALIZER; } public enum Action { diff --git a/commons/src/main/java/net/swofty/commons/protocol/objects/proxy/to/ProxyIsOnlineProtocol.java b/commons/src/main/java/net/swofty/commons/protocol/objects/proxy/to/ProxyIsOnlineProtocol.java index 555a5ccc4..2401fea1c 100644 --- a/commons/src/main/java/net/swofty/commons/protocol/objects/proxy/to/ProxyIsOnlineProtocol.java +++ b/commons/src/main/java/net/swofty/commons/protocol/objects/proxy/to/ProxyIsOnlineProtocol.java @@ -8,15 +8,19 @@ public class ProxyIsOnlineProtocol extends ProtocolObject< ProxyIsOnlineProtocol.Request, ProxyIsOnlineProtocol.Response> { + private static final Serializer SERIALIZER = + new JacksonSerializer<>(Request.class); + private static final Serializer RETURN_SERIALIZER = + new JacksonSerializer<>(Response.class); @Override public Serializer getSerializer() { - return new JacksonSerializer<>(Request.class); + return SERIALIZER; } @Override public Serializer getReturnSerializer() { - return new JacksonSerializer<>(Response.class); + return RETURN_SERIALIZER; } public record Request() {} diff --git a/commons/src/main/java/net/swofty/commons/protocol/objects/proxy/to/PunishPlayerProtocol.java b/commons/src/main/java/net/swofty/commons/protocol/objects/proxy/to/PunishPlayerProtocol.java index 3025880f4..87cc89751 100644 --- a/commons/src/main/java/net/swofty/commons/protocol/objects/proxy/to/PunishPlayerProtocol.java +++ b/commons/src/main/java/net/swofty/commons/protocol/objects/proxy/to/PunishPlayerProtocol.java @@ -7,15 +7,19 @@ public class PunishPlayerProtocol extends ProtocolObject< PunishPlayerProtocol.Request, PunishPlayerProtocol.Response> { + private static final Serializer SERIALIZER = + new JacksonSerializer<>(Request.class); + private static final Serializer RETURN_SERIALIZER = + new JacksonSerializer<>(Response.class); @Override public Serializer getSerializer() { - return new JacksonSerializer<>(Request.class); + return SERIALIZER; } @Override public Serializer getReturnSerializer() { - return new JacksonSerializer<>(Response.class); + return RETURN_SERIALIZER; } public record Request(String target, String type, String id, long expiresAt, diff --git a/commons/src/main/java/net/swofty/commons/protocol/objects/proxy/to/RegisterServerProtocol.java b/commons/src/main/java/net/swofty/commons/protocol/objects/proxy/to/RegisterServerProtocol.java index bf26b1b80..fd69e6c20 100644 --- a/commons/src/main/java/net/swofty/commons/protocol/objects/proxy/to/RegisterServerProtocol.java +++ b/commons/src/main/java/net/swofty/commons/protocol/objects/proxy/to/RegisterServerProtocol.java @@ -8,15 +8,19 @@ public class RegisterServerProtocol extends ProtocolObject< RegisterServerProtocol.Request, RegisterServerProtocol.Response> { + private static final Serializer SERIALIZER = + new JacksonSerializer<>(Request.class); + private static final Serializer RETURN_SERIALIZER = + new JacksonSerializer<>(Response.class); @Override public Serializer getSerializer() { - return new JacksonSerializer<>(Request.class); + return SERIALIZER; } @Override public Serializer getReturnSerializer() { - return new JacksonSerializer<>(Response.class); + return RETURN_SERIALIZER; } public record Request(String type, int maxPlayers, String host, Integer port, diff --git a/commons/src/main/java/net/swofty/commons/protocol/objects/proxy/to/RegisterTestFlowProtocol.java b/commons/src/main/java/net/swofty/commons/protocol/objects/proxy/to/RegisterTestFlowProtocol.java index 6892a6cb6..61cb2f7e5 100644 --- a/commons/src/main/java/net/swofty/commons/protocol/objects/proxy/to/RegisterTestFlowProtocol.java +++ b/commons/src/main/java/net/swofty/commons/protocol/objects/proxy/to/RegisterTestFlowProtocol.java @@ -10,15 +10,19 @@ public class RegisterTestFlowProtocol extends ProtocolObject< RegisterTestFlowProtocol.Request, RegisterTestFlowProtocol.Response> { + private static final Serializer SERIALIZER = + new JacksonSerializer<>(Request.class); + private static final Serializer RETURN_SERIALIZER = + new JacksonSerializer<>(Response.class); @Override public Serializer getSerializer() { - return new JacksonSerializer<>(Request.class); + return SERIALIZER; } @Override public Serializer getReturnSerializer() { - return new JacksonSerializer<>(Response.class); + return RETURN_SERIALIZER; } public record Request(String testFlowName, String handler, List players, diff --git a/commons/src/main/java/net/swofty/commons/protocol/objects/proxy/to/RequestServerNameProtocol.java b/commons/src/main/java/net/swofty/commons/protocol/objects/proxy/to/RequestServerNameProtocol.java index 13aaef2f1..33fe1646b 100644 --- a/commons/src/main/java/net/swofty/commons/protocol/objects/proxy/to/RequestServerNameProtocol.java +++ b/commons/src/main/java/net/swofty/commons/protocol/objects/proxy/to/RequestServerNameProtocol.java @@ -8,15 +8,19 @@ public class RequestServerNameProtocol extends ProtocolObject< RequestServerNameProtocol.Request, RequestServerNameProtocol.Response> { + private static final Serializer SERIALIZER = + new JacksonSerializer<>(Request.class); + private static final Serializer RETURN_SERIALIZER = + new JacksonSerializer<>(Response.class); @Override public Serializer getSerializer() { - return new JacksonSerializer<>(Request.class); + return SERIALIZER; } @Override public Serializer getReturnSerializer() { - return new JacksonSerializer<>(Response.class); + return RETURN_SERIALIZER; } public record Request() {} diff --git a/commons/src/main/java/net/swofty/commons/protocol/objects/proxy/to/RequestServersProtocol.java b/commons/src/main/java/net/swofty/commons/protocol/objects/proxy/to/RequestServersProtocol.java index 2537efa32..d8f341555 100644 --- a/commons/src/main/java/net/swofty/commons/protocol/objects/proxy/to/RequestServersProtocol.java +++ b/commons/src/main/java/net/swofty/commons/protocol/objects/proxy/to/RequestServersProtocol.java @@ -8,15 +8,19 @@ public class RequestServersProtocol extends ProtocolObject< RequestServersProtocol.Request, RequestServersProtocol.Response> { + private static final Serializer SERIALIZER = + new JacksonSerializer<>(Request.class); + private static final Serializer RETURN_SERIALIZER = + new JacksonSerializer<>(Response.class); @Override public Serializer getSerializer() { - return new JacksonSerializer<>(Request.class); + return SERIALIZER; } @Override public Serializer getReturnSerializer() { - return new JacksonSerializer<>(Response.class); + return RETURN_SERIALIZER; } public record Request(String requestType, String type, String uuid) {} diff --git a/commons/src/main/java/net/swofty/commons/protocol/objects/proxy/to/StaffChatProtocol.java b/commons/src/main/java/net/swofty/commons/protocol/objects/proxy/to/StaffChatProtocol.java index a066c0c9a..105b61f0b 100644 --- a/commons/src/main/java/net/swofty/commons/protocol/objects/proxy/to/StaffChatProtocol.java +++ b/commons/src/main/java/net/swofty/commons/protocol/objects/proxy/to/StaffChatProtocol.java @@ -7,15 +7,19 @@ public class StaffChatProtocol extends ProtocolObject< StaffChatProtocol.Request, StaffChatProtocol.Response> { + private static final Serializer SERIALIZER = + new JacksonSerializer<>(Request.class); + private static final Serializer RETURN_SERIALIZER = + new JacksonSerializer<>(Response.class); @Override public Serializer getSerializer() { - return new JacksonSerializer<>(Request.class); + return SERIALIZER; } @Override public Serializer getReturnSerializer() { - return new JacksonSerializer<>(Response.class); + return RETURN_SERIALIZER; } public record Request(String type, String formattedMessage, String uuid) {} diff --git a/commons/src/main/java/net/swofty/commons/protocol/objects/proxy/to/TestFlowServerReadyProtocol.java b/commons/src/main/java/net/swofty/commons/protocol/objects/proxy/to/TestFlowServerReadyProtocol.java index 8d4e10242..984dd3d8e 100644 --- a/commons/src/main/java/net/swofty/commons/protocol/objects/proxy/to/TestFlowServerReadyProtocol.java +++ b/commons/src/main/java/net/swofty/commons/protocol/objects/proxy/to/TestFlowServerReadyProtocol.java @@ -7,15 +7,19 @@ public class TestFlowServerReadyProtocol extends ProtocolObject< TestFlowServerReadyProtocol.Request, TestFlowServerReadyProtocol.Response> { + private static final Serializer SERIALIZER = + new JacksonSerializer<>(Request.class); + private static final Serializer RETURN_SERIALIZER = + new JacksonSerializer<>(Response.class); @Override public Serializer getSerializer() { - return new JacksonSerializer<>(Request.class); + return SERIALIZER; } @Override public Serializer getReturnSerializer() { - return new JacksonSerializer<>(Response.class); + return RETURN_SERIALIZER; } public record Request(String testFlowName, String serverType, int serverIndex) {} diff --git a/commons/src/main/java/net/swofty/commons/protocol/objects/punishment/GetActivePunishmentProtocolObject.java b/commons/src/main/java/net/swofty/commons/protocol/objects/punishment/GetActivePunishmentProtocolObject.java index f380d478b..dbd4b276e 100644 --- a/commons/src/main/java/net/swofty/commons/protocol/objects/punishment/GetActivePunishmentProtocolObject.java +++ b/commons/src/main/java/net/swofty/commons/protocol/objects/punishment/GetActivePunishmentProtocolObject.java @@ -14,15 +14,19 @@ public class GetActivePunishmentProtocolObject extends ProtocolObject { + private static final Serializer SERIALIZER = + new JacksonSerializer<>(GetActivePunishmentMessage.class); + private static final Serializer RETURN_SERIALIZER = + new JacksonSerializer<>(GetActivePunishmentResponse.class); @Override public Serializer getSerializer() { - return new JacksonSerializer<>(GetActivePunishmentMessage.class); + return SERIALIZER; } @Override public Serializer getReturnSerializer() { - return new JacksonSerializer<>(GetActivePunishmentResponse.class); + return RETURN_SERIALIZER; } public record GetActivePunishmentMessage( diff --git a/commons/src/main/java/net/swofty/commons/protocol/objects/punishment/PunishPlayerProtocolObject.java b/commons/src/main/java/net/swofty/commons/protocol/objects/punishment/PunishPlayerProtocolObject.java index 6f22625ab..5074c5440 100644 --- a/commons/src/main/java/net/swofty/commons/protocol/objects/punishment/PunishPlayerProtocolObject.java +++ b/commons/src/main/java/net/swofty/commons/protocol/objects/punishment/PunishPlayerProtocolObject.java @@ -14,15 +14,19 @@ public class PunishPlayerProtocolObject extends ProtocolObject { + private static final Serializer SERIALIZER = + new JacksonSerializer<>(PunishPlayerMessage.class); + private static final Serializer RETURN_SERIALIZER = + new JacksonSerializer<>(PunishPlayerResponse.class); @Override public Serializer getSerializer() { - return new JacksonSerializer<>(PunishPlayerMessage.class); + return SERIALIZER; } @Override public Serializer getReturnSerializer() { - return new JacksonSerializer<>(PunishPlayerResponse.class); + return RETURN_SERIALIZER; } public record PunishPlayerMessage( diff --git a/commons/src/main/java/net/swofty/commons/protocol/objects/punishment/UnpunishPlayerProtocolObject.java b/commons/src/main/java/net/swofty/commons/protocol/objects/punishment/UnpunishPlayerProtocolObject.java index d8007bc21..bb7979c51 100644 --- a/commons/src/main/java/net/swofty/commons/protocol/objects/punishment/UnpunishPlayerProtocolObject.java +++ b/commons/src/main/java/net/swofty/commons/protocol/objects/punishment/UnpunishPlayerProtocolObject.java @@ -11,15 +11,19 @@ public class UnpunishPlayerProtocolObject extends ProtocolObject { + private static final Serializer SERIALIZER = + new JacksonSerializer<>(UnpunishPlayerMessage.class); + private static final Serializer RETURN_SERIALIZER = + new JacksonSerializer<>(UnpunishPlayerResponse.class); @Override public Serializer getSerializer() { - return new JacksonSerializer<>(UnpunishPlayerMessage.class); + return SERIALIZER; } @Override public Serializer getReturnSerializer() { - return new JacksonSerializer<>(UnpunishPlayerResponse.class); + return RETURN_SERIALIZER; } public record UnpunishPlayerMessage( From 876b1b1ad81e516e4c75e3cc3488784d83fc5674 Mon Sep 17 00:00:00 2001 From: "Jacob Nardella (Swofty)" Date: Fri, 15 May 2026 01:41:59 +1000 Subject: [PATCH 077/113] perf(protocol): hoist remaining 15 inline JacksonSerializers to static fields MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Same pattern as the previous 45-file batch — the rest of the ProtocolObject subclasses caught by the broader regex now have SERIALIZER / RETURN_SERIALIZER static fields instead of allocating per call. That's now 60 ProtocolObject classes all sharing one allocation each for their serializers. --- .../api/APIAuthenticateCodeProtocolObject.java | 14 ++++++++++++-- .../auctions/AuctionAddItemProtocolObject.java | 14 ++++++++++++-- .../objects/bazaar/BazaarBuyProtocolObject.java | 14 ++++++++++++-- .../objects/friend/AreFriendsProtocolObject.java | 14 ++++++++++++-- .../friend/GetFriendDataProtocolObject.java | 14 ++++++++++++-- .../GetPendingFriendRequestsProtocolObject.java | 14 ++++++++++++-- .../SendFriendEventToServiceProtocolObject.java | 14 ++++++++++++-- .../TrackedItemRetrieveProtocolObject.java | 14 ++++++++++++-- .../orchestrator/ChooseGameProtocolObject.java | 14 ++++++++++++-- .../orchestrator/GameHeartbeatProtocolObject.java | 14 ++++++++++++-- .../orchestrator/GetGameCountsProtocolObject.java | 14 ++++++++++++-- .../orchestrator/GetMapsProtocolObject.java | 14 ++++++++++++-- .../GetServerForMapProtocolObject.java | 14 ++++++++++++-- .../objects/party/GetPartyProtocolObject.java | 14 ++++++++++++-- .../party/IsPlayerInPartyProtocolObject.java | 14 ++++++++++++-- 15 files changed, 180 insertions(+), 30 deletions(-) diff --git a/commons/src/main/java/net/swofty/commons/protocol/objects/api/APIAuthenticateCodeProtocolObject.java b/commons/src/main/java/net/swofty/commons/protocol/objects/api/APIAuthenticateCodeProtocolObject.java index 8a708541e..0d6b5c073 100644 --- a/commons/src/main/java/net/swofty/commons/protocol/objects/api/APIAuthenticateCodeProtocolObject.java +++ b/commons/src/main/java/net/swofty/commons/protocol/objects/api/APIAuthenticateCodeProtocolObject.java @@ -9,15 +9,25 @@ public class APIAuthenticateCodeProtocolObject extends ProtocolObject { + private static final Serializer SERIALIZER = + new JacksonSerializer<>(AuthenticateCodeMessage.class); + private static final Serializer RETURN_SERIALIZER = + new JacksonSerializer<>(AuthenticateCodeResponse.class); @Override + public Serializer getSerializer() { - return new JacksonSerializer<>(AuthenticateCodeMessage.class); + + return SERIALIZER; + } @Override + public Serializer getReturnSerializer() { - return new JacksonSerializer<>(AuthenticateCodeResponse.class); + + return RETURN_SERIALIZER; + } public record AuthenticateCodeMessage(String authCode, String playerName, UUID playerUUID) {} diff --git a/commons/src/main/java/net/swofty/commons/protocol/objects/auctions/AuctionAddItemProtocolObject.java b/commons/src/main/java/net/swofty/commons/protocol/objects/auctions/AuctionAddItemProtocolObject.java index 1990ca6c4..6ce3bc468 100644 --- a/commons/src/main/java/net/swofty/commons/protocol/objects/auctions/AuctionAddItemProtocolObject.java +++ b/commons/src/main/java/net/swofty/commons/protocol/objects/auctions/AuctionAddItemProtocolObject.java @@ -12,15 +12,25 @@ public class AuctionAddItemProtocolObject extends ProtocolObject { + private static final Serializer SERIALIZER = + new JacksonSerializer<>(AuctionAddItemMessage.class); + private static final Serializer RETURN_SERIALIZER = + new JacksonSerializer<>(AuctionAddItemResponse.class); @Override + public Serializer getSerializer() { - return new JacksonSerializer<>(AuctionAddItemMessage.class); + + return SERIALIZER; + } @Override + public Serializer getReturnSerializer() { - return new JacksonSerializer<>(AuctionAddItemResponse.class); + + return RETURN_SERIALIZER; + } public record AuctionAddItemMessage(AuctionItem item, AuctionCategories category) {} diff --git a/commons/src/main/java/net/swofty/commons/protocol/objects/bazaar/BazaarBuyProtocolObject.java b/commons/src/main/java/net/swofty/commons/protocol/objects/bazaar/BazaarBuyProtocolObject.java index 6b13837f2..ed044f548 100644 --- a/commons/src/main/java/net/swofty/commons/protocol/objects/bazaar/BazaarBuyProtocolObject.java +++ b/commons/src/main/java/net/swofty/commons/protocol/objects/bazaar/BazaarBuyProtocolObject.java @@ -9,15 +9,25 @@ public class BazaarBuyProtocolObject extends ProtocolObject { + private static final Serializer SERIALIZER = + new JacksonSerializer<>(BazaarBuyMessage.class); + private static final Serializer RETURN_SERIALIZER = + new JacksonSerializer<>(BazaarBuyResponse.class); @Override + public Serializer getSerializer() { - return new JacksonSerializer<>(BazaarBuyMessage.class); + + return SERIALIZER; + } @Override + public Serializer getReturnSerializer() { - return new JacksonSerializer<>(BazaarBuyResponse.class); + + return RETURN_SERIALIZER; + } public record BazaarBuyMessage(String itemName, int amount, double price, UUID playerUUID, UUID profileUUID) {} diff --git a/commons/src/main/java/net/swofty/commons/protocol/objects/friend/AreFriendsProtocolObject.java b/commons/src/main/java/net/swofty/commons/protocol/objects/friend/AreFriendsProtocolObject.java index 38719dc80..030037dd8 100644 --- a/commons/src/main/java/net/swofty/commons/protocol/objects/friend/AreFriendsProtocolObject.java +++ b/commons/src/main/java/net/swofty/commons/protocol/objects/friend/AreFriendsProtocolObject.java @@ -10,15 +10,25 @@ public class AreFriendsProtocolObject extends ProtocolObject { + private static final Serializer SERIALIZER = + new JacksonSerializer<>(AreFriendsMessage.class); + private static final Serializer RETURN_SERIALIZER = + new JacksonSerializer<>(AreFriendsResponse.class); @Override + public Serializer getSerializer() { - return new JacksonSerializer<>(AreFriendsMessage.class); + + return SERIALIZER; + } @Override + public Serializer getReturnSerializer() { - return new JacksonSerializer<>(AreFriendsResponse.class); + + return RETURN_SERIALIZER; + } public record AreFriendsMessage(UUID player, UUID other) { diff --git a/commons/src/main/java/net/swofty/commons/protocol/objects/friend/GetFriendDataProtocolObject.java b/commons/src/main/java/net/swofty/commons/protocol/objects/friend/GetFriendDataProtocolObject.java index a48ad5439..d04ac2c20 100644 --- a/commons/src/main/java/net/swofty/commons/protocol/objects/friend/GetFriendDataProtocolObject.java +++ b/commons/src/main/java/net/swofty/commons/protocol/objects/friend/GetFriendDataProtocolObject.java @@ -11,15 +11,25 @@ public class GetFriendDataProtocolObject extends ProtocolObject { + private static final Serializer SERIALIZER = + new JacksonSerializer<>(GetFriendDataMessage.class); + private static final Serializer RETURN_SERIALIZER = + new JacksonSerializer<>(GetFriendDataResponse.class); @Override + public Serializer getSerializer() { - return new JacksonSerializer<>(GetFriendDataMessage.class); + + return SERIALIZER; + } @Override + public Serializer getReturnSerializer() { - return new JacksonSerializer<>(GetFriendDataResponse.class); + + return RETURN_SERIALIZER; + } public record GetFriendDataMessage(UUID playerUuid) { diff --git a/commons/src/main/java/net/swofty/commons/protocol/objects/friend/GetPendingFriendRequestsProtocolObject.java b/commons/src/main/java/net/swofty/commons/protocol/objects/friend/GetPendingFriendRequestsProtocolObject.java index 17a3a77a8..3fc310f48 100644 --- a/commons/src/main/java/net/swofty/commons/protocol/objects/friend/GetPendingFriendRequestsProtocolObject.java +++ b/commons/src/main/java/net/swofty/commons/protocol/objects/friend/GetPendingFriendRequestsProtocolObject.java @@ -12,15 +12,25 @@ public class GetPendingFriendRequestsProtocolObject extends ProtocolObject { + private static final Serializer SERIALIZER = + new JacksonSerializer<>(GetPendingRequestsMessage.class); + private static final Serializer RETURN_SERIALIZER = + new JacksonSerializer<>(GetPendingRequestsResponse.class); @Override + public Serializer getSerializer() { - return new JacksonSerializer<>(GetPendingRequestsMessage.class); + + return SERIALIZER; + } @Override + public Serializer getReturnSerializer() { - return new JacksonSerializer<>(GetPendingRequestsResponse.class); + + return RETURN_SERIALIZER; + } public record GetPendingRequestsMessage(UUID playerUuid) { diff --git a/commons/src/main/java/net/swofty/commons/protocol/objects/friend/SendFriendEventToServiceProtocolObject.java b/commons/src/main/java/net/swofty/commons/protocol/objects/friend/SendFriendEventToServiceProtocolObject.java index 0d8ccb924..b8da5c202 100644 --- a/commons/src/main/java/net/swofty/commons/protocol/objects/friend/SendFriendEventToServiceProtocolObject.java +++ b/commons/src/main/java/net/swofty/commons/protocol/objects/friend/SendFriendEventToServiceProtocolObject.java @@ -9,15 +9,25 @@ public class SendFriendEventToServiceProtocolObject extends ProtocolObject { + private static final Serializer SERIALIZER = + new JacksonSerializer<>(SendFriendEventToServiceMessage.class); + private static final Serializer RETURN_SERIALIZER = + new JacksonSerializer<>(SendFriendEventToServiceResponse.class); @Override + public Serializer getSerializer() { - return new JacksonSerializer<>(SendFriendEventToServiceMessage.class); + + return SERIALIZER; + } @Override + public Serializer getReturnSerializer() { - return new JacksonSerializer<>(SendFriendEventToServiceResponse.class); + + return RETURN_SERIALIZER; + } public record SendFriendEventToServiceMessage(FriendEvent event) { diff --git a/commons/src/main/java/net/swofty/commons/protocol/objects/itemtracker/TrackedItemRetrieveProtocolObject.java b/commons/src/main/java/net/swofty/commons/protocol/objects/itemtracker/TrackedItemRetrieveProtocolObject.java index 38a01f0f8..d06eb7dcb 100644 --- a/commons/src/main/java/net/swofty/commons/protocol/objects/itemtracker/TrackedItemRetrieveProtocolObject.java +++ b/commons/src/main/java/net/swofty/commons/protocol/objects/itemtracker/TrackedItemRetrieveProtocolObject.java @@ -11,15 +11,25 @@ public class TrackedItemRetrieveProtocolObject extends ProtocolObject { + private static final Serializer SERIALIZER = + new JacksonSerializer<>(TrackedItemRetrieveMessage.class); + private static final Serializer RETURN_SERIALIZER = + new JacksonSerializer<>(TrackedItemResponse.class); @Override + public Serializer getSerializer() { - return new JacksonSerializer<>(TrackedItemRetrieveMessage.class); + + return SERIALIZER; + } @Override + public Serializer getReturnSerializer() { - return new JacksonSerializer<>(TrackedItemResponse.class); + + return RETURN_SERIALIZER; + } public record TrackedItemRetrieveMessage(UUID itemUUID) { diff --git a/commons/src/main/java/net/swofty/commons/protocol/objects/orchestrator/ChooseGameProtocolObject.java b/commons/src/main/java/net/swofty/commons/protocol/objects/orchestrator/ChooseGameProtocolObject.java index 9dfb17b31..188448ae5 100644 --- a/commons/src/main/java/net/swofty/commons/protocol/objects/orchestrator/ChooseGameProtocolObject.java +++ b/commons/src/main/java/net/swofty/commons/protocol/objects/orchestrator/ChooseGameProtocolObject.java @@ -11,15 +11,25 @@ public class ChooseGameProtocolObject extends ProtocolObject { + private static final Serializer SERIALIZER = + new JacksonSerializer<>(ChooseGameMessage.class); + private static final Serializer RETURN_SERIALIZER = + new JacksonSerializer<>(ChooseGameResponse.class); @Override + public Serializer getSerializer() { - return new JacksonSerializer<>(ChooseGameMessage.class); + + return SERIALIZER; + } @Override + public Serializer getReturnSerializer() { - return new JacksonSerializer<>(ChooseGameResponse.class); + + return RETURN_SERIALIZER; + } public record ChooseGameMessage(UUID player, UnderstandableProxyServer server, String gameId) { diff --git a/commons/src/main/java/net/swofty/commons/protocol/objects/orchestrator/GameHeartbeatProtocolObject.java b/commons/src/main/java/net/swofty/commons/protocol/objects/orchestrator/GameHeartbeatProtocolObject.java index ac9519f78..22846481c 100644 --- a/commons/src/main/java/net/swofty/commons/protocol/objects/orchestrator/GameHeartbeatProtocolObject.java +++ b/commons/src/main/java/net/swofty/commons/protocol/objects/orchestrator/GameHeartbeatProtocolObject.java @@ -13,15 +13,25 @@ public class GameHeartbeatProtocolObject extends ProtocolObject { + private static final Serializer SERIALIZER = + new JacksonSerializer<>(HeartbeatMessage.class); + private static final Serializer RETURN_SERIALIZER = + new JacksonSerializer<>(HeartbeatResponse.class); @Override + public Serializer getSerializer() { - return new JacksonSerializer<>(HeartbeatMessage.class); + + return SERIALIZER; + } @Override + public Serializer getReturnSerializer() { - return new JacksonSerializer<>(HeartbeatResponse.class); + + return RETURN_SERIALIZER; + } public record HeartbeatMessage(UUID uuid, String shortName, ServerType type, int maxPlayers, int onlinePlayers, List games) { } diff --git a/commons/src/main/java/net/swofty/commons/protocol/objects/orchestrator/GetGameCountsProtocolObject.java b/commons/src/main/java/net/swofty/commons/protocol/objects/orchestrator/GetGameCountsProtocolObject.java index 2a608bb73..d392db796 100644 --- a/commons/src/main/java/net/swofty/commons/protocol/objects/orchestrator/GetGameCountsProtocolObject.java +++ b/commons/src/main/java/net/swofty/commons/protocol/objects/orchestrator/GetGameCountsProtocolObject.java @@ -9,15 +9,25 @@ public class GetGameCountsProtocolObject extends ProtocolObject { + private static final Serializer SERIALIZER = + new JacksonSerializer<>(GetGameCountsMessage.class); + private static final Serializer RETURN_SERIALIZER = + new JacksonSerializer<>(GetGameCountsResponse.class); @Override + public Serializer getSerializer() { - return new JacksonSerializer<>(GetGameCountsMessage.class); + + return SERIALIZER; + } @Override + public Serializer getReturnSerializer() { - return new JacksonSerializer<>(GetGameCountsResponse.class); + + return RETURN_SERIALIZER; + } public record GetGameCountsMessage(ServerType type, String gameTypeName, String mapName) { } diff --git a/commons/src/main/java/net/swofty/commons/protocol/objects/orchestrator/GetMapsProtocolObject.java b/commons/src/main/java/net/swofty/commons/protocol/objects/orchestrator/GetMapsProtocolObject.java index 6bc7f4232..0d2776ccf 100644 --- a/commons/src/main/java/net/swofty/commons/protocol/objects/orchestrator/GetMapsProtocolObject.java +++ b/commons/src/main/java/net/swofty/commons/protocol/objects/orchestrator/GetMapsProtocolObject.java @@ -11,15 +11,25 @@ public class GetMapsProtocolObject extends ProtocolObject { + private static final Serializer SERIALIZER = + new JacksonSerializer<>(GetMapsMessage.class); + private static final Serializer RETURN_SERIALIZER = + new JacksonSerializer<>(GetMapsResponse.class); @Override + public Serializer getSerializer() { - return new JacksonSerializer<>(GetMapsMessage.class); + + return SERIALIZER; + } @Override + public Serializer getReturnSerializer() { - return new JacksonSerializer<>(GetMapsResponse.class); + + return RETURN_SERIALIZER; + } public record GetMapsMessage(ServerType type, String mode) { } diff --git a/commons/src/main/java/net/swofty/commons/protocol/objects/orchestrator/GetServerForMapProtocolObject.java b/commons/src/main/java/net/swofty/commons/protocol/objects/orchestrator/GetServerForMapProtocolObject.java index 2c338eb00..debeec02c 100644 --- a/commons/src/main/java/net/swofty/commons/protocol/objects/orchestrator/GetServerForMapProtocolObject.java +++ b/commons/src/main/java/net/swofty/commons/protocol/objects/orchestrator/GetServerForMapProtocolObject.java @@ -10,15 +10,25 @@ public class GetServerForMapProtocolObject extends ProtocolObject { + private static final Serializer SERIALIZER = + new JacksonSerializer<>(GetServerForMapMessage.class); + private static final Serializer RETURN_SERIALIZER = + new JacksonSerializer<>(GetServerForMapResponse.class); @Override + public Serializer getSerializer() { - return new JacksonSerializer<>(GetServerForMapMessage.class); + + return SERIALIZER; + } @Override + public Serializer getReturnSerializer() { - return new JacksonSerializer<>(GetServerForMapResponse.class); + + return RETURN_SERIALIZER; + } public record GetServerForMapMessage(ServerType type, @Nullable String map, String mode, int neededSlots) { diff --git a/commons/src/main/java/net/swofty/commons/protocol/objects/party/GetPartyProtocolObject.java b/commons/src/main/java/net/swofty/commons/protocol/objects/party/GetPartyProtocolObject.java index 77f769413..218f99627 100644 --- a/commons/src/main/java/net/swofty/commons/protocol/objects/party/GetPartyProtocolObject.java +++ b/commons/src/main/java/net/swofty/commons/protocol/objects/party/GetPartyProtocolObject.java @@ -11,15 +11,25 @@ public class GetPartyProtocolObject extends ProtocolObject { + private static final Serializer SERIALIZER = + new JacksonSerializer<>(GetPartyMessage.class); + private static final Serializer RETURN_SERIALIZER = + new JacksonSerializer<>(GetPartyResponse.class); @Override + public Serializer getSerializer() { - return new JacksonSerializer<>(GetPartyMessage.class); + + return SERIALIZER; + } @Override + public Serializer getReturnSerializer() { - return new JacksonSerializer<>(GetPartyResponse.class); + + return RETURN_SERIALIZER; + } public record GetPartyMessage(UUID memberUuid) { } diff --git a/commons/src/main/java/net/swofty/commons/protocol/objects/party/IsPlayerInPartyProtocolObject.java b/commons/src/main/java/net/swofty/commons/protocol/objects/party/IsPlayerInPartyProtocolObject.java index e0b8f7efa..3e093db1c 100644 --- a/commons/src/main/java/net/swofty/commons/protocol/objects/party/IsPlayerInPartyProtocolObject.java +++ b/commons/src/main/java/net/swofty/commons/protocol/objects/party/IsPlayerInPartyProtocolObject.java @@ -10,15 +10,25 @@ public class IsPlayerInPartyProtocolObject extends ProtocolObject { + private static final Serializer SERIALIZER = + new JacksonSerializer<>(IsPlayerInPartyMessage.class); + private static final Serializer RETURN_SERIALIZER = + new JacksonSerializer<>(IsPlayerInPartyResponse.class); @Override + public Serializer getSerializer() { - return new JacksonSerializer<>(IsPlayerInPartyMessage.class); + + return SERIALIZER; + } @Override + public Serializer getReturnSerializer() { - return new JacksonSerializer<>(IsPlayerInPartyResponse.class); + + return RETURN_SERIALIZER; + } public record IsPlayerInPartyMessage(UUID playerUUID) { From b3c962cc140fb6111f0dc90ec0dedfe191f3f579 Mon Sep 17 00:00:00 2001 From: "Jacob Nardella (Swofty)" Date: Fri, 15 May 2026 01:45:07 +1000 Subject: [PATCH 078/113] chore(friend): drop unused org.json imports after Jackson migration --- .../commons/friend/events/response/FriendListResponseEvent.java | 1 - .../friend/events/response/FriendRequestsListResponseEvent.java | 1 - 2 files changed, 2 deletions(-) diff --git a/commons/src/main/java/net/swofty/commons/friend/events/response/FriendListResponseEvent.java b/commons/src/main/java/net/swofty/commons/friend/events/response/FriendListResponseEvent.java index ca949421b..563ba4510 100644 --- a/commons/src/main/java/net/swofty/commons/friend/events/response/FriendListResponseEvent.java +++ b/commons/src/main/java/net/swofty/commons/friend/events/response/FriendListResponseEvent.java @@ -6,7 +6,6 @@ import net.swofty.commons.friend.FriendResponseEvent; import net.swofty.commons.protocol.JacksonSerializer; import net.swofty.commons.protocol.Serializer; -import org.json.JSONArray; import java.util.ArrayList; import java.util.List; diff --git a/commons/src/main/java/net/swofty/commons/friend/events/response/FriendRequestsListResponseEvent.java b/commons/src/main/java/net/swofty/commons/friend/events/response/FriendRequestsListResponseEvent.java index 2689bd5a6..86374d608 100644 --- a/commons/src/main/java/net/swofty/commons/friend/events/response/FriendRequestsListResponseEvent.java +++ b/commons/src/main/java/net/swofty/commons/friend/events/response/FriendRequestsListResponseEvent.java @@ -6,7 +6,6 @@ import net.swofty.commons.friend.FriendResponseEvent; import net.swofty.commons.protocol.JacksonSerializer; import net.swofty.commons.protocol.Serializer; -import org.json.JSONArray; import java.util.ArrayList; import java.util.List; From 53683aa374afa0209e70e1fff5a2bca1c8978022 Mon Sep 17 00:00:00 2001 From: "Jacob Nardella (Swofty)" Date: Fri, 15 May 2026 01:50:27 +1000 Subject: [PATCH 079/113] chore(commons): delete unused MinecraftVersion enum MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The enum had every MC version from 1.7.2 to 1.21.11 listed with its protocol ID, but the static byProtocolId() lookup wasn't called from anywhere in the tree. Nothing else referenced MinecraftVersion either. Pure dead-weight infrastructure waiting for code that didn't show up. Removed — 76 lines. --- .../net/swofty/commons/MinecraftVersion.java | 76 ------------------- 1 file changed, 76 deletions(-) delete mode 100644 commons/src/main/java/net/swofty/commons/MinecraftVersion.java diff --git a/commons/src/main/java/net/swofty/commons/MinecraftVersion.java b/commons/src/main/java/net/swofty/commons/MinecraftVersion.java deleted file mode 100644 index 3bf3d1843..000000000 --- a/commons/src/main/java/net/swofty/commons/MinecraftVersion.java +++ /dev/null @@ -1,76 +0,0 @@ -package net.swofty.commons; - -import lombok.Getter; - -import java.util.Arrays; -@Getter -public enum MinecraftVersion { - MINECRAFT_1_7_2(4, new String[]{"1.7.2", "1.7.3", "1.7.4", "1.7.5"}), - MINECRAFT_1_7_6(5, new String[]{"1.7.6", "1.7.7", "1.7.8", "1.7.9", "1.7.10"}), - MINECRAFT_1_8(47, new String[]{"1.8", "1.8.1", "1.8.2", "1.8.3", "1.8.4", "1.8.5", "1.8.6", "1.8.7", "1.8.8", "1.8.9"}), - MINECRAFT_1_9(107, new String[]{"1.9"}), - MINECRAFT_1_9_1(108, new String[]{"1.9.1"}), - MINECRAFT_1_9_2(109, new String[]{"1.9.2"}), - MINECRAFT_1_9_4(110, new String[]{"1.9.3", "1.9.4"}), - MINECRAFT_1_10(210, new String[]{"1.10", "1.10.1", "1.10.2"}), - MINECRAFT_1_11(315, new String[]{"1.11"}), - MINECRAFT_1_11_1(316, new String[]{"1.11.1", "1.11.2"}), - MINECRAFT_1_12(335, new String[]{"1.12"}), - MINECRAFT_1_12_1(338, new String[]{"1.12.1"}), - MINECRAFT_1_12_2(340, new String[]{"1.12.2"}), - MINECRAFT_1_13(393, new String[]{"1.13"}), - MINECRAFT_1_13_1(401, new String[]{"1.13.1"}), - MINECRAFT_1_13_2(404, new String[]{"1.13.2"}), - MINECRAFT_1_14(477, new String[]{"1.14"}), - MINECRAFT_1_14_1(480, new String[]{"1.14.1"}), - MINECRAFT_1_14_2(485, new String[]{"1.14.2"}), - MINECRAFT_1_14_3(490, new String[]{"1.14.3"}), - MINECRAFT_1_14_4(498, new String[]{"1.14.4"}), - MINECRAFT_1_15(573, new String[]{"1.15"}), - MINECRAFT_1_15_1(575, new String[]{"1.15.1"}), - MINECRAFT_1_15_2(578, new String[]{"1.15.2"}), - MINECRAFT_1_16(735, new String[]{"1.16"}), - MINECRAFT_1_16_1(736, new String[]{"1.16.1"}), - MINECRAFT_1_16_2(751, new String[]{"1.16.2"}), - MINECRAFT_1_16_3(753, new String[]{"1.16.3"}), - MINECRAFT_1_16_4(754, new String[]{"1.16.4", "1.16.5"}), - MINECRAFT_1_17(755, new String[]{"1.17"}), - MINECRAFT_1_17_1(756, new String[]{"1.17.1"}), - MINECRAFT_1_18(757, new String[]{"1.18", "1.18.1"}), - MINECRAFT_1_18_2(758, new String[]{"1.18.2"}), - MINECRAFT_1_19(759, new String[]{"1.19"}), - MINECRAFT_1_19_1(760, new String[]{"1.19.1", "1.19.2"}), - MINECRAFT_1_19_3(761, new String[]{"1.19.3"}), - MINECRAFT_1_19_4(762, new String[]{"1.19.4"}), - MINECRAFT_1_20(763, new String[]{"1.20", "1.20.1"}), - MINECRAFT_1_20_2(764, new String[]{"1.20.2"}), - MINECRAFT_1_20_3(765, new String[]{"1.20.3", "1.20.4"}), - MINECRAFT_1_20_5(766, new String[]{"1.20.5", "1.20.6"}), - MINECRAFT_1_21(767, new String[]{"1.21", "1.21.1"}), - MINECRAFT_1_21_2(768, new String[]{"1.21.2", "1.21.3"}), - MINECRAFT_1_21_4(769, new String[]{"1.21.4"}), - MINECRAFT_1_21_5(770, new String[]{"1.21.5"}), - MINECRAFT_1_21_6(771, new String[]{"1.21.6"}), - MINECRAFT_1_21_7(772, new String[]{"1.21.7"}), - MINECRAFT_1_21_8(772, new String[]{"1.21.8"}), - MINECRAFT_1_21_9(773, new String[]{"1.21.9"}), - MINECRAFT_1_21_10(773, new String[]{"1.21.10"}), - MINECRAFT_1_21_11(774, new String[]{"1.21.11"}), - ; - - private final int protocol; - private final String[] versions; - - MinecraftVersion(int protocol, String[] versions) { - this.protocol = protocol; - this.versions = versions; - } - - public static MinecraftVersion byProtocolId(int protocolID) { - return Arrays.stream(MinecraftVersion.values()) - .filter(version -> version.protocol == protocolID) - .findFirst() - .orElse(null); - } - -} From 770e851b9f2e1d2f2592d4b2d237d8b8bee1bac7 Mon Sep 17 00:00:00 2001 From: "Jacob Nardella (Swofty)" Date: Fri, 15 May 2026 01:51:20 +1000 Subject: [PATCH 080/113] perf(commons): O(1) lookup for ChatColor.getLastColor MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The inner enum scan was O(n) per position — for every position where the § marker was found, it walked all 22 ChatColor values to match the code character. Built a static Map at class init and look up directly. Same behaviour, constant-time lookup instead of linear. --- .../java/net/swofty/commons/ChatColor.java | 22 ++++++++++--------- 1 file changed, 12 insertions(+), 10 deletions(-) diff --git a/commons/src/main/java/net/swofty/commons/ChatColor.java b/commons/src/main/java/net/swofty/commons/ChatColor.java index 27dae1885..293e76e08 100644 --- a/commons/src/main/java/net/swofty/commons/ChatColor.java +++ b/commons/src/main/java/net/swofty/commons/ChatColor.java @@ -31,6 +31,14 @@ public enum ChatColor { public static final char COLOR_CHAR = '§'; private static final Pattern STRIP_COLOR_PATTERN = Pattern.compile("(?i)" + '§' + "[0-9A-FK-OR]"); + private static final java.util.Map BY_CODE = new java.util.HashMap<>(); + + static { + for (ChatColor color : values()) { + BY_CODE.put(color.code, color); + } + } + private final int intCode; private final char code; private final boolean isFormat; @@ -53,16 +61,10 @@ public static ChatColor getLastColor(String text) { return null; } for (int i = text.length() - 2; i >= 0; i--) { - - char currentChar = text.charAt(i); - if (currentChar == ChatColor.COLOR_CHAR) { - - char colorCode = text.charAt(i + 1); - for (ChatColor chatColor : ChatColor.values()) { - - if (chatColor.getCode() == colorCode) { - return chatColor; - } + if (text.charAt(i) == ChatColor.COLOR_CHAR) { + ChatColor color = BY_CODE.get(text.charAt(i + 1)); + if (color != null) { + return color; } } } From 259c3b6b87e4695348317a76bb6258b29c88ded6 Mon Sep 17 00:00:00 2001 From: "Jacob Nardella (Swofty)" Date: Fri, 15 May 2026 01:54:00 +1000 Subject: [PATCH 081/113] chore: drop noisy '// stub' comments from default-empty event hooks The SimpleInteractableItem base classes in bedwars-game and murder-mystery-game declared override-friendly hooks (onItemUse, onItemDrop, etc.) with empty default bodies, each commented '// stub'. The empty braces already say the same thing; the comment was pure noise. --- .../item/SimpleInteractableItem.java | 24 +++++-------------- .../item/SimpleInteractableItem.java | 24 +++++-------------- 2 files changed, 12 insertions(+), 36 deletions(-) diff --git a/type.bedwarsgame/src/main/java/net/swofty/type/bedwarsgame/item/SimpleInteractableItem.java b/type.bedwarsgame/src/main/java/net/swofty/type/bedwarsgame/item/SimpleInteractableItem.java index a1a0c7881..b50ad4a18 100644 --- a/type.bedwarsgame/src/main/java/net/swofty/type/bedwarsgame/item/SimpleInteractableItem.java +++ b/type.bedwarsgame/src/main/java/net/swofty/type/bedwarsgame/item/SimpleInteractableItem.java @@ -28,27 +28,15 @@ public ItemStack getItemStack() { new CustomData(CompoundBinaryTag.builder().putString("item", id).build())); } - public void onItemFinishUse(PlayerFinishItemUseEvent event) { - // stub - } + public void onItemFinishUse(PlayerFinishItemUseEvent event) {} - public void onItemUseOnBlock(PlayerUseItemOnBlockEvent event) { - // stub - } + public void onItemUseOnBlock(PlayerUseItemOnBlockEvent event) {} - public void onItemUse(PlayerUseItemEvent event) { - // stub - } + public void onItemUse(PlayerUseItemEvent event) {} - public void onItemDrop(ItemDropEvent event) { - // stub - } + public void onItemDrop(ItemDropEvent event) {} - public void onItemInteract(PlayerInstanceEvent event) { - // stub - } + public void onItemInteract(PlayerInstanceEvent event) {} - public void onBlockPlace(PlayerBlockPlaceEvent event) { - // stub - } + public void onBlockPlace(PlayerBlockPlaceEvent event) {} } diff --git a/type.murdermysterygame/src/main/java/net/swofty/type/murdermysterygame/item/SimpleInteractableItem.java b/type.murdermysterygame/src/main/java/net/swofty/type/murdermysterygame/item/SimpleInteractableItem.java index d90619502..96451281a 100644 --- a/type.murdermysterygame/src/main/java/net/swofty/type/murdermysterygame/item/SimpleInteractableItem.java +++ b/type.murdermysterygame/src/main/java/net/swofty/type/murdermysterygame/item/SimpleInteractableItem.java @@ -28,27 +28,15 @@ public ItemStack getItemStack() { new CustomData(CompoundBinaryTag.builder().putString("item", id).build())); } - public void onItemFinishUse(PlayerFinishItemUseEvent event) { - // stub - } + public void onItemFinishUse(PlayerFinishItemUseEvent event) {} - public void onItemUseOnBlock(PlayerUseItemOnBlockEvent event) { - // stub - } + public void onItemUseOnBlock(PlayerUseItemOnBlockEvent event) {} - public void onItemUse(PlayerUseItemEvent event) { - // stub - } + public void onItemUse(PlayerUseItemEvent event) {} - public void onItemDrop(ItemDropEvent event) { - // stub - } + public void onItemDrop(ItemDropEvent event) {} - public void onItemInteract(PlayerInstanceEvent event) { - // stub - } + public void onItemInteract(PlayerInstanceEvent event) {} - public void onBlockPlace(PlayerBlockPlaceEvent event) { - // stub - } + public void onBlockPlace(PlayerBlockPlaceEvent event) {} } From 3cd0ca109a9c4ba1dca514aa4d3efca5c1f78142 Mon Sep 17 00:00:00 2001 From: "Jacob Nardella (Swofty)" Date: Fri, 15 May 2026 01:56:25 +1000 Subject: [PATCH 082/113] chore(player): remove commented-out showTitle in HypixelPlayer.sendTo MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The black-fade transition was commented out in the original PR — git history has it if anyone wants to revive it. Keeping it as a block comment just makes sendTo noisier to read. --- .../java/net/swofty/type/generic/user/HypixelPlayer.java | 6 ------ 1 file changed, 6 deletions(-) diff --git a/type.generic/src/main/java/net/swofty/type/generic/user/HypixelPlayer.java b/type.generic/src/main/java/net/swofty/type/generic/user/HypixelPlayer.java index a5a2882c1..6d2f22220 100644 --- a/type.generic/src/main/java/net/swofty/type/generic/user/HypixelPlayer.java +++ b/type.generic/src/main/java/net/swofty/type/generic/user/HypixelPlayer.java @@ -181,12 +181,6 @@ public void sendTo(ServerType type, boolean force) { HypixelConst.getTypeLoader().getTablistManager().nullifyCache(this); - /*showTitle(Title.title( - Component.text(HypixelTexture.FULL_SCREEN_BLACK.toString()), - Component.empty(), - Title.Times.times(Duration.ofSeconds(1), Duration.ofMillis(300), Duration.ZERO) - ));*/ - player.transferTo(type); } From 6725d0de27e6516d0fb2c1b7103839a01ccf1f1b Mon Sep 17 00:00:00 2001 From: "Jacob Nardella (Swofty)" Date: Fri, 15 May 2026 01:56:53 +1000 Subject: [PATCH 083/113] chore(velocity): drop commented-out limbo bypass in SkyBlockVelocity reconnect handler --- .../net/swofty/velocity/SkyBlockVelocity.java | 15 +++------------ 1 file changed, 3 insertions(+), 12 deletions(-) diff --git a/velocity.extension/src/main/java/net/swofty/velocity/SkyBlockVelocity.java b/velocity.extension/src/main/java/net/swofty/velocity/SkyBlockVelocity.java index 139bf511c..71db2586e 100644 --- a/velocity.extension/src/main/java/net/swofty/velocity/SkyBlockVelocity.java +++ b/velocity.extension/src/main/java/net/swofty/velocity/SkyBlockVelocity.java @@ -403,18 +403,9 @@ public void onServerCrash(KickedFromServerEvent event) { CompletableFuture.delayedExecutor(GameManager.SLEEP_TIME + 300, TimeUnit.MILLISECONDS) .execute(() -> { - // Determine if the registeredServer disconnect was due to a crash - // if it was, then we send the player back to another registeredServer - // of that type, otherwise we disconnect them for the same - // reason as the original - - /*boolean isOnline = GameManager.getFromRegisteredServer(originalServer) != null; - if (isOnline) { - transferHandler.forceRemoveFromLimbo(); - event.getPlayer().disconnect(reason); - return; - }*/ - + // Determine if the registeredServer disconnect was due to a crash — + // if it was, send the player to another server of that type; + // otherwise disconnect them with the original reason. try { ServerType serverTypeToTry = serverType; if (!GameManager.hasType(serverTypeToTry) || !GameManager.isAnyEmpty(serverTypeToTry)) { From fc1f5eb990bccd0cdf1c8ea21b4920f49ac7641b Mon Sep 17 00:00:00 2001 From: "Jacob Nardella (Swofty)" Date: Fri, 15 May 2026 01:58:50 +1000 Subject: [PATCH 084/113] perf(proxy): drop redundant ArrayList wrap in ProxyPlayerSet.asProxyPlayers stream().map(...).toList() already produces a list; wrapping that in a fresh ArrayList just to immediately discard it doubles the allocation. None of the four callers mutate the result (anyMatch, forEach, for-each) so returning the immutable view is fine. --- .../src/main/java/net/swofty/proxyapi/ProxyPlayerSet.java | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/proxy.api/src/main/java/net/swofty/proxyapi/ProxyPlayerSet.java b/proxy.api/src/main/java/net/swofty/proxyapi/ProxyPlayerSet.java index 9c0d9d172..8e4895c95 100644 --- a/proxy.api/src/main/java/net/swofty/proxyapi/ProxyPlayerSet.java +++ b/proxy.api/src/main/java/net/swofty/proxyapi/ProxyPlayerSet.java @@ -2,7 +2,6 @@ import lombok.Getter; -import java.util.ArrayList; import java.util.List; import java.util.UUID; @@ -15,6 +14,6 @@ public ProxyPlayerSet(List players) { } public List asProxyPlayers() { - return new ArrayList<>(players.stream().map(ProxyPlayer::new).toList()); + return players.stream().map(ProxyPlayer::new).toList(); } } From edf06be4c096eb5df1dff2725c3b21ae28f19739 Mon Sep 17 00:00:00 2001 From: "Jacob Nardella (Swofty)" Date: Fri, 15 May 2026 02:05:06 +1000 Subject: [PATCH 085/113] refactor(velocity): convert TestFlowManager.ServerConfig to record MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Two final fields, a constructor that just assigns, plus a static fromJson factory — fits the record shape exactly. Dropped the @Getter and updated the one method reference (ServerConfig::getCount → ServerConfig::count) inside getTotalExpectedServers. --- .../velocity/testflow/TestFlowManager.java | 20 ++++++------------- 1 file changed, 6 insertions(+), 14 deletions(-) diff --git a/velocity.extension/src/main/java/net/swofty/velocity/testflow/TestFlowManager.java b/velocity.extension/src/main/java/net/swofty/velocity/testflow/TestFlowManager.java index a52692c70..184d2797d 100644 --- a/velocity.extension/src/main/java/net/swofty/velocity/testflow/TestFlowManager.java +++ b/velocity.extension/src/main/java/net/swofty/velocity/testflow/TestFlowManager.java @@ -209,20 +209,12 @@ private static void loadTestFlowHandler(ProxyTestFlowInstance instance) { /** * Server configuration for test flows */ - @Getter - public static class ServerConfig { - private final ServerType serverType; - private final int count; - - public ServerConfig(ServerType serverType, int count) { - this.serverType = serverType; - this.count = count; - } - + public record ServerConfig(ServerType serverType, int count) { public static ServerConfig fromJson(org.json.JSONObject json) { - ServerType type = ServerType.valueOf(json.getString("type")); - int count = json.getInt("count"); - return new ServerConfig(type, count); + return new ServerConfig( + ServerType.valueOf(json.getString("type")), + json.getInt("count") + ); } } @@ -282,7 +274,7 @@ public boolean hasPlayer(String playerName) { public int getTotalExpectedServers() { return serverConfigs.stream() - .mapToInt(ServerConfig::getCount) + .mapToInt(ServerConfig::count) .sum(); } From 4a6f1095e7c20032d308ad71a4282fe3a36a744d Mon Sep 17 00:00:00 2001 From: "Jacob Nardella (Swofty)" Date: Fri, 15 May 2026 02:08:02 +1000 Subject: [PATCH 086/113] chore(bedwars): mark BedwarsLevelUtil as a proper utility class MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit final + private constructor — all methods are static, no reason to let a caller instantiate this. --- .../java/net/swofty/commons/bedwars/BedwarsLevelUtil.java | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/commons/src/main/java/net/swofty/commons/bedwars/BedwarsLevelUtil.java b/commons/src/main/java/net/swofty/commons/bedwars/BedwarsLevelUtil.java index fe0403458..c447269ef 100644 --- a/commons/src/main/java/net/swofty/commons/bedwars/BedwarsLevelUtil.java +++ b/commons/src/main/java/net/swofty/commons/bedwars/BedwarsLevelUtil.java @@ -2,7 +2,9 @@ import java.text.DecimalFormat; -public class BedwarsLevelUtil { +public final class BedwarsLevelUtil { + + private BedwarsLevelUtil() {} private static final DecimalFormat FORMAT = new DecimalFormat("#,###.#"); From 4b68125890e62f284a5c6a0460ac04306174b42a Mon Sep 17 00:00:00 2001 From: "Jacob Nardella (Swofty)" Date: Fri, 15 May 2026 02:09:04 +1000 Subject: [PATCH 087/113] chore(commons): mark YamlFileUtils + SkywarsLevelUtil as proper utility classes Both expose only static helpers but allowed implicit public no-arg construction. final + private constructor makes the intent explicit and prevents the spurious-instantiation footgun. --- commons/src/main/java/net/swofty/commons/YamlFileUtils.java | 5 ++++- .../java/net/swofty/commons/skywars/SkywarsLevelUtil.java | 4 +++- 2 files changed, 7 insertions(+), 2 deletions(-) diff --git a/commons/src/main/java/net/swofty/commons/YamlFileUtils.java b/commons/src/main/java/net/swofty/commons/YamlFileUtils.java index 4738d32ac..714cd59f3 100644 --- a/commons/src/main/java/net/swofty/commons/YamlFileUtils.java +++ b/commons/src/main/java/net/swofty/commons/YamlFileUtils.java @@ -13,7 +13,10 @@ import java.util.stream.Collectors; import java.util.stream.Stream; -public class YamlFileUtils { +public final class YamlFileUtils { + + private YamlFileUtils() {} + /** * Get all YAML files in a directory and its subdirectories * @param directory The base directory to search in diff --git a/commons/src/main/java/net/swofty/commons/skywars/SkywarsLevelUtil.java b/commons/src/main/java/net/swofty/commons/skywars/SkywarsLevelUtil.java index 0987ffaaa..9468f4400 100644 --- a/commons/src/main/java/net/swofty/commons/skywars/SkywarsLevelUtil.java +++ b/commons/src/main/java/net/swofty/commons/skywars/SkywarsLevelUtil.java @@ -2,7 +2,9 @@ import java.text.DecimalFormat; -public class SkywarsLevelUtil { +public final class SkywarsLevelUtil { + + private SkywarsLevelUtil() {} private static final DecimalFormat FORMAT = new DecimalFormat("#,###.#"); From 32a56680f86ad826f55ed33ada0299774cabe677 Mon Sep 17 00:00:00 2001 From: "Jacob Nardella (Swofty)" Date: Fri, 15 May 2026 02:09:34 +1000 Subject: [PATCH 088/113] chore(commons): mark StringUtility as a proper utility class Final + private constructor for the static-only helper. The class has been around long enough that this was a small oversight from day one. --- commons/src/main/java/net/swofty/commons/StringUtility.java | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/commons/src/main/java/net/swofty/commons/StringUtility.java b/commons/src/main/java/net/swofty/commons/StringUtility.java index 2c7b36e98..997f2ac35 100644 --- a/commons/src/main/java/net/swofty/commons/StringUtility.java +++ b/commons/src/main/java/net/swofty/commons/StringUtility.java @@ -16,7 +16,10 @@ import java.util.regex.Matcher; import java.util.regex.Pattern; -public class StringUtility { +public final class StringUtility { + + private StringUtility() {} + public static final char[] ALPHABET = { 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'W', 'X', 'Y', 'Z' }; From 894e86821944756b2d9b3d4a2438b551adf98da5 Mon Sep 17 00:00:00 2001 From: "Jacob Nardella (Swofty)" Date: Fri, 15 May 2026 02:10:06 +1000 Subject: [PATCH 089/113] chore(util): mark MathUtility as a proper utility class --- .../java/net/swofty/type/generic/utility/MathUtility.java | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/type.generic/src/main/java/net/swofty/type/generic/utility/MathUtility.java b/type.generic/src/main/java/net/swofty/type/generic/utility/MathUtility.java index 16ca4240d..212e48774 100644 --- a/type.generic/src/main/java/net/swofty/type/generic/utility/MathUtility.java +++ b/type.generic/src/main/java/net/swofty/type/generic/utility/MathUtility.java @@ -12,7 +12,10 @@ import java.util.ArrayList; import java.util.List; -public class MathUtility { +public final class MathUtility { + + private MathUtility() {} + public static double normalizeAngle(double angle, double maximum) { return (angle % maximum + maximum) % maximum - (maximum / 2); } From 9d8e3002a25cc1b4e6b007e87d610d0e2756ee27 Mon Sep 17 00:00:00 2001 From: "Jacob Nardella (Swofty)" Date: Fri, 15 May 2026 02:11:26 +1000 Subject: [PATCH 090/113] chore(util): mark BlockUtility / ChestUtility / BufferUtility as proper utility classes Three more static-only helpers got final + private constructor. --- .../java/net/swofty/type/generic/utility/BlockUtility.java | 5 ++++- .../java/net/swofty/type/generic/utility/BufferUtility.java | 5 ++++- .../java/net/swofty/type/generic/utility/ChestUtility.java | 5 ++++- 3 files changed, 12 insertions(+), 3 deletions(-) diff --git a/type.generic/src/main/java/net/swofty/type/generic/utility/BlockUtility.java b/type.generic/src/main/java/net/swofty/type/generic/utility/BlockUtility.java index 185113478..d72de76a9 100644 --- a/type.generic/src/main/java/net/swofty/type/generic/utility/BlockUtility.java +++ b/type.generic/src/main/java/net/swofty/type/generic/utility/BlockUtility.java @@ -4,7 +4,10 @@ import net.minestom.server.instance.block.Block; import org.json.JSONObject; -public class BlockUtility { +public final class BlockUtility { + + private BlockUtility() {} + public static Block applyTexture(Block block, String texture) { JSONObject json = new JSONObject(); diff --git a/type.generic/src/main/java/net/swofty/type/generic/utility/BufferUtility.java b/type.generic/src/main/java/net/swofty/type/generic/utility/BufferUtility.java index c0b32448f..cdbff83c0 100644 --- a/type.generic/src/main/java/net/swofty/type/generic/utility/BufferUtility.java +++ b/type.generic/src/main/java/net/swofty/type/generic/utility/BufferUtility.java @@ -3,7 +3,10 @@ import java.nio.ByteBuffer; import java.nio.charset.StandardCharsets; -public class BufferUtility { +public final class BufferUtility { + + private BufferUtility() {} + public static int getUnsignedShort(ByteBuffer buffer) { byte[] bytes = new byte[2]; buffer.get(bytes); diff --git a/type.generic/src/main/java/net/swofty/type/generic/utility/ChestUtility.java b/type.generic/src/main/java/net/swofty/type/generic/utility/ChestUtility.java index 84ba5137c..70e9cb30f 100644 --- a/type.generic/src/main/java/net/swofty/type/generic/utility/ChestUtility.java +++ b/type.generic/src/main/java/net/swofty/type/generic/utility/ChestUtility.java @@ -5,7 +5,10 @@ import net.minestom.server.instance.Instance; import net.minestom.server.instance.block.Block; -public class ChestUtility { +public final class ChestUtility { + + private ChestUtility() {} + public static Point[] getDoubleChestPositions(Instance instance, Point point) { Point[] positions = new Point[2]; From 8ece659e3558dd47d8364f4c4c95c0d1b399dc32 Mon Sep 17 00:00:00 2001 From: "Jacob Nardella (Swofty)" Date: Fri, 15 May 2026 02:14:32 +1000 Subject: [PATCH 091/113] chore(util): mark genuinely-static utility classes final with private ctors MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Sweep across pvp/utils (EffectUtil, FluidUtil, EntityUtil, ViewUtil, ProjectileUtil, ChorusFruitUtil), anticheat ChunkUtils, bedwars ColorUtil, dungeons DungeonUtilities, ChatUtility, and a few others. Excluded two false positives the script's name-based filter caught: UtilityEffectHandler and BlockUtils both have public constructors that take constructor arguments — they're instantiable handlers, not static-only utilities. Manually reverted those. --- .../src/main/java/net/swofty/anticheat/math/ChunkUtils.java | 5 ++++- commons/src/main/java/net/swofty/commons/ChatUtility.java | 5 ++++- .../src/main/java/net/swofty/dungeons/DungeonUtilities.java | 5 ++++- .../java/net/swofty/pvp/feature/food/ChorusFruitUtil.java | 5 ++++- pvp/src/main/java/net/swofty/pvp/utils/EffectUtil.java | 5 ++++- pvp/src/main/java/net/swofty/pvp/utils/EntityUtil.java | 5 ++++- pvp/src/main/java/net/swofty/pvp/utils/FluidUtil.java | 5 ++++- pvp/src/main/java/net/swofty/pvp/utils/ProjectileUtil.java | 5 ++++- pvp/src/main/java/net/swofty/pvp/utils/ViewUtil.java | 5 ++++- .../java/net/swofty/type/bedwarsgame/util/ColorUtil.java | 5 ++++- .../type/skyblockgeneric/block/placement/BlockUtils.java | 3 ++- .../skyblockgeneric/potion/handler/UtilityEffectHandler.java | 2 +- 12 files changed, 43 insertions(+), 12 deletions(-) diff --git a/anticheat/src/main/java/net/swofty/anticheat/math/ChunkUtils.java b/anticheat/src/main/java/net/swofty/anticheat/math/ChunkUtils.java index b1af7900d..e4bb8b787 100644 --- a/anticheat/src/main/java/net/swofty/anticheat/math/ChunkUtils.java +++ b/anticheat/src/main/java/net/swofty/anticheat/math/ChunkUtils.java @@ -1,6 +1,9 @@ package net.swofty.anticheat.math; -public class ChunkUtils { +public final class ChunkUtils { + + private ChunkUtils() {} + public static int getChunkCoordinate(double xz) { return getChunkCoordinate((int) Math.floor(xz)); } diff --git a/commons/src/main/java/net/swofty/commons/ChatUtility.java b/commons/src/main/java/net/swofty/commons/ChatUtility.java index 0b60cf6ca..1242246c5 100644 --- a/commons/src/main/java/net/swofty/commons/ChatUtility.java +++ b/commons/src/main/java/net/swofty/commons/ChatUtility.java @@ -4,7 +4,10 @@ import java.util.List; -public class ChatUtility { +public final class ChatUtility { + + private ChatUtility() {} + public enum FontInfo { A('A', 5), diff --git a/dungeons/src/main/java/net/swofty/dungeons/DungeonUtilities.java b/dungeons/src/main/java/net/swofty/dungeons/DungeonUtilities.java index 32021af2f..91536c340 100644 --- a/dungeons/src/main/java/net/swofty/dungeons/DungeonUtilities.java +++ b/dungeons/src/main/java/net/swofty/dungeons/DungeonUtilities.java @@ -3,7 +3,10 @@ import java.util.*; import java.util.stream.Stream; -public class DungeonUtilities { +public final class DungeonUtilities { + + private DungeonUtilities() {} + public static Stream> loopOverDungeonRooms(DungeonsData data) { return Stream.iterate(0, i -> i < data.getWidth() * data.getHeight(), i -> i + 1) .map(i -> Map.entry(i % data.getWidth(), i / data.getHeight())); diff --git a/pvp/src/main/java/net/swofty/pvp/feature/food/ChorusFruitUtil.java b/pvp/src/main/java/net/swofty/pvp/feature/food/ChorusFruitUtil.java index bdeea7cbf..c720f8dbc 100644 --- a/pvp/src/main/java/net/swofty/pvp/feature/food/ChorusFruitUtil.java +++ b/pvp/src/main/java/net/swofty/pvp/feature/food/ChorusFruitUtil.java @@ -13,7 +13,10 @@ import java.util.concurrent.ThreadLocalRandom; -public class ChorusFruitUtil { +public final class ChorusFruitUtil { + + private ChorusFruitUtil() {} + private static boolean randomTeleport(Entity entity, Pos to) { Instance instance = entity.getInstance(); assert instance != null; diff --git a/pvp/src/main/java/net/swofty/pvp/utils/EffectUtil.java b/pvp/src/main/java/net/swofty/pvp/utils/EffectUtil.java index 5fc291377..bd9923440 100644 --- a/pvp/src/main/java/net/swofty/pvp/utils/EffectUtil.java +++ b/pvp/src/main/java/net/swofty/pvp/utils/EffectUtil.java @@ -8,7 +8,10 @@ import net.minestom.server.instance.Instance; import net.minestom.server.utils.PacketSendingUtils; -public class EffectUtil { +public final class EffectUtil { + + private EffectUtil() {} + public static void sendNearby(@NotNull Instance instance, @NotNull WorldEvent effect, int x, int y, int z, int data, double distance, boolean global) { WorldEventPacket packet = new WorldEventPacket(effect.id(), new Pos(x, y, z), data, global); diff --git a/pvp/src/main/java/net/swofty/pvp/utils/EntityUtil.java b/pvp/src/main/java/net/swofty/pvp/utils/EntityUtil.java index 605c336c2..775c26e35 100644 --- a/pvp/src/main/java/net/swofty/pvp/utils/EntityUtil.java +++ b/pvp/src/main/java/net/swofty/pvp/utils/EntityUtil.java @@ -15,7 +15,10 @@ import java.lang.reflect.Field; import java.util.Objects; -public class EntityUtil { +public final class EntityUtil { + + private EntityUtil() {} + public static void spawnItemAtLocation(Entity entity, ItemStack itemStack, double up) { if (itemStack.isAir()) return; diff --git a/pvp/src/main/java/net/swofty/pvp/utils/FluidUtil.java b/pvp/src/main/java/net/swofty/pvp/utils/FluidUtil.java index 5ca86f4de..6249cf7b6 100644 --- a/pvp/src/main/java/net/swofty/pvp/utils/FluidUtil.java +++ b/pvp/src/main/java/net/swofty/pvp/utils/FluidUtil.java @@ -8,7 +8,10 @@ import java.util.ArrayList; import java.util.List; -public class FluidUtil { +public final class FluidUtil { + + private FluidUtil() {} + public static int getLevel(Block block) { String levelStr = block.getProperty("level"); if (levelStr == null) return 8; diff --git a/pvp/src/main/java/net/swofty/pvp/utils/ProjectileUtil.java b/pvp/src/main/java/net/swofty/pvp/utils/ProjectileUtil.java index 152ed89cf..e4896c023 100644 --- a/pvp/src/main/java/net/swofty/pvp/utils/ProjectileUtil.java +++ b/pvp/src/main/java/net/swofty/pvp/utils/ProjectileUtil.java @@ -11,7 +11,10 @@ import org.jetbrains.annotations.Nullable; // Copied from Minestom, added singleCollision parameter and removed velocity update -public class ProjectileUtil { +public final class ProjectileUtil { + + private ProjectileUtil() {} + public static @NotNull PhysicsResult simulateMovement(@NotNull Pos entityPosition, @NotNull Vec entityVelocityPerTick, @NotNull BoundingBox entityBoundingBox, @NotNull WorldBorder worldBorder, @NotNull Block.Getter blockGetter, boolean entityHasPhysics, diff --git a/pvp/src/main/java/net/swofty/pvp/utils/ViewUtil.java b/pvp/src/main/java/net/swofty/pvp/utils/ViewUtil.java index 43907c3ae..266ecc989 100644 --- a/pvp/src/main/java/net/swofty/pvp/utils/ViewUtil.java +++ b/pvp/src/main/java/net/swofty/pvp/utils/ViewUtil.java @@ -6,7 +6,10 @@ import java.util.Collections; -public class ViewUtil { +public final class ViewUtil { + + private ViewUtil() {} + public static Audience viewersAndSelf(Entity origin) { if (origin.getChunk() == null) return Audience.empty(); return origin.getChunk().getViewersAsAudience(); diff --git a/type.bedwarsgame/src/main/java/net/swofty/type/bedwarsgame/util/ColorUtil.java b/type.bedwarsgame/src/main/java/net/swofty/type/bedwarsgame/util/ColorUtil.java index c7a5c878e..e17556c78 100644 --- a/type.bedwarsgame/src/main/java/net/swofty/type/bedwarsgame/util/ColorUtil.java +++ b/type.bedwarsgame/src/main/java/net/swofty/type/bedwarsgame/util/ColorUtil.java @@ -7,7 +7,10 @@ import java.awt.*; import java.lang.reflect.Field; -public class ColorUtil { +public final class ColorUtil { + + private ColorUtil() {} + @Nullable public static Color getColorByName(String name) { diff --git a/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/block/placement/BlockUtils.java b/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/block/placement/BlockUtils.java index 011943dcc..7f14fbeda 100644 --- a/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/block/placement/BlockUtils.java +++ b/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/block/placement/BlockUtils.java @@ -10,7 +10,8 @@ import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; -public class BlockUtils { +public final class BlockUtils { + private final Instance instance; private final Point position; private final BlockState blockState; diff --git a/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/potion/handler/UtilityEffectHandler.java b/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/potion/handler/UtilityEffectHandler.java index ed98aa3c0..5031e0264 100644 --- a/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/potion/handler/UtilityEffectHandler.java +++ b/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/potion/handler/UtilityEffectHandler.java @@ -12,7 +12,7 @@ * Handler for utility potions (Night Vision, Fire Resistance, Water Breathing, etc.) * These primarily provide visual effects via Minestom and optionally stat bonuses. */ -public class UtilityEffectHandler implements PotionEffectHandler { +public final class UtilityEffectHandler implements PotionEffectHandler { private final PotionEffectType effectType; From b1e425704311f285bf454642a26d603d2c2327f6 Mon Sep 17 00:00:00 2001 From: "Jacob Nardella (Swofty)" Date: Fri, 15 May 2026 02:16:17 +1000 Subject: [PATCH 092/113] chore(item): pass the SafeConfig parse exception to Logger.error Both ItemConfigParser parse-fail catches dropped e.getMessage() as a template arg, losing the stack trace. Passing the exception directly to Logger.error(e, '...') gets both the message and the full trace into the configured log sinks. --- .../swofty/type/skyblockgeneric/item/ItemConfigParser.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/item/ItemConfigParser.java b/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/item/ItemConfigParser.java index 5366413bb..8bfde514e 100644 --- a/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/item/ItemConfigParser.java +++ b/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/item/ItemConfigParser.java @@ -74,7 +74,7 @@ public static ConfigurableSkyBlockItem parseItem(Map config) { return item; } catch (SafeConfig.ConfigParseException e) { - Logger.error("Failed to parse item: {}", e.getMessage()); + Logger.error(e, "Failed to parse item"); return null; } catch (Exception e) { Logger.error(e, "Unexpected error parsing item"); @@ -674,7 +674,7 @@ yield new PetComponent( default -> throw new IllegalArgumentException("Unknown component type: " + id); }; } catch (SafeConfig.ConfigParseException e) { - Logger.error("Failed to parse component {} for item {}: {}", id, itemId, e.getMessage()); + Logger.error(e, "Failed to parse component {} for item {}", id, itemId); return null; } catch (Exception e) { Logger.error(e, "Unexpected error parsing component {} for item {}", id, itemId); From 10cd9630e82a3dfeab40f69edb62e6c831304157 Mon Sep 17 00:00:00 2001 From: "Jacob Nardella (Swofty)" Date: Fri, 15 May 2026 08:37:56 +1000 Subject: [PATCH 093/113] feat(fishing): implement sea creature spawning on catch MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Replaces the `// TODO: sea creatures` stub in FishingService.awardCatch with a working end-to-end flow: - SeaCreatureMob abstract base extending SkyBlockMob; awards FISHING skill XP on kill (matches Hypixel — sea-creature kills feed fishing). - Six canon Hypixel sea creatures wired up: Squid, Sea Walker, Night Squid, Sea Guardian (water) plus Magma Slug, Lava Blaze (Crimson Isle lava fishing). - SeaCreatureSpawner: factory registry keyed by sea creature id, spawns the mob at the bobber position and broadcasts the canonical "SEA CREATURE!" message to the angler and players within 32 blocks. - sea_creatures.yml seeded with the six entries (level + skill XP + WATER/LAVA/NIGHT tags) so FishingRegistry tag-bonus rolls resolve. GUIParty member heads now read the real achievement-point total from DatapointAchievementData instead of hard-coding zero. --- .../skyblock/fishing/sea_creatures.yml | 25 +++++ .../net/swofty/type/lobby/gui/GUIParty.java | 6 +- .../entity/mob/seacreature/MobLavaBlaze.java | 92 +++++++++++++++++++ .../entity/mob/seacreature/MobMagmaSlug.java | 92 +++++++++++++++++++ .../entity/mob/seacreature/MobNightSquid.java | 81 ++++++++++++++++ .../mob/seacreature/MobSeaGuardian.java | 92 +++++++++++++++++++ .../entity/mob/seacreature/MobSeaWalker.java | 92 +++++++++++++++++++ .../entity/mob/seacreature/MobSquid.java | 81 ++++++++++++++++ .../mob/seacreature/SeaCreatureMob.java | 13 +++ .../mob/seacreature/SeaCreatureSpawner.java | 65 +++++++++++++ .../fishing/FishingService.java | 3 +- 11 files changed, 639 insertions(+), 3 deletions(-) create mode 100644 configuration/skyblock/fishing/sea_creatures.yml create mode 100644 type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/entity/mob/seacreature/MobLavaBlaze.java create mode 100644 type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/entity/mob/seacreature/MobMagmaSlug.java create mode 100644 type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/entity/mob/seacreature/MobNightSquid.java create mode 100644 type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/entity/mob/seacreature/MobSeaGuardian.java create mode 100644 type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/entity/mob/seacreature/MobSeaWalker.java create mode 100644 type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/entity/mob/seacreature/MobSquid.java create mode 100644 type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/entity/mob/seacreature/SeaCreatureMob.java create mode 100644 type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/entity/mob/seacreature/SeaCreatureSpawner.java diff --git a/configuration/skyblock/fishing/sea_creatures.yml b/configuration/skyblock/fishing/sea_creatures.yml new file mode 100644 index 000000000..68e64bdc8 --- /dev/null +++ b/configuration/skyblock/fishing/sea_creatures.yml @@ -0,0 +1,25 @@ +seaCreatures: + - id: SQUID + requiredFishingLevel: 1 + skillXp: 20 + tags: [WATER, COMMON] + - id: SEA_WALKER + requiredFishingLevel: 4 + skillXp: 40 + tags: [WATER, COMMON] + - id: NIGHT_SQUID + requiredFishingLevel: 6 + skillXp: 80 + tags: [WATER, NIGHT] + - id: SEA_GUARDIAN + requiredFishingLevel: 8 + skillXp: 120 + tags: [WATER] + - id: MAGMA_SLUG + requiredFishingLevel: 21 + skillXp: 450 + tags: [LAVA, CRIMSON] + - id: LAVA_BLAZE + requiredFishingLevel: 30 + skillXp: 1000 + tags: [LAVA, CRIMSON] diff --git a/type.lobby/src/main/java/net/swofty/type/lobby/gui/GUIParty.java b/type.lobby/src/main/java/net/swofty/type/lobby/gui/GUIParty.java index 5b2008dba..558e9cc06 100644 --- a/type.lobby/src/main/java/net/swofty/type/lobby/gui/GUIParty.java +++ b/type.lobby/src/main/java/net/swofty/type/lobby/gui/GUIParty.java @@ -9,6 +9,7 @@ import net.swofty.commons.StringUtility; import net.swofty.commons.party.FullParty; import net.swofty.type.generic.data.HypixelDataHandler; +import net.swofty.type.generic.data.datapoints.DatapointAchievementData; import net.swofty.type.generic.data.datapoints.DatapointHypixelExperience; import net.swofty.type.generic.data.datapoints.DatapointString; import net.swofty.type.generic.experience.HypixelExperience; @@ -368,8 +369,9 @@ private ItemStack.Builder createMemberHead(FullParty.Member member) { HypixelDataHandler account = HypixelDataHandler.getOfOfflinePlayer(memberUuid); long xp = account.get(HypixelDataHandler.Data.HYPIXEL_EXPERIENCE, DatapointHypixelExperience.class).getValue(); int level = HypixelExperience.xpToLevel(xp); - // TODO: Get actual achievement points when available - int achievementPoints = 0; + int achievementPoints = account.get(HypixelDataHandler.Data.ACHIEVEMENT_DATA, DatapointAchievementData.class) + .getValue() + .getTotalPoints(); // Get skin String skinTexture = account.get(HypixelDataHandler.Data.SKIN_TEXTURE, DatapointString.class).getValue(); diff --git a/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/entity/mob/seacreature/MobLavaBlaze.java b/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/entity/mob/seacreature/MobLavaBlaze.java new file mode 100644 index 000000000..3f6c2496c --- /dev/null +++ b/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/entity/mob/seacreature/MobLavaBlaze.java @@ -0,0 +1,92 @@ +package net.swofty.type.skyblockgeneric.entity.mob.seacreature; + +import net.minestom.server.entity.EntityType; +import net.minestom.server.entity.ai.GoalSelector; +import net.minestom.server.entity.ai.TargetSelector; +import net.minestom.server.entity.ai.goal.MeleeAttackGoal; +import net.minestom.server.entity.ai.goal.RandomStrollGoal; +import net.minestom.server.entity.ai.target.ClosestEntityTarget; +import net.minestom.server.entity.ai.target.LastEntityDamagerTarget; +import net.minestom.server.utils.time.TimeUnit; +import net.swofty.commons.skyblock.statistics.ItemStatistic; +import net.swofty.commons.skyblock.statistics.ItemStatistics; +import net.swofty.type.skyblockgeneric.entity.mob.MobType; +import net.swofty.type.skyblockgeneric.loottable.OtherLoot; +import net.swofty.type.skyblockgeneric.loottable.SkyBlockLootTable; +import net.swofty.type.skyblockgeneric.skill.SkillCategories; +import net.swofty.type.skyblockgeneric.user.SkyBlockPlayer; +import org.jetbrains.annotations.Nullable; + +import java.util.List; + +public class MobLavaBlaze extends SeaCreatureMob { + + public MobLavaBlaze() { + super(EntityType.BLAZE); + } + + @Override + public String getSeaCreatureId() { + return "LAVA_BLAZE"; + } + + @Override + public String getDisplayName() { + return "Lava Blaze"; + } + + @Override + public Integer getLevel() { + return 30; + } + + @Override + public List getGoalSelectors() { + return List.of( + new MeleeAttackGoal(this, 2.5, 20, TimeUnit.SERVER_TICK), + new RandomStrollGoal(this, 12) + ); + } + + @Override + public List getTargetSelectors() { + return List.of( + new LastEntityDamagerTarget(this, 20), + new ClosestEntityTarget(this, 20, entity -> entity instanceof SkyBlockPlayer) + ); + } + + @Override + public ItemStatistics getBaseStatistics() { + return ItemStatistics.builder() + .withBase(ItemStatistic.HEALTH, 1500D) + .withBase(ItemStatistic.DAMAGE, 250D) + .withBase(ItemStatistic.SPEED, 90D) + .build(); + } + + @Override + public @Nullable SkyBlockLootTable getLootTable() { + return null; + } + + @Override + public SkillCategories getSkillCategory() { + return SkillCategories.FISHING; + } + + @Override + public long damageCooldown() { + return 350; + } + + @Override + public OtherLoot getOtherLoot() { + return new OtherLoot(1000, 0, 18); + } + + @Override + public List getMobTypes() { + return List.of(MobType.MAGMATIC); + } +} diff --git a/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/entity/mob/seacreature/MobMagmaSlug.java b/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/entity/mob/seacreature/MobMagmaSlug.java new file mode 100644 index 000000000..862c5739e --- /dev/null +++ b/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/entity/mob/seacreature/MobMagmaSlug.java @@ -0,0 +1,92 @@ +package net.swofty.type.skyblockgeneric.entity.mob.seacreature; + +import net.minestom.server.entity.EntityType; +import net.minestom.server.entity.ai.GoalSelector; +import net.minestom.server.entity.ai.TargetSelector; +import net.minestom.server.entity.ai.goal.MeleeAttackGoal; +import net.minestom.server.entity.ai.goal.RandomStrollGoal; +import net.minestom.server.entity.ai.target.ClosestEntityTarget; +import net.minestom.server.entity.ai.target.LastEntityDamagerTarget; +import net.minestom.server.utils.time.TimeUnit; +import net.swofty.commons.skyblock.statistics.ItemStatistic; +import net.swofty.commons.skyblock.statistics.ItemStatistics; +import net.swofty.type.skyblockgeneric.entity.mob.MobType; +import net.swofty.type.skyblockgeneric.loottable.OtherLoot; +import net.swofty.type.skyblockgeneric.loottable.SkyBlockLootTable; +import net.swofty.type.skyblockgeneric.skill.SkillCategories; +import net.swofty.type.skyblockgeneric.user.SkyBlockPlayer; +import org.jetbrains.annotations.Nullable; + +import java.util.List; + +public class MobMagmaSlug extends SeaCreatureMob { + + public MobMagmaSlug() { + super(EntityType.MAGMA_CUBE); + } + + @Override + public String getSeaCreatureId() { + return "MAGMA_SLUG"; + } + + @Override + public String getDisplayName() { + return "Magma Slug"; + } + + @Override + public Integer getLevel() { + return 21; + } + + @Override + public List getGoalSelectors() { + return List.of( + new MeleeAttackGoal(this, 1.6, 20, TimeUnit.SERVER_TICK), + new RandomStrollGoal(this, 12) + ); + } + + @Override + public List getTargetSelectors() { + return List.of( + new LastEntityDamagerTarget(this, 14), + new ClosestEntityTarget(this, 14, entity -> entity instanceof SkyBlockPlayer) + ); + } + + @Override + public ItemStatistics getBaseStatistics() { + return ItemStatistics.builder() + .withBase(ItemStatistic.HEALTH, 850D) + .withBase(ItemStatistic.DAMAGE, 170D) + .withBase(ItemStatistic.SPEED, 50D) + .build(); + } + + @Override + public @Nullable SkyBlockLootTable getLootTable() { + return null; + } + + @Override + public SkillCategories getSkillCategory() { + return SkillCategories.FISHING; + } + + @Override + public long damageCooldown() { + return 400; + } + + @Override + public OtherLoot getOtherLoot() { + return new OtherLoot(450, 0, 12); + } + + @Override + public List getMobTypes() { + return List.of(MobType.MAGMATIC, MobType.CUBIC); + } +} diff --git a/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/entity/mob/seacreature/MobNightSquid.java b/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/entity/mob/seacreature/MobNightSquid.java new file mode 100644 index 000000000..533ca338f --- /dev/null +++ b/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/entity/mob/seacreature/MobNightSquid.java @@ -0,0 +1,81 @@ +package net.swofty.type.skyblockgeneric.entity.mob.seacreature; + +import net.minestom.server.entity.EntityType; +import net.minestom.server.entity.ai.GoalSelector; +import net.minestom.server.entity.ai.TargetSelector; +import net.minestom.server.entity.ai.goal.RandomStrollGoal; +import net.swofty.commons.skyblock.statistics.ItemStatistic; +import net.swofty.commons.skyblock.statistics.ItemStatistics; +import net.swofty.type.skyblockgeneric.entity.mob.MobType; +import net.swofty.type.skyblockgeneric.loottable.OtherLoot; +import net.swofty.type.skyblockgeneric.loottable.SkyBlockLootTable; +import net.swofty.type.skyblockgeneric.skill.SkillCategories; +import org.jetbrains.annotations.Nullable; + +import java.util.List; + +public class MobNightSquid extends SeaCreatureMob { + + public MobNightSquid() { + super(EntityType.GLOW_SQUID); + } + + @Override + public String getSeaCreatureId() { + return "NIGHT_SQUID"; + } + + @Override + public String getDisplayName() { + return "Night Squid"; + } + + @Override + public Integer getLevel() { + return 6; + } + + @Override + public List getGoalSelectors() { + return List.of(new RandomStrollGoal(this, 6)); + } + + @Override + public List getTargetSelectors() { + return List.of(); + } + + @Override + public ItemStatistics getBaseStatistics() { + return ItemStatistics.builder() + .withBase(ItemStatistic.HEALTH, 400D) + .withBase(ItemStatistic.DAMAGE, 15D) + .withBase(ItemStatistic.SPEED, 30D) + .build(); + } + + @Override + public @Nullable SkyBlockLootTable getLootTable() { + return null; + } + + @Override + public SkillCategories getSkillCategory() { + return SkillCategories.FISHING; + } + + @Override + public long damageCooldown() { + return 500; + } + + @Override + public OtherLoot getOtherLoot() { + return new OtherLoot(80, 0, 8); + } + + @Override + public List getMobTypes() { + return List.of(MobType.AQUATIC); + } +} diff --git a/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/entity/mob/seacreature/MobSeaGuardian.java b/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/entity/mob/seacreature/MobSeaGuardian.java new file mode 100644 index 000000000..b6ae38969 --- /dev/null +++ b/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/entity/mob/seacreature/MobSeaGuardian.java @@ -0,0 +1,92 @@ +package net.swofty.type.skyblockgeneric.entity.mob.seacreature; + +import net.minestom.server.entity.EntityType; +import net.minestom.server.entity.ai.GoalSelector; +import net.minestom.server.entity.ai.TargetSelector; +import net.minestom.server.entity.ai.goal.MeleeAttackGoal; +import net.minestom.server.entity.ai.goal.RandomStrollGoal; +import net.minestom.server.entity.ai.target.ClosestEntityTarget; +import net.minestom.server.entity.ai.target.LastEntityDamagerTarget; +import net.minestom.server.utils.time.TimeUnit; +import net.swofty.commons.skyblock.statistics.ItemStatistic; +import net.swofty.commons.skyblock.statistics.ItemStatistics; +import net.swofty.type.skyblockgeneric.entity.mob.MobType; +import net.swofty.type.skyblockgeneric.loottable.OtherLoot; +import net.swofty.type.skyblockgeneric.loottable.SkyBlockLootTable; +import net.swofty.type.skyblockgeneric.skill.SkillCategories; +import net.swofty.type.skyblockgeneric.user.SkyBlockPlayer; +import org.jetbrains.annotations.Nullable; + +import java.util.List; + +public class MobSeaGuardian extends SeaCreatureMob { + + public MobSeaGuardian() { + super(EntityType.GUARDIAN); + } + + @Override + public String getSeaCreatureId() { + return "SEA_GUARDIAN"; + } + + @Override + public String getDisplayName() { + return "Sea Guardian"; + } + + @Override + public Integer getLevel() { + return 8; + } + + @Override + public List getGoalSelectors() { + return List.of( + new MeleeAttackGoal(this, 2.0, 25, TimeUnit.SERVER_TICK), + new RandomStrollGoal(this, 10) + ); + } + + @Override + public List getTargetSelectors() { + return List.of( + new LastEntityDamagerTarget(this, 18), + new ClosestEntityTarget(this, 18, entity -> entity instanceof SkyBlockPlayer) + ); + } + + @Override + public ItemStatistics getBaseStatistics() { + return ItemStatistics.builder() + .withBase(ItemStatistic.HEALTH, 600D) + .withBase(ItemStatistic.DAMAGE, 40D) + .withBase(ItemStatistic.SPEED, 60D) + .build(); + } + + @Override + public @Nullable SkyBlockLootTable getLootTable() { + return null; + } + + @Override + public SkillCategories getSkillCategory() { + return SkillCategories.FISHING; + } + + @Override + public long damageCooldown() { + return 400; + } + + @Override + public OtherLoot getOtherLoot() { + return new OtherLoot(120, 0, 10); + } + + @Override + public List getMobTypes() { + return List.of(MobType.AQUATIC); + } +} diff --git a/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/entity/mob/seacreature/MobSeaWalker.java b/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/entity/mob/seacreature/MobSeaWalker.java new file mode 100644 index 000000000..ef576596f --- /dev/null +++ b/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/entity/mob/seacreature/MobSeaWalker.java @@ -0,0 +1,92 @@ +package net.swofty.type.skyblockgeneric.entity.mob.seacreature; + +import net.minestom.server.entity.EntityType; +import net.minestom.server.entity.ai.GoalSelector; +import net.minestom.server.entity.ai.TargetSelector; +import net.minestom.server.entity.ai.goal.MeleeAttackGoal; +import net.minestom.server.entity.ai.goal.RandomStrollGoal; +import net.minestom.server.entity.ai.target.ClosestEntityTarget; +import net.minestom.server.entity.ai.target.LastEntityDamagerTarget; +import net.minestom.server.utils.time.TimeUnit; +import net.swofty.commons.skyblock.statistics.ItemStatistic; +import net.swofty.commons.skyblock.statistics.ItemStatistics; +import net.swofty.type.skyblockgeneric.entity.mob.MobType; +import net.swofty.type.skyblockgeneric.loottable.OtherLoot; +import net.swofty.type.skyblockgeneric.loottable.SkyBlockLootTable; +import net.swofty.type.skyblockgeneric.skill.SkillCategories; +import net.swofty.type.skyblockgeneric.user.SkyBlockPlayer; +import org.jetbrains.annotations.Nullable; + +import java.util.List; + +public class MobSeaWalker extends SeaCreatureMob { + + public MobSeaWalker() { + super(EntityType.ZOMBIE); + } + + @Override + public String getSeaCreatureId() { + return "SEA_WALKER"; + } + + @Override + public String getDisplayName() { + return "Sea Walker"; + } + + @Override + public Integer getLevel() { + return 4; + } + + @Override + public List getGoalSelectors() { + return List.of( + new MeleeAttackGoal(this, 1.6, 20, TimeUnit.SERVER_TICK), + new RandomStrollGoal(this, 12) + ); + } + + @Override + public List getTargetSelectors() { + return List.of( + new LastEntityDamagerTarget(this, 16), + new ClosestEntityTarget(this, 16, entity -> entity instanceof SkyBlockPlayer) + ); + } + + @Override + public ItemStatistics getBaseStatistics() { + return ItemStatistics.builder() + .withBase(ItemStatistic.HEALTH, 240D) + .withBase(ItemStatistic.DAMAGE, 25D) + .withBase(ItemStatistic.SPEED, 70D) + .build(); + } + + @Override + public @Nullable SkyBlockLootTable getLootTable() { + return null; + } + + @Override + public SkillCategories getSkillCategory() { + return SkillCategories.FISHING; + } + + @Override + public long damageCooldown() { + return 400; + } + + @Override + public OtherLoot getOtherLoot() { + return new OtherLoot(40, 0, 6); + } + + @Override + public List getMobTypes() { + return List.of(MobType.AQUATIC, MobType.UNDEAD); + } +} diff --git a/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/entity/mob/seacreature/MobSquid.java b/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/entity/mob/seacreature/MobSquid.java new file mode 100644 index 000000000..f430a0085 --- /dev/null +++ b/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/entity/mob/seacreature/MobSquid.java @@ -0,0 +1,81 @@ +package net.swofty.type.skyblockgeneric.entity.mob.seacreature; + +import net.minestom.server.entity.EntityType; +import net.minestom.server.entity.ai.GoalSelector; +import net.minestom.server.entity.ai.TargetSelector; +import net.minestom.server.entity.ai.goal.RandomStrollGoal; +import net.swofty.commons.skyblock.statistics.ItemStatistic; +import net.swofty.commons.skyblock.statistics.ItemStatistics; +import net.swofty.type.skyblockgeneric.entity.mob.MobType; +import net.swofty.type.skyblockgeneric.loottable.OtherLoot; +import net.swofty.type.skyblockgeneric.loottable.SkyBlockLootTable; +import net.swofty.type.skyblockgeneric.skill.SkillCategories; +import org.jetbrains.annotations.Nullable; + +import java.util.List; + +public class MobSquid extends SeaCreatureMob { + + public MobSquid() { + super(EntityType.SQUID); + } + + @Override + public String getSeaCreatureId() { + return "SQUID"; + } + + @Override + public String getDisplayName() { + return "Squid"; + } + + @Override + public Integer getLevel() { + return 1; + } + + @Override + public List getGoalSelectors() { + return List.of(new RandomStrollGoal(this, 8)); + } + + @Override + public List getTargetSelectors() { + return List.of(); + } + + @Override + public ItemStatistics getBaseStatistics() { + return ItemStatistics.builder() + .withBase(ItemStatistic.HEALTH, 145D) + .withBase(ItemStatistic.DAMAGE, 5D) + .withBase(ItemStatistic.SPEED, 30D) + .build(); + } + + @Override + public @Nullable SkyBlockLootTable getLootTable() { + return null; + } + + @Override + public SkillCategories getSkillCategory() { + return SkillCategories.FISHING; + } + + @Override + public long damageCooldown() { + return 500; + } + + @Override + public OtherLoot getOtherLoot() { + return new OtherLoot(20, 0, 4); + } + + @Override + public List getMobTypes() { + return List.of(MobType.AQUATIC); + } +} diff --git a/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/entity/mob/seacreature/SeaCreatureMob.java b/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/entity/mob/seacreature/SeaCreatureMob.java new file mode 100644 index 000000000..920b31650 --- /dev/null +++ b/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/entity/mob/seacreature/SeaCreatureMob.java @@ -0,0 +1,13 @@ +package net.swofty.type.skyblockgeneric.entity.mob.seacreature; + +import net.minestom.server.entity.EntityType; +import net.swofty.type.skyblockgeneric.entity.mob.SkyBlockMob; + +public abstract class SeaCreatureMob extends SkyBlockMob { + + protected SeaCreatureMob(EntityType entityType) { + super(entityType); + } + + public abstract String getSeaCreatureId(); +} diff --git a/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/entity/mob/seacreature/SeaCreatureSpawner.java b/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/entity/mob/seacreature/SeaCreatureSpawner.java new file mode 100644 index 000000000..563456df4 --- /dev/null +++ b/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/entity/mob/seacreature/SeaCreatureSpawner.java @@ -0,0 +1,65 @@ +package net.swofty.type.skyblockgeneric.entity.mob.seacreature; + +import net.kyori.adventure.text.Component; +import net.minestom.server.coordinate.Pos; +import net.minestom.server.instance.Instance; +import net.swofty.type.skyblockgeneric.user.SkyBlockPlayer; +import org.jetbrains.annotations.Nullable; +import org.tinylog.Logger; + +import java.util.LinkedHashMap; +import java.util.Map; +import java.util.function.Supplier; + +public final class SeaCreatureSpawner { + + private static final Map> FACTORIES = new LinkedHashMap<>(); + + static { + register(MobSquid::new); + register(MobSeaWalker::new); + register(MobNightSquid::new); + register(MobSeaGuardian::new); + register(MobLavaBlaze::new); + register(MobMagmaSlug::new); + } + + private SeaCreatureSpawner() { + } + + public static void register(Supplier factory) { + FACTORIES.put(factory.get().getSeaCreatureId(), factory); + } + + public static boolean canSpawn(String seaCreatureId) { + return FACTORIES.containsKey(seaCreatureId); + } + + public static @Nullable SeaCreatureMob spawn(SkyBlockPlayer angler, String seaCreatureId, Pos position) { + Supplier factory = FACTORIES.get(seaCreatureId); + if (factory == null) { + Logger.warn("No sea creature factory registered for id={}, falling back to nothing", seaCreatureId); + return null; + } + + Instance instance = angler.getInstance(); + if (instance == null) { + return null; + } + + SeaCreatureMob mob = factory.get(); + mob.setInstance(instance, position); + + Component selfMessage = Component.text("§3§lSEA CREATURE! §bA " + mob.getDisplayName().toUpperCase() + " has spawned!"); + angler.sendMessage(selfMessage); + + Component nearbyMessage = Component.text("§3§lSEA CREATURE! §b" + angler.getUsername() + + " caught §a" + mob.getDisplayName() + "§b!"); + instance.getPlayers().stream() + .filter(player -> player.getPosition().distance(position) <= 32) + .filter(player -> !player.getUuid().equals(angler.getUuid())) + .forEach(player -> player.sendMessage(nearbyMessage)); + + return mob; + } +} diff --git a/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/fishing/FishingService.java b/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/fishing/FishingService.java index fd0ba7fef..5f112fcd5 100644 --- a/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/fishing/FishingService.java +++ b/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/fishing/FishingService.java @@ -5,6 +5,7 @@ import net.swofty.type.skyblockgeneric.data.datapoints.DatapointCollection; import net.swofty.type.skyblockgeneric.data.datapoints.DatapointTrophyFish; import net.swofty.type.skyblockgeneric.entity.FishingHook; +import net.swofty.type.skyblockgeneric.entity.mob.seacreature.SeaCreatureSpawner; import net.swofty.type.skyblockgeneric.item.SkyBlockItem; import net.swofty.type.skyblockgeneric.item.components.FishingBaitComponent; import net.swofty.type.skyblockgeneric.item.components.FishingRodPartComponent; @@ -147,7 +148,7 @@ private static void awardCatch(SkyBlockPlayer player, SkyBlockItem rod, FishingH } if (result.kind() == FishingCatchKind.SEA_CREATURE && result.seaCreatureId() != null) { - // TODO: sea creatures + SeaCreatureSpawner.spawn(player, result.seaCreatureId(), hook.getSpawnPosition()); } player.setItemInHand(rod); } From c7b89330ae950f715ca67cae020a283dfa772a32 Mon Sep 17 00:00:00 2001 From: "Jacob Nardella (Swofty)" Date: Fri, 15 May 2026 08:39:35 +1000 Subject: [PATCH 094/113] feat(fishing): gate NIGHT-tagged sea creatures to SkyBlock night Night Squid (and any future NIGHT-tagged creature) should only roll between 8pm and 6am SkyBlock time, matching Hypixel. SkyBlockCalendar.getHour() drives the check directly off the live game clock, so day/night transitions take effect immediately. --- .../skyblockgeneric/fishing/FishingLootResolver.java | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/fishing/FishingLootResolver.java b/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/fishing/FishingLootResolver.java index 6ec7f6c16..80349aba4 100644 --- a/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/fishing/FishingLootResolver.java +++ b/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/fishing/FishingLootResolver.java @@ -138,11 +138,15 @@ private static Optional tryResolveSeaCreature(FishingContext return Optional.empty(); } + boolean isNight = isSkyBlockNight(); for (FishingTableDefinition.SeaCreatureRoll roll : table.seaCreatures()) { SeaCreatureDefinition definition = FishingRegistry.getSeaCreature(roll.seaCreatureId()); if (definition != null && context.player().getSkills().getCurrentLevel(net.swofty.type.skyblockgeneric.skill.SkillCategories.FISHING) < definition.requiredFishingLevel()) { continue; } + if (definition != null && definition.tags().contains("NIGHT") && !isNight) { + continue; + } double tagBonus = definition == null ? 0.0D : getTagBonus(context, definition.tags()); if (Math.random() * 100 <= roll.chance() + seaCreatureChance + tagBonus) { double skillXp = definition == null ? 0.0D : definition.skillXp(); @@ -153,6 +157,11 @@ private static Optional tryResolveSeaCreature(FishingContext return Optional.empty(); } + private static boolean isSkyBlockNight() { + int hour = net.swofty.type.skyblockgeneric.calendar.SkyBlockCalendar.getHour(); + return hour < 6 || hour >= 20; + } + private static FishingCatchResult resolveItem(FishingContext context) { Optional tableOpt = findTable(context); if (tableOpt.isEmpty()) return DEFAULT_CATCH; From e4edace8900a69830ca1df5bf62b75914e3e0257 Mon Sep 17 00:00:00 2001 From: "Jacob Nardella (Swofty)" Date: Fri, 15 May 2026 08:44:46 +1000 Subject: [PATCH 095/113] refactor(fishing)!: replace stringly-typed tags with sealed FishingTag MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Was: \`definition.tags().contains("NIGHT") && !isNight\` — gating logic hard-coded in the resolver, tag identity = arbitrary string, every new condition would re-open the resolver to add another \`if\`. Now: \`sealed interface FishingTag permits Medium, TimeOfDay, Weather, Region, Rarity, Event\`. Each tag owns its own \`isAvailable(context)\` predicate, so the resolver just asks \`definition.isAvailable(context)\` and the right branch runs by polymorphism. Adding a new gated condition (e.g. \"only during Spooky Festival\") is one new tag class, no resolver change. - TimeOfDayTag carries an IntPredicate over the SkyBlock hour; NIGHT, DAY, DAWN, DUSK come pre-built. - WeatherTag reads instance.getWeather() directly: RAINING, CLEAR, THUNDERSTORM. - RegionTag has a typed \"requireMatch\" mode (gates) vs \"info\" mode (purely cataloguing), plus the canonical SkyBlock regions. - RarityTag holds a weight for sorting/display. - EventTag wraps a BooleanSupplier so events stay decoupled from tags. - FishingTagRegistry parses YAML strings to typed tags; unknown ids are synthesised as info-only RegionTags (visible in catalogs, never gate). SeaCreatureDefinition.tags is now List; the resolver's tag-bonus map still looks up bonuses by FishingTag.id() so user-data configs (bait/hook/line/sinker tag bonus maps) keep their string keys. --- .../fishing/FishingLootResolver.java | 16 +-- .../fishing/FishingRegistry.java | 2 +- .../fishing/SeaCreatureDefinition.java | 16 ++- .../fishing/tags/EventTag.java | 27 +++++ .../fishing/tags/FishingTag.java | 25 +++++ .../fishing/tags/FishingTagRegistry.java | 102 ++++++++++++++++++ .../fishing/tags/MediumTag.java | 20 ++++ .../fishing/tags/RarityTag.java | 14 +++ .../fishing/tags/RegionTag.java | 35 ++++++ .../fishing/tags/TimeOfDayTag.java | 19 ++++ .../fishing/tags/WeatherTag.java | 30 ++++++ 11 files changed, 293 insertions(+), 13 deletions(-) create mode 100644 type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/fishing/tags/EventTag.java create mode 100644 type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/fishing/tags/FishingTag.java create mode 100644 type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/fishing/tags/FishingTagRegistry.java create mode 100644 type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/fishing/tags/MediumTag.java create mode 100644 type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/fishing/tags/RarityTag.java create mode 100644 type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/fishing/tags/RegionTag.java create mode 100644 type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/fishing/tags/TimeOfDayTag.java create mode 100644 type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/fishing/tags/WeatherTag.java diff --git a/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/fishing/FishingLootResolver.java b/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/fishing/FishingLootResolver.java index 80349aba4..d1a6c085c 100644 --- a/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/fishing/FishingLootResolver.java +++ b/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/fishing/FishingLootResolver.java @@ -138,13 +138,12 @@ private static Optional tryResolveSeaCreature(FishingContext return Optional.empty(); } - boolean isNight = isSkyBlockNight(); for (FishingTableDefinition.SeaCreatureRoll roll : table.seaCreatures()) { SeaCreatureDefinition definition = FishingRegistry.getSeaCreature(roll.seaCreatureId()); if (definition != null && context.player().getSkills().getCurrentLevel(net.swofty.type.skyblockgeneric.skill.SkillCategories.FISHING) < definition.requiredFishingLevel()) { continue; } - if (definition != null && definition.tags().contains("NIGHT") && !isNight) { + if (definition != null && !definition.isAvailable(context)) { continue; } double tagBonus = definition == null ? 0.0D : getTagBonus(context, definition.tags()); @@ -157,11 +156,6 @@ private static Optional tryResolveSeaCreature(FishingContext return Optional.empty(); } - private static boolean isSkyBlockNight() { - int hour = net.swofty.type.skyblockgeneric.calendar.SkyBlockCalendar.getHour(); - return hour < 6 || hour >= 20; - } - private static FishingCatchResult resolveItem(FishingContext context) { Optional tableOpt = findTable(context); if (tableOpt.isEmpty()) return DEFAULT_CATCH; @@ -232,7 +226,7 @@ private static double getTotalStatistic(FishingContext context, ItemStatistic st return total; } - private static double getTagBonus(FishingContext context, List tags) { + private static double getTagBonus(FishingContext context, List tags) { double total = 0.0D; if (context.hook() != null) { total += getTagBonus(context.hook().getTagBonuses(), tags); @@ -249,10 +243,10 @@ private static double getTagBonus(FishingContext context, List tags) { return total; } - private static double getTagBonus(java.util.Map bonuses, List tags) { + private static double getTagBonus(java.util.Map bonuses, List tags) { double total = 0.0D; - for (String tag : tags) { - total += bonuses.getOrDefault(tag, 0.0D); + for (net.swofty.type.skyblockgeneric.fishing.tags.FishingTag tag : tags) { + total += bonuses.getOrDefault(tag.id(), 0.0D); } return total; } diff --git a/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/fishing/FishingRegistry.java b/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/fishing/FishingRegistry.java index cc9768e88..49d314bfb 100644 --- a/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/fishing/FishingRegistry.java +++ b/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/fishing/FishingRegistry.java @@ -138,7 +138,7 @@ private static void loadSeaCreatures(File file) throws IOException { id, intValue(entry, "requiredFishingLevel", 0), doubleValue(entry, "skillXp", 0.0D), - stringList(entry.get("tags")) + net.swofty.type.skyblockgeneric.fishing.tags.FishingTagRegistry.resolve(stringList(entry.get("tags"))) )); } } diff --git a/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/fishing/SeaCreatureDefinition.java b/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/fishing/SeaCreatureDefinition.java index d2ebd4041..f4d5a010f 100644 --- a/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/fishing/SeaCreatureDefinition.java +++ b/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/fishing/SeaCreatureDefinition.java @@ -1,11 +1,25 @@ package net.swofty.type.skyblockgeneric.fishing; +import net.swofty.type.skyblockgeneric.fishing.tags.FishingTag; + import java.util.List; public record SeaCreatureDefinition( String id, int requiredFishingLevel, double skillXp, - List tags + List tags ) { + public boolean hasTag(FishingTag tag) { + return tags.contains(tag); + } + + public boolean isAvailable(FishingContext context) { + for (FishingTag tag : tags) { + if (!tag.isAvailable(context)) { + return false; + } + } + return true; + } } diff --git a/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/fishing/tags/EventTag.java b/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/fishing/tags/EventTag.java new file mode 100644 index 000000000..3d7d49b8e --- /dev/null +++ b/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/fishing/tags/EventTag.java @@ -0,0 +1,27 @@ +package net.swofty.type.skyblockgeneric.fishing.tags; + +import net.swofty.type.skyblockgeneric.fishing.FishingContext; + +import java.util.function.BooleanSupplier; + +/** + * Gates loot behind a server-wide event being active (Spooky Festival, + * Fishing Festival, etc.). The actual liveness check is supplied at + * construction so the tag layer doesn't depend on event-specific code. + */ +public record EventTag(String id, BooleanSupplier activeCheck) implements FishingTag { + + public static EventTag of(String id, BooleanSupplier activeCheck) { + return new EventTag(id, activeCheck); + } + + /** Convenience: a never-active event tag for entries pending implementation. */ + public static EventTag dormant(String id) { + return new EventTag(id, () -> false); + } + + @Override + public boolean isAvailable(FishingContext context) { + return activeCheck.getAsBoolean(); + } +} diff --git a/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/fishing/tags/FishingTag.java b/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/fishing/tags/FishingTag.java new file mode 100644 index 000000000..fad50c6e3 --- /dev/null +++ b/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/fishing/tags/FishingTag.java @@ -0,0 +1,25 @@ +package net.swofty.type.skyblockgeneric.fishing.tags; + +import net.swofty.type.skyblockgeneric.fishing.FishingContext; + +/** + * A trait attached to a sea creature, trophy fish, or fishing-rod component + * that the loot resolver can reason about (gating, tag-bonus stacking, etc.). + * + * The sealed hierarchy carries gating logic on each implementation so the + * resolver never has to look at string identifiers to decide whether a tag's + * condition holds — that's the implementor's job. + */ +public sealed interface FishingTag + permits MediumTag, TimeOfDayTag, WeatherTag, RegionTag, RarityTag, EventTag { + + String id(); + + /** + * @return true if this tag's environmental condition currently holds. + * Informational tags (regional, rarity) always return true. + */ + default boolean isAvailable(FishingContext context) { + return true; + } +} diff --git a/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/fishing/tags/FishingTagRegistry.java b/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/fishing/tags/FishingTagRegistry.java new file mode 100644 index 000000000..e85b7508e --- /dev/null +++ b/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/fishing/tags/FishingTagRegistry.java @@ -0,0 +1,102 @@ +package net.swofty.type.skyblockgeneric.fishing.tags; + +import org.jetbrains.annotations.Nullable; +import org.tinylog.Logger; + +import java.util.LinkedHashMap; +import java.util.List; +import java.util.Map; +import java.util.Set; +import java.util.stream.Stream; + +/** + * Central lookup mapping YAML tag ids to the typed FishingTag instances + * the resolver uses. Built-in tags are pre-registered; custom tags (events, + * project-specific regions) can be added via {@link #register}. + */ +public final class FishingTagRegistry { + + private static final Map TAGS = new LinkedHashMap<>(); + + static { + registerAll( + MediumTag.WATER, + MediumTag.LAVA, + TimeOfDayTag.NIGHT, + TimeOfDayTag.DAY, + TimeOfDayTag.DAWN, + TimeOfDayTag.DUSK, + WeatherTag.RAINING, + WeatherTag.CLEAR, + WeatherTag.THUNDERSTORM, + RegionTag.CRIMSON_ISLE, + RegionTag.BACKWATER_BAYOU, + RegionTag.GALATEA, + RegionTag.PRIVATE_ISLAND, + RegionTag.HUB, + RegionTag.THE_END, + RarityTag.COMMON, + RarityTag.UNCOMMON, + RarityTag.RARE, + RarityTag.EPIC, + RarityTag.LEGENDARY, + RarityTag.MYTHIC + ); + } + + private FishingTagRegistry() { + } + + public static void register(FishingTag tag) { + TAGS.put(tag.id(), tag); + } + + public static void registerAll(FishingTag... tags) { + for (FishingTag tag : tags) { + register(tag); + } + } + + public static @Nullable FishingTag get(String id) { + return TAGS.get(id); + } + + public static List all() { + return List.copyOf(TAGS.values()); + } + + public static Set ids() { + return Set.copyOf(TAGS.keySet()); + } + + /** + * Resolves a list of YAML tag identifiers into typed tags. Unknown + * identifiers are surfaced as informational {@link RegionTag} entries + * (rather than dropped) so config typos remain visible in catalogs and + * tag-bonus maps still match by id; the resolver simply treats them as + * always-available. + */ + public static List resolve(List ids) { + if (ids == null || ids.isEmpty()) { + return List.of(); + } + return ids.stream() + .map(FishingTagRegistry::resolveOrSynth) + .toList(); + } + + private static FishingTag resolveOrSynth(String id) { + FishingTag known = TAGS.get(id); + if (known != null) { + return known; + } + Logger.debug("Unknown fishing tag id '{}', synthesising info-only tag", id); + RegionTag synthetic = RegionTag.info(id); + TAGS.put(id, synthetic); + return synthetic; + } + + public static Stream stream() { + return TAGS.values().stream(); + } +} diff --git a/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/fishing/tags/MediumTag.java b/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/fishing/tags/MediumTag.java new file mode 100644 index 000000000..a6a6bda39 --- /dev/null +++ b/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/fishing/tags/MediumTag.java @@ -0,0 +1,20 @@ +package net.swofty.type.skyblockgeneric.fishing.tags; + +import net.swofty.type.skyblockgeneric.fishing.FishingContext; +import net.swofty.type.skyblockgeneric.fishing.FishingMedium; + +public record MediumTag(FishingMedium medium) implements FishingTag { + + public static final MediumTag WATER = new MediumTag(FishingMedium.WATER); + public static final MediumTag LAVA = new MediumTag(FishingMedium.LAVA); + + @Override + public String id() { + return medium.name(); + } + + @Override + public boolean isAvailable(FishingContext context) { + return context.medium() == medium; + } +} diff --git a/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/fishing/tags/RarityTag.java b/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/fishing/tags/RarityTag.java new file mode 100644 index 000000000..ee6649707 --- /dev/null +++ b/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/fishing/tags/RarityTag.java @@ -0,0 +1,14 @@ +package net.swofty.type.skyblockgeneric.fishing.tags; + +/** + * Pure data tag — rarity is informational, never gates rolls. + */ +public record RarityTag(String id, int weight) implements FishingTag { + + public static final RarityTag COMMON = new RarityTag("COMMON", 0); + public static final RarityTag UNCOMMON = new RarityTag("UNCOMMON", 1); + public static final RarityTag RARE = new RarityTag("RARE", 2); + public static final RarityTag EPIC = new RarityTag("EPIC", 3); + public static final RarityTag LEGENDARY = new RarityTag("LEGENDARY", 4); + public static final RarityTag MYTHIC = new RarityTag("MYTHIC", 5); +} diff --git a/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/fishing/tags/RegionTag.java b/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/fishing/tags/RegionTag.java new file mode 100644 index 000000000..5f95e569f --- /dev/null +++ b/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/fishing/tags/RegionTag.java @@ -0,0 +1,35 @@ +package net.swofty.type.skyblockgeneric.fishing.tags; + +import net.swofty.type.skyblockgeneric.fishing.FishingContext; + +import java.util.Set; + +/** + * Marks loot that's themed to one or more SkyBlock regions. Acts as a + * gate when {@code requireMatch} is true, otherwise informational only. + */ +public record RegionTag(String id, Set regionIds, boolean requireMatch) implements FishingTag { + + public static final RegionTag CRIMSON_ISLE = require("CRIMSON", Set.of("CRIMSON_ISLE", "DRAGONTAIL", "STRONGHOLD")); + public static final RegionTag BACKWATER_BAYOU = require("BAYOU", Set.of("BACKWATER_BAYOU")); + public static final RegionTag GALATEA = require("GALATEA", Set.of("GALATEA")); + public static final RegionTag PRIVATE_ISLAND = require("ISLAND", Set.of("PRIVATE_ISLAND")); + public static final RegionTag HUB = require("HUB", Set.of("HUB")); + public static final RegionTag THE_END = require("END", Set.of("THE_END", "DRAGONS_NEST")); + + public static RegionTag require(String id, Set regionIds) { + return new RegionTag(id, Set.copyOf(regionIds), true); + } + + public static RegionTag info(String id) { + return new RegionTag(id, Set.of(), false); + } + + @Override + public boolean isAvailable(FishingContext context) { + if (!requireMatch || regionIds.isEmpty()) { + return true; + } + return context.regionId() != null && regionIds.contains(context.regionId()); + } +} diff --git a/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/fishing/tags/TimeOfDayTag.java b/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/fishing/tags/TimeOfDayTag.java new file mode 100644 index 000000000..4df8a77d5 --- /dev/null +++ b/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/fishing/tags/TimeOfDayTag.java @@ -0,0 +1,19 @@ +package net.swofty.type.skyblockgeneric.fishing.tags; + +import net.swofty.type.skyblockgeneric.calendar.SkyBlockCalendar; +import net.swofty.type.skyblockgeneric.fishing.FishingContext; + +import java.util.function.IntPredicate; + +public record TimeOfDayTag(String id, IntPredicate hourPredicate) implements FishingTag { + + public static final TimeOfDayTag NIGHT = new TimeOfDayTag("NIGHT", hour -> hour < 6 || hour >= 20); + public static final TimeOfDayTag DAY = new TimeOfDayTag("DAY", hour -> hour >= 6 && hour < 20); + public static final TimeOfDayTag DAWN = new TimeOfDayTag("DAWN", hour -> hour >= 5 && hour < 8); + public static final TimeOfDayTag DUSK = new TimeOfDayTag("DUSK", hour -> hour >= 17 && hour < 20); + + @Override + public boolean isAvailable(FishingContext context) { + return hourPredicate.test(SkyBlockCalendar.getHour()); + } +} diff --git a/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/fishing/tags/WeatherTag.java b/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/fishing/tags/WeatherTag.java new file mode 100644 index 000000000..f6a069de8 --- /dev/null +++ b/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/fishing/tags/WeatherTag.java @@ -0,0 +1,30 @@ +package net.swofty.type.skyblockgeneric.fishing.tags; + +import net.minestom.server.instance.Instance; +import net.minestom.server.instance.Weather; +import net.swofty.type.skyblockgeneric.fishing.FishingContext; + +public record WeatherTag(String id, Condition condition) implements FishingTag { + + public static final WeatherTag RAINING = new WeatherTag("RAINING", Condition.RAINING); + public static final WeatherTag CLEAR = new WeatherTag("CLEAR", Condition.CLEAR); + public static final WeatherTag THUNDERSTORM = new WeatherTag("THUNDERSTORM", Condition.THUNDERSTORM); + + @Override + public boolean isAvailable(FishingContext context) { + Instance instance = context.player().getInstance(); + if (instance == null) { + return condition == Condition.CLEAR; + } + Weather weather = instance.getWeather(); + return switch (condition) { + case RAINING -> weather.rainLevel() > 0.0f; + case CLEAR -> weather.rainLevel() == 0.0f; + case THUNDERSTORM -> weather.thunderLevel() > 0.0f; + }; + } + + public enum Condition { + RAINING, CLEAR, THUNDERSTORM + } +} From db4cc0a6e219038f2dae59f6afd8beaa24d4832e Mon Sep 17 00:00:00 2001 From: "Jacob Nardella (Swofty)" Date: Fri, 15 May 2026 08:47:34 +1000 Subject: [PATCH 096/113] refactor(fishing): collapse sea creature hierarchy into profile-driven model MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Was: six near-identical Mob subclasses of SkyBlockMob, each ~80 lines of boilerplate overriding the same ten abstract methods. The only thing that actually varied was data — entity type, level, stats, AI flavour. Now: a single \`SeaCreatureMob\` driven by a \`SeaCreatureProfile\` record. Adding a new creature is one builder chain in \`SeaCreatureProfiles\`, not a new class. The SkyBlockMob super-constructor calls abstract accessors before subclass fields are initialised, so a thread-local handoff (\`IN_CONSTRUCTION\`) bridges the gap during the super() call — once the constructor returns the field is set and \`live()\` hits the fast path. Behaviour is its own sealed strategy: \`Passive\`, \`Aggressive\`, \`Custom\`. The sealed interface lets us pattern-match on it later (e.g. for catalog GUIs that want to render aggressive vs passive differently) without an escape hatch. Net: deleted 480+ lines of boilerplate, replaced with ~250 lines of genuine data + one polymorphic driver. --- .../entity/mob/seacreature/MobLavaBlaze.java | 92 ------------------- .../entity/mob/seacreature/MobMagmaSlug.java | 92 ------------------- .../entity/mob/seacreature/MobNightSquid.java | 81 ---------------- .../mob/seacreature/MobSeaGuardian.java | 92 ------------------- .../entity/mob/seacreature/MobSeaWalker.java | 92 ------------------- .../entity/mob/seacreature/MobSquid.java | 81 ---------------- .../mob/seacreature/SeaCreatureBehaviour.java | 83 +++++++++++++++++ .../mob/seacreature/SeaCreatureMob.java | 71 +++++++++++++- .../mob/seacreature/SeaCreatureProfile.java | 91 ++++++++++++++++++ .../mob/seacreature/SeaCreatureProfiles.java | 85 +++++++++++++++++ .../mob/seacreature/SeaCreatureSpawner.java | 39 ++++---- 11 files changed, 345 insertions(+), 554 deletions(-) delete mode 100644 type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/entity/mob/seacreature/MobLavaBlaze.java delete mode 100644 type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/entity/mob/seacreature/MobMagmaSlug.java delete mode 100644 type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/entity/mob/seacreature/MobNightSquid.java delete mode 100644 type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/entity/mob/seacreature/MobSeaGuardian.java delete mode 100644 type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/entity/mob/seacreature/MobSeaWalker.java delete mode 100644 type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/entity/mob/seacreature/MobSquid.java create mode 100644 type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/entity/mob/seacreature/SeaCreatureBehaviour.java create mode 100644 type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/entity/mob/seacreature/SeaCreatureProfile.java create mode 100644 type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/entity/mob/seacreature/SeaCreatureProfiles.java diff --git a/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/entity/mob/seacreature/MobLavaBlaze.java b/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/entity/mob/seacreature/MobLavaBlaze.java deleted file mode 100644 index 3f6c2496c..000000000 --- a/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/entity/mob/seacreature/MobLavaBlaze.java +++ /dev/null @@ -1,92 +0,0 @@ -package net.swofty.type.skyblockgeneric.entity.mob.seacreature; - -import net.minestom.server.entity.EntityType; -import net.minestom.server.entity.ai.GoalSelector; -import net.minestom.server.entity.ai.TargetSelector; -import net.minestom.server.entity.ai.goal.MeleeAttackGoal; -import net.minestom.server.entity.ai.goal.RandomStrollGoal; -import net.minestom.server.entity.ai.target.ClosestEntityTarget; -import net.minestom.server.entity.ai.target.LastEntityDamagerTarget; -import net.minestom.server.utils.time.TimeUnit; -import net.swofty.commons.skyblock.statistics.ItemStatistic; -import net.swofty.commons.skyblock.statistics.ItemStatistics; -import net.swofty.type.skyblockgeneric.entity.mob.MobType; -import net.swofty.type.skyblockgeneric.loottable.OtherLoot; -import net.swofty.type.skyblockgeneric.loottable.SkyBlockLootTable; -import net.swofty.type.skyblockgeneric.skill.SkillCategories; -import net.swofty.type.skyblockgeneric.user.SkyBlockPlayer; -import org.jetbrains.annotations.Nullable; - -import java.util.List; - -public class MobLavaBlaze extends SeaCreatureMob { - - public MobLavaBlaze() { - super(EntityType.BLAZE); - } - - @Override - public String getSeaCreatureId() { - return "LAVA_BLAZE"; - } - - @Override - public String getDisplayName() { - return "Lava Blaze"; - } - - @Override - public Integer getLevel() { - return 30; - } - - @Override - public List getGoalSelectors() { - return List.of( - new MeleeAttackGoal(this, 2.5, 20, TimeUnit.SERVER_TICK), - new RandomStrollGoal(this, 12) - ); - } - - @Override - public List getTargetSelectors() { - return List.of( - new LastEntityDamagerTarget(this, 20), - new ClosestEntityTarget(this, 20, entity -> entity instanceof SkyBlockPlayer) - ); - } - - @Override - public ItemStatistics getBaseStatistics() { - return ItemStatistics.builder() - .withBase(ItemStatistic.HEALTH, 1500D) - .withBase(ItemStatistic.DAMAGE, 250D) - .withBase(ItemStatistic.SPEED, 90D) - .build(); - } - - @Override - public @Nullable SkyBlockLootTable getLootTable() { - return null; - } - - @Override - public SkillCategories getSkillCategory() { - return SkillCategories.FISHING; - } - - @Override - public long damageCooldown() { - return 350; - } - - @Override - public OtherLoot getOtherLoot() { - return new OtherLoot(1000, 0, 18); - } - - @Override - public List getMobTypes() { - return List.of(MobType.MAGMATIC); - } -} diff --git a/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/entity/mob/seacreature/MobMagmaSlug.java b/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/entity/mob/seacreature/MobMagmaSlug.java deleted file mode 100644 index 862c5739e..000000000 --- a/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/entity/mob/seacreature/MobMagmaSlug.java +++ /dev/null @@ -1,92 +0,0 @@ -package net.swofty.type.skyblockgeneric.entity.mob.seacreature; - -import net.minestom.server.entity.EntityType; -import net.minestom.server.entity.ai.GoalSelector; -import net.minestom.server.entity.ai.TargetSelector; -import net.minestom.server.entity.ai.goal.MeleeAttackGoal; -import net.minestom.server.entity.ai.goal.RandomStrollGoal; -import net.minestom.server.entity.ai.target.ClosestEntityTarget; -import net.minestom.server.entity.ai.target.LastEntityDamagerTarget; -import net.minestom.server.utils.time.TimeUnit; -import net.swofty.commons.skyblock.statistics.ItemStatistic; -import net.swofty.commons.skyblock.statistics.ItemStatistics; -import net.swofty.type.skyblockgeneric.entity.mob.MobType; -import net.swofty.type.skyblockgeneric.loottable.OtherLoot; -import net.swofty.type.skyblockgeneric.loottable.SkyBlockLootTable; -import net.swofty.type.skyblockgeneric.skill.SkillCategories; -import net.swofty.type.skyblockgeneric.user.SkyBlockPlayer; -import org.jetbrains.annotations.Nullable; - -import java.util.List; - -public class MobMagmaSlug extends SeaCreatureMob { - - public MobMagmaSlug() { - super(EntityType.MAGMA_CUBE); - } - - @Override - public String getSeaCreatureId() { - return "MAGMA_SLUG"; - } - - @Override - public String getDisplayName() { - return "Magma Slug"; - } - - @Override - public Integer getLevel() { - return 21; - } - - @Override - public List getGoalSelectors() { - return List.of( - new MeleeAttackGoal(this, 1.6, 20, TimeUnit.SERVER_TICK), - new RandomStrollGoal(this, 12) - ); - } - - @Override - public List getTargetSelectors() { - return List.of( - new LastEntityDamagerTarget(this, 14), - new ClosestEntityTarget(this, 14, entity -> entity instanceof SkyBlockPlayer) - ); - } - - @Override - public ItemStatistics getBaseStatistics() { - return ItemStatistics.builder() - .withBase(ItemStatistic.HEALTH, 850D) - .withBase(ItemStatistic.DAMAGE, 170D) - .withBase(ItemStatistic.SPEED, 50D) - .build(); - } - - @Override - public @Nullable SkyBlockLootTable getLootTable() { - return null; - } - - @Override - public SkillCategories getSkillCategory() { - return SkillCategories.FISHING; - } - - @Override - public long damageCooldown() { - return 400; - } - - @Override - public OtherLoot getOtherLoot() { - return new OtherLoot(450, 0, 12); - } - - @Override - public List getMobTypes() { - return List.of(MobType.MAGMATIC, MobType.CUBIC); - } -} diff --git a/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/entity/mob/seacreature/MobNightSquid.java b/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/entity/mob/seacreature/MobNightSquid.java deleted file mode 100644 index 533ca338f..000000000 --- a/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/entity/mob/seacreature/MobNightSquid.java +++ /dev/null @@ -1,81 +0,0 @@ -package net.swofty.type.skyblockgeneric.entity.mob.seacreature; - -import net.minestom.server.entity.EntityType; -import net.minestom.server.entity.ai.GoalSelector; -import net.minestom.server.entity.ai.TargetSelector; -import net.minestom.server.entity.ai.goal.RandomStrollGoal; -import net.swofty.commons.skyblock.statistics.ItemStatistic; -import net.swofty.commons.skyblock.statistics.ItemStatistics; -import net.swofty.type.skyblockgeneric.entity.mob.MobType; -import net.swofty.type.skyblockgeneric.loottable.OtherLoot; -import net.swofty.type.skyblockgeneric.loottable.SkyBlockLootTable; -import net.swofty.type.skyblockgeneric.skill.SkillCategories; -import org.jetbrains.annotations.Nullable; - -import java.util.List; - -public class MobNightSquid extends SeaCreatureMob { - - public MobNightSquid() { - super(EntityType.GLOW_SQUID); - } - - @Override - public String getSeaCreatureId() { - return "NIGHT_SQUID"; - } - - @Override - public String getDisplayName() { - return "Night Squid"; - } - - @Override - public Integer getLevel() { - return 6; - } - - @Override - public List getGoalSelectors() { - return List.of(new RandomStrollGoal(this, 6)); - } - - @Override - public List getTargetSelectors() { - return List.of(); - } - - @Override - public ItemStatistics getBaseStatistics() { - return ItemStatistics.builder() - .withBase(ItemStatistic.HEALTH, 400D) - .withBase(ItemStatistic.DAMAGE, 15D) - .withBase(ItemStatistic.SPEED, 30D) - .build(); - } - - @Override - public @Nullable SkyBlockLootTable getLootTable() { - return null; - } - - @Override - public SkillCategories getSkillCategory() { - return SkillCategories.FISHING; - } - - @Override - public long damageCooldown() { - return 500; - } - - @Override - public OtherLoot getOtherLoot() { - return new OtherLoot(80, 0, 8); - } - - @Override - public List getMobTypes() { - return List.of(MobType.AQUATIC); - } -} diff --git a/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/entity/mob/seacreature/MobSeaGuardian.java b/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/entity/mob/seacreature/MobSeaGuardian.java deleted file mode 100644 index b6ae38969..000000000 --- a/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/entity/mob/seacreature/MobSeaGuardian.java +++ /dev/null @@ -1,92 +0,0 @@ -package net.swofty.type.skyblockgeneric.entity.mob.seacreature; - -import net.minestom.server.entity.EntityType; -import net.minestom.server.entity.ai.GoalSelector; -import net.minestom.server.entity.ai.TargetSelector; -import net.minestom.server.entity.ai.goal.MeleeAttackGoal; -import net.minestom.server.entity.ai.goal.RandomStrollGoal; -import net.minestom.server.entity.ai.target.ClosestEntityTarget; -import net.minestom.server.entity.ai.target.LastEntityDamagerTarget; -import net.minestom.server.utils.time.TimeUnit; -import net.swofty.commons.skyblock.statistics.ItemStatistic; -import net.swofty.commons.skyblock.statistics.ItemStatistics; -import net.swofty.type.skyblockgeneric.entity.mob.MobType; -import net.swofty.type.skyblockgeneric.loottable.OtherLoot; -import net.swofty.type.skyblockgeneric.loottable.SkyBlockLootTable; -import net.swofty.type.skyblockgeneric.skill.SkillCategories; -import net.swofty.type.skyblockgeneric.user.SkyBlockPlayer; -import org.jetbrains.annotations.Nullable; - -import java.util.List; - -public class MobSeaGuardian extends SeaCreatureMob { - - public MobSeaGuardian() { - super(EntityType.GUARDIAN); - } - - @Override - public String getSeaCreatureId() { - return "SEA_GUARDIAN"; - } - - @Override - public String getDisplayName() { - return "Sea Guardian"; - } - - @Override - public Integer getLevel() { - return 8; - } - - @Override - public List getGoalSelectors() { - return List.of( - new MeleeAttackGoal(this, 2.0, 25, TimeUnit.SERVER_TICK), - new RandomStrollGoal(this, 10) - ); - } - - @Override - public List getTargetSelectors() { - return List.of( - new LastEntityDamagerTarget(this, 18), - new ClosestEntityTarget(this, 18, entity -> entity instanceof SkyBlockPlayer) - ); - } - - @Override - public ItemStatistics getBaseStatistics() { - return ItemStatistics.builder() - .withBase(ItemStatistic.HEALTH, 600D) - .withBase(ItemStatistic.DAMAGE, 40D) - .withBase(ItemStatistic.SPEED, 60D) - .build(); - } - - @Override - public @Nullable SkyBlockLootTable getLootTable() { - return null; - } - - @Override - public SkillCategories getSkillCategory() { - return SkillCategories.FISHING; - } - - @Override - public long damageCooldown() { - return 400; - } - - @Override - public OtherLoot getOtherLoot() { - return new OtherLoot(120, 0, 10); - } - - @Override - public List getMobTypes() { - return List.of(MobType.AQUATIC); - } -} diff --git a/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/entity/mob/seacreature/MobSeaWalker.java b/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/entity/mob/seacreature/MobSeaWalker.java deleted file mode 100644 index ef576596f..000000000 --- a/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/entity/mob/seacreature/MobSeaWalker.java +++ /dev/null @@ -1,92 +0,0 @@ -package net.swofty.type.skyblockgeneric.entity.mob.seacreature; - -import net.minestom.server.entity.EntityType; -import net.minestom.server.entity.ai.GoalSelector; -import net.minestom.server.entity.ai.TargetSelector; -import net.minestom.server.entity.ai.goal.MeleeAttackGoal; -import net.minestom.server.entity.ai.goal.RandomStrollGoal; -import net.minestom.server.entity.ai.target.ClosestEntityTarget; -import net.minestom.server.entity.ai.target.LastEntityDamagerTarget; -import net.minestom.server.utils.time.TimeUnit; -import net.swofty.commons.skyblock.statistics.ItemStatistic; -import net.swofty.commons.skyblock.statistics.ItemStatistics; -import net.swofty.type.skyblockgeneric.entity.mob.MobType; -import net.swofty.type.skyblockgeneric.loottable.OtherLoot; -import net.swofty.type.skyblockgeneric.loottable.SkyBlockLootTable; -import net.swofty.type.skyblockgeneric.skill.SkillCategories; -import net.swofty.type.skyblockgeneric.user.SkyBlockPlayer; -import org.jetbrains.annotations.Nullable; - -import java.util.List; - -public class MobSeaWalker extends SeaCreatureMob { - - public MobSeaWalker() { - super(EntityType.ZOMBIE); - } - - @Override - public String getSeaCreatureId() { - return "SEA_WALKER"; - } - - @Override - public String getDisplayName() { - return "Sea Walker"; - } - - @Override - public Integer getLevel() { - return 4; - } - - @Override - public List getGoalSelectors() { - return List.of( - new MeleeAttackGoal(this, 1.6, 20, TimeUnit.SERVER_TICK), - new RandomStrollGoal(this, 12) - ); - } - - @Override - public List getTargetSelectors() { - return List.of( - new LastEntityDamagerTarget(this, 16), - new ClosestEntityTarget(this, 16, entity -> entity instanceof SkyBlockPlayer) - ); - } - - @Override - public ItemStatistics getBaseStatistics() { - return ItemStatistics.builder() - .withBase(ItemStatistic.HEALTH, 240D) - .withBase(ItemStatistic.DAMAGE, 25D) - .withBase(ItemStatistic.SPEED, 70D) - .build(); - } - - @Override - public @Nullable SkyBlockLootTable getLootTable() { - return null; - } - - @Override - public SkillCategories getSkillCategory() { - return SkillCategories.FISHING; - } - - @Override - public long damageCooldown() { - return 400; - } - - @Override - public OtherLoot getOtherLoot() { - return new OtherLoot(40, 0, 6); - } - - @Override - public List getMobTypes() { - return List.of(MobType.AQUATIC, MobType.UNDEAD); - } -} diff --git a/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/entity/mob/seacreature/MobSquid.java b/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/entity/mob/seacreature/MobSquid.java deleted file mode 100644 index f430a0085..000000000 --- a/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/entity/mob/seacreature/MobSquid.java +++ /dev/null @@ -1,81 +0,0 @@ -package net.swofty.type.skyblockgeneric.entity.mob.seacreature; - -import net.minestom.server.entity.EntityType; -import net.minestom.server.entity.ai.GoalSelector; -import net.minestom.server.entity.ai.TargetSelector; -import net.minestom.server.entity.ai.goal.RandomStrollGoal; -import net.swofty.commons.skyblock.statistics.ItemStatistic; -import net.swofty.commons.skyblock.statistics.ItemStatistics; -import net.swofty.type.skyblockgeneric.entity.mob.MobType; -import net.swofty.type.skyblockgeneric.loottable.OtherLoot; -import net.swofty.type.skyblockgeneric.loottable.SkyBlockLootTable; -import net.swofty.type.skyblockgeneric.skill.SkillCategories; -import org.jetbrains.annotations.Nullable; - -import java.util.List; - -public class MobSquid extends SeaCreatureMob { - - public MobSquid() { - super(EntityType.SQUID); - } - - @Override - public String getSeaCreatureId() { - return "SQUID"; - } - - @Override - public String getDisplayName() { - return "Squid"; - } - - @Override - public Integer getLevel() { - return 1; - } - - @Override - public List getGoalSelectors() { - return List.of(new RandomStrollGoal(this, 8)); - } - - @Override - public List getTargetSelectors() { - return List.of(); - } - - @Override - public ItemStatistics getBaseStatistics() { - return ItemStatistics.builder() - .withBase(ItemStatistic.HEALTH, 145D) - .withBase(ItemStatistic.DAMAGE, 5D) - .withBase(ItemStatistic.SPEED, 30D) - .build(); - } - - @Override - public @Nullable SkyBlockLootTable getLootTable() { - return null; - } - - @Override - public SkillCategories getSkillCategory() { - return SkillCategories.FISHING; - } - - @Override - public long damageCooldown() { - return 500; - } - - @Override - public OtherLoot getOtherLoot() { - return new OtherLoot(20, 0, 4); - } - - @Override - public List getMobTypes() { - return List.of(MobType.AQUATIC); - } -} diff --git a/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/entity/mob/seacreature/SeaCreatureBehaviour.java b/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/entity/mob/seacreature/SeaCreatureBehaviour.java new file mode 100644 index 000000000..5e927299f --- /dev/null +++ b/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/entity/mob/seacreature/SeaCreatureBehaviour.java @@ -0,0 +1,83 @@ +package net.swofty.type.skyblockgeneric.entity.mob.seacreature; + +import net.minestom.server.entity.ai.GoalSelector; +import net.minestom.server.entity.ai.TargetSelector; +import net.minestom.server.entity.ai.goal.MeleeAttackGoal; +import net.minestom.server.entity.ai.goal.RandomStrollGoal; +import net.minestom.server.entity.ai.target.ClosestEntityTarget; +import net.minestom.server.entity.ai.target.LastEntityDamagerTarget; +import net.minestom.server.utils.time.TimeUnit; +import net.swofty.type.skyblockgeneric.entity.mob.SkyBlockMob; +import net.swofty.type.skyblockgeneric.user.SkyBlockPlayer; + +import java.util.List; + +/** + * Strategy describing how a sea creature moves and selects targets. The + * sealed hierarchy is exhaustive — pattern-match on it elsewhere if you + * need to introspect (e.g. catalog GUIs that render "aggressive" vs + * "passive" differently). + */ +public sealed interface SeaCreatureBehaviour + permits SeaCreatureBehaviour.Passive, + SeaCreatureBehaviour.Aggressive, + SeaCreatureBehaviour.Custom { + + List goals(SkyBlockMob self); + + List targets(SkyBlockMob self); + + static Passive passive(int strollRange) { + return new Passive(strollRange); + } + + static Aggressive aggressive(double speed, int attackCooldownTicks, int aggroRange) { + return new Aggressive(speed, attackCooldownTicks, aggroRange); + } + + static Custom of(List goals, List targets) { + return new Custom(goals, targets); + } + + record Passive(int strollRange) implements SeaCreatureBehaviour { + @Override + public List goals(SkyBlockMob self) { + return List.of(new RandomStrollGoal(self, strollRange)); + } + + @Override + public List targets(SkyBlockMob self) { + return List.of(); + } + } + + record Aggressive(double speed, int attackCooldownTicks, int aggroRange) implements SeaCreatureBehaviour { + @Override + public List goals(SkyBlockMob self) { + return List.of( + new MeleeAttackGoal(self, speed, attackCooldownTicks, TimeUnit.SERVER_TICK), + new RandomStrollGoal(self, Math.max(8, aggroRange / 2)) + ); + } + + @Override + public List targets(SkyBlockMob self) { + return List.of( + new LastEntityDamagerTarget(self, aggroRange), + new ClosestEntityTarget(self, aggroRange, entity -> entity instanceof SkyBlockPlayer) + ); + } + } + + record Custom(List customGoals, List customTargets) implements SeaCreatureBehaviour { + @Override + public List goals(SkyBlockMob self) { + return customGoals; + } + + @Override + public List targets(SkyBlockMob self) { + return customTargets; + } + } +} diff --git a/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/entity/mob/seacreature/SeaCreatureMob.java b/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/entity/mob/seacreature/SeaCreatureMob.java index 920b31650..11eb27b61 100644 --- a/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/entity/mob/seacreature/SeaCreatureMob.java +++ b/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/entity/mob/seacreature/SeaCreatureMob.java @@ -1,13 +1,74 @@ package net.swofty.type.skyblockgeneric.entity.mob.seacreature; -import net.minestom.server.entity.EntityType; +import net.minestom.server.entity.ai.GoalSelector; +import net.minestom.server.entity.ai.TargetSelector; +import net.swofty.commons.skyblock.statistics.ItemStatistics; +import net.swofty.type.skyblockgeneric.entity.mob.MobType; import net.swofty.type.skyblockgeneric.entity.mob.SkyBlockMob; +import net.swofty.type.skyblockgeneric.loottable.OtherLoot; +import net.swofty.type.skyblockgeneric.loottable.SkyBlockLootTable; +import net.swofty.type.skyblockgeneric.skill.SkillCategories; +import org.jetbrains.annotations.Nullable; -public abstract class SeaCreatureMob extends SkyBlockMob { +import java.util.List; - protected SeaCreatureMob(EntityType entityType) { - super(entityType); +/** + * A sea creature is fully described by a {@link SeaCreatureProfile} — one + * concrete class drives every variant. The thread-local handoff + * ({@link #IN_CONSTRUCTION}) is the standard workaround for SkyBlockMob's + * super-constructor calling abstract accessors before subclass field + * assignment happens; without it those accessors would NPE on the profile + * field. Once super() returns the field is set and future calls hit the + * fast path. + */ +public final class SeaCreatureMob extends SkyBlockMob { + + private static final ThreadLocal IN_CONSTRUCTION = new ThreadLocal<>(); + + private final SeaCreatureProfile profile; + + private SeaCreatureMob(SeaCreatureProfile profile) { + super(profile.entityType()); + this.profile = profile; + } + + public static SeaCreatureMob create(SeaCreatureProfile profile) { + IN_CONSTRUCTION.set(profile); + try { + return new SeaCreatureMob(profile); + } finally { + IN_CONSTRUCTION.remove(); + } + } + + public String getSeaCreatureId() { + return live().id(); } - public abstract String getSeaCreatureId(); + public SeaCreatureProfile getProfile() { + return live(); + } + + @Override public String getDisplayName() { return live().displayName(); } + @Override public Integer getLevel() { return live().level(); } + @Override public List getMobTypes() { return live().mobTypes(); } + @Override public ItemStatistics getBaseStatistics() { return live().asBaseStatistics(); } + @Override public OtherLoot getOtherLoot() { return live().asOtherLoot(); } + @Override public long damageCooldown() { return live().damageCooldownMs(); } + @Override public @Nullable SkyBlockLootTable getLootTable() { return live().lootTable(); } + @Override public SkillCategories getSkillCategory() { return SkillCategories.FISHING; } + + @Override + public List getGoalSelectors() { + return live().behaviour().goals(this); + } + + @Override + public List getTargetSelectors() { + return live().behaviour().targets(this); + } + + private SeaCreatureProfile live() { + return profile != null ? profile : IN_CONSTRUCTION.get(); + } } diff --git a/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/entity/mob/seacreature/SeaCreatureProfile.java b/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/entity/mob/seacreature/SeaCreatureProfile.java new file mode 100644 index 000000000..c528e6a9a --- /dev/null +++ b/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/entity/mob/seacreature/SeaCreatureProfile.java @@ -0,0 +1,91 @@ +package net.swofty.type.skyblockgeneric.entity.mob.seacreature; + +import net.minestom.server.entity.EntityType; +import net.swofty.commons.skyblock.statistics.ItemStatistic; +import net.swofty.commons.skyblock.statistics.ItemStatistics; +import net.swofty.type.skyblockgeneric.entity.mob.MobType; +import net.swofty.type.skyblockgeneric.loottable.OtherLoot; +import net.swofty.type.skyblockgeneric.loottable.SkyBlockLootTable; + +import java.util.List; + +/** + * Immutable, declarative description of a sea creature. The concrete mob + * class just hands one of these to {@link SeaCreatureMob} and the base + * class does the rest — no abstract-method ceremony, no per-creature + * duplicated builder boilerplate. + */ +public record SeaCreatureProfile( + String id, + String displayName, + int level, + EntityType entityType, + double health, + double damage, + double speed, + long damageCooldownMs, + long fishingXpReward, + int xpOrbs, + List mobTypes, + SeaCreatureBehaviour behaviour, + SkyBlockLootTable lootTable +) { + + public ItemStatistics asBaseStatistics() { + return ItemStatistics.builder() + .withBase(ItemStatistic.HEALTH, health) + .withBase(ItemStatistic.DAMAGE, damage) + .withBase(ItemStatistic.SPEED, speed) + .build(); + } + + public OtherLoot asOtherLoot() { + return new OtherLoot(fishingXpReward, 0, xpOrbs); + } + + public static Builder builder(String id) { + return new Builder(id); + } + + public static final class Builder { + private final String id; + private String displayName; + private int level = 1; + private EntityType entityType = EntityType.SQUID; + private double health = 100D; + private double damage = 0D; + private double speed = 30D; + private long damageCooldownMs = 500L; + private long fishingXpReward = 0L; + private int xpOrbs = 0; + private List mobTypes = List.of(MobType.AQUATIC); + private SeaCreatureBehaviour behaviour = SeaCreatureBehaviour.passive(8); + private SkyBlockLootTable lootTable = null; + + private Builder(String id) { + this.id = id; + this.displayName = id; + } + + public Builder displayName(String displayName) { this.displayName = displayName; return this; } + public Builder level(int level) { this.level = level; return this; } + public Builder entityType(EntityType entityType) { this.entityType = entityType; return this; } + public Builder health(double health) { this.health = health; return this; } + public Builder damage(double damage) { this.damage = damage; return this; } + public Builder speed(double speed) { this.speed = speed; return this; } + public Builder damageCooldownMs(long damageCooldownMs) { this.damageCooldownMs = damageCooldownMs; return this; } + public Builder fishingXpReward(long fishingXpReward) { this.fishingXpReward = fishingXpReward; return this; } + public Builder xpOrbs(int xpOrbs) { this.xpOrbs = xpOrbs; return this; } + public Builder mobTypes(MobType... mobTypes) { this.mobTypes = List.of(mobTypes); return this; } + public Builder behaviour(SeaCreatureBehaviour behaviour) { this.behaviour = behaviour; return this; } + public Builder lootTable(SkyBlockLootTable lootTable) { this.lootTable = lootTable; return this; } + + public SeaCreatureProfile build() { + return new SeaCreatureProfile( + id, displayName, level, entityType, + health, damage, speed, damageCooldownMs, + fishingXpReward, xpOrbs, mobTypes, behaviour, lootTable + ); + } + } +} diff --git a/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/entity/mob/seacreature/SeaCreatureProfiles.java b/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/entity/mob/seacreature/SeaCreatureProfiles.java new file mode 100644 index 000000000..50b74478c --- /dev/null +++ b/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/entity/mob/seacreature/SeaCreatureProfiles.java @@ -0,0 +1,85 @@ +package net.swofty.type.skyblockgeneric.entity.mob.seacreature; + +import net.minestom.server.entity.EntityType; +import net.swofty.type.skyblockgeneric.entity.mob.MobType; + +import java.util.List; + +/** + * Canonical Hypixel sea creature profiles. Each constant is the entire + * declarative spec for one creature: stats, AI flavour, fishing rewards. + * Adding a new creature is one builder chain, not a new class. + */ +public final class SeaCreatureProfiles { + + public static final SeaCreatureProfile SQUID = SeaCreatureProfile.builder("SQUID") + .displayName("Squid") + .level(1) + .entityType(EntityType.SQUID) + .health(145D).damage(5D).speed(30D) + .behaviour(SeaCreatureBehaviour.passive(8)) + .mobTypes(MobType.AQUATIC) + .fishingXpReward(20).xpOrbs(4) + .build(); + + public static final SeaCreatureProfile SEA_WALKER = SeaCreatureProfile.builder("SEA_WALKER") + .displayName("Sea Walker") + .level(4) + .entityType(EntityType.ZOMBIE) + .health(240D).damage(25D).speed(70D) + .behaviour(SeaCreatureBehaviour.aggressive(1.6, 20, 16)) + .mobTypes(MobType.AQUATIC, MobType.UNDEAD) + .damageCooldownMs(400) + .fishingXpReward(40).xpOrbs(6) + .build(); + + public static final SeaCreatureProfile NIGHT_SQUID = SeaCreatureProfile.builder("NIGHT_SQUID") + .displayName("Night Squid") + .level(6) + .entityType(EntityType.GLOW_SQUID) + .health(400D).damage(15D).speed(30D) + .behaviour(SeaCreatureBehaviour.passive(6)) + .mobTypes(MobType.AQUATIC) + .fishingXpReward(80).xpOrbs(8) + .build(); + + public static final SeaCreatureProfile SEA_GUARDIAN = SeaCreatureProfile.builder("SEA_GUARDIAN") + .displayName("Sea Guardian") + .level(8) + .entityType(EntityType.GUARDIAN) + .health(600D).damage(40D).speed(60D) + .behaviour(SeaCreatureBehaviour.aggressive(2.0, 25, 18)) + .mobTypes(MobType.AQUATIC) + .damageCooldownMs(400) + .fishingXpReward(120).xpOrbs(10) + .build(); + + public static final SeaCreatureProfile MAGMA_SLUG = SeaCreatureProfile.builder("MAGMA_SLUG") + .displayName("Magma Slug") + .level(21) + .entityType(EntityType.MAGMA_CUBE) + .health(850D).damage(170D).speed(50D) + .behaviour(SeaCreatureBehaviour.aggressive(1.6, 20, 14)) + .mobTypes(MobType.MAGMATIC, MobType.CUBIC) + .damageCooldownMs(400) + .fishingXpReward(450).xpOrbs(12) + .build(); + + public static final SeaCreatureProfile LAVA_BLAZE = SeaCreatureProfile.builder("LAVA_BLAZE") + .displayName("Lava Blaze") + .level(30) + .entityType(EntityType.BLAZE) + .health(1500D).damage(250D).speed(90D) + .behaviour(SeaCreatureBehaviour.aggressive(2.5, 20, 20)) + .mobTypes(MobType.MAGMATIC) + .damageCooldownMs(350) + .fishingXpReward(1000).xpOrbs(18) + .build(); + + public static final List CANONICAL = List.of( + SQUID, SEA_WALKER, NIGHT_SQUID, SEA_GUARDIAN, MAGMA_SLUG, LAVA_BLAZE + ); + + private SeaCreatureProfiles() { + } +} diff --git a/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/entity/mob/seacreature/SeaCreatureSpawner.java b/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/entity/mob/seacreature/SeaCreatureSpawner.java index 563456df4..685f8497a 100644 --- a/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/entity/mob/seacreature/SeaCreatureSpawner.java +++ b/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/entity/mob/seacreature/SeaCreatureSpawner.java @@ -9,36 +9,34 @@ import java.util.LinkedHashMap; import java.util.Map; -import java.util.function.Supplier; public final class SeaCreatureSpawner { - private static final Map> FACTORIES = new LinkedHashMap<>(); + private static final Map PROFILES = new LinkedHashMap<>(); static { - register(MobSquid::new); - register(MobSeaWalker::new); - register(MobNightSquid::new); - register(MobSeaGuardian::new); - register(MobLavaBlaze::new); - register(MobMagmaSlug::new); + SeaCreatureProfiles.CANONICAL.forEach(SeaCreatureSpawner::register); } private SeaCreatureSpawner() { } - public static void register(Supplier factory) { - FACTORIES.put(factory.get().getSeaCreatureId(), factory); + public static void register(SeaCreatureProfile profile) { + PROFILES.put(profile.id(), profile); } public static boolean canSpawn(String seaCreatureId) { - return FACTORIES.containsKey(seaCreatureId); + return PROFILES.containsKey(seaCreatureId); + } + + public static @Nullable SeaCreatureProfile getProfile(String seaCreatureId) { + return PROFILES.get(seaCreatureId); } public static @Nullable SeaCreatureMob spawn(SkyBlockPlayer angler, String seaCreatureId, Pos position) { - Supplier factory = FACTORIES.get(seaCreatureId); - if (factory == null) { - Logger.warn("No sea creature factory registered for id={}, falling back to nothing", seaCreatureId); + SeaCreatureProfile profile = PROFILES.get(seaCreatureId); + if (profile == null) { + Logger.warn("No sea creature profile registered for id={}, no spawn will occur", seaCreatureId); return null; } @@ -47,19 +45,22 @@ public static boolean canSpawn(String seaCreatureId) { return null; } - SeaCreatureMob mob = factory.get(); + SeaCreatureMob mob = SeaCreatureMob.create(profile); mob.setInstance(instance, position); - Component selfMessage = Component.text("§3§lSEA CREATURE! §bA " + mob.getDisplayName().toUpperCase() + " has spawned!"); + broadcastCatch(angler, profile, instance, position); + return mob; + } + + private static void broadcastCatch(SkyBlockPlayer angler, SeaCreatureProfile profile, Instance instance, Pos position) { + Component selfMessage = Component.text("§3§lSEA CREATURE! §bA " + profile.displayName().toUpperCase() + " has spawned!"); angler.sendMessage(selfMessage); Component nearbyMessage = Component.text("§3§lSEA CREATURE! §b" + angler.getUsername() - + " caught §a" + mob.getDisplayName() + "§b!"); + + " caught §a" + profile.displayName() + "§b!"); instance.getPlayers().stream() .filter(player -> player.getPosition().distance(position) <= 32) .filter(player -> !player.getUuid().equals(angler.getUuid())) .forEach(player -> player.sendMessage(nearbyMessage)); - - return mob; } } From 186aad2f2063892a6770b84cfa232b5c46a2f454 Mon Sep 17 00:00:00 2001 From: "Jacob Nardella (Swofty)" Date: Fri, 15 May 2026 08:50:52 +1000 Subject: [PATCH 097/113] refactor(fishing)!: replace FishingCatchResult with sealed CatchPayload MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Was: an 8-field record with @Nullable on most of them, plus a parallel FishingCatchKind enum that callers branched on. The trophy tier was deduced by string-scanning the item id ("contains _DIAMOND ? GOLD ? ...") and broadcast logic was a switch buried in FishingService.awardCatch. Now: \`sealed interface CatchPayload permits Item, SeaCreature, TrophyFish, Quest, Special\` Each variant carries only its own fields and an apply(ctx) method that does its own collection update, XP, spawn, and chat broadcast. The service just calls payload.apply() — dispatch by polymorphism, no switch on kind. - TrophyTier enum replaces the stringly-typed BRONZE/SILVER/GOLD/DIAMOND scan; it carries its own colour and display name and offers fromItemId(String) for the rare introspection case. - CatchAwardContext bundles the side-effect surface (player, rod, hook position) so payload variants don't reach into FishingHook directly. - Each variant prints Hypixel-flavoured chat lines ("GOOD CATCH!", "TREASURE!", "TROPHY FISH!", "QUEST CATCH!"), addressing the silent- catch UX gap. - FishingService.awardCatch is now five lines + bait/sinker rolls extracted to their own helpers, instead of an inline switchboard. Removed: FishingCatchResult, FishingCatchKind. --- .../fishing/FishingCatchKind.java | 10 -- .../fishing/FishingCatchResolver.java | 4 +- .../fishing/FishingCatchResult.java | 15 --- .../fishing/FishingLootResolver.java | 80 +++++++-------- .../fishing/FishingService.java | 93 +++++++++-------- .../fishing/catches/CatchAwardContext.java | 14 +++ .../fishing/catches/CatchPayload.java | 99 +++++++++++++++++++ .../fishing/catches/TrophyTier.java | 49 +++++++++ 8 files changed, 248 insertions(+), 116 deletions(-) delete mode 100644 type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/fishing/FishingCatchKind.java delete mode 100644 type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/fishing/FishingCatchResult.java create mode 100644 type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/fishing/catches/CatchAwardContext.java create mode 100644 type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/fishing/catches/CatchPayload.java create mode 100644 type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/fishing/catches/TrophyTier.java diff --git a/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/fishing/FishingCatchKind.java b/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/fishing/FishingCatchKind.java deleted file mode 100644 index 2ec736f53..000000000 --- a/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/fishing/FishingCatchKind.java +++ /dev/null @@ -1,10 +0,0 @@ -package net.swofty.type.skyblockgeneric.fishing; - -public enum FishingCatchKind { - ITEM, - TREASURE, - SEA_CREATURE, - TROPHY_FISH, - QUEST, - SPECIAL -} diff --git a/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/fishing/FishingCatchResolver.java b/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/fishing/FishingCatchResolver.java index f6a935071..4fcb6cc0c 100644 --- a/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/fishing/FishingCatchResolver.java +++ b/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/fishing/FishingCatchResolver.java @@ -1,10 +1,12 @@ package net.swofty.type.skyblockgeneric.fishing; +import net.swofty.type.skyblockgeneric.fishing.catches.CatchPayload; + public final class FishingCatchResolver { private FishingCatchResolver() { } - public static FishingCatchResult resolve(FishingContext context) { + public static CatchPayload resolve(FishingContext context) { return FishingLootResolver.resolve(context); } } diff --git a/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/fishing/FishingCatchResult.java b/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/fishing/FishingCatchResult.java deleted file mode 100644 index 79d2ce265..000000000 --- a/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/fishing/FishingCatchResult.java +++ /dev/null @@ -1,15 +0,0 @@ -package net.swofty.type.skyblockgeneric.fishing; - -import org.jetbrains.annotations.Nullable; - -public record FishingCatchResult( - FishingCatchKind kind, - @Nullable String itemId, - @Nullable String seaCreatureId, - @Nullable String trophyFishId, - int amount, - double skillXp, - boolean corrupted, - @Nullable String message -) { -} diff --git a/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/fishing/FishingLootResolver.java b/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/fishing/FishingLootResolver.java index d1a6c085c..5d70650f5 100644 --- a/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/fishing/FishingLootResolver.java +++ b/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/fishing/FishingLootResolver.java @@ -3,6 +3,9 @@ import net.swofty.commons.skyblock.item.ItemType; import net.swofty.commons.skyblock.statistics.ItemStatistic; import net.swofty.type.generic.data.datapoints.DatapointToggles; +import net.swofty.type.skyblockgeneric.fishing.catches.CatchPayload; +import net.swofty.type.skyblockgeneric.fishing.catches.TrophyTier; +import net.swofty.type.skyblockgeneric.fishing.tags.FishingTag; import net.swofty.type.skyblockgeneric.item.SkyBlockItem; import java.util.ArrayList; @@ -10,23 +13,22 @@ import java.util.List; import java.util.Optional; import java.util.function.Function; -import java.util.stream.Stream; public final class FishingLootResolver { - private static final List>> SPECIAL_CATCHES = List.of( + private static final List>> SPECIAL_CATCHES = List.of( FishingLootResolver::tryResolveQuestCatch, FishingLootResolver::tryResolveTrophyFish, FishingLootResolver::tryResolveSeaCreature ); - private static final FishingCatchResult DEFAULT_CATCH = - new FishingCatchResult(FishingCatchKind.ITEM, "RAW_FISH", null, null, 1, 5.0D, false, null); + private static final CatchPayload DEFAULT_CATCH = + new CatchPayload.Item("RAW_FISH", 1, 5.0D, false); private FishingLootResolver() { } - public static FishingCatchResult resolve(FishingContext context) { + public static CatchPayload resolve(FishingContext context) { return SPECIAL_CATCHES.stream() .map(resolver -> resolver.apply(context)) .flatMap(Optional::stream) @@ -34,7 +36,7 @@ public static FishingCatchResult resolve(FishingContext context) { .orElseGet(() -> resolveItem(context)); } - private static Optional tryResolveTrophyFish(FishingContext context) { + private static Optional tryResolveTrophyFish(FishingContext context) { if (context.medium() != FishingMedium.LAVA) { return Optional.empty(); } @@ -61,25 +63,24 @@ private static Optional tryResolveTrophyFish(FishingContext eligible.sort(Comparator.comparingDouble(TrophyFishDefinition::catchChance)); for (TrophyFishDefinition definition : eligible) { if (Math.random() * 100 <= definition.catchChance() + bonus) { - String tier = rollTrophyTier(context, definition); + TrophyTier tier = rollTrophyTier(context, definition); String itemId = switch (tier) { - case "DIAMOND" -> definition.diamondItemId(); - case "GOLD" -> definition.goldItemId(); - case "SILVER" -> definition.silverItemId(); - default -> definition.bronzeItemId(); + case DIAMOND -> definition.diamondItemId(); + case GOLD -> definition.goldItemId(); + case SILVER -> definition.silverItemId(); + case BRONZE -> definition.bronzeItemId(); }; if (itemId == null) { continue; } - return Optional.of(new FishingCatchResult( - FishingCatchKind.TROPHY_FISH, itemId, null, definition.id(), 1, 300.0D, false, null)); + return Optional.of(new CatchPayload.TrophyFish(definition.id(), tier, itemId, 300.0D)); } } return Optional.empty(); } - private static Optional tryResolveQuestCatch(FishingContext context) { + private static Optional tryResolveQuestCatch(FishingContext context) { if (context.medium() != FishingMedium.WATER) return Optional.empty(); if (context.regionId() == null) return Optional.empty(); if (!"FISHING_OUTPOST".equals(context.regionId()) && !"FISHERMANS_HUT".equals(context.regionId())) { @@ -95,25 +96,21 @@ private static Optional tryResolveQuestCatch(FishingContext if (context.player().countItem(ItemType.RUSTY_SHIP_ENGINE) > 0) return Optional.empty(); if (Math.random() * 100 > 1.0D) return Optional.empty(); - return Optional.of(new FishingCatchResult( - FishingCatchKind.QUEST, + return Optional.of(new CatchPayload.Quest( ItemType.RUSTY_SHIP_ENGINE.name(), - null, - null, 1, 15.0D, - false, "You fished up a Rusty Ship Engine!" )); } - private static String rollTrophyTier(FishingContext context, TrophyFishDefinition definition) { + private static TrophyTier rollTrophyTier(FishingContext context, TrophyFishDefinition definition) { var progress = context.player().getTrophyFishData().getProgress(definition.id()); - if (progress.getTotalCatches() + 1 >= 600 && !progress.hasTier("DIAMOND")) { - return "DIAMOND"; + if (progress.getTotalCatches() + 1 >= 600 && !progress.hasTier(TrophyTier.DIAMOND.name())) { + return TrophyTier.DIAMOND; } - if (progress.getTotalCatches() + 1 >= 100 && !progress.hasTier("GOLD")) { - return "GOLD"; + if (progress.getTotalCatches() + 1 >= 100 && !progress.hasTier(TrophyTier.GOLD.name())) { + return TrophyTier.GOLD; } double charmBonus = 0.0D; @@ -122,13 +119,13 @@ private static String rollTrophyTier(FishingContext context, TrophyFishDefinitio charmBonus = charm.level() * 2.0D; } - if (Math.random() <= (0.002D * (1 + charmBonus / 100D))) return "DIAMOND"; - if (Math.random() <= (0.02D * (1 + charmBonus / 100D))) return "GOLD"; - if (Math.random() <= (0.25D * (1 + charmBonus / 100D))) return "SILVER"; - return "BRONZE"; + if (Math.random() <= (0.002D * (1 + charmBonus / 100D))) return TrophyTier.DIAMOND; + if (Math.random() <= (0.02D * (1 + charmBonus / 100D))) return TrophyTier.GOLD; + if (Math.random() <= (0.25D * (1 + charmBonus / 100D))) return TrophyTier.SILVER; + return TrophyTier.BRONZE; } - private static Optional tryResolveSeaCreature(FishingContext context) { + private static Optional tryResolveSeaCreature(FishingContext context) { Optional tableOpt = findTable(context); if (tableOpt.isEmpty()) return Optional.empty(); FishingTableDefinition table = tableOpt.get(); @@ -149,14 +146,13 @@ private static Optional tryResolveSeaCreature(FishingContext double tagBonus = definition == null ? 0.0D : getTagBonus(context, definition.tags()); if (Math.random() * 100 <= roll.chance() + seaCreatureChance + tagBonus) { double skillXp = definition == null ? 0.0D : definition.skillXp(); - return Optional.of(new FishingCatchResult( - FishingCatchKind.SEA_CREATURE, null, roll.seaCreatureId(), null, 1, skillXp, false, null)); + return Optional.of(new CatchPayload.SeaCreature(roll.seaCreatureId(), skillXp)); } } return Optional.empty(); } - private static FishingCatchResult resolveItem(FishingContext context) { + private static CatchPayload resolveItem(FishingContext context) { Optional tableOpt = findTable(context); if (tableOpt.isEmpty()) return DEFAULT_CATCH; FishingTableDefinition table = tableOpt.get(); @@ -172,15 +168,15 @@ private static FishingCatchResult resolveItem(FishingContext context) { if (!table.treasures().isEmpty() && Math.random() * 100 <= treasureChance) { pool = context.sinker() != null && context.sinker().isBayouTreasureToJunk() ? table.junk() : table.treasures(); - return pick(pool, FishingCatchKind.TREASURE).orElse(DEFAULT_CATCH); + return pick(pool, true).orElse(DEFAULT_CATCH); } - return pick(pool, FishingCatchKind.ITEM) - .or(() -> table.junk().isEmpty() ? Optional.empty() : pick(table.junk(), FishingCatchKind.ITEM)) + return pick(pool, false) + .or(() -> table.junk().isEmpty() ? Optional.empty() : pick(table.junk(), false)) .orElse(DEFAULT_CATCH); } - private static Optional pick(List pool, FishingCatchKind kind) { + private static Optional pick(List pool, boolean fromTreasure) { if (pool.isEmpty()) return Optional.empty(); double roll = Math.random() * 100; @@ -188,13 +184,11 @@ private static Optional pick(List findTable(FishingContext context) { @@ -226,7 +220,7 @@ private static double getTotalStatistic(FishingContext context, ItemStatistic st return total; } - private static double getTagBonus(FishingContext context, List tags) { + private static double getTagBonus(FishingContext context, List tags) { double total = 0.0D; if (context.hook() != null) { total += getTagBonus(context.hook().getTagBonuses(), tags); @@ -243,9 +237,9 @@ private static double getTagBonus(FishingContext context, List bonuses, List tags) { + private static double getTagBonus(java.util.Map bonuses, List tags) { double total = 0.0D; - for (net.swofty.type.skyblockgeneric.fishing.tags.FishingTag tag : tags) { + for (FishingTag tag : tags) { total += bonuses.getOrDefault(tag.id(), 0.0D); } return total; diff --git a/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/fishing/FishingService.java b/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/fishing/FishingService.java index 5f112fcd5..aa1bffff4 100644 --- a/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/fishing/FishingService.java +++ b/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/fishing/FishingService.java @@ -1,11 +1,9 @@ package net.swofty.type.skyblockgeneric.fishing; import net.swofty.type.generic.data.datapoints.DatapointToggles; -import net.swofty.type.skyblockgeneric.data.SkyBlockDataHandler; -import net.swofty.type.skyblockgeneric.data.datapoints.DatapointCollection; -import net.swofty.type.skyblockgeneric.data.datapoints.DatapointTrophyFish; import net.swofty.type.skyblockgeneric.entity.FishingHook; -import net.swofty.type.skyblockgeneric.entity.mob.seacreature.SeaCreatureSpawner; +import net.swofty.type.skyblockgeneric.fishing.catches.CatchAwardContext; +import net.swofty.type.skyblockgeneric.fishing.catches.CatchPayload; import net.swofty.type.skyblockgeneric.item.SkyBlockItem; import net.swofty.type.skyblockgeneric.item.components.FishingBaitComponent; import net.swofty.type.skyblockgeneric.item.components.FishingRodPartComponent; @@ -69,7 +67,7 @@ public static long computeWaitTicks(SkyBlockPlayer player, SkyBlockItem rod, @Nu return Math.max(20L, Math.round(baseTicks - Math.min(50D, fishingSpeed / 2D))); } - public static @Nullable FishingCatchResult resolveCatch(SkyBlockPlayer player, SkyBlockItem rod, FishingHook hook) { + public static @Nullable CatchPayload resolveCatch(SkyBlockPlayer player, SkyBlockItem rod, FishingHook hook) { FishingSession session = getSession(player.getUuid()); if (session == null || session.resolved()) { return null; @@ -93,64 +91,65 @@ public static long computeWaitTicks(SkyBlockPlayer player, SkyBlockItem rod, @Nu System.currentTimeMillis() - session.castAt() ); - FishingCatchResult result = FishingCatchResolver.resolve(context); - if (result == null) { + CatchPayload payload = FishingCatchResolver.resolve(context); + if (payload == null) { return null; } - if (session.baitItemId() != null) { - boolean preserve = false; - var caster = rod.getAttributeHandler().getEnchantment(net.swofty.type.skyblockgeneric.enchantment.EnchantmentType.CASTER); - if (caster != null) { - preserve |= Math.random() * 100 < caster.level(); - } - FishingRodPartComponent sinker = FishingRodPartService.getSinker(rod); - if (!preserve && sinker != null && sinker.getBaitPreservationChance() > 0) { - preserve = Math.random() * 100 < sinker.getBaitPreservationChance(); - } - if (!preserve) { - FishingBaitService.consumeOneBait(player, session.baitItemId()); - } - } - - awardCatch(player, rod, hook, result); + consumeBait(player, rod, session); + awardCatch(player, rod, hook, payload); updateSession(session.withResolved(true)); - return result; + return payload; } - private static void awardCatch(SkyBlockPlayer player, SkyBlockItem rod, FishingHook hook, FishingCatchResult result) { - if (!player.getToggles().get(DatapointToggles.Toggles.ToggleType.HAS_CAUGHT_FIRST_FISH)) { - player.getToggles().set(DatapointToggles.Toggles.ToggleType.HAS_CAUGHT_FIRST_FISH, true); + private static void consumeBait(SkyBlockPlayer player, SkyBlockItem rod, FishingSession session) { + if (session.baitItemId() == null) { + return; } - - if (result.itemId() != null) { - player.addAndUpdateItem(net.swofty.commons.skyblock.item.ItemType.valueOf(result.itemId()), result.amount()); - player.getCollection().increase(net.swofty.commons.skyblock.item.ItemType.valueOf(result.itemId()), result.amount()); - player.getSkyblockDataHandler().get(SkyBlockDataHandler.Data.COLLECTION, DatapointCollection.class).setValue(player.getCollection()); + if (rollBaitPreservation(rod)) { + return; } + FishingBaitService.consumeOneBait(player, session.baitItemId()); + } - FishingRodPartComponent sinker = FishingRodPartService.getSinker(rod); - if (sinker != null && sinker.getMaterializedItemId() != null && Math.random() <= sinker.getMaterializedChance()) { - player.addAndUpdateItem(net.swofty.commons.skyblock.item.ItemType.valueOf(sinker.getMaterializedItemId())); + private static boolean rollBaitPreservation(SkyBlockItem rod) { + var caster = rod.getAttributeHandler().getEnchantment(net.swofty.type.skyblockgeneric.enchantment.EnchantmentType.CASTER); + if (caster != null && Math.random() * 100 < caster.level()) { + return true; } + FishingRodPartComponent sinker = FishingRodPartService.getSinker(rod); + return sinker != null + && sinker.getBaitPreservationChance() > 0 + && Math.random() * 100 < sinker.getBaitPreservationChance(); + } - if (result.trophyFishId() != null) { - String tier = result.itemId() != null && result.itemId().contains("_DIAMOND") ? "DIAMOND" : - result.itemId() != null && result.itemId().contains("_GOLD") ? "GOLD" : - result.itemId() != null && result.itemId().contains("_SILVER") ? "SILVER" : "BRONZE"; - DatapointTrophyFish.TrophyFishData data = player.getTrophyFishData(); - data.getProgress(result.trophyFishId()).increment(tier); - player.getSkyblockDataHandler().get(SkyBlockDataHandler.Data.TROPHY_FISH, DatapointTrophyFish.class).setValue(data); + private static void awardCatch(SkyBlockPlayer player, SkyBlockItem rod, FishingHook hook, CatchPayload payload) { + markFirstFishToggle(player); + rollSinkerMaterialize(player, rod); + + payload.apply(new CatchAwardContext(player, rod, hook.getSpawnPosition())); + + if (!(payload instanceof CatchPayload.SeaCreature) && payload.skillXp() > 0) { + player.getSkills().increase(player, net.swofty.type.skyblockgeneric.skill.SkillCategories.FISHING, payload.skillXp()); } - if (result.kind() != FishingCatchKind.SEA_CREATURE && result.skillXp() > 0) { - player.getSkills().increase(player, net.swofty.type.skyblockgeneric.skill.SkillCategories.FISHING, result.skillXp()); + player.setItemInHand(rod); + } + + private static void markFirstFishToggle(SkyBlockPlayer player) { + if (!player.getToggles().get(DatapointToggles.Toggles.ToggleType.HAS_CAUGHT_FIRST_FISH)) { + player.getToggles().set(DatapointToggles.Toggles.ToggleType.HAS_CAUGHT_FIRST_FISH, true); } + } - if (result.kind() == FishingCatchKind.SEA_CREATURE && result.seaCreatureId() != null) { - SeaCreatureSpawner.spawn(player, result.seaCreatureId(), hook.getSpawnPosition()); + private static void rollSinkerMaterialize(SkyBlockPlayer player, SkyBlockItem rod) { + FishingRodPartComponent sinker = FishingRodPartService.getSinker(rod); + if (sinker == null || sinker.getMaterializedItemId() == null) { + return; + } + if (Math.random() <= sinker.getMaterializedChance()) { + player.addAndUpdateItem(net.swofty.commons.skyblock.item.ItemType.valueOf(sinker.getMaterializedItemId())); } - player.setItemInHand(rod); } private static boolean hasAnyBuffValue(net.swofty.commons.skyblock.statistics.ItemStatistics statistics) { diff --git a/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/fishing/catches/CatchAwardContext.java b/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/fishing/catches/CatchAwardContext.java new file mode 100644 index 000000000..a117300a8 --- /dev/null +++ b/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/fishing/catches/CatchAwardContext.java @@ -0,0 +1,14 @@ +package net.swofty.type.skyblockgeneric.fishing.catches; + +import net.minestom.server.coordinate.Pos; +import net.swofty.type.skyblockgeneric.item.SkyBlockItem; +import net.swofty.type.skyblockgeneric.user.SkyBlockPlayer; + +/** + * Side-effect surface a {@link CatchPayload} sees when it's applied. + * Keeps the payload variants free of FishingHook coupling while still + * giving them everything they need (player, the rod that pulled them + * up, and the bobber position for spawn placement). + */ +public record CatchAwardContext(SkyBlockPlayer player, SkyBlockItem rod, Pos hookPosition) { +} diff --git a/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/fishing/catches/CatchPayload.java b/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/fishing/catches/CatchPayload.java new file mode 100644 index 000000000..93e20153f --- /dev/null +++ b/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/fishing/catches/CatchPayload.java @@ -0,0 +1,99 @@ +package net.swofty.type.skyblockgeneric.fishing.catches; + +import net.kyori.adventure.text.Component; +import net.swofty.commons.skyblock.item.ItemType; +import net.swofty.type.skyblockgeneric.data.SkyBlockDataHandler; +import net.swofty.type.skyblockgeneric.data.datapoints.DatapointCollection; +import net.swofty.type.skyblockgeneric.data.datapoints.DatapointTrophyFish; +import net.swofty.type.skyblockgeneric.entity.mob.seacreature.SeaCreatureSpawner; +import net.swofty.type.skyblockgeneric.user.SkyBlockPlayer; + +/** + * Sealed view of what the rod can pull out of the water. Each variant + * carries exactly its own fields — no bag of nullable @Nullable strings — + * and owns its own {@link #apply(CatchAwardContext)} so the FishingService + * dispatches by polymorphism rather than switch-on-kind. + */ +public sealed interface CatchPayload { + + /** Fishing skill XP to award; sea creatures intentionally return 0 (their kill awards XP separately). */ + double skillXp(); + + /** Short human label for telemetry / chat — variants pick the format. */ + String summary(); + + /** Run the catch's side-effects on the player. */ + void apply(CatchAwardContext ctx); + + /* ------------------------------------------------------------------ */ + /* Variants */ + /* ------------------------------------------------------------------ */ + + record Item(String itemId, int amount, double skillXp, boolean fromTreasure) implements CatchPayload { + @Override public String summary() { return (fromTreasure ? "treasure " : "") + amount + "x " + itemId; } + + @Override + public void apply(CatchAwardContext ctx) { + ItemType type = ItemType.valueOf(itemId); + ctx.player().addAndUpdateItem(type, amount); + ctx.player().getCollection().increase(type, amount); + ctx.player().getSkyblockDataHandler() + .get(SkyBlockDataHandler.Data.COLLECTION, DatapointCollection.class) + .setValue(ctx.player().getCollection()); + + String prefix = fromTreasure ? "§b§lTREASURE! §7" : "§b§lGOOD CATCH! §7"; + ctx.player().sendMessage(Component.text(prefix + "You found " + amount + "x §a" + itemId + "§7!")); + } + } + + record SeaCreature(String seaCreatureId, double skillXp) implements CatchPayload { + @Override public String summary() { return "sea creature " + seaCreatureId; } + + @Override + public void apply(CatchAwardContext ctx) { + SeaCreatureSpawner.spawn(ctx.player(), seaCreatureId, ctx.hookPosition()); + } + } + + record TrophyFish(String definitionId, TrophyTier tier, String itemId, double skillXp) implements CatchPayload { + @Override public String summary() { return "trophy " + tier.name() + " " + definitionId; } + + @Override + public void apply(CatchAwardContext ctx) { + ItemType type = ItemType.valueOf(itemId); + ctx.player().addAndUpdateItem(type, 1); + + DatapointTrophyFish.TrophyFishData data = ctx.player().getTrophyFishData(); + data.getProgress(definitionId).increment(tier.name()); + ctx.player().getSkyblockDataHandler() + .get(SkyBlockDataHandler.Data.TROPHY_FISH, DatapointTrophyFish.class) + .setValue(data); + + ctx.player().sendMessage(Component.text("§b§lTROPHY FISH! §7You reeled in a " + + tier.colour() + tier.displayName() + " §a" + definitionId + "§7!")); + } + } + + record Quest(String itemId, int amount, double skillXp, String message) implements CatchPayload { + @Override public String summary() { return "quest " + itemId; } + + @Override + public void apply(CatchAwardContext ctx) { + ctx.player().addAndUpdateItem(ItemType.valueOf(itemId), amount); + ctx.player().sendMessage(Component.text("§d§lQUEST CATCH! §7" + message)); + } + } + + record Special(String itemId, int amount, double skillXp, boolean corrupted) implements CatchPayload { + @Override public String summary() { return "special " + itemId; } + + @Override + public void apply(CatchAwardContext ctx) { + ItemType type = ItemType.valueOf(itemId); + ctx.player().addAndUpdateItem(type, amount); + ctx.player().getCollection().increase(type, amount); + String prefix = corrupted ? "§5§lCORRUPTED! §7" : "§d§lWONDROUS CATCH! §7"; + ctx.player().sendMessage(Component.text(prefix + "You found §a" + itemId + "§7!")); + } + } +} diff --git a/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/fishing/catches/TrophyTier.java b/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/fishing/catches/TrophyTier.java new file mode 100644 index 000000000..dfaeeebb8 --- /dev/null +++ b/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/fishing/catches/TrophyTier.java @@ -0,0 +1,49 @@ +package net.swofty.type.skyblockgeneric.fishing.catches; + +import java.util.List; +import java.util.Optional; + +/** + * Enumerated trophy fish tier. Replaces the previous stringly-typed + * deduction that scanned item IDs for "_DIAMOND"/"_GOLD" substrings. + */ +public enum TrophyTier { + BRONZE("§c", "Bronze"), + SILVER("§7", "Silver"), + GOLD("§6", "Gold"), + DIAMOND("§b", "Diamond"); + + private final String colour; + private final String displayName; + + TrophyTier(String colour, String displayName) { + this.colour = colour; + this.displayName = displayName; + } + + public String colour() { + return colour; + } + + public String displayName() { + return displayName; + } + + public String suffix() { + return "_" + name(); + } + + public static Optional fromItemId(String itemId) { + if (itemId == null) return Optional.empty(); + for (TrophyTier tier : values()) { + if (itemId.contains(tier.suffix())) { + return Optional.of(tier); + } + } + return Optional.empty(); + } + + public static List orderedDescending() { + return List.of(DIAMOND, GOLD, SILVER, BRONZE); + } +} From f95b8f0e1891a9d7fd0fb164a96684bc08944db7 Mon Sep 17 00:00:00 2001 From: "Jacob Nardella (Swofty)" Date: Fri, 15 May 2026 08:53:58 +1000 Subject: [PATCH 098/113] feat(fishing): Double Hook for paired sea creature spawns MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Hypixel's canonical Double Hook mechanic: DOUBLE_HOOK_CHANCE % of the time, a sea-creature catch spawns two mobs instead of one. The chance reads from the player's DOUBLE_HOOK_CHANCE statistic (rod stats + hotspot buffs + rod parts) plus any bait doubleHookChanceBonus. On a successful roll, the SeaCreature payload is rebound via .withDoubleHook() (one extra field, no scattered state) and apply() loops the spawn twice, prefixing the canonical "§a§lDOUBLE HOOK!" line. --- .../fishing/FishingLootResolver.java | 14 ++++++++++++- .../fishing/catches/CatchPayload.java | 21 ++++++++++++++++--- 2 files changed, 31 insertions(+), 4 deletions(-) diff --git a/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/fishing/FishingLootResolver.java b/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/fishing/FishingLootResolver.java index 5d70650f5..4c71a4d12 100644 --- a/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/fishing/FishingLootResolver.java +++ b/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/fishing/FishingLootResolver.java @@ -146,7 +146,11 @@ private static Optional tryResolveSeaCreature(FishingContext conte double tagBonus = definition == null ? 0.0D : getTagBonus(context, definition.tags()); if (Math.random() * 100 <= roll.chance() + seaCreatureChance + tagBonus) { double skillXp = definition == null ? 0.0D : definition.skillXp(); - return Optional.of(new CatchPayload.SeaCreature(roll.seaCreatureId(), skillXp)); + CatchPayload.SeaCreature payload = new CatchPayload.SeaCreature(roll.seaCreatureId(), skillXp); + if (rollDoubleHook(context)) { + payload = payload.withDoubleHook(); + } + return Optional.of(payload); } } return Optional.empty(); @@ -207,6 +211,14 @@ private static Optional findTable(FishingContext context return Optional.ofNullable(fallback); } + private static boolean rollDoubleHook(FishingContext context) { + double chance = getTotalStatistic(context, ItemStatistic.DOUBLE_HOOK_CHANCE); + if (context.bait() != null) { + chance += context.bait().getDoubleHookChanceBonus(); + } + return chance > 0 && Math.random() * 100 <= chance; + } + private static double getTotalStatistic(FishingContext context, ItemStatistic statistic) { double total = context.rod().getAttributeHandler().getStatistics().getOverall(statistic) + FishingRodPartService.getStatistics(context.rod()).getOverall(statistic); diff --git a/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/fishing/catches/CatchPayload.java b/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/fishing/catches/CatchPayload.java index 93e20153f..3d3df94de 100644 --- a/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/fishing/catches/CatchPayload.java +++ b/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/fishing/catches/CatchPayload.java @@ -46,12 +46,27 @@ public void apply(CatchAwardContext ctx) { } } - record SeaCreature(String seaCreatureId, double skillXp) implements CatchPayload { - @Override public String summary() { return "sea creature " + seaCreatureId; } + record SeaCreature(String seaCreatureId, double skillXp, int spawnCount) implements CatchPayload { + public SeaCreature(String seaCreatureId, double skillXp) { + this(seaCreatureId, skillXp, 1); + } + + public SeaCreature withDoubleHook() { + return new SeaCreature(seaCreatureId, skillXp, 2); + } + + @Override public String summary() { + return spawnCount > 1 ? "double-hook " + seaCreatureId : "sea creature " + seaCreatureId; + } @Override public void apply(CatchAwardContext ctx) { - SeaCreatureSpawner.spawn(ctx.player(), seaCreatureId, ctx.hookPosition()); + if (spawnCount > 1) { + ctx.player().sendMessage(net.kyori.adventure.text.Component.text("§a§lDOUBLE HOOK!")); + } + for (int i = 0; i < spawnCount; i++) { + SeaCreatureSpawner.spawn(ctx.player(), seaCreatureId, ctx.hookPosition()); + } } } From 323c87116de28a22af29adece75ab45db84fde5a Mon Sep 17 00:00:00 2001 From: "Jacob Nardella (Swofty)" Date: Fri, 15 May 2026 08:55:34 +1000 Subject: [PATCH 099/113] feat(fishing): expand sea creature roster to 20 canonical Hypixel creatures MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Was: 6 creatures (4 water, 2 lava) — minimum-viable. Now: 13 water + 8 lava, covering the canonical Hypixel SkyBlock roster from Squid (Lv 1) through The Sea Emperor (Lv 80) on water, and Magma Slug (Lv 21) through Lord Jawbus (Lv 45) on lava. Each profile picks a sensible Minestom entity to render the creature (GUARDIAN for Sea Guardian, ELDER_GUARDIAN for The Sea Emperor, HOGLIN for Taurus, GHAST for Lord Jawbus, etc.), uses Aggressive or Passive behaviour appropriately, and sets reward XP scaled to the wiki's catch-rarity tiers. Catfish is tagged RAINING — Hypixel's mechanic that the WeatherTag gate now enforces automatically (only rolls while the instance has rain). Other creatures pick up RarityTag (COMMON/UNCOMMON/RARE/EPIC/ LEGENDARY/MYTHIC) which is informational today but ready for catalog GUIs and tag-bonus stacking. sea_creatures.yml updated with all 21 entries. --- .../skyblock/fishing/sea_creatures.yml | 71 ++++++- .../mob/seacreature/SeaCreatureProfiles.java | 177 +++++++++++++++++- 2 files changed, 243 insertions(+), 5 deletions(-) diff --git a/configuration/skyblock/fishing/sea_creatures.yml b/configuration/skyblock/fishing/sea_creatures.yml index 68e64bdc8..8b96f3547 100644 --- a/configuration/skyblock/fishing/sea_creatures.yml +++ b/configuration/skyblock/fishing/sea_creatures.yml @@ -1,4 +1,5 @@ seaCreatures: + # ---------- water ---------- - id: SQUID requiredFishingLevel: 1 skillXp: 20 @@ -10,16 +11,78 @@ seaCreatures: - id: NIGHT_SQUID requiredFishingLevel: 6 skillXp: 80 - tags: [WATER, NIGHT] + tags: [WATER, NIGHT, UNCOMMON] - id: SEA_GUARDIAN requiredFishingLevel: 8 skillXp: 120 - tags: [WATER] + tags: [WATER, UNCOMMON] + - id: SEA_WITCH + requiredFishingLevel: 10 + skillXp: 150 + tags: [WATER, UNCOMMON] + - id: SEA_ARCHER + requiredFishingLevel: 15 + skillXp: 200 + tags: [WATER, RARE] + - id: MONSTER_OF_THE_DEEP + requiredFishingLevel: 20 + skillXp: 300 + tags: [WATER, RARE] + - id: CATFISH + requiredFishingLevel: 24 + skillXp: 400 + tags: [WATER, RAINING, RARE] + - id: CARROT_KING + requiredFishingLevel: 26 + skillXp: 500 + tags: [WATER, RARE] + - id: SEA_LEECH + requiredFishingLevel: 30 + skillXp: 650 + tags: [WATER, EPIC] + - id: GUARDIAN_DEFENDER + requiredFishingLevel: 35 + skillXp: 900 + tags: [WATER, EPIC] + - id: WATER_HYDRA + requiredFishingLevel: 60 + skillXp: 7500 + tags: [WATER, LEGENDARY] + - id: THE_SEA_EMPEROR + requiredFishingLevel: 80 + skillXp: 20000 + tags: [WATER, MYTHIC] + + # ---------- lava (Crimson Isle) ---------- - id: MAGMA_SLUG requiredFishingLevel: 21 skillXp: 450 - tags: [LAVA, CRIMSON] + tags: [LAVA, CRIMSON, COMMON] + - id: MOOGMA + requiredFishingLevel: 22 + skillXp: 500 + tags: [LAVA, CRIMSON, COMMON] + - id: LAVA_LEECH + requiredFishingLevel: 24 + skillXp: 550 + tags: [LAVA, CRIMSON, COMMON] + - id: PYROCLASTIC_WORM + requiredFishingLevel: 28 + skillXp: 800 + tags: [LAVA, CRIMSON, UNCOMMON] + - id: FIRE_EEL + requiredFishingLevel: 28 + skillXp: 800 + tags: [LAVA, CRIMSON, UNCOMMON] - id: LAVA_BLAZE requiredFishingLevel: 30 skillXp: 1000 - tags: [LAVA, CRIMSON] + tags: [LAVA, CRIMSON, RARE] + - id: TAURUS + requiredFishingLevel: 36 + skillXp: 2500 + tags: [LAVA, CRIMSON, EPIC] + - id: LORD_JAWBUS + requiredFishingLevel: 45 + skillXp: 15000 + tags: [LAVA, CRIMSON, LEGENDARY] diff --git a/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/entity/mob/seacreature/SeaCreatureProfiles.java b/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/entity/mob/seacreature/SeaCreatureProfiles.java index 50b74478c..780e6d17e 100644 --- a/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/entity/mob/seacreature/SeaCreatureProfiles.java +++ b/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/entity/mob/seacreature/SeaCreatureProfiles.java @@ -12,6 +12,8 @@ */ public final class SeaCreatureProfiles { + /* ---------- water ---------- */ + public static final SeaCreatureProfile SQUID = SeaCreatureProfile.builder("SQUID") .displayName("Squid") .level(1) @@ -54,6 +56,107 @@ public final class SeaCreatureProfiles { .fishingXpReward(120).xpOrbs(10) .build(); + public static final SeaCreatureProfile SEA_WITCH = SeaCreatureProfile.builder("SEA_WITCH") + .displayName("Sea Witch") + .level(10) + .entityType(EntityType.WITCH) + .health(800D).damage(60D).speed(60D) + .behaviour(SeaCreatureBehaviour.aggressive(1.5, 30, 16)) + .mobTypes(MobType.AQUATIC, MobType.ARCANE) + .damageCooldownMs(450) + .fishingXpReward(150).xpOrbs(12) + .build(); + + public static final SeaCreatureProfile SEA_ARCHER = SeaCreatureProfile.builder("SEA_ARCHER") + .displayName("Sea Archer") + .level(15) + .entityType(EntityType.SKELETON) + .health(1000D).damage(80D).speed(75D) + .behaviour(SeaCreatureBehaviour.aggressive(1.7, 25, 20)) + .mobTypes(MobType.AQUATIC, MobType.SKELETAL) + .damageCooldownMs(400) + .fishingXpReward(200).xpOrbs(14) + .build(); + + public static final SeaCreatureProfile MONSTER_OF_THE_DEEP = SeaCreatureProfile.builder("MONSTER_OF_THE_DEEP") + .displayName("Monster of the Deep") + .level(20) + .entityType(EntityType.DROWNED) + .health(1500D).damage(120D).speed(80D) + .behaviour(SeaCreatureBehaviour.aggressive(2.0, 22, 20)) + .mobTypes(MobType.AQUATIC, MobType.UNDEAD) + .damageCooldownMs(400) + .fishingXpReward(300).xpOrbs(16) + .build(); + + public static final SeaCreatureProfile CATFISH = SeaCreatureProfile.builder("CATFISH") + .displayName("Catfish") + .level(24) + .entityType(EntityType.OCELOT) + .health(2000D).damage(150D).speed(90D) + .behaviour(SeaCreatureBehaviour.aggressive(2.2, 18, 18)) + .mobTypes(MobType.AQUATIC, MobType.ANIMAL) + .damageCooldownMs(350) + .fishingXpReward(400).xpOrbs(18) + .build(); + + public static final SeaCreatureProfile CARROT_KING = SeaCreatureProfile.builder("CARROT_KING") + .displayName("Carrot King") + .level(26) + .entityType(EntityType.RABBIT) + .health(2500D).damage(170D).speed(95D) + .behaviour(SeaCreatureBehaviour.aggressive(2.0, 25, 16)) + .mobTypes(MobType.AQUATIC, MobType.ANIMAL) + .damageCooldownMs(400) + .fishingXpReward(500).xpOrbs(20) + .build(); + + public static final SeaCreatureProfile SEA_LEECH = SeaCreatureProfile.builder("SEA_LEECH") + .displayName("Sea Leech") + .level(30) + .entityType(EntityType.SILVERFISH) + .health(3000D).damage(200D).speed(110D) + .behaviour(SeaCreatureBehaviour.aggressive(2.4, 18, 14)) + .mobTypes(MobType.AQUATIC, MobType.ARTHROPOD) + .damageCooldownMs(350) + .fishingXpReward(650).xpOrbs(22) + .build(); + + public static final SeaCreatureProfile GUARDIAN_DEFENDER = SeaCreatureProfile.builder("GUARDIAN_DEFENDER") + .displayName("Guardian Defender") + .level(35) + .entityType(EntityType.GUARDIAN) + .health(5000D).damage(250D).speed(70D) + .behaviour(SeaCreatureBehaviour.aggressive(1.8, 30, 20)) + .mobTypes(MobType.AQUATIC, MobType.SHIELDED) + .damageCooldownMs(450) + .fishingXpReward(900).xpOrbs(26) + .build(); + + public static final SeaCreatureProfile WATER_HYDRA = SeaCreatureProfile.builder("WATER_HYDRA") + .displayName("Water Hydra") + .level(60) + .entityType(EntityType.WITHER) + .health(50000D).damage(800D).speed(80D) + .behaviour(SeaCreatureBehaviour.aggressive(2.5, 20, 28)) + .mobTypes(MobType.AQUATIC, MobType.ELUSIVE) + .damageCooldownMs(300) + .fishingXpReward(7500).xpOrbs(60) + .build(); + + public static final SeaCreatureProfile THE_SEA_EMPEROR = SeaCreatureProfile.builder("THE_SEA_EMPEROR") + .displayName("The Sea Emperor") + .level(80) + .entityType(EntityType.ELDER_GUARDIAN) + .health(150000D).damage(1500D).speed(60D) + .behaviour(SeaCreatureBehaviour.aggressive(2.0, 30, 32)) + .mobTypes(MobType.AQUATIC, MobType.MYTHOLOGICAL, MobType.ELUSIVE) + .damageCooldownMs(400) + .fishingXpReward(20000).xpOrbs(120) + .build(); + + /* ---------- lava (Crimson Isle) ---------- */ + public static final SeaCreatureProfile MAGMA_SLUG = SeaCreatureProfile.builder("MAGMA_SLUG") .displayName("Magma Slug") .level(21) @@ -65,6 +168,50 @@ public final class SeaCreatureProfiles { .fishingXpReward(450).xpOrbs(12) .build(); + public static final SeaCreatureProfile MOOGMA = SeaCreatureProfile.builder("MOOGMA") + .displayName("Moogma") + .level(22) + .entityType(EntityType.STRIDER) + .health(900D).damage(180D).speed(75D) + .behaviour(SeaCreatureBehaviour.aggressive(1.8, 22, 16)) + .mobTypes(MobType.MAGMATIC, MobType.ANIMAL) + .damageCooldownMs(400) + .fishingXpReward(500).xpOrbs(14) + .build(); + + public static final SeaCreatureProfile LAVA_LEECH = SeaCreatureProfile.builder("LAVA_LEECH") + .displayName("Lava Leech") + .level(24) + .entityType(EntityType.SILVERFISH) + .health(1100D).damage(200D).speed(100D) + .behaviour(SeaCreatureBehaviour.aggressive(2.4, 18, 14)) + .mobTypes(MobType.MAGMATIC, MobType.ARTHROPOD) + .damageCooldownMs(350) + .fishingXpReward(550).xpOrbs(14) + .build(); + + public static final SeaCreatureProfile PYROCLASTIC_WORM = SeaCreatureProfile.builder("PYROCLASTIC_WORM") + .displayName("Pyroclastic Worm") + .level(28) + .entityType(EntityType.ENDERMITE) + .health(1400D).damage(240D).speed(95D) + .behaviour(SeaCreatureBehaviour.aggressive(2.2, 18, 16)) + .mobTypes(MobType.MAGMATIC, MobType.ARTHROPOD) + .damageCooldownMs(350) + .fishingXpReward(800).xpOrbs(16) + .build(); + + public static final SeaCreatureProfile FIRE_EEL = SeaCreatureProfile.builder("FIRE_EEL") + .displayName("Fire Eel") + .level(28) + .entityType(EntityType.PHANTOM) + .health(1300D).damage(220D).speed(100D) + .behaviour(SeaCreatureBehaviour.aggressive(2.5, 18, 18)) + .mobTypes(MobType.MAGMATIC, MobType.AIRBORNE) + .damageCooldownMs(350) + .fishingXpReward(800).xpOrbs(16) + .build(); + public static final SeaCreatureProfile LAVA_BLAZE = SeaCreatureProfile.builder("LAVA_BLAZE") .displayName("Lava Blaze") .level(30) @@ -76,8 +223,36 @@ public final class SeaCreatureProfiles { .fishingXpReward(1000).xpOrbs(18) .build(); + public static final SeaCreatureProfile TAURUS = SeaCreatureProfile.builder("TAURUS") + .displayName("Taurus") + .level(36) + .entityType(EntityType.HOGLIN) + .health(6000D).damage(400D).speed(85D) + .behaviour(SeaCreatureBehaviour.aggressive(2.4, 22, 22)) + .mobTypes(MobType.MAGMATIC, MobType.ANIMAL) + .damageCooldownMs(400) + .fishingXpReward(2500).xpOrbs(32) + .build(); + + public static final SeaCreatureProfile LORD_JAWBUS = SeaCreatureProfile.builder("LORD_JAWBUS") + .displayName("Lord Jawbus") + .level(45) + .entityType(EntityType.GHAST) + .health(40000D).damage(900D).speed(70D) + .behaviour(SeaCreatureBehaviour.aggressive(2.0, 25, 30)) + .mobTypes(MobType.MAGMATIC, MobType.INFERNAL, MobType.ELUSIVE) + .damageCooldownMs(350) + .fishingXpReward(15000).xpOrbs(80) + .build(); + public static final List CANONICAL = List.of( - SQUID, SEA_WALKER, NIGHT_SQUID, SEA_GUARDIAN, MAGMA_SLUG, LAVA_BLAZE + // Water + SQUID, SEA_WALKER, NIGHT_SQUID, SEA_GUARDIAN, + SEA_WITCH, SEA_ARCHER, MONSTER_OF_THE_DEEP, CATFISH, CARROT_KING, + SEA_LEECH, GUARDIAN_DEFENDER, WATER_HYDRA, THE_SEA_EMPEROR, + // Lava + MAGMA_SLUG, MOOGMA, LAVA_LEECH, PYROCLASTIC_WORM, FIRE_EEL, + LAVA_BLAZE, TAURUS, LORD_JAWBUS ); private SeaCreatureProfiles() { From 4ffc87120ad6556b913881f7affd191413fc27c3 Mon Sep 17 00:00:00 2001 From: "Jacob Nardella (Swofty)" Date: Fri, 15 May 2026 09:00:33 +1000 Subject: [PATCH 100/113] refactor(fishing)!: nest fishing package into logical sub-packages MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Was: 19 top-level files in a flat \`fishing/\` package mixing services, config records, resolvers, and helpers. Sea creature mobs at \`entity.mob.seacreature\` — skipping the \`.mobs\` layer that every other mob group (deepcaverns, dwarvenmines, hub, island, minionMobs) uses. Now: fishing/ — public API: Service, Session, Context, Medium fishing/bait/ — bait management fishing/catches/ — sealed CatchPayload + variants + TrophyTier fishing/hotspot/ — hotspot service + HotspotDefinition fishing/item/ — item lookup helpers fishing/registry/ — FishingRegistry + the 4 *Definition records fishing/resolver/ — FishingLootResolver + FishingCatchResolver fishing/rod/ — rod-part service, lore builder, categories fishing/ship/ — ship service fishing/tag/ — sealed FishingTag hierarchy (was \`tags/\`) entity/mob/mobs/seacreature/ — sea creature mob driver, profile, behaviour, registry, spawner (was at entity/mob/seacreature/, missing the .mobs/ layer) Each moved file got explicit cross-package imports added; all 34 external consumers updated; imports re-sorted alphabetically. Full project still compiles; tests still pass. --- .../swofty/type/hub/npcs/NPCCaptainBaha.java | 4 ++-- .../SkyBlockGenericLoader.java | 2 +- .../skyblockgeneric/entity/FishingHook.java | 2 +- .../seacreature/SeaCreatureBehaviour.java | 5 ++-- .../seacreature/SeaCreatureMob.java | 5 ++-- .../seacreature/SeaCreatureProfile.java | 5 ++-- .../seacreature/SeaCreatureProfiles.java | 5 ++-- .../seacreature/SeaCreatureSpawner.java | 7 +++--- .../fishing/FishingService.java | 12 ++++++---- .../fishing/FishingSession.java | 3 +-- .../{ => bait}/FishingBaitService.java | 3 ++- .../fishing/catches/CatchPayload.java | 3 ++- .../{ => hotspot}/FishingHotspotService.java | 5 +++- .../{ => hotspot}/HotspotDefinition.java | 6 ++--- .../{ => item}/FishingItemSupport.java | 9 ++++---- .../{ => registry}/FishingRegistry.java | 19 +++++++-------- .../FishingTableDefinition.java | 3 ++- .../{ => registry}/SeaCreatureDefinition.java | 6 ++--- .../{ => registry}/TrophyFishDefinition.java | 5 ++-- .../{ => resolver}/FishingCatchResolver.java | 3 ++- .../{ => resolver}/FishingLootResolver.java | 23 ++++++++++++------- .../{ => rod}/FishingPartCategory.java | 2 +- .../{ => rod}/FishingRodLoreBuilder.java | 7 +++--- .../{ => rod}/FishingRodPartService.java | 3 ++- .../{ => rod}/FishingShipPartSlot.java | 2 +- .../{ => ship}/FishingShipService.java | 2 +- .../fishing/{tags => tag}/EventTag.java | 5 ++-- .../fishing/{tags => tag}/FishingTag.java | 2 +- .../{tags => tag}/FishingTagRegistry.java | 7 +++--- .../fishing/{tags => tag}/MediumTag.java | 2 +- .../fishing/{tags => tag}/RarityTag.java | 2 +- .../fishing/{tags => tag}/RegionTag.java | 5 ++-- .../fishing/{tags => tag}/TimeOfDayTag.java | 5 ++-- .../fishing/{tags => tag}/WeatherTag.java | 2 +- .../gui/inventories/fishing/GUIBaitGuide.java | 2 +- .../fishing/GUIFishingRodParts.java | 2 +- .../inventories/fishing/GUIFishingShip.java | 4 ++-- .../gui/inventories/fishing/GUIHookGuide.java | 4 ++-- .../gui/inventories/fishing/GUILineGuide.java | 4 ++-- .../inventories/fishing/GUISinkerGuide.java | 4 ++-- .../item/ItemConfigParser.java | 4 ++-- .../type/skyblockgeneric/item/ItemLore.java | 2 +- .../item/components/FishingRodComponent.java | 2 +- .../components/FishingRodPartComponent.java | 2 +- .../components/FishingShipPartComponent.java | 2 +- .../item/handlers/lore/LoreRegistry.java | 2 +- 46 files changed, 111 insertions(+), 104 deletions(-) rename type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/entity/mob/{ => mobs}/seacreature/SeaCreatureBehaviour.java (97%) rename type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/entity/mob/{ => mobs}/seacreature/SeaCreatureMob.java (97%) rename type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/entity/mob/{ => mobs}/seacreature/SeaCreatureProfile.java (98%) rename type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/entity/mob/{ => mobs}/seacreature/SeaCreatureProfiles.java (99%) rename type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/entity/mob/{ => mobs}/seacreature/SeaCreatureSpawner.java (97%) rename type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/fishing/{ => bait}/FishingBaitService.java (94%) rename type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/fishing/{ => hotspot}/FishingHotspotService.java (92%) rename type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/fishing/{ => hotspot}/HotspotDefinition.java (80%) rename type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/fishing/{ => item}/FishingItemSupport.java (98%) rename type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/fishing/{ => registry}/FishingRegistry.java (97%) rename type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/fishing/{ => registry}/FishingTableDefinition.java (78%) rename type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/fishing/{ => registry}/SeaCreatureDefinition.java (71%) rename type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/fishing/{ => registry}/TrophyFishDefinition.java (91%) rename type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/fishing/{ => resolver}/FishingCatchResolver.java (70%) rename type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/fishing/{ => resolver}/FishingLootResolver.java (94%) rename type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/fishing/{ => rod}/FishingPartCategory.java (56%) rename type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/fishing/{ => rod}/FishingRodLoreBuilder.java (98%) rename type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/fishing/{ => rod}/FishingRodPartService.java (95%) rename type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/fishing/{ => rod}/FishingShipPartSlot.java (56%) rename type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/fishing/{ => ship}/FishingShipService.java (96%) rename type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/fishing/{tags => tag}/EventTag.java (93%) rename type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/fishing/{tags => tag}/FishingTag.java (93%) rename type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/fishing/{tags => tag}/FishingTagRegistry.java (98%) rename type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/fishing/{tags => tag}/MediumTag.java (91%) rename type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/fishing/{tags => tag}/RarityTag.java (91%) rename type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/fishing/{tags => tag}/RegionTag.java (96%) rename type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/fishing/{tags => tag}/TimeOfDayTag.java (93%) rename type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/fishing/{tags => tag}/WeatherTag.java (95%) diff --git a/type.hub/src/main/java/net/swofty/type/hub/npcs/NPCCaptainBaha.java b/type.hub/src/main/java/net/swofty/type/hub/npcs/NPCCaptainBaha.java index 58702288e..b5eddb236 100644 --- a/type.hub/src/main/java/net/swofty/type/hub/npcs/NPCCaptainBaha.java +++ b/type.hub/src/main/java/net/swofty/type/hub/npcs/NPCCaptainBaha.java @@ -10,8 +10,8 @@ import net.swofty.type.generic.event.custom.NPCInteractEvent; import net.swofty.type.generic.user.HypixelPlayer; import net.swofty.type.hub.gui.fishing.GUIGFishingShip; -import net.swofty.type.skyblockgeneric.fishing.FishingItemSupport; -import net.swofty.type.skyblockgeneric.fishing.FishingShipService; +import net.swofty.type.skyblockgeneric.fishing.item.FishingItemSupport; +import net.swofty.type.skyblockgeneric.fishing.ship.FishingShipService; import net.swofty.type.skyblockgeneric.user.SkyBlockPlayer; import java.util.stream.Stream; diff --git a/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/SkyBlockGenericLoader.java b/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/SkyBlockGenericLoader.java index c8310cf16..83675e217 100644 --- a/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/SkyBlockGenericLoader.java +++ b/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/SkyBlockGenericLoader.java @@ -61,7 +61,7 @@ import net.swofty.type.skyblockgeneric.entity.mob.MobRegistry; import net.swofty.type.skyblockgeneric.entity.mob.SkyBlockMob; import net.swofty.type.skyblockgeneric.event.value.SkyBlockValueEvent; -import net.swofty.type.skyblockgeneric.fishing.FishingRegistry; +import net.swofty.type.skyblockgeneric.fishing.registry.FishingRegistry; import net.swofty.type.skyblockgeneric.item.ItemConfigParser; import net.swofty.type.skyblockgeneric.item.SkyBlockItem; import net.swofty.type.skyblockgeneric.item.components.CraftableComponent; diff --git a/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/entity/FishingHook.java b/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/entity/FishingHook.java index 23d854b30..0e0d48236 100644 --- a/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/entity/FishingHook.java +++ b/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/entity/FishingHook.java @@ -17,7 +17,7 @@ import net.minestom.server.timer.Scheduler; import net.minestom.server.timer.Task; import net.minestom.server.timer.TaskSchedule; -import net.swofty.type.skyblockgeneric.fishing.FishingItemSupport; +import net.swofty.type.skyblockgeneric.fishing.item.FishingItemSupport; import net.swofty.type.skyblockgeneric.fishing.FishingMedium; import net.swofty.type.skyblockgeneric.fishing.FishingService; import net.swofty.type.skyblockgeneric.fishing.FishingSession; diff --git a/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/entity/mob/seacreature/SeaCreatureBehaviour.java b/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/entity/mob/mobs/seacreature/SeaCreatureBehaviour.java similarity index 97% rename from type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/entity/mob/seacreature/SeaCreatureBehaviour.java rename to type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/entity/mob/mobs/seacreature/SeaCreatureBehaviour.java index 5e927299f..e06c304b7 100644 --- a/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/entity/mob/seacreature/SeaCreatureBehaviour.java +++ b/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/entity/mob/mobs/seacreature/SeaCreatureBehaviour.java @@ -1,5 +1,6 @@ -package net.swofty.type.skyblockgeneric.entity.mob.seacreature; +package net.swofty.type.skyblockgeneric.entity.mob.mobs.seacreature; +import java.util.List; import net.minestom.server.entity.ai.GoalSelector; import net.minestom.server.entity.ai.TargetSelector; import net.minestom.server.entity.ai.goal.MeleeAttackGoal; @@ -10,8 +11,6 @@ import net.swofty.type.skyblockgeneric.entity.mob.SkyBlockMob; import net.swofty.type.skyblockgeneric.user.SkyBlockPlayer; -import java.util.List; - /** * Strategy describing how a sea creature moves and selects targets. The * sealed hierarchy is exhaustive — pattern-match on it elsewhere if you diff --git a/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/entity/mob/seacreature/SeaCreatureMob.java b/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/entity/mob/mobs/seacreature/SeaCreatureMob.java similarity index 97% rename from type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/entity/mob/seacreature/SeaCreatureMob.java rename to type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/entity/mob/mobs/seacreature/SeaCreatureMob.java index 11eb27b61..1bbc864ed 100644 --- a/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/entity/mob/seacreature/SeaCreatureMob.java +++ b/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/entity/mob/mobs/seacreature/SeaCreatureMob.java @@ -1,5 +1,6 @@ -package net.swofty.type.skyblockgeneric.entity.mob.seacreature; +package net.swofty.type.skyblockgeneric.entity.mob.mobs.seacreature; +import java.util.List; import net.minestom.server.entity.ai.GoalSelector; import net.minestom.server.entity.ai.TargetSelector; import net.swofty.commons.skyblock.statistics.ItemStatistics; @@ -10,8 +11,6 @@ import net.swofty.type.skyblockgeneric.skill.SkillCategories; import org.jetbrains.annotations.Nullable; -import java.util.List; - /** * A sea creature is fully described by a {@link SeaCreatureProfile} — one * concrete class drives every variant. The thread-local handoff diff --git a/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/entity/mob/seacreature/SeaCreatureProfile.java b/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/entity/mob/mobs/seacreature/SeaCreatureProfile.java similarity index 98% rename from type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/entity/mob/seacreature/SeaCreatureProfile.java rename to type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/entity/mob/mobs/seacreature/SeaCreatureProfile.java index c528e6a9a..57df50113 100644 --- a/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/entity/mob/seacreature/SeaCreatureProfile.java +++ b/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/entity/mob/mobs/seacreature/SeaCreatureProfile.java @@ -1,5 +1,6 @@ -package net.swofty.type.skyblockgeneric.entity.mob.seacreature; +package net.swofty.type.skyblockgeneric.entity.mob.mobs.seacreature; +import java.util.List; import net.minestom.server.entity.EntityType; import net.swofty.commons.skyblock.statistics.ItemStatistic; import net.swofty.commons.skyblock.statistics.ItemStatistics; @@ -7,8 +8,6 @@ import net.swofty.type.skyblockgeneric.loottable.OtherLoot; import net.swofty.type.skyblockgeneric.loottable.SkyBlockLootTable; -import java.util.List; - /** * Immutable, declarative description of a sea creature. The concrete mob * class just hands one of these to {@link SeaCreatureMob} and the base diff --git a/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/entity/mob/seacreature/SeaCreatureProfiles.java b/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/entity/mob/mobs/seacreature/SeaCreatureProfiles.java similarity index 99% rename from type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/entity/mob/seacreature/SeaCreatureProfiles.java rename to type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/entity/mob/mobs/seacreature/SeaCreatureProfiles.java index 780e6d17e..d0c8c2d1d 100644 --- a/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/entity/mob/seacreature/SeaCreatureProfiles.java +++ b/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/entity/mob/mobs/seacreature/SeaCreatureProfiles.java @@ -1,10 +1,9 @@ -package net.swofty.type.skyblockgeneric.entity.mob.seacreature; +package net.swofty.type.skyblockgeneric.entity.mob.mobs.seacreature; +import java.util.List; import net.minestom.server.entity.EntityType; import net.swofty.type.skyblockgeneric.entity.mob.MobType; -import java.util.List; - /** * Canonical Hypixel sea creature profiles. Each constant is the entire * declarative spec for one creature: stats, AI flavour, fishing rewards. diff --git a/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/entity/mob/seacreature/SeaCreatureSpawner.java b/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/entity/mob/mobs/seacreature/SeaCreatureSpawner.java similarity index 97% rename from type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/entity/mob/seacreature/SeaCreatureSpawner.java rename to type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/entity/mob/mobs/seacreature/SeaCreatureSpawner.java index 685f8497a..c5288c554 100644 --- a/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/entity/mob/seacreature/SeaCreatureSpawner.java +++ b/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/entity/mob/mobs/seacreature/SeaCreatureSpawner.java @@ -1,5 +1,7 @@ -package net.swofty.type.skyblockgeneric.entity.mob.seacreature; +package net.swofty.type.skyblockgeneric.entity.mob.mobs.seacreature; +import java.util.LinkedHashMap; +import java.util.Map; import net.kyori.adventure.text.Component; import net.minestom.server.coordinate.Pos; import net.minestom.server.instance.Instance; @@ -7,9 +9,6 @@ import org.jetbrains.annotations.Nullable; import org.tinylog.Logger; -import java.util.LinkedHashMap; -import java.util.Map; - public final class SeaCreatureSpawner { private static final Map PROFILES = new LinkedHashMap<>(); diff --git a/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/fishing/FishingService.java b/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/fishing/FishingService.java index aa1bffff4..1e8cf7bab 100644 --- a/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/fishing/FishingService.java +++ b/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/fishing/FishingService.java @@ -1,9 +1,17 @@ package net.swofty.type.skyblockgeneric.fishing; +import java.util.Map; +import java.util.UUID; +import java.util.concurrent.ConcurrentHashMap; import net.swofty.type.generic.data.datapoints.DatapointToggles; import net.swofty.type.skyblockgeneric.entity.FishingHook; +import net.swofty.type.skyblockgeneric.fishing.bait.FishingBaitService; import net.swofty.type.skyblockgeneric.fishing.catches.CatchAwardContext; import net.swofty.type.skyblockgeneric.fishing.catches.CatchPayload; +import net.swofty.type.skyblockgeneric.fishing.hotspot.FishingHotspotService; +import net.swofty.type.skyblockgeneric.fishing.item.FishingItemSupport; +import net.swofty.type.skyblockgeneric.fishing.resolver.FishingCatchResolver; +import net.swofty.type.skyblockgeneric.fishing.rod.FishingRodPartService; import net.swofty.type.skyblockgeneric.item.SkyBlockItem; import net.swofty.type.skyblockgeneric.item.components.FishingBaitComponent; import net.swofty.type.skyblockgeneric.item.components.FishingRodPartComponent; @@ -11,10 +19,6 @@ import net.swofty.type.skyblockgeneric.user.SkyBlockPlayer; import org.jetbrains.annotations.Nullable; -import java.util.Map; -import java.util.UUID; -import java.util.concurrent.ConcurrentHashMap; - public final class FishingService { private static final Map SESSIONS = new ConcurrentHashMap<>(); diff --git a/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/fishing/FishingSession.java b/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/fishing/FishingSession.java index 1b8c71a5b..41ce6ec9f 100644 --- a/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/fishing/FishingSession.java +++ b/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/fishing/FishingSession.java @@ -1,8 +1,7 @@ package net.swofty.type.skyblockgeneric.fishing; -import org.jetbrains.annotations.Nullable; - import java.util.UUID; +import org.jetbrains.annotations.Nullable; public record FishingSession( UUID ownerUuid, diff --git a/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/fishing/FishingBaitService.java b/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/fishing/bait/FishingBaitService.java similarity index 94% rename from type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/fishing/FishingBaitService.java rename to type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/fishing/bait/FishingBaitService.java index a95eecec4..889039d19 100644 --- a/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/fishing/FishingBaitService.java +++ b/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/fishing/bait/FishingBaitService.java @@ -1,7 +1,8 @@ -package net.swofty.type.skyblockgeneric.fishing; +package net.swofty.type.skyblockgeneric.fishing.bait; import net.minestom.server.item.ItemStack; import net.swofty.commons.skyblock.item.ItemType; +import net.swofty.type.skyblockgeneric.fishing.FishingMedium; import net.swofty.type.skyblockgeneric.item.SkyBlockItem; import net.swofty.type.skyblockgeneric.item.components.FishingBaitComponent; import net.swofty.type.skyblockgeneric.item.updater.PlayerItemUpdater; diff --git a/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/fishing/catches/CatchPayload.java b/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/fishing/catches/CatchPayload.java index 3d3df94de..1990c6e80 100644 --- a/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/fishing/catches/CatchPayload.java +++ b/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/fishing/catches/CatchPayload.java @@ -5,7 +5,8 @@ import net.swofty.type.skyblockgeneric.data.SkyBlockDataHandler; import net.swofty.type.skyblockgeneric.data.datapoints.DatapointCollection; import net.swofty.type.skyblockgeneric.data.datapoints.DatapointTrophyFish; -import net.swofty.type.skyblockgeneric.entity.mob.seacreature.SeaCreatureSpawner; +import net.swofty.type.skyblockgeneric.entity.mob.mobs.seacreature.SeaCreatureSpawner; +import net.swofty.type.skyblockgeneric.fishing.FishingService; import net.swofty.type.skyblockgeneric.user.SkyBlockPlayer; /** diff --git a/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/fishing/FishingHotspotService.java b/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/fishing/hotspot/FishingHotspotService.java similarity index 92% rename from type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/fishing/FishingHotspotService.java rename to type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/fishing/hotspot/FishingHotspotService.java index babc132cc..c92abab42 100644 --- a/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/fishing/FishingHotspotService.java +++ b/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/fishing/hotspot/FishingHotspotService.java @@ -1,9 +1,12 @@ -package net.swofty.type.skyblockgeneric.fishing; +package net.swofty.type.skyblockgeneric.fishing.hotspot; import net.minestom.server.coordinate.Pos; import net.swofty.commons.skyblock.statistics.ItemStatistic; import net.swofty.commons.skyblock.statistics.ItemStatistics; import net.swofty.type.generic.HypixelConst; +import net.swofty.type.skyblockgeneric.fishing.FishingMedium; +import net.swofty.type.skyblockgeneric.fishing.registry.FishingRegistry; +import net.swofty.type.skyblockgeneric.fishing.rod.FishingRodPartService; import net.swofty.type.skyblockgeneric.region.SkyBlockRegion; import net.swofty.type.skyblockgeneric.user.SkyBlockPlayer; diff --git a/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/fishing/HotspotDefinition.java b/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/fishing/hotspot/HotspotDefinition.java similarity index 80% rename from type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/fishing/HotspotDefinition.java rename to type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/fishing/hotspot/HotspotDefinition.java index a3c48b9c0..dc48d70bf 100644 --- a/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/fishing/HotspotDefinition.java +++ b/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/fishing/hotspot/HotspotDefinition.java @@ -1,8 +1,8 @@ -package net.swofty.type.skyblockgeneric.fishing; - -import net.swofty.commons.skyblock.statistics.ItemStatistics; +package net.swofty.type.skyblockgeneric.fishing.hotspot; import java.util.List; +import net.swofty.commons.skyblock.statistics.ItemStatistics; +import net.swofty.type.skyblockgeneric.fishing.FishingMedium; public record HotspotDefinition( String id, diff --git a/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/fishing/FishingItemSupport.java b/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/fishing/item/FishingItemSupport.java similarity index 98% rename from type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/fishing/FishingItemSupport.java rename to type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/fishing/item/FishingItemSupport.java index 3b5f39fa5..87ab6ab64 100644 --- a/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/fishing/FishingItemSupport.java +++ b/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/fishing/item/FishingItemSupport.java @@ -1,5 +1,8 @@ -package net.swofty.type.skyblockgeneric.fishing; +package net.swofty.type.skyblockgeneric.fishing.item; +import java.util.ArrayList; +import java.util.Comparator; +import java.util.List; import net.swofty.commons.skyblock.item.ItemType; import net.swofty.type.skyblockgeneric.item.ConfigurableSkyBlockItem; import net.swofty.type.skyblockgeneric.item.SkyBlockItem; @@ -10,10 +13,6 @@ import net.swofty.type.skyblockgeneric.item.components.FishingShipPartComponent; import org.jetbrains.annotations.Nullable; -import java.util.ArrayList; -import java.util.Comparator; -import java.util.List; - public final class FishingItemSupport { private FishingItemSupport() { } diff --git a/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/fishing/FishingRegistry.java b/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/fishing/registry/FishingRegistry.java similarity index 97% rename from type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/fishing/FishingRegistry.java rename to type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/fishing/registry/FishingRegistry.java index 49d314bfb..ecb5bb764 100644 --- a/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/fishing/FishingRegistry.java +++ b/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/fishing/registry/FishingRegistry.java @@ -1,11 +1,4 @@ -package net.swofty.type.skyblockgeneric.fishing; - -import net.swofty.commons.ServerType; -import net.swofty.commons.YamlFileUtils; -import net.swofty.commons.skyblock.statistics.ItemStatistic; -import net.swofty.commons.skyblock.statistics.ItemStatistics; -import org.jetbrains.annotations.Nullable; -import org.tinylog.Logger; +package net.swofty.type.skyblockgeneric.fishing.registry; import java.io.File; import java.io.IOException; @@ -14,6 +7,14 @@ import java.util.LinkedHashMap; import java.util.List; import java.util.Map; +import net.swofty.commons.ServerType; +import net.swofty.commons.YamlFileUtils; +import net.swofty.commons.skyblock.statistics.ItemStatistic; +import net.swofty.commons.skyblock.statistics.ItemStatistics; +import net.swofty.type.skyblockgeneric.fishing.FishingMedium; +import net.swofty.type.skyblockgeneric.fishing.hotspot.HotspotDefinition; +import org.jetbrains.annotations.Nullable; +import org.tinylog.Logger; public final class FishingRegistry { private static final File FISHING_DIR = new File("./configuration/skyblock/fishing"); @@ -138,7 +139,7 @@ private static void loadSeaCreatures(File file) throws IOException { id, intValue(entry, "requiredFishingLevel", 0), doubleValue(entry, "skillXp", 0.0D), - net.swofty.type.skyblockgeneric.fishing.tags.FishingTagRegistry.resolve(stringList(entry.get("tags"))) + net.swofty.type.skyblockgeneric.fishing.tag.FishingTagRegistry.resolve(stringList(entry.get("tags"))) )); } } diff --git a/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/fishing/FishingTableDefinition.java b/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/fishing/registry/FishingTableDefinition.java similarity index 78% rename from type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/fishing/FishingTableDefinition.java rename to type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/fishing/registry/FishingTableDefinition.java index 13d287fbd..36b3dd77b 100644 --- a/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/fishing/FishingTableDefinition.java +++ b/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/fishing/registry/FishingTableDefinition.java @@ -1,6 +1,7 @@ -package net.swofty.type.skyblockgeneric.fishing; +package net.swofty.type.skyblockgeneric.fishing.registry; import java.util.List; +import net.swofty.type.skyblockgeneric.fishing.FishingMedium; public record FishingTableDefinition( String id, diff --git a/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/fishing/SeaCreatureDefinition.java b/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/fishing/registry/SeaCreatureDefinition.java similarity index 71% rename from type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/fishing/SeaCreatureDefinition.java rename to type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/fishing/registry/SeaCreatureDefinition.java index f4d5a010f..dc5cd1c3a 100644 --- a/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/fishing/SeaCreatureDefinition.java +++ b/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/fishing/registry/SeaCreatureDefinition.java @@ -1,8 +1,8 @@ -package net.swofty.type.skyblockgeneric.fishing; - -import net.swofty.type.skyblockgeneric.fishing.tags.FishingTag; +package net.swofty.type.skyblockgeneric.fishing.registry; import java.util.List; +import net.swofty.type.skyblockgeneric.fishing.FishingContext; +import net.swofty.type.skyblockgeneric.fishing.tag.FishingTag; public record SeaCreatureDefinition( String id, diff --git a/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/fishing/TrophyFishDefinition.java b/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/fishing/registry/TrophyFishDefinition.java similarity index 91% rename from type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/fishing/TrophyFishDefinition.java rename to type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/fishing/registry/TrophyFishDefinition.java index e3736b5ab..b3ea9a5c6 100644 --- a/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/fishing/TrophyFishDefinition.java +++ b/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/fishing/registry/TrophyFishDefinition.java @@ -1,8 +1,7 @@ -package net.swofty.type.skyblockgeneric.fishing; - -import org.jetbrains.annotations.Nullable; +package net.swofty.type.skyblockgeneric.fishing.registry; import java.util.List; +import org.jetbrains.annotations.Nullable; public record TrophyFishDefinition( String id, diff --git a/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/fishing/FishingCatchResolver.java b/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/fishing/resolver/FishingCatchResolver.java similarity index 70% rename from type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/fishing/FishingCatchResolver.java rename to type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/fishing/resolver/FishingCatchResolver.java index 4fcb6cc0c..24818fa40 100644 --- a/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/fishing/FishingCatchResolver.java +++ b/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/fishing/resolver/FishingCatchResolver.java @@ -1,5 +1,6 @@ -package net.swofty.type.skyblockgeneric.fishing; +package net.swofty.type.skyblockgeneric.fishing.resolver; +import net.swofty.type.skyblockgeneric.fishing.FishingContext; import net.swofty.type.skyblockgeneric.fishing.catches.CatchPayload; public final class FishingCatchResolver { diff --git a/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/fishing/FishingLootResolver.java b/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/fishing/resolver/FishingLootResolver.java similarity index 94% rename from type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/fishing/FishingLootResolver.java rename to type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/fishing/resolver/FishingLootResolver.java index 4c71a4d12..5224c92af 100644 --- a/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/fishing/FishingLootResolver.java +++ b/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/fishing/resolver/FishingLootResolver.java @@ -1,19 +1,26 @@ -package net.swofty.type.skyblockgeneric.fishing; +package net.swofty.type.skyblockgeneric.fishing.resolver; +import java.util.ArrayList; +import java.util.Comparator; +import java.util.List; +import java.util.Optional; +import java.util.function.Function; import net.swofty.commons.skyblock.item.ItemType; import net.swofty.commons.skyblock.statistics.ItemStatistic; import net.swofty.type.generic.data.datapoints.DatapointToggles; +import net.swofty.type.skyblockgeneric.fishing.FishingContext; +import net.swofty.type.skyblockgeneric.fishing.FishingMedium; import net.swofty.type.skyblockgeneric.fishing.catches.CatchPayload; import net.swofty.type.skyblockgeneric.fishing.catches.TrophyTier; -import net.swofty.type.skyblockgeneric.fishing.tags.FishingTag; +import net.swofty.type.skyblockgeneric.fishing.item.FishingItemSupport; +import net.swofty.type.skyblockgeneric.fishing.registry.FishingRegistry; +import net.swofty.type.skyblockgeneric.fishing.registry.FishingTableDefinition; +import net.swofty.type.skyblockgeneric.fishing.registry.SeaCreatureDefinition; +import net.swofty.type.skyblockgeneric.fishing.registry.TrophyFishDefinition; +import net.swofty.type.skyblockgeneric.fishing.rod.FishingRodPartService; +import net.swofty.type.skyblockgeneric.fishing.tag.FishingTag; import net.swofty.type.skyblockgeneric.item.SkyBlockItem; -import java.util.ArrayList; -import java.util.Comparator; -import java.util.List; -import java.util.Optional; -import java.util.function.Function; - public final class FishingLootResolver { private static final List>> SPECIAL_CATCHES = List.of( diff --git a/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/fishing/FishingPartCategory.java b/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/fishing/rod/FishingPartCategory.java similarity index 56% rename from type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/fishing/FishingPartCategory.java rename to type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/fishing/rod/FishingPartCategory.java index 36995d73c..ab1a92069 100644 --- a/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/fishing/FishingPartCategory.java +++ b/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/fishing/rod/FishingPartCategory.java @@ -1,4 +1,4 @@ -package net.swofty.type.skyblockgeneric.fishing; +package net.swofty.type.skyblockgeneric.fishing.rod; public enum FishingPartCategory { HOOK, diff --git a/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/fishing/FishingRodLoreBuilder.java b/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/fishing/rod/FishingRodLoreBuilder.java similarity index 98% rename from type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/fishing/FishingRodLoreBuilder.java rename to type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/fishing/rod/FishingRodLoreBuilder.java index acdd1317b..06f6afda6 100644 --- a/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/fishing/FishingRodLoreBuilder.java +++ b/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/fishing/rod/FishingRodLoreBuilder.java @@ -1,5 +1,7 @@ -package net.swofty.type.skyblockgeneric.fishing; +package net.swofty.type.skyblockgeneric.fishing.rod; +import java.util.ArrayList; +import java.util.List; import net.swofty.commons.StringUtility; import net.swofty.commons.skyblock.item.ItemType; import net.swofty.commons.skyblock.statistics.ItemStatistic; @@ -10,9 +12,6 @@ import net.swofty.type.skyblockgeneric.user.SkyBlockPlayer; import org.jetbrains.annotations.Nullable; -import java.util.ArrayList; -import java.util.List; - public final class FishingRodLoreBuilder { private static final List STAT_ORDER = List.of( ItemStatistic.DAMAGE, diff --git a/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/fishing/FishingRodPartService.java b/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/fishing/rod/FishingRodPartService.java similarity index 95% rename from type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/fishing/FishingRodPartService.java rename to type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/fishing/rod/FishingRodPartService.java index 3c5ebb102..42aedb327 100644 --- a/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/fishing/FishingRodPartService.java +++ b/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/fishing/rod/FishingRodPartService.java @@ -1,6 +1,7 @@ -package net.swofty.type.skyblockgeneric.fishing; +package net.swofty.type.skyblockgeneric.fishing.rod; import net.swofty.commons.skyblock.statistics.ItemStatistics; +import net.swofty.type.skyblockgeneric.fishing.item.FishingItemSupport; import net.swofty.type.skyblockgeneric.item.SkyBlockItem; import net.swofty.type.skyblockgeneric.item.components.FishingRodPartComponent; import org.jetbrains.annotations.Nullable; diff --git a/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/fishing/FishingShipPartSlot.java b/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/fishing/rod/FishingShipPartSlot.java similarity index 56% rename from type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/fishing/FishingShipPartSlot.java rename to type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/fishing/rod/FishingShipPartSlot.java index 7a93807a5..80bae36fd 100644 --- a/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/fishing/FishingShipPartSlot.java +++ b/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/fishing/rod/FishingShipPartSlot.java @@ -1,4 +1,4 @@ -package net.swofty.type.skyblockgeneric.fishing; +package net.swofty.type.skyblockgeneric.fishing.rod; public enum FishingShipPartSlot { HELM, diff --git a/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/fishing/FishingShipService.java b/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/fishing/ship/FishingShipService.java similarity index 96% rename from type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/fishing/FishingShipService.java rename to type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/fishing/ship/FishingShipService.java index a2ae344c8..e497ede0a 100644 --- a/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/fishing/FishingShipService.java +++ b/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/fishing/ship/FishingShipService.java @@ -1,4 +1,4 @@ -package net.swofty.type.skyblockgeneric.fishing; +package net.swofty.type.skyblockgeneric.fishing.ship; import net.swofty.type.skyblockgeneric.data.SkyBlockDataHandler; import net.swofty.type.skyblockgeneric.data.datapoints.DatapointShipState; diff --git a/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/fishing/tags/EventTag.java b/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/fishing/tag/EventTag.java similarity index 93% rename from type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/fishing/tags/EventTag.java rename to type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/fishing/tag/EventTag.java index 3d7d49b8e..5228e5f6c 100644 --- a/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/fishing/tags/EventTag.java +++ b/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/fishing/tag/EventTag.java @@ -1,8 +1,7 @@ -package net.swofty.type.skyblockgeneric.fishing.tags; - -import net.swofty.type.skyblockgeneric.fishing.FishingContext; +package net.swofty.type.skyblockgeneric.fishing.tag; import java.util.function.BooleanSupplier; +import net.swofty.type.skyblockgeneric.fishing.FishingContext; /** * Gates loot behind a server-wide event being active (Spooky Festival, diff --git a/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/fishing/tags/FishingTag.java b/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/fishing/tag/FishingTag.java similarity index 93% rename from type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/fishing/tags/FishingTag.java rename to type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/fishing/tag/FishingTag.java index fad50c6e3..5fa48ee48 100644 --- a/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/fishing/tags/FishingTag.java +++ b/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/fishing/tag/FishingTag.java @@ -1,4 +1,4 @@ -package net.swofty.type.skyblockgeneric.fishing.tags; +package net.swofty.type.skyblockgeneric.fishing.tag; import net.swofty.type.skyblockgeneric.fishing.FishingContext; diff --git a/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/fishing/tags/FishingTagRegistry.java b/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/fishing/tag/FishingTagRegistry.java similarity index 98% rename from type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/fishing/tags/FishingTagRegistry.java rename to type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/fishing/tag/FishingTagRegistry.java index e85b7508e..946686e5b 100644 --- a/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/fishing/tags/FishingTagRegistry.java +++ b/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/fishing/tag/FishingTagRegistry.java @@ -1,13 +1,12 @@ -package net.swofty.type.skyblockgeneric.fishing.tags; - -import org.jetbrains.annotations.Nullable; -import org.tinylog.Logger; +package net.swofty.type.skyblockgeneric.fishing.tag; import java.util.LinkedHashMap; import java.util.List; import java.util.Map; import java.util.Set; import java.util.stream.Stream; +import org.jetbrains.annotations.Nullable; +import org.tinylog.Logger; /** * Central lookup mapping YAML tag ids to the typed FishingTag instances diff --git a/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/fishing/tags/MediumTag.java b/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/fishing/tag/MediumTag.java similarity index 91% rename from type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/fishing/tags/MediumTag.java rename to type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/fishing/tag/MediumTag.java index a6a6bda39..be4e3e290 100644 --- a/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/fishing/tags/MediumTag.java +++ b/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/fishing/tag/MediumTag.java @@ -1,4 +1,4 @@ -package net.swofty.type.skyblockgeneric.fishing.tags; +package net.swofty.type.skyblockgeneric.fishing.tag; import net.swofty.type.skyblockgeneric.fishing.FishingContext; import net.swofty.type.skyblockgeneric.fishing.FishingMedium; diff --git a/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/fishing/tags/RarityTag.java b/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/fishing/tag/RarityTag.java similarity index 91% rename from type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/fishing/tags/RarityTag.java rename to type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/fishing/tag/RarityTag.java index ee6649707..3cba9580a 100644 --- a/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/fishing/tags/RarityTag.java +++ b/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/fishing/tag/RarityTag.java @@ -1,4 +1,4 @@ -package net.swofty.type.skyblockgeneric.fishing.tags; +package net.swofty.type.skyblockgeneric.fishing.tag; /** * Pure data tag — rarity is informational, never gates rolls. diff --git a/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/fishing/tags/RegionTag.java b/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/fishing/tag/RegionTag.java similarity index 96% rename from type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/fishing/tags/RegionTag.java rename to type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/fishing/tag/RegionTag.java index 5f95e569f..071ca0d88 100644 --- a/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/fishing/tags/RegionTag.java +++ b/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/fishing/tag/RegionTag.java @@ -1,8 +1,7 @@ -package net.swofty.type.skyblockgeneric.fishing.tags; - -import net.swofty.type.skyblockgeneric.fishing.FishingContext; +package net.swofty.type.skyblockgeneric.fishing.tag; import java.util.Set; +import net.swofty.type.skyblockgeneric.fishing.FishingContext; /** * Marks loot that's themed to one or more SkyBlock regions. Acts as a diff --git a/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/fishing/tags/TimeOfDayTag.java b/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/fishing/tag/TimeOfDayTag.java similarity index 93% rename from type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/fishing/tags/TimeOfDayTag.java rename to type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/fishing/tag/TimeOfDayTag.java index 4df8a77d5..b846fc179 100644 --- a/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/fishing/tags/TimeOfDayTag.java +++ b/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/fishing/tag/TimeOfDayTag.java @@ -1,10 +1,9 @@ -package net.swofty.type.skyblockgeneric.fishing.tags; +package net.swofty.type.skyblockgeneric.fishing.tag; +import java.util.function.IntPredicate; import net.swofty.type.skyblockgeneric.calendar.SkyBlockCalendar; import net.swofty.type.skyblockgeneric.fishing.FishingContext; -import java.util.function.IntPredicate; - public record TimeOfDayTag(String id, IntPredicate hourPredicate) implements FishingTag { public static final TimeOfDayTag NIGHT = new TimeOfDayTag("NIGHT", hour -> hour < 6 || hour >= 20); diff --git a/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/fishing/tags/WeatherTag.java b/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/fishing/tag/WeatherTag.java similarity index 95% rename from type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/fishing/tags/WeatherTag.java rename to type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/fishing/tag/WeatherTag.java index f6a069de8..4c802a829 100644 --- a/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/fishing/tags/WeatherTag.java +++ b/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/fishing/tag/WeatherTag.java @@ -1,4 +1,4 @@ -package net.swofty.type.skyblockgeneric.fishing.tags; +package net.swofty.type.skyblockgeneric.fishing.tag; import net.minestom.server.instance.Instance; import net.minestom.server.instance.Weather; diff --git a/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/gui/inventories/fishing/GUIBaitGuide.java b/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/gui/inventories/fishing/GUIBaitGuide.java index 7b14e8009..db464cbff 100644 --- a/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/gui/inventories/fishing/GUIBaitGuide.java +++ b/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/gui/inventories/fishing/GUIBaitGuide.java @@ -9,7 +9,7 @@ import net.swofty.type.generic.gui.v2.ViewConfiguration; import net.swofty.type.generic.gui.v2.ViewLayout; import net.swofty.type.generic.gui.v2.context.ViewContext; -import net.swofty.type.skyblockgeneric.fishing.FishingItemSupport; +import net.swofty.type.skyblockgeneric.fishing.item.FishingItemSupport; public class GUIBaitGuide extends StatelessView { private static final int[] BAIT_SLOTS = {10, 11, 12, 13, 14, 15, 16, 19, 20, 21, 22, 23, 24, 25, 28, 29, 30, 31, 32, 33, 34}; diff --git a/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/gui/inventories/fishing/GUIFishingRodParts.java b/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/gui/inventories/fishing/GUIFishingRodParts.java index 6a8f4b2ed..dd7202981 100644 --- a/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/gui/inventories/fishing/GUIFishingRodParts.java +++ b/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/gui/inventories/fishing/GUIFishingRodParts.java @@ -12,7 +12,7 @@ import net.swofty.type.generic.gui.v2.ViewLayout; import net.swofty.type.generic.gui.v2.ViewSession; import net.swofty.type.generic.gui.v2.context.ViewContext; -import net.swofty.type.skyblockgeneric.fishing.FishingItemSupport; +import net.swofty.type.skyblockgeneric.fishing.item.FishingItemSupport; import net.swofty.type.skyblockgeneric.item.SkyBlockItem; import net.swofty.type.skyblockgeneric.user.SkyBlockPlayer; diff --git a/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/gui/inventories/fishing/GUIFishingShip.java b/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/gui/inventories/fishing/GUIFishingShip.java index 0307a956b..abf7518be 100644 --- a/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/gui/inventories/fishing/GUIFishingShip.java +++ b/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/gui/inventories/fishing/GUIFishingShip.java @@ -9,8 +9,8 @@ import net.swofty.type.generic.gui.inventory.item.GUIClickableItem; import net.swofty.type.generic.gui.inventory.item.GUIItem; import net.swofty.type.generic.user.HypixelPlayer; -import net.swofty.type.skyblockgeneric.fishing.FishingItemSupport; -import net.swofty.type.skyblockgeneric.fishing.FishingShipService; +import net.swofty.type.skyblockgeneric.fishing.item.FishingItemSupport; +import net.swofty.type.skyblockgeneric.fishing.ship.FishingShipService; import net.swofty.type.skyblockgeneric.user.SkyBlockPlayer; public class GUIFishingShip extends HypixelInventoryGUI { diff --git a/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/gui/inventories/fishing/GUIHookGuide.java b/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/gui/inventories/fishing/GUIHookGuide.java index 3fa81e827..8347b19ce 100644 --- a/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/gui/inventories/fishing/GUIHookGuide.java +++ b/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/gui/inventories/fishing/GUIHookGuide.java @@ -9,8 +9,8 @@ import net.swofty.type.generic.gui.v2.ViewConfiguration; import net.swofty.type.generic.gui.v2.ViewLayout; import net.swofty.type.generic.gui.v2.context.ViewContext; -import net.swofty.type.skyblockgeneric.fishing.FishingItemSupport; -import net.swofty.type.skyblockgeneric.fishing.FishingPartCategory; +import net.swofty.type.skyblockgeneric.fishing.item.FishingItemSupport; +import net.swofty.type.skyblockgeneric.fishing.rod.FishingPartCategory; public class GUIHookGuide extends StatelessView { private static final int[] PART_SLOTS = {10, 11, 12, 13, 14, 15, 16}; diff --git a/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/gui/inventories/fishing/GUILineGuide.java b/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/gui/inventories/fishing/GUILineGuide.java index 6d53c13d8..6113c6239 100644 --- a/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/gui/inventories/fishing/GUILineGuide.java +++ b/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/gui/inventories/fishing/GUILineGuide.java @@ -9,8 +9,8 @@ import net.swofty.type.generic.gui.v2.ViewConfiguration; import net.swofty.type.generic.gui.v2.ViewLayout; import net.swofty.type.generic.gui.v2.context.ViewContext; -import net.swofty.type.skyblockgeneric.fishing.FishingItemSupport; -import net.swofty.type.skyblockgeneric.fishing.FishingPartCategory; +import net.swofty.type.skyblockgeneric.fishing.item.FishingItemSupport; +import net.swofty.type.skyblockgeneric.fishing.rod.FishingPartCategory; public class GUILineGuide extends StatelessView { private static final int[] PART_SLOTS = {10, 11, 12, 13, 14, 15, 16}; diff --git a/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/gui/inventories/fishing/GUISinkerGuide.java b/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/gui/inventories/fishing/GUISinkerGuide.java index 420f50b1c..e37c1c213 100644 --- a/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/gui/inventories/fishing/GUISinkerGuide.java +++ b/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/gui/inventories/fishing/GUISinkerGuide.java @@ -9,8 +9,8 @@ import net.swofty.type.generic.gui.v2.ViewConfiguration; import net.swofty.type.generic.gui.v2.ViewLayout; import net.swofty.type.generic.gui.v2.context.ViewContext; -import net.swofty.type.skyblockgeneric.fishing.FishingItemSupport; -import net.swofty.type.skyblockgeneric.fishing.FishingPartCategory; +import net.swofty.type.skyblockgeneric.fishing.item.FishingItemSupport; +import net.swofty.type.skyblockgeneric.fishing.rod.FishingPartCategory; public class GUISinkerGuide extends StatelessView { private static final int[] PART_SLOTS = {10, 11, 12, 13, 14, 15, 16, 19, 20}; diff --git a/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/item/ItemConfigParser.java b/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/item/ItemConfigParser.java index 8bfde514e..be4b4bf03 100644 --- a/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/item/ItemConfigParser.java +++ b/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/item/ItemConfigParser.java @@ -12,8 +12,8 @@ import net.swofty.commons.skyblock.statistics.ItemStatistic; import net.swofty.commons.skyblock.statistics.ItemStatistics; import net.swofty.type.skyblockgeneric.fishing.FishingMedium; -import net.swofty.type.skyblockgeneric.fishing.FishingPartCategory; -import net.swofty.type.skyblockgeneric.fishing.FishingShipPartSlot; +import net.swofty.type.skyblockgeneric.fishing.rod.FishingPartCategory; +import net.swofty.type.skyblockgeneric.fishing.rod.FishingShipPartSlot; import net.swofty.type.skyblockgeneric.gems.GemRarity; import net.swofty.type.skyblockgeneric.gems.Gemstone; import net.swofty.type.skyblockgeneric.item.components.*; diff --git a/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/item/ItemLore.java b/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/item/ItemLore.java index 59c98d68b..d4d9f27f2 100644 --- a/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/item/ItemLore.java +++ b/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/item/ItemLore.java @@ -21,7 +21,7 @@ import net.swofty.commons.skyblock.statistics.ItemStatistics; import net.swofty.type.generic.i18n.I18n; import net.swofty.type.skyblockgeneric.collection.CollectionCategories; -import net.swofty.type.skyblockgeneric.fishing.FishingRodLoreBuilder; +import net.swofty.type.skyblockgeneric.fishing.rod.FishingRodLoreBuilder; import net.swofty.type.skyblockgeneric.gems.GemRarity; import net.swofty.type.skyblockgeneric.gems.Gemstone; import net.swofty.type.skyblockgeneric.item.components.*; diff --git a/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/item/components/FishingRodComponent.java b/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/item/components/FishingRodComponent.java index c7dba0d77..5b8749e9f 100644 --- a/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/item/components/FishingRodComponent.java +++ b/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/item/components/FishingRodComponent.java @@ -3,7 +3,7 @@ import net.kyori.adventure.key.Key; import net.kyori.adventure.sound.Sound; import net.swofty.type.skyblockgeneric.entity.FishingHook; -import net.swofty.type.skyblockgeneric.fishing.FishingItemSupport; +import net.swofty.type.skyblockgeneric.fishing.item.FishingItemSupport; import net.swofty.type.skyblockgeneric.fishing.FishingService; import net.swofty.type.skyblockgeneric.item.SkyBlockItemComponent; diff --git a/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/item/components/FishingRodPartComponent.java b/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/item/components/FishingRodPartComponent.java index 1cc4f105e..43307b3db 100644 --- a/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/item/components/FishingRodPartComponent.java +++ b/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/item/components/FishingRodPartComponent.java @@ -2,7 +2,7 @@ import lombok.Getter; import net.swofty.commons.skyblock.item.ItemType; -import net.swofty.type.skyblockgeneric.fishing.FishingPartCategory; +import net.swofty.type.skyblockgeneric.fishing.rod.FishingPartCategory; import java.util.Map; diff --git a/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/item/components/FishingShipPartComponent.java b/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/item/components/FishingShipPartComponent.java index 3ef56d3d2..7ae781930 100644 --- a/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/item/components/FishingShipPartComponent.java +++ b/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/item/components/FishingShipPartComponent.java @@ -2,7 +2,7 @@ import lombok.Getter; import net.swofty.commons.skyblock.item.ItemType; -import net.swofty.type.skyblockgeneric.fishing.FishingShipPartSlot; +import net.swofty.type.skyblockgeneric.fishing.rod.FishingShipPartSlot; @Getter public class FishingShipPartComponent extends net.swofty.type.skyblockgeneric.item.SkyBlockItemComponent { diff --git a/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/item/handlers/lore/LoreRegistry.java b/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/item/handlers/lore/LoreRegistry.java index 1b4a8bcde..b9aee99cd 100644 --- a/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/item/handlers/lore/LoreRegistry.java +++ b/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/item/handlers/lore/LoreRegistry.java @@ -3,7 +3,7 @@ import net.swofty.commons.StringUtility; import net.swofty.commons.skyblock.item.PotatoType; import net.swofty.type.skyblockgeneric.enchantment.SkyBlockEnchantment; -import net.swofty.type.skyblockgeneric.fishing.FishingRodLoreBuilder; +import net.swofty.type.skyblockgeneric.fishing.rod.FishingRodLoreBuilder; import net.swofty.type.skyblockgeneric.utility.groups.EnchantItemGroups; import java.util.ArrayList; From 05fddd2324d970e6dadcbdffa4a9ad42b9040cd0 Mon Sep 17 00:00:00 2001 From: "Jacob Nardella (Swofty)" Date: Fri, 15 May 2026 11:23:46 +1000 Subject: [PATCH 101/113] refactor(events): phase listener and island load lifecycle --- .../events/ActionPlayerJoin.java | 5 +- .../events/ActionBedWarsLobbyDataLoad.java | 7 +- .../events/ActionBedWarsLobbyDataSave.java | 7 +- .../events/ActionPlayerBreak.java | 5 +- .../events/ActionPlayerDataSpawn.java | 7 +- .../events/ActionPlayerJoin.java | 5 +- .../events/ActionEntityAttack.java | 5 +- .../bedwarsgame/events/ActionGameBreak.java | 5 +- .../events/ActionGameCombatTrack.java | 5 +- .../events/ActionGameCustomItems.java | 15 +- .../bedwarsgame/events/ActionGameDeath.java | 5 +- .../bedwarsgame/events/ActionGameMove.java | 5 +- .../bedwarsgame/events/ActionGamePickup.java | 5 +- .../bedwarsgame/events/ActionGamePlace.java | 5 +- .../events/ActionGamePlayerEvent.java | 11 +- .../bedwarsgame/events/ActionPlayerChat.java | 5 +- .../events/ActionPlayerDataSpawn.java | 7 +- .../events/ActionPlayerDisconnect.java | 5 +- .../bedwarsgame/events/ActionPlayerJoin.java | 5 +- .../bedwarslobby/events/ActionPlayerChat.java | 5 +- .../events/ActionPlayerDataSpawn.java | 7 +- .../events/ActionPlayerDisconnect.java | 5 +- .../events/ActionPlayerSpawn.java | 5 +- .../events/ActionRejoinCheck.java | 5 +- .../crimsonisle/events/ActionPlayerJoin.java | 5 +- .../deepcaverns/events/ActionPlayerJoin.java | 5 +- .../dungeonhub/events/ActionPlayerJoin.java | 5 +- .../events/ActionPlayerCommissions.java | 5 +- .../dwarvenmines/events/ActionPlayerJoin.java | 5 +- .../type/galatea/events/ActionPlayerJoin.java | 5 +- .../swofty/type/generic/event/EventNodes.java | 35 +-- .../generic/event/HypixelEventHandler.java | 208 ++++++++-------- .../ActionPlayerClickedInteractionEntity.java | 5 +- .../event/actions/ActionPlayerMute.java | 5 +- .../actions/data/ActionPlayerClearCache.java | 7 +- .../actions/data/ActionPlayerDataLoad.java | 75 +----- .../actions/data/ActionPlayerDataSave.java | 117 +-------- .../actions/data/ActionPlayerDataSpawn.java | 47 +--- .../gui/ActionPlayerInventoryClick.java | 5 +- .../gui/ActionPlayerInventoryClickAnvil.java | 5 +- .../gui/ActionPlayerInventoryClose.java | 5 +- .../gui/ActionPlayerInventoryCloseAnvil.java | 5 +- .../gui/ActionPlayerInventoryPostClick.java | 5 +- .../actions/npc/ActionPlayerClickedNPC.java | 5 +- .../party/ActionPlayerRejoinParty.java | 5 +- .../type/generic/event/phase/EventPhase.java | 31 +++ .../PhasedEvent.java} | 12 +- .../gui/v2/event/ActionInventoryClose.java | 7 +- .../gui/v2/event/ActionInventoryOpen.java | 7 +- .../v2/event/ActionInventoryPostClick.java | 7 +- .../gui/v2/event/ActionInventoryPreClick.java | 7 +- .../user/flow/GenericPlayerDataFlow.java | 170 +++++++++++++ .../type/generic/user/flow/PlayerFlow.java | 32 +++ .../goldmine/events/ActionPlayerJoin.java | 5 +- .../ActionPlayerClickMuseumDisplay.java | 5 +- .../ActionPlayerClicksMuseumNPCDisplay.java | 5 +- .../ActionPlayerClicksOnRunePedestal.java | 5 +- .../hub/events/ActionPlayerDisplayMuseum.java | 5 +- .../ActionPlayerHandleTargetArchery.java | 9 +- .../type/hub/events/ActionPlayerJoin.java | 5 +- .../events/ActionPlayerQuitDarkAuction.java | 5 +- .../type/hub/events/ActionPlayerSpawn.java | 5 +- .../swofty/type/island/TypeIslandLoader.java | 10 +- .../custom/ActionCreateStarterChest.java | 28 --- .../custom/ActionIslandCreatePortals.java | 18 -- .../events/custom/ActionIslandInitJerry.java | 19 -- .../custom/ActionIslandLoadMinions.java | 75 ------ .../events/custom/ActionIslandSaveJerry.java | 33 --- .../custom/ActionIslandSaveMinions.java | 18 -- .../custom/ActionPlayerSpawnFirstMinion.java | 28 --- .../events/traditional/ActionIslandSave.java | 7 +- .../traditional/ActionPlayerClickMinion.java | 5 +- .../ActionPlayerClickedJerryNPC.java | 5 +- .../events/traditional/ActionPlayerJoin.java | 5 +- .../traditional/ActionPlayerTeleport.java | 14 +- .../traditional/ActionStartIslandMission.java | 5 +- .../island/lifecycle/FirstMinionStep.java | 36 +++ .../lifecycle/IslandLifecycleSteps.java | 25 ++ .../island/lifecycle/JerryDefaultsStep.java | 19 ++ .../JerryLoadStep.java} | 40 ++-- .../type/island/lifecycle/JerrySaveStep.java | 41 ++++ .../type/island/lifecycle/MinionLoadStep.java | 69 ++++++ .../type/island/lifecycle/MinionSaveStep.java | 20 ++ .../island/lifecycle/PortalBuildStep.java | 25 ++ .../island/lifecycle/StarterChestStep.java | 36 +++ .../events/ActionPlayerJoin.java | 5 +- .../type/lobby/events/LobbyBlockBreak.java | 5 +- .../type/lobby/events/LobbyItemEvents.java | 13 +- .../lobby/events/LobbyLaunchPadEvents.java | 5 +- .../type/lobby/events/LobbyParkourEvents.java | 9 +- .../lobby/events/LobbyPlayerJoinEvents.java | 5 +- .../type/lobby/events/LobbyPlayerMove.java | 5 +- .../events/ActionPlayerBreak.java | 5 +- .../events/ActionPlayerDataSpawn.java | 5 +- .../events/ActionPlayerJoin.java | 5 +- .../events/ActionArrowHit.java | 5 +- .../events/ActionArrowShoot.java | 5 +- .../events/ActionBlockInteraction.java | 5 +- .../events/ActionGameCustomItems.java | 11 +- .../events/ActionGoldDrop.java | 5 +- .../events/ActionGoldInventoryMove.java | 5 +- .../events/ActionGoldPickup.java | 5 +- .../events/ActionPlayerChat.java | 5 +- .../events/ActionPlayerCombat.java | 5 +- .../events/ActionPlayerDataSpawn.java | 5 +- .../events/ActionPlayerDisconnect.java | 5 +- .../events/ActionPlayerJoin.java | 5 +- .../events/ActionPlayerTick.java | 5 +- .../ActionPreventBlockModification.java | 7 +- .../events/ActionPreventFallDamage.java | 5 +- .../events/ActionWaterDeath.java | 5 +- .../events/ActionWeaknessSplash.java | 5 +- .../events/ActionPlayerChat.java | 5 +- .../events/ActionPlayerDataSpawn.java | 5 +- .../events/ActionPlayerDisconnect.java | 5 +- .../events/ActionPlayerSpawn.java | 5 +- .../events/ActionPlayerChat.java | 5 +- .../events/ActionPlayerDataSpawn.java | 7 +- .../events/ActionPlayerDisconnect.java | 5 +- .../events/ActionPlayerSpawn.java | 5 +- .../ActionPlayerFirstSpawnTexturePack.java | 5 +- .../actions/player/ActionPlayerJoin.java | 5 +- .../data/ActionPlayerClearRavengardCache.java | 5 +- .../data/ActionPlayerRavengardDataLoad.java | 5 +- .../data/ActionPlayerRavengardDataSave.java | 5 +- .../data/ActionPlayerRavengardDataSpawn.java | 5 +- .../events/ActionPlayerVoid.java | 5 +- .../SkyBlockGenericLoader.java | 2 +- .../custom/ActionChangeMiningRegion.java | 5 +- .../custom/ActionChangeTimeCalender.java | 5 +- .../actions/custom/ActionDisplayMenu.java | 5 +- .../actions/custom/ActionNewZoneDisplay.java | 5 +- .../custom/ActionPlayerDamageBlock.java | 5 +- .../custom/ActionRegionChangeDisplay.java | 5 +- .../actions/custom/ActionRegionPlaySong.java | 5 +- .../bestiary/ActionBestiaryLevelUp.java | 5 +- .../collection/ActionCollectionAdd.java | 5 +- .../collection/ActionCollectionDisplay.java | 7 +- .../ActionCollectionHypixelLevel.java | 5 +- .../custom/levels/ActionChangeHypixelXP.java | 5 +- .../actions/custom/loot/CoinDropHandler.java | 5 +- .../custom/loot/VanillaExperienceHandler.java | 5 +- .../skill/ActionSkillCarpentryGain.java | 5 +- .../custom/skill/ActionSkillDisplay.java | 5 +- .../custom/skill/ActionSkillHypixelLevel.java | 5 +- .../custom/skill/ActionSkillLevelUp.java | 5 +- .../skill/ActionSkillMiningHandler.java | 5 +- .../custom/skill/ActionSkillPetLevel.java | 5 +- .../custom/skill/ActionSkillUpdateLast.java | 5 +- .../entity/ActionAnimateEntityDamage.java | 5 +- .../actions/entity/ActionChunkUnload.java | 5 +- .../event/actions/item/ActionDrinkPotion.java | 5 +- .../item/ActionItemAbilityBlockLeftUse.java | 5 +- .../item/ActionItemAbilityBlockRightUse.java | 5 +- .../item/ActionItemAbilityLeftUse.java | 5 +- .../item/ActionItemAbilityRightUse.java | 5 +- .../ActionItemDisableEatingAnimation.java | 5 +- .../event/actions/item/ActionItemDrop.java | 5 +- .../event/actions/item/ActionItemLeftUse.java | 5 +- .../event/actions/item/ActionItemPlace.java | 5 +- .../actions/item/ActionItemRightUse.java | 5 +- .../actions/item/ActionPlayerItemPickup.java | 5 +- .../actions/item/ActionThrowSplashPotion.java | 5 +- .../event/actions/item/ActionUseBow.java | 5 +- .../event/actions/item/ActionUseShortBow.java | 5 +- .../actions/npc/ActionPlayerInteractNPC.java | 5 +- .../player/ActionAddSkyBlockXPToNametag.java | 5 +- .../actions/player/ActionAnvilClick.java | 5 +- .../player/ActionClearPendingBazaar.java | 5 +- .../player/ActionCraftingTableClick.java | 5 +- .../player/ActionEnchantmentTableClick.java | 5 +- .../player/ActionPlayerBankAddInterest.java | 5 +- .../ActionPlayerChangeHypixelMenuDisplay.java | 5 +- .../actions/player/ActionPlayerChat.java | 5 +- .../player/ActionPlayerInteractFairySoul.java | 5 +- .../actions/player/ActionPlayerJoin.java | 5 +- .../player/ActionPlayerLaunchPads.java | 5 +- .../actions/player/ActionPlayerRemoveTab.java | 7 +- .../ActionPlayerRightClickOnPlayer.java | 5 +- .../player/ActionPlayerStrayTooFar.java | 5 +- .../ActionPlayerTransferServerParty.java | 5 +- .../actions/player/ActionPlayerTravel.java | 5 +- .../player/blocks/ActionBlockDestroy.java | 5 +- .../player/blocks/ActionBlockInteract.java | 5 +- .../player/blocks/ActionBlockPlaceable.java | 5 +- .../blocks/ActionPlayerSetupMining.java | 7 +- .../data/ActionPlayerClearSkyBlockCache.java | 7 +- .../player/data/ActionPlayerDataLoaded.java | 129 +--------- .../data/ActionPlayerSkyBlockDataLoad.java | 99 +------- .../data/ActionPlayerSkyBlockDataSave.java | 43 +--- .../actions/player/fall/ActionPlayerFall.java | 5 +- .../actions/player/fall/ActionPlayerVoid.java | 5 +- .../gui/ActionPlayerClickItemUpdate.java | 5 +- .../gui/ActionPlayerInteractWithCrafting.java | 5 +- .../mobdamage/PlayerActionArrowDamageMob.java | 7 +- .../mobdamage/PlayerActionDamageMob.java | 7 +- .../PlayerActionDamagedAttacked.java | 5 +- .../offhand/ActionOffhandHandClick.java | 5 +- .../offhand/ActionOffhandItemClick.java | 5 +- .../player/region/ActionRegionBlockBreak.java | 5 +- .../player/region/ActionRegionBlockPlace.java | 5 +- .../event/actions/race/RaceEvents.java | 9 +- .../IslandFetchedFromDatabaseEvent.java | 24 -- .../event/custom/IslandFirstCreatedEvent.java | 21 -- .../event/custom/IslandPlayerLoadedEvent.java | 26 -- .../custom/IslandSavedIntoDatabaseEvent.java | 21 -- .../item/events/RuneItemEvent.java | 5 +- .../interactable/InteractableRegistry.java | 2 +- .../minion/IslandMinionData.java | 2 +- .../mission/missions/MissionBreakLog.java | 7 +- .../missions/MissionCraftWoodenPickaxe.java | 7 +- .../missions/MissionCraftWorkbench.java | 5 +- .../mission/missions/MissionKillZombies.java | 7 +- .../mission/missions/MissionTalkJerry.java | 5 +- .../missions/MissionTalkToAuctionMaster.java | 5 +- .../mission/missions/MissionTalkToBanker.java | 5 +- .../missions/MissionTalkToLibrarian.java | 5 +- .../missions/MissionUseTeleporter.java | 7 +- .../barn/MissionCraftWheatMinion.java | 5 +- .../missions/barn/MissionTalkToFarmHand.java | 5 +- .../missions/blacksmith/MissionMineCoal.java | 5 +- .../blacksmith/MissionTalkToBlacksmith.java | 5 +- .../missions/farmer/MissionCollectWheat.java | 5 +- .../missions/farmer/MissionTalkToFarmer.java | 5 +- .../missions/lumber/MissionBreakOaklog.java | 5 +- .../lumber/MissionTalkToLumberjack.java | 5 +- .../missions/sheperd/MissionShearSheep.java | 5 +- .../sheperd/MissionTalkToShepherd.java | 5 +- .../birchpark/MissionCollectBirchLogs.java | 5 +- .../MissionCollectDarkOakLogs.java | 5 +- .../jungle/MissionCollectJungleLogs.java | 5 +- .../thepark/jungle/MissionLeaveTheArea.java | 5 +- .../jungle/MissionLeaveTheAreaAgain.java | 5 +- .../savanna/MissionCollectAcaciaLogs.java | 5 +- .../spruce/MissionCollectSpruceLogs.java | 5 +- .../redis/RedisHasIslandLoaded.java | 2 +- .../skyblockgeneric/user/SkyBlockIsland.java | 203 ---------------- .../skyblockgeneric/user/SkyBlockPlayer.java | 1 + .../user/flow/SkyBlockPlayerDataFlow.java | 226 ++++++++++++++++++ .../user/island/IslandLifecycle.java | 47 ++++ .../user/island/IslandLifecycleContext.java | 13 + .../user/island/IslandLifecyclePhase.java | 7 + .../user/island/IslandLifecycleStep.java | 11 + .../user/island/IslandMembers.java | 29 +++ .../user/island/IslandWorldStorage.java | 55 +++++ .../user/island/SkyBlockIsland.java | 175 ++++++++++++++ .../events/ActionPlayerDataSpawn.java | 5 +- .../events/ActionPlayerJoin.java | 5 +- .../skywarsgame/events/ActionArrowStats.java | 7 +- .../skywarsgame/events/ActionChestClose.java | 5 +- .../skywarsgame/events/ActionChestOpen.java | 5 +- .../events/ActionGameCustomItems.java | 9 +- .../events/ActionLuckyBlockArrows.java | 9 +- .../events/ActionLuckyBlockBreak.java | 5 +- .../events/ActionLuckyBlockPlace.java | 5 +- .../skywarsgame/events/ActionMobAttack.java | 5 +- .../skywarsgame/events/ActionMobKill.java | 5 +- .../skywarsgame/events/ActionPlayerChat.java | 5 +- .../events/ActionPlayerCombat.java | 5 +- .../events/ActionPlayerDisconnect.java | 5 +- .../skywarsgame/events/ActionPlayerJoin.java | 5 +- .../events/ActionPlayerNameColors.java | 5 +- .../skywarslobby/events/ActionPlayerChat.java | 5 +- .../events/ActionPlayerDataSpawn.java | 5 +- .../events/ActionPlayerDisconnect.java | 5 +- .../events/ActionPlayerSpawn.java | 5 +- .../events/ActionSoulWellInteract.java | 5 +- .../spidersden/events/ActionPlayerJoin.java | 5 +- .../type/theend/events/ActionPlayerJoin.java | 5 +- .../events/ActionPlayerJoin.java | 5 +- .../events/ActionContinueParkMission.java | 5 +- .../type/thepark/events/ActionPlayerJoin.java | 5 +- 272 files changed, 1999 insertions(+), 1638 deletions(-) create mode 100644 type.generic/src/main/java/net/swofty/type/generic/event/phase/EventPhase.java rename type.generic/src/main/java/net/swofty/type/generic/event/{HypixelEvent.java => phase/PhasedEvent.java} (52%) create mode 100644 type.generic/src/main/java/net/swofty/type/generic/user/flow/GenericPlayerDataFlow.java create mode 100644 type.generic/src/main/java/net/swofty/type/generic/user/flow/PlayerFlow.java delete mode 100644 type.island/src/main/java/net/swofty/type/island/events/custom/ActionCreateStarterChest.java delete mode 100644 type.island/src/main/java/net/swofty/type/island/events/custom/ActionIslandCreatePortals.java delete mode 100644 type.island/src/main/java/net/swofty/type/island/events/custom/ActionIslandInitJerry.java delete mode 100644 type.island/src/main/java/net/swofty/type/island/events/custom/ActionIslandLoadMinions.java delete mode 100644 type.island/src/main/java/net/swofty/type/island/events/custom/ActionIslandSaveJerry.java delete mode 100644 type.island/src/main/java/net/swofty/type/island/events/custom/ActionIslandSaveMinions.java delete mode 100644 type.island/src/main/java/net/swofty/type/island/events/custom/ActionPlayerSpawnFirstMinion.java create mode 100644 type.island/src/main/java/net/swofty/type/island/lifecycle/FirstMinionStep.java create mode 100644 type.island/src/main/java/net/swofty/type/island/lifecycle/IslandLifecycleSteps.java create mode 100644 type.island/src/main/java/net/swofty/type/island/lifecycle/JerryDefaultsStep.java rename type.island/src/main/java/net/swofty/type/island/{events/custom/ActionIslandLoadJerry.java => lifecycle/JerryLoadStep.java} (58%) create mode 100644 type.island/src/main/java/net/swofty/type/island/lifecycle/JerrySaveStep.java create mode 100644 type.island/src/main/java/net/swofty/type/island/lifecycle/MinionLoadStep.java create mode 100644 type.island/src/main/java/net/swofty/type/island/lifecycle/MinionSaveStep.java create mode 100644 type.island/src/main/java/net/swofty/type/island/lifecycle/PortalBuildStep.java create mode 100644 type.island/src/main/java/net/swofty/type/island/lifecycle/StarterChestStep.java delete mode 100644 type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/event/custom/IslandFetchedFromDatabaseEvent.java delete mode 100644 type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/event/custom/IslandFirstCreatedEvent.java delete mode 100644 type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/event/custom/IslandPlayerLoadedEvent.java delete mode 100644 type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/event/custom/IslandSavedIntoDatabaseEvent.java delete mode 100644 type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/user/SkyBlockIsland.java create mode 100644 type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/user/flow/SkyBlockPlayerDataFlow.java create mode 100644 type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/user/island/IslandLifecycle.java create mode 100644 type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/user/island/IslandLifecycleContext.java create mode 100644 type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/user/island/IslandLifecyclePhase.java create mode 100644 type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/user/island/IslandLifecycleStep.java create mode 100644 type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/user/island/IslandMembers.java create mode 100644 type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/user/island/IslandWorldStorage.java create mode 100644 type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/user/island/SkyBlockIsland.java diff --git a/type.backwaterbayou/src/main/java/net/swofty/type/backwaterbayou/events/ActionPlayerJoin.java b/type.backwaterbayou/src/main/java/net/swofty/type/backwaterbayou/events/ActionPlayerJoin.java index 173ba7c29..1459fce2e 100644 --- a/type.backwaterbayou/src/main/java/net/swofty/type/backwaterbayou/events/ActionPlayerJoin.java +++ b/type.backwaterbayou/src/main/java/net/swofty/type/backwaterbayou/events/ActionPlayerJoin.java @@ -4,14 +4,15 @@ import net.minestom.server.event.player.AsyncPlayerConfigurationEvent; import net.swofty.type.generic.HypixelConst; import net.swofty.type.generic.event.EventNodes; -import net.swofty.type.generic.event.HypixelEvent; import net.swofty.type.generic.event.HypixelEventClass; +import net.swofty.type.generic.event.phase.EventPhase; +import net.swofty.type.generic.event.phase.PhasedEvent; import net.swofty.type.skyblockgeneric.user.SkyBlockPlayer; public class ActionPlayerJoin implements HypixelEventClass { @SneakyThrows - @HypixelEvent(node = EventNodes.PLAYER, requireDataLoaded = false) + @PhasedEvent(node = EventNodes.PLAYER, requireDataLoaded = false, phase = EventPhase.CONNECT) public void run(AsyncPlayerConfigurationEvent event) { final SkyBlockPlayer player = (SkyBlockPlayer) event.getPlayer(); diff --git a/type.bedwarsconfigurator/src/main/java/net/swofty/type/bedwarsconfigurator/events/ActionBedWarsLobbyDataLoad.java b/type.bedwarsconfigurator/src/main/java/net/swofty/type/bedwarsconfigurator/events/ActionBedWarsLobbyDataLoad.java index d888024e5..d48a3bc16 100644 --- a/type.bedwarsconfigurator/src/main/java/net/swofty/type/bedwarsconfigurator/events/ActionBedWarsLobbyDataLoad.java +++ b/type.bedwarsconfigurator/src/main/java/net/swofty/type/bedwarsconfigurator/events/ActionBedWarsLobbyDataLoad.java @@ -5,8 +5,9 @@ import net.swofty.type.generic.data.handlers.BedWarsDataHandler; import net.swofty.type.generic.data.mongodb.UserDatabase; import net.swofty.type.generic.event.EventNodes; -import net.swofty.type.generic.event.HypixelEvent; import net.swofty.type.generic.event.HypixelEventClass; +import net.swofty.type.generic.event.phase.EventPhase; +import net.swofty.type.generic.event.phase.PhasedEvent; import net.swofty.type.generic.user.HypixelPlayer; import org.bson.Document; import org.tinylog.Logger; @@ -16,7 +17,7 @@ public class ActionBedWarsLobbyDataLoad implements HypixelEventClass { @SneakyThrows - @HypixelEvent(node = EventNodes.PLAYER_DATA, requireDataLoaded = false) + @PhasedEvent(node = EventNodes.PLAYER_DATA, requireDataLoaded = false, phase = EventPhase.LOAD_DATA, order = 10) public void run(AsyncPlayerConfigurationEvent event) { Logger.info("Loading BedWars data for player: " + event.getPlayer().getUsername() + "..."); @@ -38,4 +39,4 @@ public void run(AsyncPlayerConfigurationEvent event) { Logger.info("Successfully loaded BedWars data for player: " + player.getUsername()); } -} \ No newline at end of file +} diff --git a/type.bedwarsconfigurator/src/main/java/net/swofty/type/bedwarsconfigurator/events/ActionBedWarsLobbyDataSave.java b/type.bedwarsconfigurator/src/main/java/net/swofty/type/bedwarsconfigurator/events/ActionBedWarsLobbyDataSave.java index 45decca71..13e20d4f8 100644 --- a/type.bedwarsconfigurator/src/main/java/net/swofty/type/bedwarsconfigurator/events/ActionBedWarsLobbyDataSave.java +++ b/type.bedwarsconfigurator/src/main/java/net/swofty/type/bedwarsconfigurator/events/ActionBedWarsLobbyDataSave.java @@ -5,8 +5,9 @@ import net.swofty.type.generic.data.handlers.BedWarsDataHandler; import net.swofty.type.generic.data.mongodb.UserDatabase; import net.swofty.type.generic.event.EventNodes; -import net.swofty.type.generic.event.HypixelEvent; import net.swofty.type.generic.event.HypixelEventClass; +import net.swofty.type.generic.event.phase.EventPhase; +import net.swofty.type.generic.event.phase.PhasedEvent; import net.swofty.type.generic.user.HypixelPlayer; import org.tinylog.Logger; @@ -14,7 +15,7 @@ public class ActionBedWarsLobbyDataSave implements HypixelEventClass { @SneakyThrows - @HypixelEvent(node = EventNodes.PLAYER, requireDataLoaded = false, isAsync = true) + @PhasedEvent(node = EventNodes.PLAYER, requireDataLoaded = false, isAsync = true, phase = EventPhase.PERSIST, order = 10) public void run(PlayerDisconnectEvent event) { final HypixelPlayer player = (HypixelPlayer) event.getPlayer(); UUID uuid = player.getUuid(); @@ -36,4 +37,4 @@ public void run(PlayerDisconnectEvent event) { Logger.info("Successfully saved BedWars account data for: " + player.getUsername()); } -} \ No newline at end of file +} diff --git a/type.bedwarsconfigurator/src/main/java/net/swofty/type/bedwarsconfigurator/events/ActionPlayerBreak.java b/type.bedwarsconfigurator/src/main/java/net/swofty/type/bedwarsconfigurator/events/ActionPlayerBreak.java index 0025f6908..bcf8b49ec 100644 --- a/type.bedwarsconfigurator/src/main/java/net/swofty/type/bedwarsconfigurator/events/ActionPlayerBreak.java +++ b/type.bedwarsconfigurator/src/main/java/net/swofty/type/bedwarsconfigurator/events/ActionPlayerBreak.java @@ -3,13 +3,14 @@ import lombok.SneakyThrows; import net.minestom.server.event.player.PlayerBlockBreakEvent; import net.swofty.type.generic.event.EventNodes; -import net.swofty.type.generic.event.HypixelEvent; import net.swofty.type.generic.event.HypixelEventClass; +import net.swofty.type.generic.event.phase.EventPhase; +import net.swofty.type.generic.event.phase.PhasedEvent; public class ActionPlayerBreak implements HypixelEventClass { @SneakyThrows - @HypixelEvent(node = EventNodes.PLAYER , requireDataLoaded = false) + @PhasedEvent(node = EventNodes.PLAYER , requireDataLoaded = false, phase = EventPhase.GAMEPLAY) public void run(PlayerBlockBreakEvent event) { event.setCancelled(true); } diff --git a/type.bedwarsconfigurator/src/main/java/net/swofty/type/bedwarsconfigurator/events/ActionPlayerDataSpawn.java b/type.bedwarsconfigurator/src/main/java/net/swofty/type/bedwarsconfigurator/events/ActionPlayerDataSpawn.java index 0b83de168..447bb9eeb 100644 --- a/type.bedwarsconfigurator/src/main/java/net/swofty/type/bedwarsconfigurator/events/ActionPlayerDataSpawn.java +++ b/type.bedwarsconfigurator/src/main/java/net/swofty/type/bedwarsconfigurator/events/ActionPlayerDataSpawn.java @@ -5,14 +5,15 @@ import net.swofty.type.generic.HypixelConst; import net.swofty.type.generic.data.handlers.BedWarsDataHandler; import net.swofty.type.generic.event.EventNodes; -import net.swofty.type.generic.event.HypixelEvent; import net.swofty.type.generic.event.HypixelEventClass; +import net.swofty.type.generic.event.phase.EventPhase; +import net.swofty.type.generic.event.phase.PhasedEvent; import net.swofty.type.generic.user.HypixelPlayer; import net.swofty.type.generic.user.categories.Rank; public class ActionPlayerDataSpawn implements HypixelEventClass { - @HypixelEvent(node = EventNodes.PLAYER_DATA, requireDataLoaded = false, isAsync = true) + @PhasedEvent(node = EventNodes.PLAYER_DATA, requireDataLoaded = false, isAsync = true, phase = EventPhase.POST_SPAWN) public void run(PlayerSpawnEvent event) { if (!event.isFirstSpawn()) return; if (!(HypixelConst.getTypeLoader().getType() == ServerType.BEDWARS_CONFIGURATOR)) return; @@ -25,4 +26,4 @@ public void run(PlayerSpawnEvent event) { BedWarsDataHandler handler = BedWarsDataHandler.getUser(player.getUuid()); handler.runOnLoad(player); } -} \ No newline at end of file +} diff --git a/type.bedwarsconfigurator/src/main/java/net/swofty/type/bedwarsconfigurator/events/ActionPlayerJoin.java b/type.bedwarsconfigurator/src/main/java/net/swofty/type/bedwarsconfigurator/events/ActionPlayerJoin.java index 9b316ab7c..5622fd508 100644 --- a/type.bedwarsconfigurator/src/main/java/net/swofty/type/bedwarsconfigurator/events/ActionPlayerJoin.java +++ b/type.bedwarsconfigurator/src/main/java/net/swofty/type/bedwarsconfigurator/events/ActionPlayerJoin.java @@ -4,15 +4,16 @@ import net.minestom.server.event.player.AsyncPlayerConfigurationEvent; import net.swofty.type.generic.HypixelConst; import net.swofty.type.generic.event.EventNodes; -import net.swofty.type.generic.event.HypixelEvent; import net.swofty.type.generic.event.HypixelEventClass; +import net.swofty.type.generic.event.phase.EventPhase; +import net.swofty.type.generic.event.phase.PhasedEvent; import net.swofty.type.generic.user.HypixelPlayer; import org.tinylog.Logger; public class ActionPlayerJoin implements HypixelEventClass { @SneakyThrows - @HypixelEvent(node = EventNodes.PLAYER, requireDataLoaded = false) + @PhasedEvent(node = EventNodes.PLAYER, requireDataLoaded = false, phase = EventPhase.CONNECT) public void run(AsyncPlayerConfigurationEvent event) { final HypixelPlayer player = (HypixelPlayer) event.getPlayer(); diff --git a/type.bedwarsgame/src/main/java/net/swofty/type/bedwarsgame/events/ActionEntityAttack.java b/type.bedwarsgame/src/main/java/net/swofty/type/bedwarsgame/events/ActionEntityAttack.java index ec8123da2..915ea4190 100644 --- a/type.bedwarsgame/src/main/java/net/swofty/type/bedwarsgame/events/ActionEntityAttack.java +++ b/type.bedwarsgame/src/main/java/net/swofty/type/bedwarsgame/events/ActionEntityAttack.java @@ -7,12 +7,13 @@ import net.swofty.type.bedwarsgame.user.BedWarsPlayer; import net.swofty.type.generic.entity.npc.HypixelNPC; import net.swofty.type.generic.event.EventNodes; -import net.swofty.type.generic.event.HypixelEvent; import net.swofty.type.generic.event.HypixelEventClass; +import net.swofty.type.generic.event.phase.EventPhase; +import net.swofty.type.generic.event.phase.PhasedEvent; public class ActionEntityAttack implements HypixelEventClass { - @HypixelEvent(node = EventNodes.ALL, requireDataLoaded = false) + @PhasedEvent(node = EventNodes.ALL, requireDataLoaded = false, phase = EventPhase.GAMEPLAY) public void run(PrepareAttackEvent event) { if (event.getEntity() instanceof BedWarsPlayer player) { Game game = player.getGame(); diff --git a/type.bedwarsgame/src/main/java/net/swofty/type/bedwarsgame/events/ActionGameBreak.java b/type.bedwarsgame/src/main/java/net/swofty/type/bedwarsgame/events/ActionGameBreak.java index 59e52345c..b415738a3 100644 --- a/type.bedwarsgame/src/main/java/net/swofty/type/bedwarsgame/events/ActionGameBreak.java +++ b/type.bedwarsgame/src/main/java/net/swofty/type/bedwarsgame/events/ActionGameBreak.java @@ -16,15 +16,16 @@ import net.swofty.type.bedwarsgame.stats.BedWarsStatsRecorder; import net.swofty.type.bedwarsgame.user.BedWarsPlayer; import net.swofty.type.generic.event.EventNodes; -import net.swofty.type.generic.event.HypixelEvent; import net.swofty.type.generic.event.HypixelEventClass; +import net.swofty.type.generic.event.phase.EventPhase; +import net.swofty.type.generic.event.phase.PhasedEvent; import java.util.Map; import java.util.Objects; public class ActionGameBreak implements HypixelEventClass { - @HypixelEvent(node = EventNodes.PLAYER, requireDataLoaded = true) + @PhasedEvent(node = EventNodes.PLAYER, requireDataLoaded = true, phase = EventPhase.GAMEPLAY) public void run(PlayerBlockBreakEvent event) { BedWarsPlayer player = (BedWarsPlayer) event.getPlayer(); Block blockBeingBroken = event.getBlock(); diff --git a/type.bedwarsgame/src/main/java/net/swofty/type/bedwarsgame/events/ActionGameCombatTrack.java b/type.bedwarsgame/src/main/java/net/swofty/type/bedwarsgame/events/ActionGameCombatTrack.java index c9bfa0323..dac83263e 100644 --- a/type.bedwarsgame/src/main/java/net/swofty/type/bedwarsgame/events/ActionGameCombatTrack.java +++ b/type.bedwarsgame/src/main/java/net/swofty/type/bedwarsgame/events/ActionGameCombatTrack.java @@ -7,12 +7,13 @@ import net.swofty.type.bedwarsgame.game.GameStatus; import net.swofty.type.bedwarsgame.user.BedWarsPlayer; import net.swofty.type.generic.event.EventNodes; -import net.swofty.type.generic.event.HypixelEvent; import net.swofty.type.generic.event.HypixelEventClass; +import net.swofty.type.generic.event.phase.EventPhase; +import net.swofty.type.generic.event.phase.PhasedEvent; public class ActionGameCombatTrack implements HypixelEventClass { - @HypixelEvent(node = EventNodes.ENTITY, requireDataLoaded = false) + @PhasedEvent(node = EventNodes.ENTITY, requireDataLoaded = false, phase = EventPhase.GAMEPLAY) public void run(FinalDamageEvent event) { if (!(event.getEntity() instanceof BedWarsPlayer victim)) { return; diff --git a/type.bedwarsgame/src/main/java/net/swofty/type/bedwarsgame/events/ActionGameCustomItems.java b/type.bedwarsgame/src/main/java/net/swofty/type/bedwarsgame/events/ActionGameCustomItems.java index 1f7fff373..d2d06946b 100644 --- a/type.bedwarsgame/src/main/java/net/swofty/type/bedwarsgame/events/ActionGameCustomItems.java +++ b/type.bedwarsgame/src/main/java/net/swofty/type/bedwarsgame/events/ActionGameCustomItems.java @@ -19,8 +19,9 @@ import net.swofty.type.bedwarsgame.game.GameStatus; import net.swofty.type.bedwarsgame.user.BedWarsPlayer; import net.swofty.type.generic.event.EventNodes; -import net.swofty.type.generic.event.HypixelEvent; import net.swofty.type.generic.event.HypixelEventClass; +import net.swofty.type.generic.event.phase.EventPhase; +import net.swofty.type.generic.event.phase.PhasedEvent; import java.util.UUID; @@ -64,14 +65,14 @@ private static void handleFireballExplosion(FireballProjectile fireball) { fireball.remove(); } - @HypixelEvent(node = EventNodes.ALL, requireDataLoaded = true) + @PhasedEvent(node = EventNodes.ALL, requireDataLoaded = true, phase = EventPhase.GAMEPLAY) public void run(ProjectileCollideWithBlockEvent event) { if (event.getEntity().getEntityType() == EntityType.FIREBALL) { handleFireballExplosion((FireballProjectile) event.getEntity()); } } - @HypixelEvent(node = EventNodes.ALL, requireDataLoaded = true) + @PhasedEvent(node = EventNodes.ALL, requireDataLoaded = true, phase = EventPhase.GAMEPLAY) public void run(ProjectileCollideWithEntityEvent event) { if (event.getEntity().getEntityType() != EntityType.FIREBALL) { return; @@ -97,22 +98,22 @@ public void run(ProjectileCollideWithEntityEvent event) { handleFireballExplosion(fireball); } - @HypixelEvent(node = EventNodes.ALL, requireDataLoaded = true) + @PhasedEvent(node = EventNodes.ALL, requireDataLoaded = true, phase = EventPhase.GAMEPLAY) public void run(PlayerUseItemOnBlockEvent event) { TypeBedWarsGameLoader.getItemHandler().onItemUseOnBlock(event); } - @HypixelEvent(node = EventNodes.ALL, requireDataLoaded = true) + @PhasedEvent(node = EventNodes.ALL, requireDataLoaded = true, phase = EventPhase.GAMEPLAY) public void run(PlayerFinishItemUseEvent event) { TypeBedWarsGameLoader.getItemHandler().onItemFinishUse(event); } - @HypixelEvent(node = EventNodes.ALL, requireDataLoaded = true) + @PhasedEvent(node = EventNodes.ALL, requireDataLoaded = true, phase = EventPhase.GAMEPLAY) public void run(PlayerUseItemEvent event) { TypeBedWarsGameLoader.getItemHandler().onItemUse(event); } - @HypixelEvent(node = EventNodes.ALL, requireDataLoaded = true) + @PhasedEvent(node = EventNodes.ALL, requireDataLoaded = true, phase = EventPhase.GAMEPLAY) public void run(PlayerBlockPlaceEvent event) { TypeBedWarsGameLoader.getItemHandler().onBlockPlace(event); } diff --git a/type.bedwarsgame/src/main/java/net/swofty/type/bedwarsgame/events/ActionGameDeath.java b/type.bedwarsgame/src/main/java/net/swofty/type/bedwarsgame/events/ActionGameDeath.java index 51e723331..a6fe9d52a 100644 --- a/type.bedwarsgame/src/main/java/net/swofty/type/bedwarsgame/events/ActionGameDeath.java +++ b/type.bedwarsgame/src/main/java/net/swofty/type/bedwarsgame/events/ActionGameDeath.java @@ -30,8 +30,9 @@ import net.swofty.type.bedwarsgame.stats.BedWarsStatsRecorder; import net.swofty.type.bedwarsgame.user.BedWarsPlayer; import net.swofty.type.generic.event.EventNodes; -import net.swofty.type.generic.event.HypixelEvent; import net.swofty.type.generic.event.HypixelEventClass; +import net.swofty.type.generic.event.phase.EventPhase; +import net.swofty.type.generic.event.phase.PhasedEvent; import org.tinylog.Logger; import java.time.Duration; @@ -41,7 +42,7 @@ public class ActionGameDeath implements HypixelEventClass { - @HypixelEvent(node = EventNodes.PLAYER, requireDataLoaded = false) + @PhasedEvent(node = EventNodes.PLAYER, requireDataLoaded = false, phase = EventPhase.GAMEPLAY) public void run(PlayerDeathEvent event) { BedWarsPlayer player = (BedWarsPlayer) event.getPlayer(); diff --git a/type.bedwarsgame/src/main/java/net/swofty/type/bedwarsgame/events/ActionGameMove.java b/type.bedwarsgame/src/main/java/net/swofty/type/bedwarsgame/events/ActionGameMove.java index 5a272d88b..c6fb88df9 100644 --- a/type.bedwarsgame/src/main/java/net/swofty/type/bedwarsgame/events/ActionGameMove.java +++ b/type.bedwarsgame/src/main/java/net/swofty/type/bedwarsgame/events/ActionGameMove.java @@ -14,15 +14,16 @@ import net.swofty.type.bedwarsgame.game.GameStatus; import net.swofty.type.bedwarsgame.user.BedWarsPlayer; import net.swofty.type.generic.event.EventNodes; -import net.swofty.type.generic.event.HypixelEvent; import net.swofty.type.generic.event.HypixelEventClass; +import net.swofty.type.generic.event.phase.EventPhase; +import net.swofty.type.generic.event.phase.PhasedEvent; import java.util.List; import java.util.Map; public class ActionGameMove implements HypixelEventClass { - @HypixelEvent(node = EventNodes.PLAYER, requireDataLoaded = false, isAsync = true) + @PhasedEvent(node = EventNodes.PLAYER, requireDataLoaded = false, isAsync = true, phase = EventPhase.GAMEPLAY) public void run(PlayerMoveEvent event) { BedWarsPlayer player = (BedWarsPlayer) event.getPlayer(); diff --git a/type.bedwarsgame/src/main/java/net/swofty/type/bedwarsgame/events/ActionGamePickup.java b/type.bedwarsgame/src/main/java/net/swofty/type/bedwarsgame/events/ActionGamePickup.java index 4d557a9bb..60aceab6c 100644 --- a/type.bedwarsgame/src/main/java/net/swofty/type/bedwarsgame/events/ActionGamePickup.java +++ b/type.bedwarsgame/src/main/java/net/swofty/type/bedwarsgame/events/ActionGamePickup.java @@ -9,13 +9,14 @@ import net.swofty.type.bedwarsgame.user.BedWarsPlayer; import net.swofty.type.bedwarsgame.user.ExperienceCause; import net.swofty.type.generic.event.EventNodes; -import net.swofty.type.generic.event.HypixelEvent; import net.swofty.type.generic.event.HypixelEventClass; +import net.swofty.type.generic.event.phase.EventPhase; +import net.swofty.type.generic.event.phase.PhasedEvent; import org.jetbrains.annotations.Nullable; public class ActionGamePickup implements HypixelEventClass { - @HypixelEvent(node = EventNodes.ALL, requireDataLoaded = false) + @PhasedEvent(node = EventNodes.ALL, requireDataLoaded = false, phase = EventPhase.GAMEPLAY) public void run(PickupItemEvent event) { ItemStack itemStack = event.getItemEntity().getItemStack(); if (event.getLivingEntity() instanceof BedWarsPlayer player) { diff --git a/type.bedwarsgame/src/main/java/net/swofty/type/bedwarsgame/events/ActionGamePlace.java b/type.bedwarsgame/src/main/java/net/swofty/type/bedwarsgame/events/ActionGamePlace.java index fb8034568..87acc11ce 100644 --- a/type.bedwarsgame/src/main/java/net/swofty/type/bedwarsgame/events/ActionGamePlace.java +++ b/type.bedwarsgame/src/main/java/net/swofty/type/bedwarsgame/events/ActionGamePlace.java @@ -15,14 +15,15 @@ import net.swofty.type.bedwarsgame.game.GameStatus; import net.swofty.type.bedwarsgame.user.BedWarsPlayer; import net.swofty.type.generic.event.EventNodes; -import net.swofty.type.generic.event.HypixelEvent; import net.swofty.type.generic.event.HypixelEventClass; +import net.swofty.type.generic.event.phase.EventPhase; +import net.swofty.type.generic.event.phase.PhasedEvent; import net.swofty.type.generic.utility.MathUtility; import org.tinylog.Logger; public class ActionGamePlace implements HypixelEventClass { - @HypixelEvent(node = EventNodes.PLAYER, requireDataLoaded = false) + @PhasedEvent(node = EventNodes.PLAYER, requireDataLoaded = false, phase = EventPhase.GAMEPLAY) public void run(PlayerBlockPlaceEvent event) { BedWarsPlayer player = (BedWarsPlayer) event.getPlayer(); Game game = player.getGame(); diff --git a/type.bedwarsgame/src/main/java/net/swofty/type/bedwarsgame/events/ActionGamePlayerEvent.java b/type.bedwarsgame/src/main/java/net/swofty/type/bedwarsgame/events/ActionGamePlayerEvent.java index 7cc7efef7..210fee9c9 100644 --- a/type.bedwarsgame/src/main/java/net/swofty/type/bedwarsgame/events/ActionGamePlayerEvent.java +++ b/type.bedwarsgame/src/main/java/net/swofty/type/bedwarsgame/events/ActionGamePlayerEvent.java @@ -20,8 +20,9 @@ import net.swofty.type.bedwarsgame.user.BedWarsPlayer; import net.swofty.type.bedwarsgame.util.BedWarsInventoryManipulator; import net.swofty.type.generic.event.EventNodes; -import net.swofty.type.generic.event.HypixelEvent; import net.swofty.type.generic.event.HypixelEventClass; +import net.swofty.type.generic.event.phase.EventPhase; +import net.swofty.type.generic.event.phase.PhasedEvent; import org.tinylog.Logger; import java.time.Duration; @@ -32,7 +33,7 @@ public class ActionGamePlayerEvent implements HypixelEventClass { public static final ConcurrentHashMap ACTIVE_TEAM_CHESTS = new ConcurrentHashMap<>(); - @HypixelEvent(node = EventNodes.PLAYER, requireDataLoaded = false) + @PhasedEvent(node = EventNodes.PLAYER, requireDataLoaded = false, phase = EventPhase.GAMEPLAY) public void run(InventoryPreClickEvent event) { if (!(event.getInventory() instanceof PlayerInventory)) { return; @@ -64,7 +65,7 @@ public void run(InventoryPreClickEvent event) { "diamond_axe" ); - @HypixelEvent(node = EventNodes.PLAYER, requireDataLoaded = false) + @PhasedEvent(node = EventNodes.PLAYER, requireDataLoaded = false, phase = EventPhase.GAMEPLAY) public void run(ItemDropEvent event) { if (UNDROPPABLE_TOOLS.contains(event.getItemStack().material().name())) { event.setCancelled(true); @@ -79,7 +80,7 @@ public void run(ItemDropEvent event) { itemEntity.setPickupDelay(Duration.ofMillis(500)); } - @HypixelEvent(node = EventNodes.PLAYER, requireDataLoaded = false, isAsync = true) + @PhasedEvent(node = EventNodes.PLAYER, requireDataLoaded = false, isAsync = true, phase = EventPhase.GAMEPLAY) public void run(PlayerBlockInteractEvent event) { Block block = event.getBlock(); BedWarsPlayer player = (BedWarsPlayer) event.getPlayer(); @@ -149,7 +150,7 @@ public void run(PlayerBlockInteractEvent event) { } } - @HypixelEvent(node = EventNodes.PLAYER, requireDataLoaded = false) + @PhasedEvent(node = EventNodes.PLAYER, requireDataLoaded = false, phase = EventPhase.GAMEPLAY) public void run(PlayerStartDiggingEvent event) { Block block = event.getBlock(); BedWarsPlayer player = (BedWarsPlayer) event.getPlayer(); diff --git a/type.bedwarsgame/src/main/java/net/swofty/type/bedwarsgame/events/ActionPlayerChat.java b/type.bedwarsgame/src/main/java/net/swofty/type/bedwarsgame/events/ActionPlayerChat.java index a1eba9d36..e0764f85b 100644 --- a/type.bedwarsgame/src/main/java/net/swofty/type/bedwarsgame/events/ActionPlayerChat.java +++ b/type.bedwarsgame/src/main/java/net/swofty/type/bedwarsgame/events/ActionPlayerChat.java @@ -12,8 +12,9 @@ import net.swofty.type.generic.data.datapoints.DatapointLeaderboardLong; import net.swofty.type.generic.data.handlers.BedWarsDataHandler; import net.swofty.type.generic.event.EventNodes; -import net.swofty.type.generic.event.HypixelEvent; import net.swofty.type.generic.event.HypixelEventClass; +import net.swofty.type.generic.event.phase.EventPhase; +import net.swofty.type.generic.event.phase.PhasedEvent; import net.swofty.type.generic.party.PartyManager; import net.swofty.type.generic.user.categories.Rank; @@ -21,7 +22,7 @@ public class ActionPlayerChat implements HypixelEventClass { - @HypixelEvent(node = EventNodes.PLAYER, requireDataLoaded = false) + @PhasedEvent(node = EventNodes.PLAYER, requireDataLoaded = false, phase = EventPhase.GAMEPLAY) public void run(PlayerChatEvent event) { final BedWarsPlayer player = (BedWarsPlayer) event.getPlayer(); event.setCancelled(true); diff --git a/type.bedwarsgame/src/main/java/net/swofty/type/bedwarsgame/events/ActionPlayerDataSpawn.java b/type.bedwarsgame/src/main/java/net/swofty/type/bedwarsgame/events/ActionPlayerDataSpawn.java index 4b8d9a8e0..6ae7713c7 100644 --- a/type.bedwarsgame/src/main/java/net/swofty/type/bedwarsgame/events/ActionPlayerDataSpawn.java +++ b/type.bedwarsgame/src/main/java/net/swofty/type/bedwarsgame/events/ActionPlayerDataSpawn.java @@ -6,13 +6,14 @@ import net.swofty.pvp.projectile.entities.ArrowProjectile; import net.swofty.type.generic.data.handlers.BedWarsDataHandler; import net.swofty.type.generic.event.EventNodes; -import net.swofty.type.generic.event.HypixelEvent; import net.swofty.type.generic.event.HypixelEventClass; +import net.swofty.type.generic.event.phase.EventPhase; +import net.swofty.type.generic.event.phase.PhasedEvent; import net.swofty.type.generic.user.HypixelPlayer; public class ActionPlayerDataSpawn implements HypixelEventClass { - @HypixelEvent(node = EventNodes.PLAYER_DATA, requireDataLoaded = false, isAsync = true) + @PhasedEvent(node = EventNodes.PLAYER_DATA, requireDataLoaded = false, isAsync = true, phase = EventPhase.POST_SPAWN) public void run(PlayerSpawnEvent event) { if (!event.isFirstSpawn()) return; final HypixelPlayer player = (HypixelPlayer) event.getPlayer(); @@ -23,4 +24,4 @@ public void run(PlayerSpawnEvent event) { // Registers the bow module, which creates event nodes for the player for bow behavior new BowModule(player.eventNode(), (p, i) -> new ArrowProjectile(EntityType.ARROW, p)); } -} \ No newline at end of file +} diff --git a/type.bedwarsgame/src/main/java/net/swofty/type/bedwarsgame/events/ActionPlayerDisconnect.java b/type.bedwarsgame/src/main/java/net/swofty/type/bedwarsgame/events/ActionPlayerDisconnect.java index c266a5140..d60d3471e 100644 --- a/type.bedwarsgame/src/main/java/net/swofty/type/bedwarsgame/events/ActionPlayerDisconnect.java +++ b/type.bedwarsgame/src/main/java/net/swofty/type/bedwarsgame/events/ActionPlayerDisconnect.java @@ -7,13 +7,14 @@ import net.swofty.type.bedwarsgame.game.GameStatus; import net.swofty.type.bedwarsgame.user.BedWarsPlayer; import net.swofty.type.generic.event.EventNodes; -import net.swofty.type.generic.event.HypixelEvent; import net.swofty.type.generic.event.HypixelEventClass; +import net.swofty.type.generic.event.phase.EventPhase; +import net.swofty.type.generic.event.phase.PhasedEvent; public class ActionPlayerDisconnect implements HypixelEventClass { @SneakyThrows - @HypixelEvent(node = EventNodes.PLAYER, requireDataLoaded = false) + @PhasedEvent(node = EventNodes.PLAYER, requireDataLoaded = false, phase = EventPhase.DISCONNECT) public void run(PlayerDisconnectEvent event) { final BedWarsPlayer player = (BedWarsPlayer) event.getPlayer(); Game game = player.getGame(); diff --git a/type.bedwarsgame/src/main/java/net/swofty/type/bedwarsgame/events/ActionPlayerJoin.java b/type.bedwarsgame/src/main/java/net/swofty/type/bedwarsgame/events/ActionPlayerJoin.java index e878f3ff7..eacf679a5 100644 --- a/type.bedwarsgame/src/main/java/net/swofty/type/bedwarsgame/events/ActionPlayerJoin.java +++ b/type.bedwarsgame/src/main/java/net/swofty/type/bedwarsgame/events/ActionPlayerJoin.java @@ -9,8 +9,9 @@ import net.swofty.type.bedwarsgame.user.BedWarsPlayer; import net.swofty.type.generic.HypixelConst; import net.swofty.type.generic.event.EventNodes; -import net.swofty.type.generic.event.HypixelEvent; import net.swofty.type.generic.event.HypixelEventClass; +import net.swofty.type.generic.event.phase.EventPhase; +import net.swofty.type.generic.event.phase.PhasedEvent; import net.swofty.type.generic.redis.service.TypedGameInformationHandler; import net.swofty.type.generic.utility.MathUtility; import org.tinylog.Logger; @@ -18,7 +19,7 @@ public class ActionPlayerJoin implements HypixelEventClass { @SneakyThrows - @HypixelEvent(node = EventNodes.PLAYER, requireDataLoaded = false) + @PhasedEvent(node = EventNodes.PLAYER, requireDataLoaded = false, phase = EventPhase.CONNECT) public void run(AsyncPlayerConfigurationEvent event) { final BedWarsPlayer player = (BedWarsPlayer) event.getPlayer(); Logger.info("Player " + player.getUsername() + " joined the server from origin server " + player.getOriginServer()); diff --git a/type.bedwarslobby/src/main/java/net/swofty/type/bedwarslobby/events/ActionPlayerChat.java b/type.bedwarslobby/src/main/java/net/swofty/type/bedwarslobby/events/ActionPlayerChat.java index ec5500b25..5c7f62d8e 100644 --- a/type.bedwarslobby/src/main/java/net/swofty/type/bedwarslobby/events/ActionPlayerChat.java +++ b/type.bedwarslobby/src/main/java/net/swofty/type/bedwarslobby/events/ActionPlayerChat.java @@ -11,8 +11,9 @@ import net.swofty.type.generic.data.datapoints.DatapointLeaderboardLong; import net.swofty.type.generic.data.handlers.BedWarsDataHandler; import net.swofty.type.generic.event.EventNodes; -import net.swofty.type.generic.event.HypixelEvent; import net.swofty.type.generic.event.HypixelEventClass; +import net.swofty.type.generic.event.phase.EventPhase; +import net.swofty.type.generic.event.phase.PhasedEvent; import net.swofty.type.generic.party.PartyManager; import net.swofty.type.generic.user.HypixelPlayer; import net.swofty.type.generic.user.categories.Rank; @@ -21,7 +22,7 @@ public class ActionPlayerChat implements HypixelEventClass { - @HypixelEvent(node = EventNodes.PLAYER , requireDataLoaded = false) + @PhasedEvent(node = EventNodes.PLAYER , requireDataLoaded = false, phase = EventPhase.GAMEPLAY) public void run(PlayerChatEvent event) { final HypixelPlayer player = (HypixelPlayer) event.getPlayer(); event.setCancelled(true); diff --git a/type.bedwarslobby/src/main/java/net/swofty/type/bedwarslobby/events/ActionPlayerDataSpawn.java b/type.bedwarslobby/src/main/java/net/swofty/type/bedwarslobby/events/ActionPlayerDataSpawn.java index a246e477c..9deece03b 100644 --- a/type.bedwarslobby/src/main/java/net/swofty/type/bedwarslobby/events/ActionPlayerDataSpawn.java +++ b/type.bedwarslobby/src/main/java/net/swofty/type/bedwarslobby/events/ActionPlayerDataSpawn.java @@ -11,8 +11,9 @@ import net.swofty.type.generic.data.datapoints.DatapointToggles; import net.swofty.type.generic.data.handlers.BedWarsDataHandler; import net.swofty.type.generic.event.EventNodes; -import net.swofty.type.generic.event.HypixelEvent; import net.swofty.type.generic.event.HypixelEventClass; +import net.swofty.type.generic.event.phase.EventPhase; +import net.swofty.type.generic.event.phase.PhasedEvent; import net.swofty.type.generic.quest.QuestData; import net.swofty.type.generic.quest.QuestDefinition; import net.swofty.type.generic.quest.QuestRegistry; @@ -22,7 +23,7 @@ public class ActionPlayerDataSpawn implements HypixelEventClass { - @HypixelEvent(node = EventNodes.PLAYER_DATA, requireDataLoaded = false, isAsync = true) + @PhasedEvent(node = EventNodes.PLAYER_DATA, requireDataLoaded = false, isAsync = true, phase = EventPhase.POST_SPAWN) public void run(PlayerSpawnEvent event) { if (!event.isFirstSpawn()) return; if (!(HypixelConst.getTypeLoader().getType() == ServerType.BEDWARS_LOBBY)) return; @@ -79,4 +80,4 @@ private void autoAcceptQuests(HypixelPlayer player, AchievementCategory category " " + category.getDisplayName() + " quest" + (startedCount > 1 ? "s" : "") + "!"); } } -} \ No newline at end of file +} diff --git a/type.bedwarslobby/src/main/java/net/swofty/type/bedwarslobby/events/ActionPlayerDisconnect.java b/type.bedwarslobby/src/main/java/net/swofty/type/bedwarslobby/events/ActionPlayerDisconnect.java index d894b267e..b590cd78c 100644 --- a/type.bedwarslobby/src/main/java/net/swofty/type/bedwarslobby/events/ActionPlayerDisconnect.java +++ b/type.bedwarslobby/src/main/java/net/swofty/type/bedwarslobby/events/ActionPlayerDisconnect.java @@ -3,13 +3,14 @@ import net.minestom.server.event.player.PlayerDisconnectEvent; import net.swofty.type.bedwarslobby.BedWarsLobbyScoreboard; import net.swofty.type.generic.event.EventNodes; -import net.swofty.type.generic.event.HypixelEvent; import net.swofty.type.generic.event.HypixelEventClass; +import net.swofty.type.generic.event.phase.EventPhase; +import net.swofty.type.generic.event.phase.PhasedEvent; import net.swofty.type.generic.user.HypixelPlayer; public class ActionPlayerDisconnect implements HypixelEventClass { - @HypixelEvent(node = EventNodes.PLAYER, requireDataLoaded = false) + @PhasedEvent(node = EventNodes.PLAYER, requireDataLoaded = false, phase = EventPhase.DISCONNECT) public void run(PlayerDisconnectEvent event) { HypixelPlayer player = (HypixelPlayer) event.getPlayer(); BedWarsLobbyScoreboard.removeCache(player); diff --git a/type.bedwarslobby/src/main/java/net/swofty/type/bedwarslobby/events/ActionPlayerSpawn.java b/type.bedwarslobby/src/main/java/net/swofty/type/bedwarslobby/events/ActionPlayerSpawn.java index 8910be21a..1ec3d8511 100644 --- a/type.bedwarslobby/src/main/java/net/swofty/type/bedwarslobby/events/ActionPlayerSpawn.java +++ b/type.bedwarslobby/src/main/java/net/swofty/type/bedwarslobby/events/ActionPlayerSpawn.java @@ -4,15 +4,16 @@ import net.minestom.server.event.player.PlayerSpawnEvent; import net.swofty.type.bedwarslobby.TypeBedWarsLobbyLoader; import net.swofty.type.generic.event.EventNodes; -import net.swofty.type.generic.event.HypixelEvent; import net.swofty.type.generic.event.HypixelEventClass; +import net.swofty.type.generic.event.phase.EventPhase; +import net.swofty.type.generic.event.phase.PhasedEvent; import net.swofty.type.generic.user.HypixelPlayer; import net.minestom.server.entity.GameMode; public class ActionPlayerSpawn implements HypixelEventClass { @SneakyThrows - @HypixelEvent(node = EventNodes.PLAYER, requireDataLoaded = false, isAsync = true) + @PhasedEvent(node = EventNodes.PLAYER, requireDataLoaded = false, isAsync = true, phase = EventPhase.SPAWN) public void run(PlayerSpawnEvent event) { final HypixelPlayer player = (HypixelPlayer) event.getPlayer(); player.setGameMode(GameMode.SURVIVAL); //noticed stayed in Spectator after Bedwars game end. This is Hacky, but I don't see a reason why gamemode shouldn't be enforced on lobby join. -petethepossum diff --git a/type.bedwarslobby/src/main/java/net/swofty/type/bedwarslobby/events/ActionRejoinCheck.java b/type.bedwarslobby/src/main/java/net/swofty/type/bedwarslobby/events/ActionRejoinCheck.java index 77d539c7e..c5c37698e 100644 --- a/type.bedwarslobby/src/main/java/net/swofty/type/bedwarslobby/events/ActionRejoinCheck.java +++ b/type.bedwarslobby/src/main/java/net/swofty/type/bedwarslobby/events/ActionRejoinCheck.java @@ -8,15 +8,16 @@ import net.swofty.commons.protocol.objects.orchestrator.RejoinGameProtocolObject; import net.swofty.proxyapi.ProxyService; import net.swofty.type.generic.event.EventNodes; -import net.swofty.type.generic.event.HypixelEvent; import net.swofty.type.generic.event.HypixelEventClass; +import net.swofty.type.generic.event.phase.EventPhase; +import net.swofty.type.generic.event.phase.PhasedEvent; import net.swofty.type.generic.user.HypixelPlayer; import net.swofty.type.generic.utility.MathUtility; public class ActionRejoinCheck implements HypixelEventClass { private static final ProxyService ORCHESTRATOR = new ProxyService(ServiceType.ORCHESTRATOR); - @HypixelEvent(node = EventNodes.PLAYER, requireDataLoaded = false, isAsync = true) + @PhasedEvent(node = EventNodes.PLAYER, requireDataLoaded = false, isAsync = true, phase = EventPhase.GAMEPLAY) public void run(PlayerSpawnEvent event) { final HypixelPlayer player = (HypixelPlayer) event.getPlayer(); diff --git a/type.crimsonisle/src/main/java/net/swofty/type/crimsonisle/events/ActionPlayerJoin.java b/type.crimsonisle/src/main/java/net/swofty/type/crimsonisle/events/ActionPlayerJoin.java index c2345763d..42cdfb306 100644 --- a/type.crimsonisle/src/main/java/net/swofty/type/crimsonisle/events/ActionPlayerJoin.java +++ b/type.crimsonisle/src/main/java/net/swofty/type/crimsonisle/events/ActionPlayerJoin.java @@ -4,14 +4,15 @@ import net.minestom.server.event.player.AsyncPlayerConfigurationEvent; import net.swofty.type.generic.HypixelConst; import net.swofty.type.generic.event.EventNodes; -import net.swofty.type.generic.event.HypixelEvent; import net.swofty.type.generic.event.HypixelEventClass; +import net.swofty.type.generic.event.phase.EventPhase; +import net.swofty.type.generic.event.phase.PhasedEvent; import net.swofty.type.skyblockgeneric.user.SkyBlockPlayer; public class ActionPlayerJoin implements HypixelEventClass { @SneakyThrows - @HypixelEvent(node = EventNodes.PLAYER, requireDataLoaded = false) + @PhasedEvent(node = EventNodes.PLAYER, requireDataLoaded = false, phase = EventPhase.CONNECT) public void run(AsyncPlayerConfigurationEvent event) { final SkyBlockPlayer player = (SkyBlockPlayer) event.getPlayer(); diff --git a/type.deepcaverns/src/main/java/net/swofty/type/deepcaverns/events/ActionPlayerJoin.java b/type.deepcaverns/src/main/java/net/swofty/type/deepcaverns/events/ActionPlayerJoin.java index f0a580201..1ea029ff4 100644 --- a/type.deepcaverns/src/main/java/net/swofty/type/deepcaverns/events/ActionPlayerJoin.java +++ b/type.deepcaverns/src/main/java/net/swofty/type/deepcaverns/events/ActionPlayerJoin.java @@ -4,14 +4,15 @@ import net.minestom.server.event.player.AsyncPlayerConfigurationEvent; import net.swofty.type.generic.HypixelConst; import net.swofty.type.generic.event.EventNodes; -import net.swofty.type.generic.event.HypixelEvent; import net.swofty.type.generic.event.HypixelEventClass; +import net.swofty.type.generic.event.phase.EventPhase; +import net.swofty.type.generic.event.phase.PhasedEvent; import net.swofty.type.skyblockgeneric.user.SkyBlockPlayer; public class ActionPlayerJoin implements HypixelEventClass { @SneakyThrows - @HypixelEvent(node = EventNodes.PLAYER, requireDataLoaded = false) + @PhasedEvent(node = EventNodes.PLAYER, requireDataLoaded = false, phase = EventPhase.CONNECT) public void run(AsyncPlayerConfigurationEvent event) { final SkyBlockPlayer player = (SkyBlockPlayer) event.getPlayer(); diff --git a/type.dungeonhub/src/main/java/net/swofty/type/dungeonhub/events/ActionPlayerJoin.java b/type.dungeonhub/src/main/java/net/swofty/type/dungeonhub/events/ActionPlayerJoin.java index a5b97d44d..600c7f9de 100644 --- a/type.dungeonhub/src/main/java/net/swofty/type/dungeonhub/events/ActionPlayerJoin.java +++ b/type.dungeonhub/src/main/java/net/swofty/type/dungeonhub/events/ActionPlayerJoin.java @@ -4,15 +4,16 @@ import net.minestom.server.event.player.AsyncPlayerConfigurationEvent; import net.swofty.type.generic.HypixelConst; import net.swofty.type.generic.event.EventNodes; -import net.swofty.type.generic.event.HypixelEvent; import net.swofty.type.generic.event.HypixelEventClass; +import net.swofty.type.generic.event.phase.EventPhase; +import net.swofty.type.generic.event.phase.PhasedEvent; import net.swofty.type.skyblockgeneric.user.SkyBlockPlayer; import org.tinylog.Logger; public class ActionPlayerJoin implements HypixelEventClass { @SneakyThrows - @HypixelEvent(node = EventNodes.PLAYER, requireDataLoaded = false) + @PhasedEvent(node = EventNodes.PLAYER, requireDataLoaded = false, phase = EventPhase.CONNECT) public void run(AsyncPlayerConfigurationEvent event) { final SkyBlockPlayer player = (SkyBlockPlayer) event.getPlayer(); diff --git a/type.dwarvenmines/src/main/java/net/swofty/type/dwarvenmines/events/ActionPlayerCommissions.java b/type.dwarvenmines/src/main/java/net/swofty/type/dwarvenmines/events/ActionPlayerCommissions.java index af9c1d81b..b1582ffb4 100644 --- a/type.dwarvenmines/src/main/java/net/swofty/type/dwarvenmines/events/ActionPlayerCommissions.java +++ b/type.dwarvenmines/src/main/java/net/swofty/type/dwarvenmines/events/ActionPlayerCommissions.java @@ -7,8 +7,9 @@ import net.swofty.type.dwarvenmines.commission.Objective; import net.swofty.type.dwarvenmines.commission.ObjectiveType; import net.swofty.type.generic.event.EventNodes; -import net.swofty.type.generic.event.HypixelEvent; import net.swofty.type.generic.event.HypixelEventClass; +import net.swofty.type.generic.event.phase.EventPhase; +import net.swofty.type.generic.event.phase.PhasedEvent; import net.swofty.type.skyblockgeneric.data.SkyBlockDataHandler; import net.swofty.type.skyblockgeneric.data.datapoints.DatapointCommissions; import net.swofty.type.skyblockgeneric.region.RegionType; @@ -23,7 +24,7 @@ public class ActionPlayerCommissions implements HypixelEventClass { private static final Set TITANIUM_BLOCKS = Set.of(Material.POLISHED_DIORITE); - @HypixelEvent(node = EventNodes.PLAYER, requireDataLoaded = true) + @PhasedEvent(node = EventNodes.PLAYER, requireDataLoaded = true, phase = EventPhase.GAMEPLAY) public void run(PlayerBlockBreakEvent event) { if (!(event.getPlayer() instanceof SkyBlockPlayer player)) return; diff --git a/type.dwarvenmines/src/main/java/net/swofty/type/dwarvenmines/events/ActionPlayerJoin.java b/type.dwarvenmines/src/main/java/net/swofty/type/dwarvenmines/events/ActionPlayerJoin.java index 1a8d7d7a5..51a62b68c 100644 --- a/type.dwarvenmines/src/main/java/net/swofty/type/dwarvenmines/events/ActionPlayerJoin.java +++ b/type.dwarvenmines/src/main/java/net/swofty/type/dwarvenmines/events/ActionPlayerJoin.java @@ -4,14 +4,15 @@ import net.minestom.server.event.player.AsyncPlayerConfigurationEvent; import net.swofty.type.generic.HypixelConst; import net.swofty.type.generic.event.EventNodes; -import net.swofty.type.generic.event.HypixelEvent; import net.swofty.type.generic.event.HypixelEventClass; +import net.swofty.type.generic.event.phase.EventPhase; +import net.swofty.type.generic.event.phase.PhasedEvent; import net.swofty.type.skyblockgeneric.user.SkyBlockPlayer; public class ActionPlayerJoin implements HypixelEventClass { @SneakyThrows - @HypixelEvent(node = EventNodes.PLAYER, requireDataLoaded = false) + @PhasedEvent(node = EventNodes.PLAYER, requireDataLoaded = false, phase = EventPhase.CONNECT) public void run(AsyncPlayerConfigurationEvent event) { final SkyBlockPlayer player = (SkyBlockPlayer) event.getPlayer(); diff --git a/type.galatea/src/main/java/net/swofty/type/galatea/events/ActionPlayerJoin.java b/type.galatea/src/main/java/net/swofty/type/galatea/events/ActionPlayerJoin.java index 322539e91..8807402e1 100644 --- a/type.galatea/src/main/java/net/swofty/type/galatea/events/ActionPlayerJoin.java +++ b/type.galatea/src/main/java/net/swofty/type/galatea/events/ActionPlayerJoin.java @@ -4,14 +4,15 @@ import net.minestom.server.event.player.AsyncPlayerConfigurationEvent; import net.swofty.type.generic.HypixelConst; import net.swofty.type.generic.event.EventNodes; -import net.swofty.type.generic.event.HypixelEvent; import net.swofty.type.generic.event.HypixelEventClass; +import net.swofty.type.generic.event.phase.EventPhase; +import net.swofty.type.generic.event.phase.PhasedEvent; import net.swofty.type.skyblockgeneric.user.SkyBlockPlayer; public class ActionPlayerJoin implements HypixelEventClass { @SneakyThrows - @HypixelEvent(node = EventNodes.PLAYER, requireDataLoaded = false) + @PhasedEvent(node = EventNodes.PLAYER, requireDataLoaded = false, phase = EventPhase.CONNECT) public void run(AsyncPlayerConfigurationEvent event) { final SkyBlockPlayer player = (SkyBlockPlayer) event.getPlayer(); diff --git a/type.generic/src/main/java/net/swofty/type/generic/event/EventNodes.java b/type.generic/src/main/java/net/swofty/type/generic/event/EventNodes.java index 62fb02282..222901224 100644 --- a/type.generic/src/main/java/net/swofty/type/generic/event/EventNodes.java +++ b/type.generic/src/main/java/net/swofty/type/generic/event/EventNodes.java @@ -6,23 +6,28 @@ public enum EventNodes { - // Overarching eventnodes - CUSTOM(EventNode.all("custom-listener")), - MISSION(EventNode.type("mission-listener", EventFilter.ENTITY)), - ENTITY(EventNode.type("entity-listener", EventFilter.ENTITY)), - PLAYER(EventNode.type("player-listener", EventFilter.PLAYER).setPriority(2)), - PLAYER_DATA(EventNode.type("player-data", EventFilter.PLAYER).setPriority(1)), - ITEM(EventNode.type("item-listener", EventFilter.PLAYER)), - PING(EventNode.type("ping-listener", EventFilter.ALL)), - INVENTORY(EventNode.type("inventory-listener", EventFilter.INVENTORY)), - ALL(EventNode.all("all-listener")), - // Player nodes - - ; + CUSTOM("custom-listener", EventFilter.ALL), + MISSION("mission-listener", EventFilter.ENTITY), + ENTITY("entity-listener", EventFilter.ENTITY), + PLAYER("player-listener", EventFilter.PLAYER), + PLAYER_DATA("player-data", EventFilter.PLAYER), + ITEM("item-listener", EventFilter.PLAYER), + PING("ping-listener", EventFilter.ALL), + INVENTORY("inventory-listener", EventFilter.INVENTORY), + ALL("all-listener", EventFilter.ALL); public final EventNode eventNode; + private final String nodeName; + private final EventFilter filter; + + EventNodes(String nodeName, EventFilter filter) { + this.nodeName = nodeName; + this.filter = filter; + this.eventNode = EventNode.event(nodeName, filter, (_) -> true); + } - EventNodes(EventNode eventNode) { - this.eventNode = eventNode; + @SuppressWarnings("unchecked") + public EventNode newNode(String name, int priority) { + return EventNode.event(nodeName + "-" + name, (EventFilter) filter, (_) -> true).setPriority(priority); } } diff --git a/type.generic/src/main/java/net/swofty/type/generic/event/HypixelEventHandler.java b/type.generic/src/main/java/net/swofty/type/generic/event/HypixelEventHandler.java index 92d7cdf64..f875d1ed6 100644 --- a/type.generic/src/main/java/net/swofty/type/generic/event/HypixelEventHandler.java +++ b/type.generic/src/main/java/net/swofty/type/generic/event/HypixelEventHandler.java @@ -12,6 +12,8 @@ import net.minestom.server.timer.TaskSchedule; import net.swofty.type.generic.HypixelConst; import net.swofty.type.generic.data.HypixelDataHandler; +import net.swofty.type.generic.event.phase.EventPhase; +import net.swofty.type.generic.event.phase.PhasedEvent; import net.swofty.type.generic.user.HypixelPlayer; import net.swofty.type.generic.user.PlayerHookManager; import org.tinylog.Logger; @@ -19,116 +21,53 @@ import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; import java.util.ArrayList; -import java.util.HashMap; import java.util.List; -import java.util.Map; public class HypixelEventHandler { - private static final HashMap, List> cachedEvents = new HashMap<>(); - private static final ArrayList cachedCustomEvents = new ArrayList<>(); - private static final EventNode customEventNode = (EventNode) EventNodes.CUSTOM.eventNode; + private static final ArrayList cachedEvents = new ArrayList<>(); + private static final EventNode rootNode = EventNode.all("hypixel-phased-events"); + private static boolean registered = false; private record EventMethodEntry(Method method, Object instance, - HypixelEvent hypixelEvent) { } + EventNodes node, + EventPhase phase, + int order, + boolean requireDataLoaded, + boolean isAsync) { } public static void registerEventMethods(Object instance) { Class clazz = instance.getClass(); for (Method method : clazz.getDeclaredMethods()) { - if (method.isAnnotationPresent(HypixelEvent.class)) { - HypixelEvent hypixelEvent = method.getAnnotation(HypixelEvent.class); - EventNodes paramNode = hypixelEvent.node(); - - if (paramNode == EventNodes.CUSTOM) { - if (cachedCustomEvents.contains(new EventMethodEntry(method, instance, hypixelEvent))) { - continue; - } - cachedCustomEvents.add(new EventMethodEntry(method, instance, hypixelEvent)); - continue; - } - - if (!cachedEvents.containsKey(method.getParameterTypes()[0])) { - cachedEvents.put(method.getParameterTypes()[0], new ArrayList<>()); - } - cachedEvents.get(method.getParameterTypes()[0]).add(new EventMethodEntry(method, instance, hypixelEvent)); + EventMethodEntry entry = eventMethodEntry(instance, method); + if (entry != null && !cachedEvents.contains(entry)) { + cachedEvents.add(entry); } } } public static void register(GlobalEventHandler eventHandler) { - cachedCustomEvents.forEach(skyBlockEvent -> { - try { - Class eventType = (Class) skyBlockEvent.method.getParameterTypes()[0]; - customEventNode.addListener(eventType, (event) -> { - try { - skyBlockEvent.method.invoke(skyBlockEvent.instance, event); - } catch (IllegalAccessException | InvocationTargetException e) { - throw new RuntimeException(e); - } - }); - } catch (Exception e) { - Logger.error(e, "Error occurred while registering custom event: {}", skyBlockEvent.getClass().getSimpleName()); - } - }); - - eventHandler.addChild(customEventNode); - - Map, List> eventNodes = new HashMap<>(); - cachedEvents.forEach((eventTypeUncasted, methodPair) -> { - Class eventType = (Class) eventTypeUncasted; - - methodPair.forEach(eventMethod -> { - EventNodes paramNode = eventMethod.hypixelEvent().node(); - - ((EventNode) paramNode.eventNode).addListener(eventType, rawEvent -> { - Event concreteEvent = eventType.cast(rawEvent); - - if (concreteEvent instanceof PlayerEvent event - && eventMethod.hypixelEvent().requireDataLoaded() - && (HypixelDataHandler.getUser(event.getPlayer()) == null - || (HypixelConst.isIslandServer() && - !((HypixelPlayer) event.getPlayer()).isReadyForEvents()))) { - Scheduler scheduler = MinecraftServer.getSchedulerManager(); - - scheduler.submitTask(() -> { - Player player = event.getPlayer(); - if (!player.isOnline()) return TaskSchedule.stop(); - if (HypixelDataHandler.getUser(player) == null) return TaskSchedule.millis(2); - if (HypixelConst.isIslandServer() && - !((HypixelPlayer) player).isReadyForEvents()) return TaskSchedule.millis(2); - - runEvent(eventMethod.hypixelEvent(), eventMethod.method, eventMethod.instance, concreteEvent); - return TaskSchedule.stop(); - }); - } else { - // Now run the event with the properly cast type - try { - runEvent(eventMethod.hypixelEvent(), eventMethod.method, eventMethod.instance, concreteEvent); - } catch (Exception ex) { - Logger.error(ex, "Exception occurred while running event {} with event type {}", - eventMethod.method.getClass().getSimpleName(), - concreteEvent.getClass().getSimpleName()); - } - } - }); - - if (eventNodes.containsKey(paramNode.eventNode)) { - eventNodes.get(paramNode.eventNode).add(eventMethod); - } else { - eventNodes.put(paramNode.eventNode, new ArrayList<>()); - eventNodes.get(paramNode.eventNode).add(eventMethod); - } - }); - }); + if (registered) return; - for (EventNode paramNode : eventNodes.keySet()) { - eventHandler.addChild(paramNode); + for (EventPhase phase : EventPhase.values()) { + rootNode.addChild(phase.node()); } + + cachedEvents.stream() + .sorted((first, second) -> { + int phaseCompare = Integer.compare(first.phase().priority(), second.phase().priority()); + if (phaseCompare != 0) return phaseCompare; + return Integer.compare(first.order(), second.order()); + }) + .forEach(HypixelEventHandler::registerEntry); + + eventHandler.addChild(rootNode); + registered = true; } @SneakyThrows - private static void runEvent(HypixelEvent event, Method method, Object eventClassInstance, Event concreteEvent) { + private static void runEvent(EventMethodEntry entry, Event concreteEvent) { PlayerHookManager hookManager = null; if (concreteEvent instanceof PlayerEvent) @@ -138,40 +77,101 @@ private static void runEvent(HypixelEvent event, Method method, Object eventClas if (hookManager != null) hookManager.callAndClearHooks( - eventClassInstance.getClass(), true); + entry.instance().getClass(), true); - if (event.isAsync()) { + if (entry.isAsync()) { PlayerHookManager finalHookManager = hookManager; Thread.startVirtualThread(() -> { try { - method.invoke(eventClassInstance, concreteEvent); + entry.method().invoke(entry.instance(), concreteEvent); } catch (IllegalAccessException | InvocationTargetException e) { throw new RuntimeException(e); } if (finalHookManager != null) finalHookManager.callAndClearHooks( - eventClassInstance.getClass(), false); + entry.instance().getClass(), false); }); } else { - method.invoke(eventClassInstance, concreteEvent); + entry.method().invoke(entry.instance(), concreteEvent); if (hookManager != null) hookManager.callAndClearHooks( - eventClassInstance.getClass(), false); + entry.instance().getClass(), false); } } public static void callCustomEvent(Event event) { - if (customEventNode != null) { - if (event instanceof PlayerEvent playerEvent) { - if (HypixelDataHandler.getUser(playerEvent.getPlayer()) == null) { - Logger.warn("Tried to call custom event {} for player {} but their data is not loaded.", - event.getClass().getSimpleName(), - playerEvent.getPlayer().getUsername()); - return; - } + if (event instanceof PlayerEvent playerEvent) { + if (HypixelDataHandler.getUser(playerEvent.getPlayer()) == null) { + Logger.warn("Tried to call custom event {} for player {} but their data is not loaded.", + event.getClass().getSimpleName(), + playerEvent.getPlayer().getUsername()); + return; } - customEventNode.call(event); + } + rootNode.call(event); + } + + private static EventMethodEntry eventMethodEntry(Object instance, Method method) { + if (method.isAnnotationPresent(PhasedEvent.class)) { + PhasedEvent phasedEvent = method.getAnnotation(PhasedEvent.class); + return new EventMethodEntry( + method, + instance, + phasedEvent.node(), + phasedEvent.phase(), + phasedEvent.order(), + phasedEvent.requireDataLoaded(), + phasedEvent.isAsync()); + } + + return null; + } + + @SuppressWarnings("unchecked") + private static void registerEntry(EventMethodEntry entry) { + try { + Class eventType = (Class) entry.method().getParameterTypes()[0]; + EventNode listenerNode = (EventNode) entry.node().newNode( + entry.phase().name().toLowerCase() + "-" + entry.instance().getClass().getName().replace('.', '-') + "-" + entry.method().getName(), + entry.order()); + + listenerNode.addListener(eventType, rawEvent -> { + Event concreteEvent = eventType.cast(rawEvent); + runOrWaitForData(entry, concreteEvent); + }); + + entry.phase().node().addChild(listenerNode); + } catch (Exception e) { + Logger.error(e, "Error occurred while registering event: {}", entry.instance().getClass().getSimpleName()); + } + } + + private static void runOrWaitForData(EventMethodEntry entry, Event concreteEvent) { + if (concreteEvent instanceof PlayerEvent event + && entry.requireDataLoaded() + && (HypixelDataHandler.getUser(event.getPlayer()) == null + || (HypixelConst.isIslandServer() && !((HypixelPlayer) event.getPlayer()).isReadyForEvents()))) { + Scheduler scheduler = MinecraftServer.getSchedulerManager(); + + scheduler.submitTask(() -> { + Player player = event.getPlayer(); + if (!player.isOnline()) return TaskSchedule.stop(); + if (HypixelDataHandler.getUser(player) == null) return TaskSchedule.millis(2); + if (HypixelConst.isIslandServer() && !((HypixelPlayer) player).isReadyForEvents()) return TaskSchedule.millis(2); + + runEvent(entry, concreteEvent); + return TaskSchedule.stop(); + }); + return; + } + + try { + runEvent(entry, concreteEvent); + } catch (Exception ex) { + Logger.error(ex, "Exception occurred while running event {} with event type {}", + entry.method().getClass().getSimpleName(), + concreteEvent.getClass().getSimpleName()); } } } diff --git a/type.generic/src/main/java/net/swofty/type/generic/event/actions/ActionPlayerClickedInteractionEntity.java b/type.generic/src/main/java/net/swofty/type/generic/event/actions/ActionPlayerClickedInteractionEntity.java index 81be34bed..73922fd49 100644 --- a/type.generic/src/main/java/net/swofty/type/generic/event/actions/ActionPlayerClickedInteractionEntity.java +++ b/type.generic/src/main/java/net/swofty/type/generic/event/actions/ActionPlayerClickedInteractionEntity.java @@ -4,13 +4,14 @@ import net.minestom.server.event.player.PlayerEntityInteractEvent; import net.swofty.type.generic.entity.InteractionEntity; import net.swofty.type.generic.event.EventNodes; -import net.swofty.type.generic.event.HypixelEvent; import net.swofty.type.generic.event.HypixelEventClass; +import net.swofty.type.generic.event.phase.EventPhase; +import net.swofty.type.generic.event.phase.PhasedEvent; import net.swofty.type.generic.user.HypixelPlayer; public class ActionPlayerClickedInteractionEntity implements HypixelEventClass { - @HypixelEvent(node = EventNodes.PLAYER, requireDataLoaded = true) + @PhasedEvent(node = EventNodes.PLAYER, requireDataLoaded = true, phase = EventPhase.GAMEPLAY) public void run(PlayerEntityInteractEvent event) { final HypixelPlayer player = (HypixelPlayer) event.getPlayer(); if (event.getHand() != PlayerHand.MAIN) return; diff --git a/type.generic/src/main/java/net/swofty/type/generic/event/actions/ActionPlayerMute.java b/type.generic/src/main/java/net/swofty/type/generic/event/actions/ActionPlayerMute.java index b23220cb7..4c48bd8fd 100644 --- a/type.generic/src/main/java/net/swofty/type/generic/event/actions/ActionPlayerMute.java +++ b/type.generic/src/main/java/net/swofty/type/generic/event/actions/ActionPlayerMute.java @@ -11,15 +11,16 @@ import net.swofty.commons.punishment.PunishmentType; import net.swofty.proxyapi.ProxyService; import net.swofty.type.generic.event.EventNodes; -import net.swofty.type.generic.event.HypixelEvent; import net.swofty.type.generic.event.HypixelEventClass; +import net.swofty.type.generic.event.phase.EventPhase; +import net.swofty.type.generic.event.phase.PhasedEvent; import java.util.List; import java.util.concurrent.TimeUnit; public class ActionPlayerMute implements HypixelEventClass { - @HypixelEvent(node = EventNodes.PLAYER, requireDataLoaded = false) + @PhasedEvent(node = EventNodes.PLAYER, requireDataLoaded = false, phase = EventPhase.GAMEPLAY) public void onPlayerChat(PlayerChatEvent event) { Player player = event.getPlayer(); try { diff --git a/type.generic/src/main/java/net/swofty/type/generic/event/actions/data/ActionPlayerClearCache.java b/type.generic/src/main/java/net/swofty/type/generic/event/actions/data/ActionPlayerClearCache.java index e1b843122..3ee7f17fe 100644 --- a/type.generic/src/main/java/net/swofty/type/generic/event/actions/data/ActionPlayerClearCache.java +++ b/type.generic/src/main/java/net/swofty/type/generic/event/actions/data/ActionPlayerClearCache.java @@ -6,8 +6,9 @@ import net.swofty.type.generic.entity.hologram.PlayerHolograms; import net.swofty.type.generic.entity.npc.HypixelNPC; import net.swofty.type.generic.event.EventNodes; -import net.swofty.type.generic.event.HypixelEvent; import net.swofty.type.generic.event.HypixelEventClass; +import net.swofty.type.generic.event.phase.EventPhase; +import net.swofty.type.generic.event.phase.PhasedEvent; import net.swofty.type.generic.gui.HypixelAnvilGUI; import net.swofty.type.generic.gui.HypixelSignGUI; import net.swofty.type.generic.gui.inventory.HypixelInventoryGUI; @@ -17,7 +18,7 @@ public class ActionPlayerClearCache implements HypixelEventClass { @SneakyThrows - @HypixelEvent(node = EventNodes.PLAYER, requireDataLoaded = false) + @PhasedEvent(node = EventNodes.PLAYER, requireDataLoaded = false, phase = EventPhase.DISCONNECT) public void run(PlayerDisconnectEvent event) { final HypixelPlayer player = (HypixelPlayer) event.getPlayer(); @@ -51,4 +52,4 @@ public void run(PlayerDisconnectEvent event) { return false; }); } -} \ No newline at end of file +} diff --git a/type.generic/src/main/java/net/swofty/type/generic/event/actions/data/ActionPlayerDataLoad.java b/type.generic/src/main/java/net/swofty/type/generic/event/actions/data/ActionPlayerDataLoad.java index e4e051ee3..fd4143479 100644 --- a/type.generic/src/main/java/net/swofty/type/generic/event/actions/data/ActionPlayerDataLoad.java +++ b/type.generic/src/main/java/net/swofty/type/generic/event/actions/data/ActionPlayerDataLoad.java @@ -2,79 +2,20 @@ import lombok.SneakyThrows; import net.minestom.server.event.player.AsyncPlayerConfigurationEvent; -import net.swofty.type.generic.HypixelConst; -import net.swofty.type.generic.data.DataHandler; -import net.swofty.type.generic.data.GameDataHandler; -import net.swofty.type.generic.data.GameDataHandlerRegistry; -import net.swofty.type.generic.data.HypixelDataHandler; -import net.swofty.type.generic.data.datapoints.DatapointLocale; -import net.swofty.type.generic.data.mongodb.UserDatabase; import net.swofty.type.generic.event.EventNodes; -import net.swofty.type.generic.event.HypixelEvent; import net.swofty.type.generic.event.HypixelEventClass; +import net.swofty.type.generic.event.phase.EventPhase; +import net.swofty.type.generic.event.phase.PhasedEvent; import net.swofty.type.generic.user.HypixelPlayer; -import org.bson.Document; -import org.tinylog.Logger; - -import java.util.List; -import java.util.Locale; -import java.util.UUID; +import net.swofty.type.generic.user.flow.GenericPlayerDataFlow; +import net.swofty.type.generic.user.flow.PlayerFlow; public class ActionPlayerDataLoad implements HypixelEventClass { @SneakyThrows - @HypixelEvent(node = EventNodes.PLAYER_DATA, requireDataLoaded = false) + @PhasedEvent(node = EventNodes.PLAYER_DATA, requireDataLoaded = false, phase = EventPhase.LOAD_DATA) public void run(AsyncPlayerConfigurationEvent event) { - Logger.info("Loading Hypixel account data for player: " + event.getPlayer().getUsername() + "..."); - - final HypixelPlayer player = (HypixelPlayer) event.getPlayer(); - UUID playerUuid = player.getUuid(); - - UserDatabase userDatabase = new UserDatabase(playerUuid); - HypixelDataHandler handler; - Document userDocument = null; - - if (userDatabase.exists()) { - userDocument = userDatabase.getHypixelData(); - handler = HypixelDataHandler.createFromDocument(userDocument); - HypixelDataHandler.userCache.put(playerUuid, handler); - } else { - handler = HypixelDataHandler.initUserWithDefaultData(playerUuid); - HypixelDataHandler.userCache.put(playerUuid, handler); - userDatabase.saveData(handler); - } - - Locale loc = handler.get(HypixelDataHandler.Data.LOCALE, DatapointLocale.class).getValue().getCurrentLocale().getLocale(); - player.setLocale(loc); - - // Load additional game handlers based on TypeLoader configuration - List> additionalHandlers = - HypixelConst.getTypeLoader().getAdditionalDataHandlers(); - - for (Class handlerClass : additionalHandlers) { - GameDataHandler gameHandler = GameDataHandlerRegistry.get(handlerClass); - if (gameHandler == null) { - Logger.warn("GameDataHandler not registered: " + handlerClass.getSimpleName()); - continue; - } - - Logger.info("Loading " + gameHandler.getHandlerId() + " data for: " + player.getUsername()); - - DataHandler gameDataHandler; - if (userDocument != null && gameHandler.hasDataInDocument(userDocument)) { - gameDataHandler = gameHandler.createFromDocument(playerUuid, userDocument); - } else { - gameDataHandler = gameHandler.initWithDefaults(playerUuid); - } - - gameHandler.cacheHandler(playerUuid, gameDataHandler); - - // Save if this is new data - if (userDocument == null || !gameHandler.hasDataInDocument(userDocument)) { - userDatabase.saveData(gameDataHandler); - } - } - - Logger.info("Successfully loaded all data for player: " + player.getUsername()); + HypixelPlayer player = (HypixelPlayer) event.getPlayer(); + PlayerFlow.run(player, "generic-data/load", () -> GenericPlayerDataFlow.load(player)); } -} \ No newline at end of file +} diff --git a/type.generic/src/main/java/net/swofty/type/generic/event/actions/data/ActionPlayerDataSave.java b/type.generic/src/main/java/net/swofty/type/generic/event/actions/data/ActionPlayerDataSave.java index d67a5f71f..9491d2cf9 100644 --- a/type.generic/src/main/java/net/swofty/type/generic/event/actions/data/ActionPlayerDataSave.java +++ b/type.generic/src/main/java/net/swofty/type/generic/event/actions/data/ActionPlayerDataSave.java @@ -2,120 +2,19 @@ import lombok.SneakyThrows; import net.minestom.server.event.player.PlayerDisconnectEvent; -import net.swofty.commons.protocol.objects.proxy.to.FinishedWithPlayerProtocol; -import net.swofty.proxyapi.redis.ServerOutboundMessage; -import net.swofty.type.generic.HypixelConst; -import net.swofty.type.generic.data.DataHandler; -import net.swofty.type.generic.data.Datapoint; -import net.swofty.type.generic.data.GameDataHandler; -import net.swofty.type.generic.data.GameDataHandlerRegistry; -import net.swofty.type.generic.data.HypixelDataHandler; -import net.swofty.type.generic.data.mongodb.UserDatabase; import net.swofty.type.generic.event.EventNodes; -import net.swofty.type.generic.event.HypixelEvent; import net.swofty.type.generic.event.HypixelEventClass; -import net.swofty.type.generic.leaderboard.LeaderboardService; -import net.swofty.type.generic.leaderboard.LeaderboardTracked; -import net.swofty.type.generic.leaderboard.MapLeaderboardTracked; -import net.swofty.type.generic.resourcepack.ResourcePackManager; +import net.swofty.type.generic.event.phase.EventPhase; +import net.swofty.type.generic.event.phase.PhasedEvent; import net.swofty.type.generic.user.HypixelPlayer; -import net.swofty.type.generic.utility.MathUtility; -import org.tinylog.Logger; - -import java.util.List; -import java.util.Map; -import java.util.UUID; +import net.swofty.type.generic.user.flow.GenericPlayerDataFlow; +import net.swofty.type.generic.user.flow.PlayerFlow; public class ActionPlayerDataSave implements HypixelEventClass { @SneakyThrows - @HypixelEvent(node = EventNodes.PLAYER, requireDataLoaded = false, isAsync = true) + @PhasedEvent(node = EventNodes.PLAYER, requireDataLoaded = false, isAsync = true, phase = EventPhase.PERSIST) public void run(PlayerDisconnectEvent event) { - final HypixelPlayer player = (HypixelPlayer) event.getPlayer(); - UUID uuid = player.getUuid(); - - ResourcePackManager packManager = HypixelConst.getResourcePackManager(); - if (packManager != null) { - packManager.getActivePack().onPlayerQuit(player); - } - - Logger.info("Saving Hypixel account data for: " + player.getUsername() + "..."); - - HypixelDataHandler handler = player.getDataHandler(); - - // Run onSave callbacks for basic Hypixel functionality - handler.runOnSave(player); - - // Save Hypixel data to UserDatabase (account-wide data) - UserDatabase userDatabase = new UserDatabase(uuid); - userDatabase.saveData(handler); - - // Sync all leaderboard-tracked datapoints for Hypixel data - syncLeaderboards(uuid, handler); - - // Remove from cache - HypixelDataHandler.userCache.remove(uuid); - - // Save additional game handlers - List> additionalHandlers = - HypixelConst.getTypeLoader().getAdditionalDataHandlers(); - - for (Class handlerClass : additionalHandlers) { - GameDataHandler gameHandler = GameDataHandlerRegistry.get(handlerClass); - if (gameHandler == null) continue; - - DataHandler gameDataHandler = gameHandler.getHandler(uuid); - if (gameDataHandler == null) continue; - - Logger.info("Saving " + gameHandler.getHandlerId() + " data for: " + player.getUsername()); - - gameDataHandler.runOnSave(player); - userDatabase.saveData(gameDataHandler); - - // Sync leaderboards for this game handler - syncLeaderboards(uuid, gameDataHandler); - - gameHandler.removeFromCache(uuid); - } - - ServerOutboundMessage.sendToProxy(new FinishedWithPlayerProtocol(), - new FinishedWithPlayerProtocol.Request(uuid.toString()), - response -> {}); - - // Clean up tablist entries - MathUtility.delay(() -> { - HypixelConst.getTypeLoader().getTablistManager().deleteTablistEntries(player); - }, 5); - - Logger.info("Successfully saved all data for: " + player.getUsername()); - } - - /** - * Syncs all leaderboard-tracked datapoints in a handler to Redis. - * This ensures the final values are persisted to leaderboards on disconnect. - */ - private void syncLeaderboards(UUID uuid, DataHandler handler) { - if (!LeaderboardService.isInitialized()) return; - - for (Datapoint dp : handler.getDatapoints().values()) { - // Simple leaderboard (single value like XP, coins) - if (dp instanceof LeaderboardTracked tracked) { - String key = tracked.getLeaderboardKey(); - if (key != null) { - LeaderboardService.updateScore(key, uuid, tracked.getLeaderboardScore()); - } - } - - // Map-based leaderboard (collections, skills) - if (dp instanceof MapLeaderboardTracked mapTracked) { - Map scores = mapTracked.getAllLeaderboardScores(); - for (Map.Entry entry : scores.entrySet()) { - LeaderboardService.updateScore( - mapTracked.getLeaderboardKeyFor(entry.getKey()), - uuid, - entry.getValue() - ); - } - } - } + HypixelPlayer player = (HypixelPlayer) event.getPlayer(); + PlayerFlow.run(player, "generic-data/save", () -> GenericPlayerDataFlow.save(player)); } -} \ No newline at end of file +} diff --git a/type.generic/src/main/java/net/swofty/type/generic/event/actions/data/ActionPlayerDataSpawn.java b/type.generic/src/main/java/net/swofty/type/generic/event/actions/data/ActionPlayerDataSpawn.java index 983647724..867cf68a0 100644 --- a/type.generic/src/main/java/net/swofty/type/generic/event/actions/data/ActionPlayerDataSpawn.java +++ b/type.generic/src/main/java/net/swofty/type/generic/event/actions/data/ActionPlayerDataSpawn.java @@ -1,52 +1,21 @@ package net.swofty.type.generic.event.actions.data; import net.minestom.server.event.player.PlayerSpawnEvent; -import net.swofty.type.generic.HypixelConst; -import net.swofty.type.generic.data.GameDataHandler; -import net.swofty.type.generic.data.GameDataHandlerRegistry; -import net.swofty.type.generic.data.HypixelDataHandler; -import net.swofty.type.generic.entity.hologram.PlayerHolograms; -import net.swofty.type.generic.entity.npc.HypixelNPC; -import net.swofty.type.generic.resourcepack.ResourcePackManager; import net.swofty.type.generic.event.EventNodes; -import net.swofty.type.generic.event.HypixelEvent; import net.swofty.type.generic.event.HypixelEventClass; +import net.swofty.type.generic.event.phase.EventPhase; +import net.swofty.type.generic.event.phase.PhasedEvent; import net.swofty.type.generic.user.HypixelPlayer; - -import java.util.List; -import java.util.UUID; +import net.swofty.type.generic.user.flow.GenericPlayerDataFlow; +import net.swofty.type.generic.user.flow.PlayerFlow; public class ActionPlayerDataSpawn implements HypixelEventClass { - @HypixelEvent(node = EventNodes.PLAYER_DATA, requireDataLoaded = false, isAsync = true) + @PhasedEvent(node = EventNodes.PLAYER_DATA, requireDataLoaded = false, isAsync = true, phase = EventPhase.POST_SPAWN) public void run(PlayerSpawnEvent event) { if (!event.isFirstSpawn()) return; - final HypixelPlayer player = (HypixelPlayer) event.getPlayer(); - UUID uuid = player.getUuid(); - - HypixelDataHandler handler = player.getDataHandler(); - handler.runOnLoad(player); - - // Run onLoad for additional game handlers - List> additionalHandlers = - HypixelConst.getTypeLoader().getAdditionalDataHandlers(); - - for (Class handlerClass : additionalHandlers) { - GameDataHandler gameHandler = GameDataHandlerRegistry.get(handlerClass); - if (gameHandler != null) { - gameHandler.runOnLoad(uuid, player); - } - } - - ResourcePackManager packManager = HypixelConst.getResourcePackManager(); - if (packManager != null) { - packManager.sendPack(player); - packManager.getActivePack().onPlayerJoin(player); - } - - HypixelNPC.updateForPlayer(player); - if (HypixelConst.isIslandServer()) return; - PlayerHolograms.spawnAll(player); + HypixelPlayer player = (HypixelPlayer) event.getPlayer(); + PlayerFlow.run(player, "generic-data/post-spawn", () -> GenericPlayerDataFlow.postSpawn(player)); } -} \ No newline at end of file +} diff --git a/type.generic/src/main/java/net/swofty/type/generic/event/actions/gui/ActionPlayerInventoryClick.java b/type.generic/src/main/java/net/swofty/type/generic/event/actions/gui/ActionPlayerInventoryClick.java index 89af1717e..6b42aa29e 100644 --- a/type.generic/src/main/java/net/swofty/type/generic/event/actions/gui/ActionPlayerInventoryClick.java +++ b/type.generic/src/main/java/net/swofty/type/generic/event/actions/gui/ActionPlayerInventoryClick.java @@ -10,8 +10,9 @@ import net.minestom.server.item.Material; import net.swofty.commons.StringUtility; import net.swofty.type.generic.event.EventNodes; -import net.swofty.type.generic.event.HypixelEvent; import net.swofty.type.generic.event.HypixelEventClass; +import net.swofty.type.generic.event.phase.EventPhase; +import net.swofty.type.generic.event.phase.PhasedEvent; import net.swofty.type.generic.gui.HypixelSignGUI; import net.swofty.type.generic.gui.inventory.HypixelInventoryGUI; import net.swofty.type.generic.gui.inventory.item.GUIClickableItem; @@ -21,7 +22,7 @@ public class ActionPlayerInventoryClick implements HypixelEventClass { - @HypixelEvent(node = EventNodes.PLAYER, requireDataLoaded = false) + @PhasedEvent(node = EventNodes.PLAYER, requireDataLoaded = false, phase = EventPhase.GAMEPLAY) public void run(InventoryPreClickEvent event) { final HypixelPlayer player = (HypixelPlayer) event.getPlayer(); try { diff --git a/type.generic/src/main/java/net/swofty/type/generic/event/actions/gui/ActionPlayerInventoryClickAnvil.java b/type.generic/src/main/java/net/swofty/type/generic/event/actions/gui/ActionPlayerInventoryClickAnvil.java index 4a4fdb346..42ae59f3f 100644 --- a/type.generic/src/main/java/net/swofty/type/generic/event/actions/gui/ActionPlayerInventoryClickAnvil.java +++ b/type.generic/src/main/java/net/swofty/type/generic/event/actions/gui/ActionPlayerInventoryClickAnvil.java @@ -6,14 +6,15 @@ import net.minestom.server.network.packet.server.play.WindowPropertyPacket; import net.minestom.server.timer.TaskSchedule; import net.swofty.type.generic.event.EventNodes; -import net.swofty.type.generic.event.HypixelEvent; import net.swofty.type.generic.event.HypixelEventClass; +import net.swofty.type.generic.event.phase.EventPhase; +import net.swofty.type.generic.event.phase.PhasedEvent; import net.swofty.type.generic.gui.HypixelAnvilGUI; import net.swofty.type.generic.user.HypixelPlayer; public class ActionPlayerInventoryClickAnvil implements HypixelEventClass { - @HypixelEvent(node = EventNodes.PLAYER, requireDataLoaded = true) + @PhasedEvent(node = EventNodes.PLAYER, requireDataLoaded = true, phase = EventPhase.GAMEPLAY) public void run(InventoryPreClickEvent event) { final HypixelPlayer player = (HypixelPlayer) event.getPlayer(); diff --git a/type.generic/src/main/java/net/swofty/type/generic/event/actions/gui/ActionPlayerInventoryClose.java b/type.generic/src/main/java/net/swofty/type/generic/event/actions/gui/ActionPlayerInventoryClose.java index bad7de827..780cec211 100644 --- a/type.generic/src/main/java/net/swofty/type/generic/event/actions/gui/ActionPlayerInventoryClose.java +++ b/type.generic/src/main/java/net/swofty/type/generic/event/actions/gui/ActionPlayerInventoryClose.java @@ -2,14 +2,15 @@ import net.minestom.server.event.inventory.InventoryCloseEvent; import net.swofty.type.generic.event.EventNodes; -import net.swofty.type.generic.event.HypixelEvent; import net.swofty.type.generic.event.HypixelEventClass; +import net.swofty.type.generic.event.phase.EventPhase; +import net.swofty.type.generic.event.phase.PhasedEvent; import net.swofty.type.generic.gui.inventory.HypixelInventoryGUI; import net.swofty.type.generic.user.HypixelPlayer; public class ActionPlayerInventoryClose implements HypixelEventClass { - @HypixelEvent(node = EventNodes.PLAYER, requireDataLoaded = true) + @PhasedEvent(node = EventNodes.PLAYER, requireDataLoaded = true, phase = EventPhase.GAMEPLAY) public void run(InventoryCloseEvent event) { final HypixelPlayer player = (HypixelPlayer) event.getPlayer(); diff --git a/type.generic/src/main/java/net/swofty/type/generic/event/actions/gui/ActionPlayerInventoryCloseAnvil.java b/type.generic/src/main/java/net/swofty/type/generic/event/actions/gui/ActionPlayerInventoryCloseAnvil.java index 0309f31f6..1944f560d 100644 --- a/type.generic/src/main/java/net/swofty/type/generic/event/actions/gui/ActionPlayerInventoryCloseAnvil.java +++ b/type.generic/src/main/java/net/swofty/type/generic/event/actions/gui/ActionPlayerInventoryCloseAnvil.java @@ -3,14 +3,15 @@ import net.minestom.server.event.inventory.InventoryCloseEvent; import net.minestom.server.inventory.type.AnvilInventory; import net.swofty.type.generic.event.EventNodes; -import net.swofty.type.generic.event.HypixelEvent; import net.swofty.type.generic.event.HypixelEventClass; +import net.swofty.type.generic.event.phase.EventPhase; +import net.swofty.type.generic.event.phase.PhasedEvent; import net.swofty.type.generic.gui.HypixelAnvilGUI; import net.swofty.type.generic.user.HypixelPlayer; public class ActionPlayerInventoryCloseAnvil implements HypixelEventClass { - @HypixelEvent(node = EventNodes.PLAYER, requireDataLoaded = true) + @PhasedEvent(node = EventNodes.PLAYER, requireDataLoaded = true, phase = EventPhase.GAMEPLAY) public void run(InventoryCloseEvent event) { final HypixelPlayer player = (HypixelPlayer) event.getPlayer(); diff --git a/type.generic/src/main/java/net/swofty/type/generic/event/actions/gui/ActionPlayerInventoryPostClick.java b/type.generic/src/main/java/net/swofty/type/generic/event/actions/gui/ActionPlayerInventoryPostClick.java index 9e06119e7..775c9bb20 100644 --- a/type.generic/src/main/java/net/swofty/type/generic/event/actions/gui/ActionPlayerInventoryPostClick.java +++ b/type.generic/src/main/java/net/swofty/type/generic/event/actions/gui/ActionPlayerInventoryPostClick.java @@ -2,8 +2,9 @@ import net.minestom.server.event.inventory.InventoryClickEvent; import net.swofty.type.generic.event.EventNodes; -import net.swofty.type.generic.event.HypixelEvent; import net.swofty.type.generic.event.HypixelEventClass; +import net.swofty.type.generic.event.phase.EventPhase; +import net.swofty.type.generic.event.phase.PhasedEvent; import net.swofty.type.generic.gui.inventory.HypixelInventoryGUI; import net.swofty.type.generic.gui.inventory.item.GUIClickableItem; import net.swofty.type.generic.gui.inventory.item.GUIItem; @@ -11,7 +12,7 @@ public class ActionPlayerInventoryPostClick implements HypixelEventClass { - @HypixelEvent(node = EventNodes.PLAYER, requireDataLoaded = true) + @PhasedEvent(node = EventNodes.PLAYER, requireDataLoaded = true, phase = EventPhase.GAMEPLAY) public void run(InventoryClickEvent event) { final HypixelPlayer player = (HypixelPlayer) event.getPlayer(); diff --git a/type.generic/src/main/java/net/swofty/type/generic/event/actions/npc/ActionPlayerClickedNPC.java b/type.generic/src/main/java/net/swofty/type/generic/event/actions/npc/ActionPlayerClickedNPC.java index d01deab86..6cda53860 100644 --- a/type.generic/src/main/java/net/swofty/type/generic/event/actions/npc/ActionPlayerClickedNPC.java +++ b/type.generic/src/main/java/net/swofty/type/generic/event/actions/npc/ActionPlayerClickedNPC.java @@ -8,8 +8,9 @@ import net.swofty.type.generic.entity.npc.impl.NPCEntityImpl; import net.swofty.type.generic.entity.npc.impl.NPCVillagerEntityImpl; import net.swofty.type.generic.event.EventNodes; -import net.swofty.type.generic.event.HypixelEvent; import net.swofty.type.generic.event.HypixelEventClass; +import net.swofty.type.generic.event.phase.EventPhase; +import net.swofty.type.generic.event.phase.PhasedEvent; import net.swofty.type.generic.event.HypixelEventHandler; import net.swofty.type.generic.event.custom.NPCInteractEvent; import net.swofty.type.generic.user.HypixelPlayer; @@ -17,7 +18,7 @@ public class ActionPlayerClickedNPC implements HypixelEventClass { - @HypixelEvent(node = EventNodes.PLAYER, requireDataLoaded = true) + @PhasedEvent(node = EventNodes.PLAYER, requireDataLoaded = true, phase = EventPhase.GAMEPLAY) public void run(PlayerEntityInteractEvent event) { final HypixelPlayer player = (HypixelPlayer) event.getPlayer(); diff --git a/type.generic/src/main/java/net/swofty/type/generic/event/actions/party/ActionPlayerRejoinParty.java b/type.generic/src/main/java/net/swofty/type/generic/event/actions/party/ActionPlayerRejoinParty.java index 9dfce91c7..a474a94b8 100644 --- a/type.generic/src/main/java/net/swofty/type/generic/event/actions/party/ActionPlayerRejoinParty.java +++ b/type.generic/src/main/java/net/swofty/type/generic/event/actions/party/ActionPlayerRejoinParty.java @@ -5,15 +5,16 @@ import net.swofty.commons.ServiceType; import net.swofty.proxyapi.ProxyService; import net.swofty.type.generic.event.EventNodes; -import net.swofty.type.generic.event.HypixelEvent; import net.swofty.type.generic.event.HypixelEventClass; +import net.swofty.type.generic.event.phase.EventPhase; +import net.swofty.type.generic.event.phase.PhasedEvent; import net.swofty.type.generic.party.PartyManager; import net.swofty.type.generic.user.HypixelPlayer; public class ActionPlayerRejoinParty implements HypixelEventClass { @SneakyThrows - @HypixelEvent(node = EventNodes.PLAYER_DATA, requireDataLoaded = false, isAsync = true) + @PhasedEvent(node = EventNodes.PLAYER_DATA, requireDataLoaded = false, isAsync = true, phase = EventPhase.GAMEPLAY) public void run(AsyncPlayerConfigurationEvent event) { final HypixelPlayer player = (HypixelPlayer) event.getPlayer(); diff --git a/type.generic/src/main/java/net/swofty/type/generic/event/phase/EventPhase.java b/type.generic/src/main/java/net/swofty/type/generic/event/phase/EventPhase.java new file mode 100644 index 000000000..326ea4311 --- /dev/null +++ b/type.generic/src/main/java/net/swofty/type/generic/event/phase/EventPhase.java @@ -0,0 +1,31 @@ +package net.swofty.type.generic.event.phase; + +import net.minestom.server.event.Event; +import net.minestom.server.event.EventNode; + +public enum EventPhase { + CONNECT(10), + LOAD_DATA(20), + POST_DATA(30), + SPAWN(40), + POST_SPAWN(50), + GAMEPLAY(60), + PERSIST(80), + DISCONNECT(90); + + private final int priority; + private final EventNode node; + + EventPhase(int priority) { + this.priority = priority; + this.node = EventNode.all("phase-" + name().toLowerCase()).setPriority(priority); + } + + public int priority() { + return priority; + } + + public EventNode node() { + return node; + } +} diff --git a/type.generic/src/main/java/net/swofty/type/generic/event/HypixelEvent.java b/type.generic/src/main/java/net/swofty/type/generic/event/phase/PhasedEvent.java similarity index 52% rename from type.generic/src/main/java/net/swofty/type/generic/event/HypixelEvent.java rename to type.generic/src/main/java/net/swofty/type/generic/event/phase/PhasedEvent.java index 1a8c0576e..84bea0b9b 100644 --- a/type.generic/src/main/java/net/swofty/type/generic/event/HypixelEvent.java +++ b/type.generic/src/main/java/net/swofty/type/generic/event/phase/PhasedEvent.java @@ -1,4 +1,6 @@ -package net.swofty.type.generic.event; +package net.swofty.type.generic.event.phase; + +import net.swofty.type.generic.event.EventNodes; import java.lang.annotation.ElementType; import java.lang.annotation.Retention; @@ -7,8 +9,10 @@ @Retention(RetentionPolicy.RUNTIME) @Target(ElementType.METHOD) -public @interface HypixelEvent { +public @interface PhasedEvent { EventNodes node(); - boolean requireDataLoaded(); + EventPhase phase() default EventPhase.GAMEPLAY; + int order() default 0; + boolean requireDataLoaded() default false; boolean isAsync() default false; -} \ No newline at end of file +} diff --git a/type.generic/src/main/java/net/swofty/type/generic/gui/v2/event/ActionInventoryClose.java b/type.generic/src/main/java/net/swofty/type/generic/gui/v2/event/ActionInventoryClose.java index 183940c26..6cfd003bf 100644 --- a/type.generic/src/main/java/net/swofty/type/generic/gui/v2/event/ActionInventoryClose.java +++ b/type.generic/src/main/java/net/swofty/type/generic/gui/v2/event/ActionInventoryClose.java @@ -2,15 +2,16 @@ import net.minestom.server.event.inventory.InventoryCloseEvent; import net.swofty.type.generic.event.EventNodes; -import net.swofty.type.generic.event.HypixelEvent; import net.swofty.type.generic.event.HypixelEventClass; +import net.swofty.type.generic.event.phase.EventPhase; +import net.swofty.type.generic.event.phase.PhasedEvent; import net.swofty.type.generic.gui.v2.ViewNavigator; import net.swofty.type.generic.gui.v2.ViewSession; import net.swofty.type.generic.user.HypixelPlayer; public class ActionInventoryClose implements HypixelEventClass { - @HypixelEvent(node = EventNodes.INVENTORY, requireDataLoaded = false) + @PhasedEvent(node = EventNodes.INVENTORY, requireDataLoaded = false, phase = EventPhase.GAMEPLAY) public void onPlayerInventoryClose(InventoryCloseEvent event) { HypixelPlayer player = (HypixelPlayer) event.getPlayer(); ViewNavigator.find(player).ifPresent(navigator -> { @@ -26,4 +27,4 @@ public void onPlayerInventoryClose(InventoryCloseEvent event) { }); } -} \ No newline at end of file +} diff --git a/type.generic/src/main/java/net/swofty/type/generic/gui/v2/event/ActionInventoryOpen.java b/type.generic/src/main/java/net/swofty/type/generic/gui/v2/event/ActionInventoryOpen.java index de70b4c71..185c6e621 100644 --- a/type.generic/src/main/java/net/swofty/type/generic/gui/v2/event/ActionInventoryOpen.java +++ b/type.generic/src/main/java/net/swofty/type/generic/gui/v2/event/ActionInventoryOpen.java @@ -3,15 +3,16 @@ import net.minestom.server.MinecraftServer; import net.minestom.server.event.inventory.InventoryOpenEvent; import net.swofty.type.generic.event.EventNodes; -import net.swofty.type.generic.event.HypixelEvent; import net.swofty.type.generic.event.HypixelEventClass; +import net.swofty.type.generic.event.phase.EventPhase; +import net.swofty.type.generic.event.phase.PhasedEvent; import net.swofty.type.generic.gui.v2.ViewNavigator; import net.swofty.type.generic.user.HypixelPlayer; import org.tinylog.Logger; public class ActionInventoryOpen implements HypixelEventClass { - @HypixelEvent(node = EventNodes.INVENTORY, requireDataLoaded = false) + @PhasedEvent(node = EventNodes.INVENTORY, requireDataLoaded = false, phase = EventPhase.GAMEPLAY) public void onPlayerInventoryOpen(InventoryOpenEvent event) { MinecraftServer.getSchedulerManager().scheduleNextTick(() -> { HypixelPlayer player = (HypixelPlayer) event.getPlayer(); @@ -26,4 +27,4 @@ public void onPlayerInventoryOpen(InventoryOpenEvent event) { } -} \ No newline at end of file +} diff --git a/type.generic/src/main/java/net/swofty/type/generic/gui/v2/event/ActionInventoryPostClick.java b/type.generic/src/main/java/net/swofty/type/generic/gui/v2/event/ActionInventoryPostClick.java index 5d111577e..acf0083be 100644 --- a/type.generic/src/main/java/net/swofty/type/generic/gui/v2/event/ActionInventoryPostClick.java +++ b/type.generic/src/main/java/net/swofty/type/generic/gui/v2/event/ActionInventoryPostClick.java @@ -2,14 +2,15 @@ import net.minestom.server.event.inventory.InventoryClickEvent; import net.swofty.type.generic.event.EventNodes; -import net.swofty.type.generic.event.HypixelEvent; import net.swofty.type.generic.event.HypixelEventClass; +import net.swofty.type.generic.event.phase.EventPhase; +import net.swofty.type.generic.event.phase.PhasedEvent; import net.swofty.type.generic.gui.v2.ViewNavigator; import net.swofty.type.generic.user.HypixelPlayer; public class ActionInventoryPostClick implements HypixelEventClass { - @HypixelEvent(node = EventNodes.INVENTORY, requireDataLoaded = false) + @PhasedEvent(node = EventNodes.INVENTORY, requireDataLoaded = false, phase = EventPhase.GAMEPLAY) public void onInventoryPostClick(InventoryClickEvent event) { HypixelPlayer player = (HypixelPlayer) event.getPlayer(); ViewNavigator.find(player).ifPresent(navigator -> { @@ -20,4 +21,4 @@ public void onInventoryPostClick(InventoryClickEvent event) { }); } -} \ No newline at end of file +} diff --git a/type.generic/src/main/java/net/swofty/type/generic/gui/v2/event/ActionInventoryPreClick.java b/type.generic/src/main/java/net/swofty/type/generic/gui/v2/event/ActionInventoryPreClick.java index f5f2d5bd5..af1fc7bda 100644 --- a/type.generic/src/main/java/net/swofty/type/generic/gui/v2/event/ActionInventoryPreClick.java +++ b/type.generic/src/main/java/net/swofty/type/generic/gui/v2/event/ActionInventoryPreClick.java @@ -2,14 +2,15 @@ import net.minestom.server.event.inventory.InventoryPreClickEvent; import net.swofty.type.generic.event.EventNodes; -import net.swofty.type.generic.event.HypixelEvent; import net.swofty.type.generic.event.HypixelEventClass; +import net.swofty.type.generic.event.phase.EventPhase; +import net.swofty.type.generic.event.phase.PhasedEvent; import net.swofty.type.generic.gui.v2.ViewNavigator; import net.swofty.type.generic.user.HypixelPlayer; public class ActionInventoryPreClick implements HypixelEventClass { - @HypixelEvent(node = EventNodes.INVENTORY, requireDataLoaded = false) + @PhasedEvent(node = EventNodes.INVENTORY, requireDataLoaded = false, phase = EventPhase.GAMEPLAY) public void onActionPlayerInventoryPreClick(InventoryPreClickEvent event) { HypixelPlayer player = (HypixelPlayer) event.getPlayer(); ViewNavigator.find(player).ifPresent(navigator -> { @@ -20,4 +21,4 @@ public void onActionPlayerInventoryPreClick(InventoryPreClickEvent event) { }); } -} \ No newline at end of file +} diff --git a/type.generic/src/main/java/net/swofty/type/generic/user/flow/GenericPlayerDataFlow.java b/type.generic/src/main/java/net/swofty/type/generic/user/flow/GenericPlayerDataFlow.java new file mode 100644 index 000000000..24a740b32 --- /dev/null +++ b/type.generic/src/main/java/net/swofty/type/generic/user/flow/GenericPlayerDataFlow.java @@ -0,0 +1,170 @@ +package net.swofty.type.generic.user.flow; + +import net.swofty.commons.protocol.objects.proxy.to.FinishedWithPlayerProtocol; +import net.swofty.proxyapi.redis.ServerOutboundMessage; +import net.swofty.type.generic.HypixelConst; +import net.swofty.type.generic.data.DataHandler; +import net.swofty.type.generic.data.Datapoint; +import net.swofty.type.generic.data.GameDataHandler; +import net.swofty.type.generic.data.GameDataHandlerRegistry; +import net.swofty.type.generic.data.HypixelDataHandler; +import net.swofty.type.generic.data.datapoints.DatapointLocale; +import net.swofty.type.generic.data.mongodb.UserDatabase; +import net.swofty.type.generic.entity.hologram.PlayerHolograms; +import net.swofty.type.generic.entity.npc.HypixelNPC; +import net.swofty.type.generic.leaderboard.LeaderboardService; +import net.swofty.type.generic.leaderboard.LeaderboardTracked; +import net.swofty.type.generic.leaderboard.MapLeaderboardTracked; +import net.swofty.type.generic.resourcepack.ResourcePackManager; +import net.swofty.type.generic.user.HypixelPlayer; +import net.swofty.type.generic.utility.MathUtility; +import org.bson.Document; +import org.tinylog.Logger; + +import java.util.List; +import java.util.Locale; +import java.util.Map; +import java.util.UUID; + +public final class GenericPlayerDataFlow { + private GenericPlayerDataFlow() { + } + + public static void load(HypixelPlayer player) { + UUID playerUuid = player.getUuid(); + UserDatabase userDatabase = new UserDatabase(playerUuid); + HypixelDataHandler handler; + Document userDocument = null; + + if (userDatabase.exists()) { + userDocument = userDatabase.getHypixelData(); + handler = HypixelDataHandler.createFromDocument(userDocument); + } else { + handler = HypixelDataHandler.initUserWithDefaultData(playerUuid); + userDatabase.saveData(handler); + } + + HypixelDataHandler.userCache.put(playerUuid, handler); + + Locale locale = handler.get(HypixelDataHandler.Data.LOCALE, DatapointLocale.class) + .getValue() + .getCurrentLocale() + .getLocale(); + player.setLocale(locale); + + loadAdditionalHandlers(player, userDatabase, userDocument); + } + + public static void postSpawn(HypixelPlayer player) { + UUID uuid = player.getUuid(); + + player.getDataHandler().runOnLoad(player); + + for (Class handlerClass : HypixelConst.getTypeLoader().getAdditionalDataHandlers()) { + GameDataHandler gameHandler = GameDataHandlerRegistry.get(handlerClass); + if (gameHandler != null) { + gameHandler.runOnLoad(uuid, player); + } + } + + ResourcePackManager packManager = HypixelConst.getResourcePackManager(); + if (packManager != null) { + packManager.sendPack(player); + packManager.getActivePack().onPlayerJoin(player); + } + + HypixelNPC.updateForPlayer(player); + if (!HypixelConst.isIslandServer()) { + PlayerHolograms.spawnAll(player); + } + } + + public static void save(HypixelPlayer player) { + UUID uuid = player.getUuid(); + + ResourcePackManager packManager = HypixelConst.getResourcePackManager(); + if (packManager != null) { + packManager.getActivePack().onPlayerQuit(player); + } + + HypixelDataHandler handler = player.getDataHandler(); + handler.runOnSave(player); + + UserDatabase userDatabase = new UserDatabase(uuid); + userDatabase.saveData(handler); + syncLeaderboards(uuid, handler); + HypixelDataHandler.userCache.remove(uuid); + + for (Class handlerClass : HypixelConst.getTypeLoader().getAdditionalDataHandlers()) { + GameDataHandler gameHandler = GameDataHandlerRegistry.get(handlerClass); + if (gameHandler == null) continue; + + DataHandler gameDataHandler = gameHandler.getHandler(uuid); + if (gameDataHandler == null) continue; + + Logger.info("Saving {} data for {}", gameHandler.getHandlerId(), player.getUsername()); + gameDataHandler.runOnSave(player); + userDatabase.saveData(gameDataHandler); + syncLeaderboards(uuid, gameDataHandler); + gameHandler.removeFromCache(uuid); + } + + ServerOutboundMessage.sendToProxy(new FinishedWithPlayerProtocol(), + new FinishedWithPlayerProtocol.Request(uuid.toString()), + response -> {}); + + MathUtility.delay(() -> HypixelConst.getTypeLoader().getTablistManager().deleteTablistEntries(player), 5); + } + + private static void loadAdditionalHandlers(HypixelPlayer player, UserDatabase userDatabase, Document userDocument) { + UUID playerUuid = player.getUuid(); + List> additionalHandlers = HypixelConst.getTypeLoader().getAdditionalDataHandlers(); + + for (Class handlerClass : additionalHandlers) { + GameDataHandler gameHandler = GameDataHandlerRegistry.get(handlerClass); + if (gameHandler == null) { + Logger.warn("GameDataHandler not registered: {}", handlerClass.getSimpleName()); + continue; + } + + Logger.info("Loading {} data for {}", gameHandler.getHandlerId(), player.getUsername()); + + DataHandler gameDataHandler; + if (userDocument != null && gameHandler.hasDataInDocument(userDocument)) { + gameDataHandler = gameHandler.createFromDocument(playerUuid, userDocument); + } else { + gameDataHandler = gameHandler.initWithDefaults(playerUuid); + } + + gameHandler.cacheHandler(playerUuid, gameDataHandler); + + if (userDocument == null || !gameHandler.hasDataInDocument(userDocument)) { + userDatabase.saveData(gameDataHandler); + } + } + } + + private static void syncLeaderboards(UUID uuid, DataHandler handler) { + if (!LeaderboardService.isInitialized()) return; + + for (Datapoint datapoint : handler.getDatapoints().values()) { + if (datapoint instanceof LeaderboardTracked tracked) { + String key = tracked.getLeaderboardKey(); + if (key != null) { + LeaderboardService.updateScore(key, uuid, tracked.getLeaderboardScore()); + } + } + + if (datapoint instanceof MapLeaderboardTracked mapTracked) { + Map scores = mapTracked.getAllLeaderboardScores(); + for (Map.Entry entry : scores.entrySet()) { + LeaderboardService.updateScore( + mapTracked.getLeaderboardKeyFor(entry.getKey()), + uuid, + entry.getValue() + ); + } + } + } + } +} diff --git a/type.generic/src/main/java/net/swofty/type/generic/user/flow/PlayerFlow.java b/type.generic/src/main/java/net/swofty/type/generic/user/flow/PlayerFlow.java new file mode 100644 index 000000000..c3365acdc --- /dev/null +++ b/type.generic/src/main/java/net/swofty/type/generic/user/flow/PlayerFlow.java @@ -0,0 +1,32 @@ +package net.swofty.type.generic.user.flow; + +import net.swofty.type.generic.user.HypixelPlayer; +import org.tinylog.Logger; + +public final class PlayerFlow { + private PlayerFlow() { + } + + public static void run(HypixelPlayer player, String stage, Runnable action) { + long started = System.currentTimeMillis(); + Logger.info("[{}] Starting {} for {}", player.getUuid(), stage, player.getUsername()); + + try { + action.run(); + Logger.info("[{}] Completed {} for {} in {}ms", + player.getUuid(), + stage, + player.getUsername(), + System.currentTimeMillis() - started); + } catch (Throwable throwable) { + Logger.error(throwable, "[{}] Failed {} for {} after {}ms", + player.getUuid(), + stage, + player.getUsername(), + System.currentTimeMillis() - started); + if (throwable instanceof RuntimeException runtimeException) throw runtimeException; + if (throwable instanceof Error error) throw error; + throw new RuntimeException(throwable); + } + } +} diff --git a/type.goldmine/src/main/java/net/swofty/type/goldmine/events/ActionPlayerJoin.java b/type.goldmine/src/main/java/net/swofty/type/goldmine/events/ActionPlayerJoin.java index 83264f0ca..1de6c2347 100644 --- a/type.goldmine/src/main/java/net/swofty/type/goldmine/events/ActionPlayerJoin.java +++ b/type.goldmine/src/main/java/net/swofty/type/goldmine/events/ActionPlayerJoin.java @@ -4,14 +4,15 @@ import net.minestom.server.event.player.AsyncPlayerConfigurationEvent; import net.swofty.type.generic.HypixelConst; import net.swofty.type.generic.event.EventNodes; -import net.swofty.type.generic.event.HypixelEvent; import net.swofty.type.generic.event.HypixelEventClass; +import net.swofty.type.generic.event.phase.EventPhase; +import net.swofty.type.generic.event.phase.PhasedEvent; import net.swofty.type.skyblockgeneric.user.SkyBlockPlayer; public class ActionPlayerJoin implements HypixelEventClass { @SneakyThrows - @HypixelEvent(node = EventNodes.PLAYER, requireDataLoaded = false) + @PhasedEvent(node = EventNodes.PLAYER, requireDataLoaded = false, phase = EventPhase.CONNECT) public void run(AsyncPlayerConfigurationEvent event) { final SkyBlockPlayer player = (SkyBlockPlayer) event.getPlayer(); diff --git a/type.hub/src/main/java/net/swofty/type/hub/events/ActionPlayerClickMuseumDisplay.java b/type.hub/src/main/java/net/swofty/type/hub/events/ActionPlayerClickMuseumDisplay.java index a701ac671..f45dd6ca2 100644 --- a/type.hub/src/main/java/net/swofty/type/hub/events/ActionPlayerClickMuseumDisplay.java +++ b/type.hub/src/main/java/net/swofty/type/hub/events/ActionPlayerClickMuseumDisplay.java @@ -2,8 +2,9 @@ import net.minestom.server.event.player.PlayerEntityInteractEvent; import net.swofty.type.generic.event.EventNodes; -import net.swofty.type.generic.event.HypixelEvent; import net.swofty.type.generic.event.HypixelEventClass; +import net.swofty.type.generic.event.phase.EventPhase; +import net.swofty.type.generic.event.phase.PhasedEvent; import net.swofty.type.skyblockgeneric.gui.inventories.museum.GUIMuseumEmptyDisplay; import net.swofty.type.skyblockgeneric.gui.inventories.museum.GUIMuseumNonEmptyDisplay; import net.swofty.type.skyblockgeneric.museum.MuseumDisplayEntityImpl; @@ -11,7 +12,7 @@ public class ActionPlayerClickMuseumDisplay implements HypixelEventClass { - @HypixelEvent(node = EventNodes.PLAYER, requireDataLoaded = true) + @PhasedEvent(node = EventNodes.PLAYER, requireDataLoaded = true, phase = EventPhase.GAMEPLAY) public void run(PlayerEntityInteractEvent event) { SkyBlockPlayer player = (SkyBlockPlayer) event.getPlayer(); diff --git a/type.hub/src/main/java/net/swofty/type/hub/events/ActionPlayerClicksMuseumNPCDisplay.java b/type.hub/src/main/java/net/swofty/type/hub/events/ActionPlayerClicksMuseumNPCDisplay.java index b3090656e..852e1a588 100644 --- a/type.hub/src/main/java/net/swofty/type/hub/events/ActionPlayerClicksMuseumNPCDisplay.java +++ b/type.hub/src/main/java/net/swofty/type/hub/events/ActionPlayerClicksMuseumNPCDisplay.java @@ -3,15 +3,16 @@ import net.minestom.server.coordinate.Pos; import net.minestom.server.event.player.PlayerBlockInteractEvent; import net.swofty.type.generic.event.EventNodes; -import net.swofty.type.generic.event.HypixelEvent; import net.swofty.type.generic.event.HypixelEventClass; +import net.swofty.type.generic.event.phase.EventPhase; +import net.swofty.type.generic.event.phase.PhasedEvent; import net.swofty.type.skyblockgeneric.gui.inventories.museum.GUIYourMuseum; import net.swofty.type.skyblockgeneric.user.SkyBlockPlayer; public class ActionPlayerClicksMuseumNPCDisplay implements HypixelEventClass { - @HypixelEvent(node = EventNodes.PLAYER, requireDataLoaded = true, isAsync = true) + @PhasedEvent(node = EventNodes.PLAYER, requireDataLoaded = true, isAsync = true, phase = EventPhase.GAMEPLAY) public void run(PlayerBlockInteractEvent event) { SkyBlockPlayer player = (SkyBlockPlayer) event.getPlayer(); Pos displayPosition = new Pos(-23, 67, 80); diff --git a/type.hub/src/main/java/net/swofty/type/hub/events/ActionPlayerClicksOnRunePedestal.java b/type.hub/src/main/java/net/swofty/type/hub/events/ActionPlayerClicksOnRunePedestal.java index 5d676b97d..fbb81cf6d 100644 --- a/type.hub/src/main/java/net/swofty/type/hub/events/ActionPlayerClicksOnRunePedestal.java +++ b/type.hub/src/main/java/net/swofty/type/hub/events/ActionPlayerClicksOnRunePedestal.java @@ -3,15 +3,16 @@ import net.minestom.server.coordinate.BlockVec; import net.minestom.server.event.player.PlayerBlockInteractEvent; import net.swofty.type.generic.event.EventNodes; -import net.swofty.type.generic.event.HypixelEvent; import net.swofty.type.generic.event.HypixelEventClass; +import net.swofty.type.generic.event.phase.EventPhase; +import net.swofty.type.generic.event.phase.PhasedEvent; import net.swofty.type.hub.gui.GUIRunicPedestal; import net.swofty.type.skyblockgeneric.user.SkyBlockPlayer; public class ActionPlayerClicksOnRunePedestal implements HypixelEventClass { - @HypixelEvent(node = EventNodes.PLAYER, requireDataLoaded = true) + @PhasedEvent(node = EventNodes.PLAYER, requireDataLoaded = true, phase = EventPhase.GAMEPLAY) public void run(PlayerBlockInteractEvent event) { if (!event.getBlockPosition().equals(new BlockVec(23, 64, -135))) return; diff --git a/type.hub/src/main/java/net/swofty/type/hub/events/ActionPlayerDisplayMuseum.java b/type.hub/src/main/java/net/swofty/type/hub/events/ActionPlayerDisplayMuseum.java index 151a7cc3a..a4fc83151 100644 --- a/type.hub/src/main/java/net/swofty/type/hub/events/ActionPlayerDisplayMuseum.java +++ b/type.hub/src/main/java/net/swofty/type/hub/events/ActionPlayerDisplayMuseum.java @@ -2,8 +2,9 @@ import net.minestom.server.event.player.PlayerSpawnEvent; import net.swofty.type.generic.event.EventNodes; -import net.swofty.type.generic.event.HypixelEvent; import net.swofty.type.generic.event.HypixelEventClass; +import net.swofty.type.generic.event.phase.EventPhase; +import net.swofty.type.generic.event.phase.PhasedEvent; import net.swofty.type.skyblockgeneric.museum.MuseumDisplays; import net.swofty.type.skyblockgeneric.user.SkyBlockPlayer; @@ -12,7 +13,7 @@ public class ActionPlayerDisplayMuseum implements HypixelEventClass { - @HypixelEvent(node = EventNodes.PLAYER, requireDataLoaded = true, isAsync = true) + @PhasedEvent(node = EventNodes.PLAYER, requireDataLoaded = true, isAsync = true, phase = EventPhase.GAMEPLAY) public void run(PlayerSpawnEvent event) { final SkyBlockPlayer player = (SkyBlockPlayer) event.getPlayer(); if (!event.isFirstSpawn()) return; diff --git a/type.hub/src/main/java/net/swofty/type/hub/events/ActionPlayerHandleTargetArchery.java b/type.hub/src/main/java/net/swofty/type/hub/events/ActionPlayerHandleTargetArchery.java index da9e25669..04b49036e 100644 --- a/type.hub/src/main/java/net/swofty/type/hub/events/ActionPlayerHandleTargetArchery.java +++ b/type.hub/src/main/java/net/swofty/type/hub/events/ActionPlayerHandleTargetArchery.java @@ -10,8 +10,9 @@ import net.minestom.server.tag.Tag; import net.swofty.commons.StringUtility; import net.swofty.type.generic.event.EventNodes; -import net.swofty.type.generic.event.HypixelEvent; import net.swofty.type.generic.event.HypixelEventClass; +import net.swofty.type.generic.event.phase.EventPhase; +import net.swofty.type.generic.event.phase.PhasedEvent; import net.swofty.type.generic.utility.TimedActivityHandler; import net.swofty.type.skyblockgeneric.targetpractice.PracticeTargets; import net.swofty.type.skyblockgeneric.data.datapoints.DatapointArcheryPractice; @@ -33,7 +34,7 @@ public class ActionPlayerHandleTargetArchery implements HypixelEventClass { public ActionPlayerHandleTargetArchery() {} - @HypixelEvent(node = EventNodes.PLAYER, requireDataLoaded = true, isAsync = true) + @PhasedEvent(node = EventNodes.PLAYER, requireDataLoaded = true, isAsync = true, phase = EventPhase.GAMEPLAY) public void handleOnJoin(PlayerSpawnEvent event) { final SkyBlockPlayer player = (SkyBlockPlayer) event.getPlayer(); if (!event.isFirstSpawn()) return; @@ -42,7 +43,7 @@ public void handleOnJoin(PlayerSpawnEvent event) { } - @HypixelEvent(node = EventNodes.CUSTOM, requireDataLoaded = false, isAsync = true) + @PhasedEvent(node = EventNodes.CUSTOM, requireDataLoaded = false, isAsync = true, phase = EventPhase.GAMEPLAY) public void handleOnArrowHit(ArrowHitBlockEvent event) { if (!event.isSkyBlockPlayer()) return; final SkyBlockPlayer player = (SkyBlockPlayer) event.getShooter(); @@ -69,7 +70,7 @@ public void handleOnArrowHit(ArrowHitBlockEvent event) { } } - @HypixelEvent(node = EventNodes.PLAYER, requireDataLoaded = true, isAsync = true) + @PhasedEvent(node = EventNodes.PLAYER, requireDataLoaded = true, isAsync = true, phase = EventPhase.GAMEPLAY) public void handleOnMove(PlayerMoveEvent event) { final SkyBlockPlayer player = (SkyBlockPlayer) event.getPlayer(); boolean isNearArchery = event.getNewPosition().distance(ARCHERY_POSITION) < 0.5; diff --git a/type.hub/src/main/java/net/swofty/type/hub/events/ActionPlayerJoin.java b/type.hub/src/main/java/net/swofty/type/hub/events/ActionPlayerJoin.java index 6e1cafb45..c235e177a 100644 --- a/type.hub/src/main/java/net/swofty/type/hub/events/ActionPlayerJoin.java +++ b/type.hub/src/main/java/net/swofty/type/hub/events/ActionPlayerJoin.java @@ -4,15 +4,16 @@ import net.minestom.server.event.player.AsyncPlayerConfigurationEvent; import net.swofty.type.generic.HypixelConst; import net.swofty.type.generic.event.EventNodes; -import net.swofty.type.generic.event.HypixelEvent; import net.swofty.type.generic.event.HypixelEventClass; +import net.swofty.type.generic.event.phase.EventPhase; +import net.swofty.type.generic.event.phase.PhasedEvent; import net.swofty.type.skyblockgeneric.user.SkyBlockPlayer; import org.tinylog.Logger; public class ActionPlayerJoin implements HypixelEventClass { @SneakyThrows - @HypixelEvent(node = EventNodes.PLAYER, requireDataLoaded = false) + @PhasedEvent(node = EventNodes.PLAYER, requireDataLoaded = false, phase = EventPhase.CONNECT) public void run(AsyncPlayerConfigurationEvent event) { final SkyBlockPlayer player = (SkyBlockPlayer) event.getPlayer(); diff --git a/type.hub/src/main/java/net/swofty/type/hub/events/ActionPlayerQuitDarkAuction.java b/type.hub/src/main/java/net/swofty/type/hub/events/ActionPlayerQuitDarkAuction.java index c7904823b..32c068881 100644 --- a/type.hub/src/main/java/net/swofty/type/hub/events/ActionPlayerQuitDarkAuction.java +++ b/type.hub/src/main/java/net/swofty/type/hub/events/ActionPlayerQuitDarkAuction.java @@ -2,8 +2,9 @@ import net.minestom.server.event.player.PlayerDisconnectEvent; import net.swofty.type.generic.event.EventNodes; -import net.swofty.type.generic.event.HypixelEvent; import net.swofty.type.generic.event.HypixelEventClass; +import net.swofty.type.generic.event.phase.EventPhase; +import net.swofty.type.generic.event.phase.PhasedEvent; import net.swofty.type.skyblockgeneric.darkauction.DarkAuctionHandler; import net.swofty.type.skyblockgeneric.user.SkyBlockPlayer; @@ -13,7 +14,7 @@ */ public class ActionPlayerQuitDarkAuction implements HypixelEventClass { - @HypixelEvent(node = EventNodes.PLAYER, requireDataLoaded = false) + @PhasedEvent(node = EventNodes.PLAYER, requireDataLoaded = false, phase = EventPhase.GAMEPLAY) public void run(PlayerDisconnectEvent event) { SkyBlockPlayer player = (SkyBlockPlayer) event.getPlayer(); diff --git a/type.hub/src/main/java/net/swofty/type/hub/events/ActionPlayerSpawn.java b/type.hub/src/main/java/net/swofty/type/hub/events/ActionPlayerSpawn.java index 76135c1bc..f43bbf74a 100644 --- a/type.hub/src/main/java/net/swofty/type/hub/events/ActionPlayerSpawn.java +++ b/type.hub/src/main/java/net/swofty/type/hub/events/ActionPlayerSpawn.java @@ -3,15 +3,16 @@ import lombok.SneakyThrows; import net.minestom.server.event.player.PlayerSpawnEvent; import net.swofty.type.generic.event.EventNodes; -import net.swofty.type.generic.event.HypixelEvent; import net.swofty.type.generic.event.HypixelEventClass; +import net.swofty.type.generic.event.phase.EventPhase; +import net.swofty.type.generic.event.phase.PhasedEvent; import net.swofty.type.hub.util.HubMap; import net.swofty.type.skyblockgeneric.user.SkyBlockPlayer; public class ActionPlayerSpawn implements HypixelEventClass { @SneakyThrows - @HypixelEvent(node = EventNodes.PLAYER, requireDataLoaded = false, isAsync = true) + @PhasedEvent(node = EventNodes.PLAYER, requireDataLoaded = false, isAsync = true, phase = EventPhase.SPAWN) public void run(PlayerSpawnEvent event) { final SkyBlockPlayer player = (SkyBlockPlayer) event.getPlayer(); diff --git a/type.island/src/main/java/net/swofty/type/island/TypeIslandLoader.java b/type.island/src/main/java/net/swofty/type/island/TypeIslandLoader.java index 99cb82e1b..9bfcf8190 100644 --- a/type.island/src/main/java/net/swofty/type/island/TypeIslandLoader.java +++ b/type.island/src/main/java/net/swofty/type/island/TypeIslandLoader.java @@ -14,6 +14,7 @@ import net.swofty.type.generic.event.HypixelEventClass; import net.swofty.type.generic.tab.TablistManager; import net.swofty.type.generic.tab.TablistModule; +import net.swofty.type.island.lifecycle.IslandLifecycleSteps; import net.swofty.type.island.tab.IslandGuestsModule; import net.swofty.type.island.tab.IslandMemberModule; import net.swofty.type.island.tab.IslandServerModule; @@ -39,9 +40,7 @@ public ServerType getType() { public void onInitialize(MinecraftServer server) { Logger.info("TypeIslandLoader initialized!"); - /** - * Initialize Minions - */ + IslandLifecycleSteps.register(); new MinionHandler(MinecraftServer.getSchedulerManager()).start(); } @@ -83,10 +82,7 @@ public List getTraditionalEvents() { @Override public List getCustomEvents() { - return SkyBlockGenericLoader.loopThroughPackage( - "net.swofty.type.island.events.custom", - HypixelEventClass.class - ).collect(Collectors.toList()); + return List.of(); } @Override diff --git a/type.island/src/main/java/net/swofty/type/island/events/custom/ActionCreateStarterChest.java b/type.island/src/main/java/net/swofty/type/island/events/custom/ActionCreateStarterChest.java deleted file mode 100644 index e202308e3..000000000 --- a/type.island/src/main/java/net/swofty/type/island/events/custom/ActionCreateStarterChest.java +++ /dev/null @@ -1,28 +0,0 @@ -package net.swofty.type.island.events.custom; - -import net.minestom.server.coordinate.Pos; -import net.minestom.server.item.ItemStack; -import net.minestom.server.item.Material; -import net.swofty.type.generic.event.EventNodes; -import net.swofty.type.generic.event.HypixelEvent; -import net.swofty.type.generic.event.HypixelEventClass; -import net.swofty.type.generic.utility.MathUtility; -import net.swofty.type.skyblockgeneric.block.placement.states.state.Facing; -import net.swofty.type.skyblockgeneric.chest.ChestBuilder; -import net.swofty.type.skyblockgeneric.chest.ChestType; -import net.swofty.type.skyblockgeneric.event.custom.IslandFirstCreatedEvent; - -public class ActionCreateStarterChest implements HypixelEventClass { - - @HypixelEvent(node = EventNodes.CUSTOM, requireDataLoaded = true) - public void run(IslandFirstCreatedEvent event) { - MathUtility.delay(() -> new ChestBuilder(event.getIsland().getIslandInstance(), new Pos(10, 93, 38), ChestType.SINGLE, Facing.WEST) - .setItem(0, ItemStack.of(Material.DIRT, 5)) - .setItem(1, ItemStack.of(Material.GRASS_BLOCK, 7)) - .setItem(2, ItemStack.of(Material.COBBLESTONE, 8)) - .setItem(3, ItemStack.of(Material.WATER_BUCKET)) - .setItem(4, ItemStack.of(Material.LAVA_BUCKET)) - .setItem(5, ItemStack.of(Material.BONE_MEAL, 3)) - .build(), 60); - } -} diff --git a/type.island/src/main/java/net/swofty/type/island/events/custom/ActionIslandCreatePortals.java b/type.island/src/main/java/net/swofty/type/island/events/custom/ActionIslandCreatePortals.java deleted file mode 100644 index ddbb8835b..000000000 --- a/type.island/src/main/java/net/swofty/type/island/events/custom/ActionIslandCreatePortals.java +++ /dev/null @@ -1,18 +0,0 @@ -package net.swofty.type.island.events.custom; - -import net.swofty.type.generic.event.EventNodes; -import net.swofty.type.generic.event.HypixelEvent; -import net.swofty.type.generic.event.HypixelEventClass; -import net.swofty.type.skyblockgeneric.event.custom.IslandFetchedFromDatabaseEvent; -import net.swofty.type.skyblockgeneric.structure.structures.IslandPortal; - -public class ActionIslandCreatePortals implements HypixelEventClass { - - @HypixelEvent(node = EventNodes.CUSTOM, requireDataLoaded = false) - public void run(IslandFetchedFromDatabaseEvent event) { - IslandPortal portal = new IslandPortal(0, 6, 100, 43); - portal.setType(IslandPortal.PortalType.HUB); - - portal.build(event.getIsland().getIslandInstance()); - } -} diff --git a/type.island/src/main/java/net/swofty/type/island/events/custom/ActionIslandInitJerry.java b/type.island/src/main/java/net/swofty/type/island/events/custom/ActionIslandInitJerry.java deleted file mode 100644 index faf9ff212..000000000 --- a/type.island/src/main/java/net/swofty/type/island/events/custom/ActionIslandInitJerry.java +++ /dev/null @@ -1,19 +0,0 @@ -package net.swofty.type.island.events.custom; - -import net.minestom.server.coordinate.Pos; -import net.swofty.type.generic.event.EventNodes; -import net.swofty.type.generic.event.HypixelEvent; -import net.swofty.type.generic.event.HypixelEventClass; -import net.swofty.type.skyblockgeneric.event.custom.IslandFirstCreatedEvent; -import net.swofty.type.skyblockgeneric.utility.JerryInformation; - -public class ActionIslandInitJerry implements HypixelEventClass { - - - @HypixelEvent(node = EventNodes.CUSTOM, requireDataLoaded = false) - public void run(IslandFirstCreatedEvent event) { - event.getIsland().setJerryInformation( - new JerryInformation(null, new Pos(9.5, 100, 33.5, 145, 0), null) - ); - } -} diff --git a/type.island/src/main/java/net/swofty/type/island/events/custom/ActionIslandLoadMinions.java b/type.island/src/main/java/net/swofty/type/island/events/custom/ActionIslandLoadMinions.java deleted file mode 100644 index 376216187..000000000 --- a/type.island/src/main/java/net/swofty/type/island/events/custom/ActionIslandLoadMinions.java +++ /dev/null @@ -1,75 +0,0 @@ -package net.swofty.type.island.events.custom; - -import net.swofty.commons.skyblock.item.ItemType; -import net.swofty.type.generic.event.EventNodes; -import net.swofty.type.generic.event.HypixelEvent; -import net.swofty.type.generic.event.HypixelEventClass; -import net.swofty.type.skyblockgeneric.event.custom.IslandFetchedFromDatabaseEvent; -import net.swofty.type.skyblockgeneric.item.SkyBlockItem; -import net.swofty.type.skyblockgeneric.minion.IslandMinionData; -import net.swofty.type.skyblockgeneric.minion.MinionAction; -import net.swofty.type.skyblockgeneric.minion.SkyBlockMinion; -import net.swofty.type.skyblockgeneric.minion.extension.MinionExtensionData; -import net.swofty.type.skyblockgeneric.minion.extension.extensions.MinionFuelExtension; -import org.bson.Document; - -import java.util.List; -import java.util.Map; - -public class ActionIslandLoadMinions implements HypixelEventClass { - - - @HypixelEvent(node = EventNodes.CUSTOM, requireDataLoaded = false) - public void run(IslandFetchedFromDatabaseEvent event) { - Document document = event.getIsland().getDatabase().getDocument(); - - if (document == null) { - event.getIsland().setMinionData(new IslandMinionData(event.getIsland())); - return; - } - - Map rawData = (Map) document.get("minions"); - IslandMinionData minionData = IslandMinionData.deserialize( - rawData, - event.getIsland() - ); - - event.getIsland().setMinionData(minionData); - - long lastSaved = event.getIsland().getLastSaved(); - long currentTime = System.currentTimeMillis(); - - minionData.getMinions().forEach((data) -> { - int tierIndex = data.getTier(); - SkyBlockMinion.MinionTier tier = data.getMinion().asSkyBlockMinion().getTiers().get(tierIndex - 1); - MinionExtensionData extensionData = data.getExtensionData(); - - long timeBetweenActions = (long) tier.timeBetweenActions(); - ItemType minionFuel = extensionData.getOfType(MinionFuelExtension.class).getItemTypePassedIn(); - - // Handle percentage speed increase from both fuels and minion upgrades - double percentageSpeedIncrease = data.getSpeedPercentage(); - - // Decrease timeBetweenActions by the percentage speed increase, so if above is 300, then it's 3x faster - timeBetweenActions = (long) (timeBetweenActions / (1 + (percentageSpeedIncrease / 100))); - - int amountOfActions = Math.round((float) (currentTime - lastSaved) / (timeBetweenActions * 1000L)); - - data.spawnMinion(event.getIsland().getIslandInstance()); - if (lastSaved != 0) { - Thread.startVirtualThread(() -> { - for (int i = 0; i < amountOfActions; i++) { - MinionAction action = data.getMinion().asSkyBlockMinion().getAction(); - List items = action.onAction( - new MinionAction.MinionActionEvent(), - data, - event.getIsland().getIslandInstance()); - - if (!items.isEmpty()) - MinionAction.onMinionIteration(data, data.getMinionEntity().getMinion(), items); - } - }); - } - }); - } -} diff --git a/type.island/src/main/java/net/swofty/type/island/events/custom/ActionIslandSaveJerry.java b/type.island/src/main/java/net/swofty/type/island/events/custom/ActionIslandSaveJerry.java deleted file mode 100644 index adb222885..000000000 --- a/type.island/src/main/java/net/swofty/type/island/events/custom/ActionIslandSaveJerry.java +++ /dev/null @@ -1,33 +0,0 @@ -package net.swofty.type.island.events.custom; - -import net.swofty.type.generic.entity.hologram.ServerHolograms; -import net.swofty.type.generic.event.EventNodes; -import net.swofty.type.generic.event.HypixelEvent; -import net.swofty.type.generic.event.HypixelEventClass; -import net.swofty.type.skyblockgeneric.event.custom.IslandSavedIntoDatabaseEvent; -import net.swofty.type.skyblockgeneric.utility.JerryInformation; - -public class ActionIslandSaveJerry implements HypixelEventClass { - - @HypixelEvent(node = EventNodes.CUSTOM, requireDataLoaded = false) - public void run(IslandSavedIntoDatabaseEvent event) { - JerryInformation jerryInformation = event.getIsland().getJerryInformation(); - - if (jerryInformation == null) return; - - if (jerryInformation.getJerry() != null) { - jerryInformation.getJerry().remove(); - } - if (jerryInformation.getHologram() != null) { - ServerHolograms.removeExternalHologram(jerryInformation.getHologram()); - } - - if (jerryInformation.getJerryPosition() == null) return; - - event.getIsland().getDatabase().insertOrUpdate("jerry_position_x", jerryInformation.getJerryPosition().x()); - event.getIsland().getDatabase().insertOrUpdate("jerry_position_y", jerryInformation.getJerryPosition().y()); - event.getIsland().getDatabase().insertOrUpdate("jerry_position_z", jerryInformation.getJerryPosition().z()); - event.getIsland().getDatabase().insertOrUpdate("jerry_position_yaw", (double) jerryInformation.getJerryPosition().yaw()); - event.getIsland().getDatabase().insertOrUpdate("jerry_position_pitch", (double) jerryInformation.getJerryPosition().pitch()); - } -} diff --git a/type.island/src/main/java/net/swofty/type/island/events/custom/ActionIslandSaveMinions.java b/type.island/src/main/java/net/swofty/type/island/events/custom/ActionIslandSaveMinions.java deleted file mode 100644 index 1b7573206..000000000 --- a/type.island/src/main/java/net/swofty/type/island/events/custom/ActionIslandSaveMinions.java +++ /dev/null @@ -1,18 +0,0 @@ -package net.swofty.type.island.events.custom; - -import net.swofty.type.generic.event.EventNodes; -import net.swofty.type.generic.event.HypixelEvent; -import net.swofty.type.generic.event.HypixelEventClass; -import net.swofty.type.skyblockgeneric.event.custom.IslandSavedIntoDatabaseEvent; -import net.swofty.type.skyblockgeneric.minion.IslandMinionData; - -public class ActionIslandSaveMinions implements HypixelEventClass { - - @HypixelEvent(node = EventNodes.CUSTOM, requireDataLoaded = false) - public void run(IslandSavedIntoDatabaseEvent event) { - IslandMinionData minionData = event.getIsland().getMinionData(); - minionData.getMinions().forEach(IslandMinionData.IslandMinion::removeMinion); - - event.getIsland().getDatabase().insertOrUpdate("minions", event.getIsland().getMinionData().serialize()); - } -} diff --git a/type.island/src/main/java/net/swofty/type/island/events/custom/ActionPlayerSpawnFirstMinion.java b/type.island/src/main/java/net/swofty/type/island/events/custom/ActionPlayerSpawnFirstMinion.java deleted file mode 100644 index c27937cd8..000000000 --- a/type.island/src/main/java/net/swofty/type/island/events/custom/ActionPlayerSpawnFirstMinion.java +++ /dev/null @@ -1,28 +0,0 @@ -package net.swofty.type.island.events.custom; - -import net.minestom.server.coordinate.Pos; -import net.swofty.commons.skyblock.item.attribute.attributes.ItemAttributeMinionData; -import net.swofty.type.generic.event.EventNodes; -import net.swofty.type.generic.event.HypixelEvent; -import net.swofty.type.generic.event.HypixelEventClass; -import net.swofty.type.generic.utility.MathUtility; -import net.swofty.type.skyblockgeneric.event.custom.IslandFirstCreatedEvent; -import net.swofty.type.skyblockgeneric.minion.IslandMinionData; -import net.swofty.type.skyblockgeneric.minion.MinionRegistry; - -public class ActionPlayerSpawnFirstMinion implements HypixelEventClass { - - @HypixelEvent(node = EventNodes.CUSTOM, requireDataLoaded = true) - public void run(IslandFirstCreatedEvent event) { - MathUtility.delay(() -> { - IslandMinionData.IslandMinion minion = event.getIsland().getMinionData().initializeMinion( - new Pos(3, 100, 36), // Default Cobble Minion position - MinionRegistry.COBBLESTONE, - new ItemAttributeMinionData.MinionData(1, 0), - false - ); - - event.getIsland().getMinionData().spawn(minion); - }, 40); // delay to let island load properly - } -} diff --git a/type.island/src/main/java/net/swofty/type/island/events/traditional/ActionIslandSave.java b/type.island/src/main/java/net/swofty/type/island/events/traditional/ActionIslandSave.java index dcf86acf1..5f3d8d7ce 100644 --- a/type.island/src/main/java/net/swofty/type/island/events/traditional/ActionIslandSave.java +++ b/type.island/src/main/java/net/swofty/type/island/events/traditional/ActionIslandSave.java @@ -3,15 +3,16 @@ import lombok.SneakyThrows; import net.minestom.server.event.player.PlayerDisconnectEvent; import net.swofty.type.generic.event.EventNodes; -import net.swofty.type.generic.event.HypixelEvent; import net.swofty.type.generic.event.HypixelEventClass; -import net.swofty.type.skyblockgeneric.user.SkyBlockIsland; +import net.swofty.type.generic.event.phase.EventPhase; +import net.swofty.type.generic.event.phase.PhasedEvent; +import net.swofty.type.skyblockgeneric.user.island.SkyBlockIsland; import net.swofty.type.skyblockgeneric.user.SkyBlockPlayer; public class ActionIslandSave implements HypixelEventClass { @SneakyThrows - @HypixelEvent(node = EventNodes.PLAYER, requireDataLoaded = false) + @PhasedEvent(node = EventNodes.PLAYER, requireDataLoaded = false, phase = EventPhase.PERSIST, order = 20) public void run(PlayerDisconnectEvent event) { SkyBlockPlayer player = (SkyBlockPlayer) event.getPlayer(); SkyBlockIsland island = player.getSkyBlockIsland(); diff --git a/type.island/src/main/java/net/swofty/type/island/events/traditional/ActionPlayerClickMinion.java b/type.island/src/main/java/net/swofty/type/island/events/traditional/ActionPlayerClickMinion.java index 6ec6b6844..994dbfe3b 100644 --- a/type.island/src/main/java/net/swofty/type/island/events/traditional/ActionPlayerClickMinion.java +++ b/type.island/src/main/java/net/swofty/type/island/events/traditional/ActionPlayerClickMinion.java @@ -2,8 +2,9 @@ import net.minestom.server.event.player.PlayerEntityInteractEvent; import net.swofty.type.generic.event.EventNodes; -import net.swofty.type.generic.event.HypixelEvent; import net.swofty.type.generic.event.HypixelEventClass; +import net.swofty.type.generic.event.phase.EventPhase; +import net.swofty.type.generic.event.phase.PhasedEvent; import net.swofty.type.skyblockgeneric.entity.MinionEntityImpl; import net.swofty.type.skyblockgeneric.gui.inventories.GUIMinion; import net.swofty.type.skyblockgeneric.user.SkyBlockPlayer; @@ -11,7 +12,7 @@ public class ActionPlayerClickMinion implements HypixelEventClass { - @HypixelEvent(node = EventNodes.PLAYER, requireDataLoaded = true) + @PhasedEvent(node = EventNodes.PLAYER, requireDataLoaded = true, phase = EventPhase.GAMEPLAY) public void run(PlayerEntityInteractEvent event) { SkyBlockPlayer player = (SkyBlockPlayer) event.getPlayer(); diff --git a/type.island/src/main/java/net/swofty/type/island/events/traditional/ActionPlayerClickedJerryNPC.java b/type.island/src/main/java/net/swofty/type/island/events/traditional/ActionPlayerClickedJerryNPC.java index 8635407ed..f75363aed 100644 --- a/type.island/src/main/java/net/swofty/type/island/events/traditional/ActionPlayerClickedJerryNPC.java +++ b/type.island/src/main/java/net/swofty/type/island/events/traditional/ActionPlayerClickedJerryNPC.java @@ -4,8 +4,9 @@ import net.minestom.server.entity.PlayerHand; import net.minestom.server.event.player.PlayerEntityInteractEvent; import net.swofty.type.generic.event.EventNodes; -import net.swofty.type.generic.event.HypixelEvent; import net.swofty.type.generic.event.HypixelEventClass; +import net.swofty.type.generic.event.phase.EventPhase; +import net.swofty.type.generic.event.phase.PhasedEvent; import net.swofty.type.generic.event.HypixelEventHandler; import net.swofty.type.island.gui.GUIJerry; import net.swofty.type.skyblockgeneric.event.custom.JerryClickedEvent; @@ -13,7 +14,7 @@ public class ActionPlayerClickedJerryNPC implements HypixelEventClass { - @HypixelEvent(node = EventNodes.PLAYER, requireDataLoaded = true) + @PhasedEvent(node = EventNodes.PLAYER, requireDataLoaded = true, phase = EventPhase.GAMEPLAY) public void run(PlayerEntityInteractEvent event) { final SkyBlockPlayer player = (SkyBlockPlayer) event.getPlayer(); diff --git a/type.island/src/main/java/net/swofty/type/island/events/traditional/ActionPlayerJoin.java b/type.island/src/main/java/net/swofty/type/island/events/traditional/ActionPlayerJoin.java index 14d930be4..01d736e32 100644 --- a/type.island/src/main/java/net/swofty/type/island/events/traditional/ActionPlayerJoin.java +++ b/type.island/src/main/java/net/swofty/type/island/events/traditional/ActionPlayerJoin.java @@ -4,15 +4,16 @@ import net.minestom.server.event.player.AsyncPlayerConfigurationEvent; import net.swofty.type.generic.HypixelConst; import net.swofty.type.generic.event.EventNodes; -import net.swofty.type.generic.event.HypixelEvent; import net.swofty.type.generic.event.HypixelEventClass; +import net.swofty.type.generic.event.phase.EventPhase; +import net.swofty.type.generic.event.phase.PhasedEvent; import net.swofty.type.island.TypeIslandLoader; import net.swofty.type.skyblockgeneric.user.SkyBlockPlayer; public class ActionPlayerJoin implements HypixelEventClass { @SneakyThrows - @HypixelEvent(node = EventNodes.PLAYER, requireDataLoaded = false) + @PhasedEvent(node = EventNodes.PLAYER, requireDataLoaded = false, phase = EventPhase.CONNECT) public void run(AsyncPlayerConfigurationEvent event) { final SkyBlockPlayer player = (SkyBlockPlayer) event.getPlayer(); event.setSpawningInstance(HypixelConst.getEmptyInstance()); diff --git a/type.island/src/main/java/net/swofty/type/island/events/traditional/ActionPlayerTeleport.java b/type.island/src/main/java/net/swofty/type/island/events/traditional/ActionPlayerTeleport.java index 5223ad7e1..a1ed5333f 100644 --- a/type.island/src/main/java/net/swofty/type/island/events/traditional/ActionPlayerTeleport.java +++ b/type.island/src/main/java/net/swofty/type/island/events/traditional/ActionPlayerTeleport.java @@ -3,20 +3,24 @@ import net.minestom.server.event.player.PlayerSpawnEvent; import net.minestom.server.instance.SharedInstance; import net.swofty.type.generic.event.EventNodes; -import net.swofty.type.generic.event.HypixelEvent; import net.swofty.type.generic.event.HypixelEventClass; +import net.swofty.type.generic.event.phase.EventPhase; +import net.swofty.type.generic.event.phase.PhasedEvent; +import net.swofty.type.generic.user.flow.PlayerFlow; import net.swofty.type.skyblockgeneric.user.SkyBlockPlayer; public class ActionPlayerTeleport implements HypixelEventClass { - @HypixelEvent(node = EventNodes.PLAYER, requireDataLoaded = false) + @PhasedEvent(node = EventNodes.PLAYER, requireDataLoaded = false, phase = EventPhase.SPAWN, order = -50) public void run(PlayerSpawnEvent event) { SkyBlockPlayer player = (SkyBlockPlayer) event.getPlayer(); if (!event.isFirstSpawn()) return; - SharedInstance instance = player.getSkyBlockIsland().getSharedInstance().join(); - player.setInstance(instance, player.getRespawnPoint()); - player.teleport(player.getRespawnPoint()); + PlayerFlow.run(player, "island-instance/load-and-teleport", () -> { + SharedInstance instance = player.getSkyBlockIsland().getSharedInstance().join(); + player.setInstance(instance, player.getRespawnPoint()); + player.teleport(player.getRespawnPoint()); + }); } } diff --git a/type.island/src/main/java/net/swofty/type/island/events/traditional/ActionStartIslandMission.java b/type.island/src/main/java/net/swofty/type/island/events/traditional/ActionStartIslandMission.java index 042c4a1a5..392066348 100644 --- a/type.island/src/main/java/net/swofty/type/island/events/traditional/ActionStartIslandMission.java +++ b/type.island/src/main/java/net/swofty/type/island/events/traditional/ActionStartIslandMission.java @@ -2,15 +2,16 @@ import net.minestom.server.event.player.AsyncPlayerConfigurationEvent; import net.swofty.type.generic.event.EventNodes; -import net.swofty.type.generic.event.HypixelEvent; import net.swofty.type.generic.event.HypixelEventClass; +import net.swofty.type.generic.event.phase.EventPhase; +import net.swofty.type.generic.event.phase.PhasedEvent; import net.swofty.type.skyblockgeneric.mission.MissionData; import net.swofty.type.skyblockgeneric.mission.missions.MissionBreakLog; import net.swofty.type.skyblockgeneric.user.SkyBlockPlayer; public class ActionStartIslandMission implements HypixelEventClass { - @HypixelEvent(node = EventNodes.PLAYER, requireDataLoaded = true) + @PhasedEvent(node = EventNodes.PLAYER, requireDataLoaded = true, phase = EventPhase.POST_DATA) public void run(AsyncPlayerConfigurationEvent event) { MissionData data = ((SkyBlockPlayer) event.getPlayer()).getMissionData(); diff --git a/type.island/src/main/java/net/swofty/type/island/lifecycle/FirstMinionStep.java b/type.island/src/main/java/net/swofty/type/island/lifecycle/FirstMinionStep.java new file mode 100644 index 000000000..5d9a6e4b3 --- /dev/null +++ b/type.island/src/main/java/net/swofty/type/island/lifecycle/FirstMinionStep.java @@ -0,0 +1,36 @@ +package net.swofty.type.island.lifecycle; + +import net.minestom.server.coordinate.Pos; +import net.swofty.commons.skyblock.item.attribute.attributes.ItemAttributeMinionData; +import net.swofty.type.generic.utility.MathUtility; +import net.swofty.type.skyblockgeneric.minion.IslandMinionData; +import net.swofty.type.skyblockgeneric.minion.MinionRegistry; +import net.swofty.type.skyblockgeneric.user.island.IslandLifecycleContext; +import net.swofty.type.skyblockgeneric.user.island.IslandLifecyclePhase; +import net.swofty.type.skyblockgeneric.user.island.IslandLifecycleStep; + +public class FirstMinionStep implements IslandLifecycleStep { + @Override + public IslandLifecyclePhase phase() { + return IslandLifecyclePhase.CREATE; + } + + @Override + public int order() { + return 20; + } + + @Override + public void run(IslandLifecycleContext context) { + MathUtility.delay(() -> { + IslandMinionData.IslandMinion minion = context.island().getMinionData().initializeMinion( + new Pos(3, 100, 36), + MinionRegistry.COBBLESTONE, + new ItemAttributeMinionData.MinionData(1, 0), + false + ); + + context.island().getMinionData().spawn(minion); + }, 40); + } +} diff --git a/type.island/src/main/java/net/swofty/type/island/lifecycle/IslandLifecycleSteps.java b/type.island/src/main/java/net/swofty/type/island/lifecycle/IslandLifecycleSteps.java new file mode 100644 index 000000000..033280014 --- /dev/null +++ b/type.island/src/main/java/net/swofty/type/island/lifecycle/IslandLifecycleSteps.java @@ -0,0 +1,25 @@ +package net.swofty.type.island.lifecycle; + +import net.swofty.type.skyblockgeneric.user.island.IslandLifecycle; + +public final class IslandLifecycleSteps { + private static boolean registered = false; + + private IslandLifecycleSteps() { + } + + public static void register() { + if (registered) return; + + IslandLifecycle.register(new JerryDefaultsStep()); + IslandLifecycle.register(new StarterChestStep()); + IslandLifecycle.register(new FirstMinionStep()); + IslandLifecycle.register(new JerryLoadStep()); + IslandLifecycle.register(new MinionLoadStep()); + IslandLifecycle.register(new PortalBuildStep()); + IslandLifecycle.register(new MinionSaveStep()); + IslandLifecycle.register(new JerrySaveStep()); + + registered = true; + } +} diff --git a/type.island/src/main/java/net/swofty/type/island/lifecycle/JerryDefaultsStep.java b/type.island/src/main/java/net/swofty/type/island/lifecycle/JerryDefaultsStep.java new file mode 100644 index 000000000..52a12c5bc --- /dev/null +++ b/type.island/src/main/java/net/swofty/type/island/lifecycle/JerryDefaultsStep.java @@ -0,0 +1,19 @@ +package net.swofty.type.island.lifecycle; + +import net.minestom.server.coordinate.Pos; +import net.swofty.type.skyblockgeneric.user.island.IslandLifecycleContext; +import net.swofty.type.skyblockgeneric.user.island.IslandLifecyclePhase; +import net.swofty.type.skyblockgeneric.user.island.IslandLifecycleStep; +import net.swofty.type.skyblockgeneric.utility.JerryInformation; + +public class JerryDefaultsStep implements IslandLifecycleStep { + @Override + public IslandLifecyclePhase phase() { + return IslandLifecyclePhase.CREATE; + } + + @Override + public void run(IslandLifecycleContext context) { + context.island().setJerryInformation(new JerryInformation(null, new Pos(9.5, 100, 33.5, 145, 0), null)); + } +} diff --git a/type.island/src/main/java/net/swofty/type/island/events/custom/ActionIslandLoadJerry.java b/type.island/src/main/java/net/swofty/type/island/lifecycle/JerryLoadStep.java similarity index 58% rename from type.island/src/main/java/net/swofty/type/island/events/custom/ActionIslandLoadJerry.java rename to type.island/src/main/java/net/swofty/type/island/lifecycle/JerryLoadStep.java index 20c1964c7..f712ff3cb 100644 --- a/type.island/src/main/java/net/swofty/type/island/events/custom/ActionIslandLoadJerry.java +++ b/type.island/src/main/java/net/swofty/type/island/lifecycle/JerryLoadStep.java @@ -1,24 +1,26 @@ -package net.swofty.type.island.events.custom; +package net.swofty.type.island.lifecycle; import net.minestom.server.coordinate.Pos; import net.minestom.server.entity.Entity; import net.minestom.server.entity.EntityType; import net.swofty.type.generic.entity.hologram.ServerHolograms; -import net.swofty.type.generic.event.EventNodes; -import net.swofty.type.generic.event.HypixelEvent; -import net.swofty.type.generic.event.HypixelEventClass; import net.swofty.type.generic.utility.MathUtility; -import net.swofty.type.skyblockgeneric.event.custom.IslandFetchedFromDatabaseEvent; +import net.swofty.type.skyblockgeneric.user.island.IslandLifecycleContext; +import net.swofty.type.skyblockgeneric.user.island.IslandLifecyclePhase; +import net.swofty.type.skyblockgeneric.user.island.IslandLifecycleStep; import net.swofty.type.skyblockgeneric.utility.JerryInformation; import org.bson.Document; -public class ActionIslandLoadJerry implements HypixelEventClass { - +public class JerryLoadStep implements IslandLifecycleStep { + @Override + public IslandLifecyclePhase phase() { + return IslandLifecyclePhase.LOAD; + } - @HypixelEvent(node = EventNodes.CUSTOM, requireDataLoaded = false) - public void run(IslandFetchedFromDatabaseEvent event) { - Document document = event.getIsland().getDatabase().getDocument(); - JerryInformation jerryInformation = event.getIsland().getJerryInformation(); + @Override + public void run(IslandLifecycleContext context) { + Document document = context.island().getDatabase().getDocument(); + JerryInformation jerryInformation = context.island().getJerryInformation(); if (jerryInformation == null) { jerryInformation = new JerryInformation(null, null, null); @@ -35,31 +37,25 @@ public void run(IslandFetchedFromDatabaseEvent event) { ) ); } else { - jerryInformation.setJerryPosition( - new Pos(9.5, 100, 33.5, 145, 0) - ); + jerryInformation.setJerryPosition(new Pos(9.5, 100, 33.5, 145, 0)); } Entity jerry = new Entity(EntityType.VILLAGER); jerry.setAutoViewable(true); - jerry.setInstance( - event.getIsland().getIslandInstance(), - jerryInformation.getJerryPosition() - ); + jerry.setInstance(context.island().getIslandInstance(), jerryInformation.getJerryPosition()); jerry.setNoGravity(true); jerryInformation.setJerry(jerry); ServerHolograms.ExternalHologram hologram = ServerHolograms.ExternalHologram.builder() .text(new String[]{"§6§lNEW UPDATE", "Jerry", "§e§lCLICK"}) - .instance(event.getIsland().getIslandInstance()) - .pos(jerryInformation.getJerryPosition().add(0, 1.8, 0)) + .instance(context.island().getIslandInstance()) + .pos(jerryInformation.getJerryPosition().add(0, 1.8, 0)) .build(); ServerHolograms.addExternalHologram(hologram); jerryInformation.setHologram(hologram); - - event.getIsland().setJerryInformation(jerryInformation); + context.island().setJerryInformation(jerryInformation); } } diff --git a/type.island/src/main/java/net/swofty/type/island/lifecycle/JerrySaveStep.java b/type.island/src/main/java/net/swofty/type/island/lifecycle/JerrySaveStep.java new file mode 100644 index 000000000..c5bc97efa --- /dev/null +++ b/type.island/src/main/java/net/swofty/type/island/lifecycle/JerrySaveStep.java @@ -0,0 +1,41 @@ +package net.swofty.type.island.lifecycle; + +import net.swofty.type.generic.entity.hologram.ServerHolograms; +import net.swofty.type.skyblockgeneric.user.island.IslandLifecycleContext; +import net.swofty.type.skyblockgeneric.user.island.IslandLifecyclePhase; +import net.swofty.type.skyblockgeneric.user.island.IslandLifecycleStep; +import net.swofty.type.skyblockgeneric.utility.JerryInformation; + +public class JerrySaveStep implements IslandLifecycleStep { + @Override + public IslandLifecyclePhase phase() { + return IslandLifecyclePhase.SAVE; + } + + @Override + public int order() { + return 10; + } + + @Override + public void run(IslandLifecycleContext context) { + JerryInformation jerryInformation = context.island().getJerryInformation(); + + if (jerryInformation == null) return; + + if (jerryInformation.getJerry() != null) { + jerryInformation.getJerry().remove(); + } + if (jerryInformation.getHologram() != null) { + ServerHolograms.removeExternalHologram(jerryInformation.getHologram()); + } + + if (jerryInformation.getJerryPosition() == null) return; + + context.island().getDatabase().insertOrUpdate("jerry_position_x", jerryInformation.getJerryPosition().x()); + context.island().getDatabase().insertOrUpdate("jerry_position_y", jerryInformation.getJerryPosition().y()); + context.island().getDatabase().insertOrUpdate("jerry_position_z", jerryInformation.getJerryPosition().z()); + context.island().getDatabase().insertOrUpdate("jerry_position_yaw", (double) jerryInformation.getJerryPosition().yaw()); + context.island().getDatabase().insertOrUpdate("jerry_position_pitch", (double) jerryInformation.getJerryPosition().pitch()); + } +} diff --git a/type.island/src/main/java/net/swofty/type/island/lifecycle/MinionLoadStep.java b/type.island/src/main/java/net/swofty/type/island/lifecycle/MinionLoadStep.java new file mode 100644 index 000000000..df3a23d12 --- /dev/null +++ b/type.island/src/main/java/net/swofty/type/island/lifecycle/MinionLoadStep.java @@ -0,0 +1,69 @@ +package net.swofty.type.island.lifecycle; + +import net.swofty.type.skyblockgeneric.item.SkyBlockItem; +import net.swofty.type.skyblockgeneric.minion.IslandMinionData; +import net.swofty.type.skyblockgeneric.minion.MinionAction; +import net.swofty.type.skyblockgeneric.minion.SkyBlockMinion; +import net.swofty.type.skyblockgeneric.user.island.IslandLifecycleContext; +import net.swofty.type.skyblockgeneric.user.island.IslandLifecyclePhase; +import net.swofty.type.skyblockgeneric.user.island.IslandLifecycleStep; +import org.bson.Document; + +import java.util.List; +import java.util.Map; + +public class MinionLoadStep implements IslandLifecycleStep { + @Override + public IslandLifecyclePhase phase() { + return IslandLifecyclePhase.LOAD; + } + + @Override + public int order() { + return 10; + } + + @Override + public void run(IslandLifecycleContext context) { + Document document = context.island().getDatabase().getDocument(); + Map rawData = document == null ? null : (Map) document.get("minions"); + + IslandMinionData minionData = rawData == null + ? new IslandMinionData(context.island()) + : IslandMinionData.deserialize(rawData, context.island()); + + context.island().setMinionData(minionData); + + long lastSaved = context.island().getLastSaved(); + long currentTime = System.currentTimeMillis(); + + minionData.getMinions().forEach(data -> { + int tierIndex = data.getTier(); + SkyBlockMinion.MinionTier tier = data.getMinion().asSkyBlockMinion().getTiers().get(tierIndex - 1); + + long timeBetweenActions = (long) tier.timeBetweenActions(); + double percentageSpeedIncrease = data.getSpeedPercentage(); + + timeBetweenActions = (long) (timeBetweenActions / (1 + (percentageSpeedIncrease / 100))); + + int amountOfActions = Math.round((float) (currentTime - lastSaved) / (timeBetweenActions * 1000L)); + + data.spawnMinion(context.island().getIslandInstance()); + if (lastSaved != 0) { + Thread.startVirtualThread(() -> { + for (int i = 0; i < amountOfActions; i++) { + MinionAction action = data.getMinion().asSkyBlockMinion().getAction(); + List items = action.onAction( + new MinionAction.MinionActionEvent(), + data, + context.island().getIslandInstance()); + + if (!items.isEmpty()) { + MinionAction.onMinionIteration(data, data.getMinionEntity().getMinion(), items); + } + } + }); + } + }); + } +} diff --git a/type.island/src/main/java/net/swofty/type/island/lifecycle/MinionSaveStep.java b/type.island/src/main/java/net/swofty/type/island/lifecycle/MinionSaveStep.java new file mode 100644 index 000000000..a20dfc49b --- /dev/null +++ b/type.island/src/main/java/net/swofty/type/island/lifecycle/MinionSaveStep.java @@ -0,0 +1,20 @@ +package net.swofty.type.island.lifecycle; + +import net.swofty.type.skyblockgeneric.minion.IslandMinionData; +import net.swofty.type.skyblockgeneric.user.island.IslandLifecycleContext; +import net.swofty.type.skyblockgeneric.user.island.IslandLifecyclePhase; +import net.swofty.type.skyblockgeneric.user.island.IslandLifecycleStep; + +public class MinionSaveStep implements IslandLifecycleStep { + @Override + public IslandLifecyclePhase phase() { + return IslandLifecyclePhase.SAVE; + } + + @Override + public void run(IslandLifecycleContext context) { + IslandMinionData minionData = context.island().getMinionData(); + minionData.getMinions().forEach(IslandMinionData.IslandMinion::removeMinion); + context.island().getDatabase().insertOrUpdate("minions", minionData.serialize()); + } +} diff --git a/type.island/src/main/java/net/swofty/type/island/lifecycle/PortalBuildStep.java b/type.island/src/main/java/net/swofty/type/island/lifecycle/PortalBuildStep.java new file mode 100644 index 000000000..6c7351226 --- /dev/null +++ b/type.island/src/main/java/net/swofty/type/island/lifecycle/PortalBuildStep.java @@ -0,0 +1,25 @@ +package net.swofty.type.island.lifecycle; + +import net.swofty.type.skyblockgeneric.structure.structures.IslandPortal; +import net.swofty.type.skyblockgeneric.user.island.IslandLifecycleContext; +import net.swofty.type.skyblockgeneric.user.island.IslandLifecyclePhase; +import net.swofty.type.skyblockgeneric.user.island.IslandLifecycleStep; + +public class PortalBuildStep implements IslandLifecycleStep { + @Override + public IslandLifecyclePhase phase() { + return IslandLifecyclePhase.LOAD; + } + + @Override + public int order() { + return 20; + } + + @Override + public void run(IslandLifecycleContext context) { + IslandPortal portal = new IslandPortal(0, 6, 100, 43); + portal.setType(IslandPortal.PortalType.HUB); + portal.build(context.island().getIslandInstance()); + } +} diff --git a/type.island/src/main/java/net/swofty/type/island/lifecycle/StarterChestStep.java b/type.island/src/main/java/net/swofty/type/island/lifecycle/StarterChestStep.java new file mode 100644 index 000000000..b297a6c72 --- /dev/null +++ b/type.island/src/main/java/net/swofty/type/island/lifecycle/StarterChestStep.java @@ -0,0 +1,36 @@ +package net.swofty.type.island.lifecycle; + +import net.minestom.server.coordinate.Pos; +import net.minestom.server.item.ItemStack; +import net.minestom.server.item.Material; +import net.swofty.type.generic.utility.MathUtility; +import net.swofty.type.skyblockgeneric.block.placement.states.state.Facing; +import net.swofty.type.skyblockgeneric.chest.ChestBuilder; +import net.swofty.type.skyblockgeneric.chest.ChestType; +import net.swofty.type.skyblockgeneric.user.island.IslandLifecycleContext; +import net.swofty.type.skyblockgeneric.user.island.IslandLifecyclePhase; +import net.swofty.type.skyblockgeneric.user.island.IslandLifecycleStep; + +public class StarterChestStep implements IslandLifecycleStep { + @Override + public IslandLifecyclePhase phase() { + return IslandLifecyclePhase.CREATE; + } + + @Override + public int order() { + return 10; + } + + @Override + public void run(IslandLifecycleContext context) { + MathUtility.delay(() -> new ChestBuilder(context.island().getIslandInstance(), new Pos(10, 93, 38), ChestType.SINGLE, Facing.WEST) + .setItem(0, ItemStack.of(Material.DIRT, 5)) + .setItem(1, ItemStack.of(Material.GRASS_BLOCK, 7)) + .setItem(2, ItemStack.of(Material.COBBLESTONE, 8)) + .setItem(3, ItemStack.of(Material.WATER_BUCKET)) + .setItem(4, ItemStack.of(Material.LAVA_BUCKET)) + .setItem(5, ItemStack.of(Material.BONE_MEAL, 3)) + .build(), 60); + } +} diff --git a/type.jerrysworkshop/src/main/java/net/swofty/type/jerrysworkshop/events/ActionPlayerJoin.java b/type.jerrysworkshop/src/main/java/net/swofty/type/jerrysworkshop/events/ActionPlayerJoin.java index 59b201f03..465e3fb5e 100644 --- a/type.jerrysworkshop/src/main/java/net/swofty/type/jerrysworkshop/events/ActionPlayerJoin.java +++ b/type.jerrysworkshop/src/main/java/net/swofty/type/jerrysworkshop/events/ActionPlayerJoin.java @@ -4,14 +4,15 @@ import net.minestom.server.event.player.AsyncPlayerConfigurationEvent; import net.swofty.type.generic.HypixelConst; import net.swofty.type.generic.event.EventNodes; -import net.swofty.type.generic.event.HypixelEvent; import net.swofty.type.generic.event.HypixelEventClass; +import net.swofty.type.generic.event.phase.EventPhase; +import net.swofty.type.generic.event.phase.PhasedEvent; import net.swofty.type.skyblockgeneric.user.SkyBlockPlayer; public class ActionPlayerJoin implements HypixelEventClass { @SneakyThrows - @HypixelEvent(node = EventNodes.PLAYER, requireDataLoaded = false) + @PhasedEvent(node = EventNodes.PLAYER, requireDataLoaded = false, phase = EventPhase.CONNECT) public void run(AsyncPlayerConfigurationEvent event) { final SkyBlockPlayer player = (SkyBlockPlayer) event.getPlayer(); diff --git a/type.lobby/src/main/java/net/swofty/type/lobby/events/LobbyBlockBreak.java b/type.lobby/src/main/java/net/swofty/type/lobby/events/LobbyBlockBreak.java index da1b913ed..3138e4cb7 100644 --- a/type.lobby/src/main/java/net/swofty/type/lobby/events/LobbyBlockBreak.java +++ b/type.lobby/src/main/java/net/swofty/type/lobby/events/LobbyBlockBreak.java @@ -2,12 +2,13 @@ import net.minestom.server.event.player.PlayerBlockBreakEvent; import net.swofty.type.generic.event.EventNodes; -import net.swofty.type.generic.event.HypixelEvent; import net.swofty.type.generic.event.HypixelEventClass; +import net.swofty.type.generic.event.phase.EventPhase; +import net.swofty.type.generic.event.phase.PhasedEvent; public class LobbyBlockBreak implements HypixelEventClass { - @HypixelEvent(node = EventNodes.PLAYER, requireDataLoaded = false) + @PhasedEvent(node = EventNodes.PLAYER, requireDataLoaded = false, phase = EventPhase.GAMEPLAY) public void onBlockBreak(PlayerBlockBreakEvent event) { event.setCancelled(true); } diff --git a/type.lobby/src/main/java/net/swofty/type/lobby/events/LobbyItemEvents.java b/type.lobby/src/main/java/net/swofty/type/lobby/events/LobbyItemEvents.java index 0091c19ae..ebab2dba7 100644 --- a/type.lobby/src/main/java/net/swofty/type/lobby/events/LobbyItemEvents.java +++ b/type.lobby/src/main/java/net/swofty/type/lobby/events/LobbyItemEvents.java @@ -7,8 +7,9 @@ import net.minestom.server.event.player.PlayerUseItemOnBlockEvent; import net.swofty.type.generic.HypixelConst; import net.swofty.type.generic.event.EventNodes; -import net.swofty.type.generic.event.HypixelEvent; import net.swofty.type.generic.event.HypixelEventClass; +import net.swofty.type.generic.event.phase.EventPhase; +import net.swofty.type.generic.event.phase.PhasedEvent; import net.swofty.type.lobby.LobbyTypeLoader; import net.swofty.type.lobby.item.LobbyItemHandler; @@ -21,7 +22,7 @@ private static LobbyItemHandler getHandler() { return null; } - @HypixelEvent(node = EventNodes.PLAYER, requireDataLoaded = true) + @PhasedEvent(node = EventNodes.PLAYER, requireDataLoaded = true, phase = EventPhase.GAMEPLAY) public void onItemFinishUse(PlayerFinishItemUseEvent event) { LobbyItemHandler handler = getHandler(); if (handler != null) { @@ -29,7 +30,7 @@ public void onItemFinishUse(PlayerFinishItemUseEvent event) { } } - @HypixelEvent(node = EventNodes.PLAYER, requireDataLoaded = true) + @PhasedEvent(node = EventNodes.PLAYER, requireDataLoaded = true, phase = EventPhase.GAMEPLAY) public void onItemUseOnBlock(PlayerUseItemOnBlockEvent event) { LobbyItemHandler handler = getHandler(); if (handler != null) { @@ -37,7 +38,7 @@ public void onItemUseOnBlock(PlayerUseItemOnBlockEvent event) { } } - @HypixelEvent(node = EventNodes.PLAYER, requireDataLoaded = true) + @PhasedEvent(node = EventNodes.PLAYER, requireDataLoaded = true, phase = EventPhase.GAMEPLAY) public void onItemUse(PlayerUseItemEvent event) { LobbyItemHandler handler = getHandler(); if (handler != null) { @@ -45,7 +46,7 @@ public void onItemUse(PlayerUseItemEvent event) { } } - @HypixelEvent(node = EventNodes.ITEM, requireDataLoaded = true) + @PhasedEvent(node = EventNodes.ITEM, requireDataLoaded = true, phase = EventPhase.GAMEPLAY) public void onItemDrop(ItemDropEvent event) { LobbyItemHandler handler = getHandler(); if (handler != null) { @@ -53,7 +54,7 @@ public void onItemDrop(ItemDropEvent event) { } } - @HypixelEvent(node = EventNodes.PLAYER, requireDataLoaded = true) + @PhasedEvent(node = EventNodes.PLAYER, requireDataLoaded = true, phase = EventPhase.GAMEPLAY) public void onBlockPlace(PlayerBlockPlaceEvent event) { LobbyItemHandler handler = getHandler(); if (handler != null) { diff --git a/type.lobby/src/main/java/net/swofty/type/lobby/events/LobbyLaunchPadEvents.java b/type.lobby/src/main/java/net/swofty/type/lobby/events/LobbyLaunchPadEvents.java index f1a59e3a9..58d483a21 100644 --- a/type.lobby/src/main/java/net/swofty/type/lobby/events/LobbyLaunchPadEvents.java +++ b/type.lobby/src/main/java/net/swofty/type/lobby/events/LobbyLaunchPadEvents.java @@ -7,15 +7,16 @@ import net.minestom.server.network.packet.server.play.ParticlePacket; import net.minestom.server.particle.Particle; import net.swofty.type.generic.event.EventNodes; -import net.swofty.type.generic.event.HypixelEvent; import net.swofty.type.generic.event.HypixelEventClass; +import net.swofty.type.generic.event.phase.EventPhase; +import net.swofty.type.generic.event.phase.PhasedEvent; import net.swofty.type.generic.user.HypixelPlayer; import net.swofty.type.lobby.launchpad.LaunchPad; import net.swofty.type.lobby.launchpad.LaunchPadHandler; public class LobbyLaunchPadEvents implements HypixelEventClass { - @HypixelEvent(node = EventNodes.PLAYER, requireDataLoaded = true, isAsync = true) + @PhasedEvent(node = EventNodes.PLAYER, requireDataLoaded = true, isAsync = true, phase = EventPhase.GAMEPLAY) public void run(PlayerMoveEvent event) { HypixelPlayer player = (HypixelPlayer) event.getPlayer(); diff --git a/type.lobby/src/main/java/net/swofty/type/lobby/events/LobbyParkourEvents.java b/type.lobby/src/main/java/net/swofty/type/lobby/events/LobbyParkourEvents.java index ac4dd3701..f2445daa3 100644 --- a/type.lobby/src/main/java/net/swofty/type/lobby/events/LobbyParkourEvents.java +++ b/type.lobby/src/main/java/net/swofty/type/lobby/events/LobbyParkourEvents.java @@ -8,8 +8,9 @@ import net.minestom.server.event.player.PlayerSpawnEvent; import net.swofty.type.generic.HypixelConst; import net.swofty.type.generic.event.EventNodes; -import net.swofty.type.generic.event.HypixelEvent; import net.swofty.type.generic.event.HypixelEventClass; +import net.swofty.type.generic.event.phase.EventPhase; +import net.swofty.type.generic.event.phase.PhasedEvent; import net.swofty.type.generic.user.HypixelPlayer; import net.swofty.type.generic.utility.MathUtility; import net.swofty.type.lobby.LobbyTypeLoader; @@ -22,7 +23,7 @@ public class LobbyParkourEvents implements HypixelEventClass { private final HashMap lastClickedTimes = new HashMap<>(); - @HypixelEvent(node = EventNodes.PLAYER, requireDataLoaded = false) + @PhasedEvent(node = EventNodes.PLAYER, requireDataLoaded = false, phase = EventPhase.GAMEPLAY) public void onPlayerJoin(PlayerSpawnEvent event) { HypixelPlayer player = (HypixelPlayer) event.getPlayer(); LobbyTypeLoader loader = (LobbyTypeLoader) HypixelConst.getTypeLoader(); @@ -33,7 +34,7 @@ public void onPlayerJoin(PlayerSpawnEvent event) { parkourManager.updateForPlayer(HypixelConst.getInstanceContainer(), player); } - @HypixelEvent(node = EventNodes.PLAYER, requireDataLoaded = false) + @PhasedEvent(node = EventNodes.PLAYER, requireDataLoaded = false, phase = EventPhase.GAMEPLAY) public void onPlayerDisconnect(PlayerDisconnectEvent event) { HypixelPlayer player = (HypixelPlayer) event.getPlayer(); lastClickedTimes.remove(player.getUuid()); @@ -45,7 +46,7 @@ public void onPlayerDisconnect(PlayerDisconnectEvent event) { parkourManager.cancelParkour(player); } - @HypixelEvent(node = EventNodes.PLAYER, requireDataLoaded = true) + @PhasedEvent(node = EventNodes.PLAYER, requireDataLoaded = true, phase = EventPhase.GAMEPLAY) public void run(PlayerMoveEvent event) { LobbyTypeLoader loader = (LobbyTypeLoader) HypixelConst.getTypeLoader(); final HypixelPlayer player = (HypixelPlayer) event.getPlayer(); diff --git a/type.lobby/src/main/java/net/swofty/type/lobby/events/LobbyPlayerJoinEvents.java b/type.lobby/src/main/java/net/swofty/type/lobby/events/LobbyPlayerJoinEvents.java index 354dafdee..68272e57e 100644 --- a/type.lobby/src/main/java/net/swofty/type/lobby/events/LobbyPlayerJoinEvents.java +++ b/type.lobby/src/main/java/net/swofty/type/lobby/events/LobbyPlayerJoinEvents.java @@ -5,8 +5,9 @@ import net.minestom.server.event.player.AsyncPlayerConfigurationEvent; import net.swofty.type.generic.HypixelConst; import net.swofty.type.generic.event.EventNodes; -import net.swofty.type.generic.event.HypixelEvent; import net.swofty.type.generic.event.HypixelEventClass; +import net.swofty.type.generic.event.phase.EventPhase; +import net.swofty.type.generic.event.phase.PhasedEvent; import net.swofty.type.generic.user.HypixelPlayer; import net.swofty.type.lobby.LobbyTypeLoader; import net.swofty.type.lobby.item.LobbyItem; @@ -22,7 +23,7 @@ public class LobbyPlayerJoinEvents implements HypixelEventClass { @SneakyThrows - @HypixelEvent(node = EventNodes.PLAYER, requireDataLoaded = false) + @PhasedEvent(node = EventNodes.PLAYER, requireDataLoaded = false, phase = EventPhase.GAMEPLAY) public void run(AsyncPlayerConfigurationEvent event) { final HypixelPlayer player = (HypixelPlayer) event.getPlayer(); diff --git a/type.lobby/src/main/java/net/swofty/type/lobby/events/LobbyPlayerMove.java b/type.lobby/src/main/java/net/swofty/type/lobby/events/LobbyPlayerMove.java index 2e20ff4e0..715cf48a9 100644 --- a/type.lobby/src/main/java/net/swofty/type/lobby/events/LobbyPlayerMove.java +++ b/type.lobby/src/main/java/net/swofty/type/lobby/events/LobbyPlayerMove.java @@ -4,8 +4,9 @@ import net.minestom.server.entity.Player; import net.minestom.server.event.player.PlayerMoveEvent; import net.swofty.type.generic.event.EventNodes; -import net.swofty.type.generic.event.HypixelEvent; import net.swofty.type.generic.event.HypixelEventClass; +import net.swofty.type.generic.event.phase.EventPhase; +import net.swofty.type.generic.event.phase.PhasedEvent; public class LobbyPlayerMove implements HypixelEventClass { private final Pos spawnPoint; @@ -14,7 +15,7 @@ public LobbyPlayerMove(Pos spawnPoint) { this.spawnPoint = spawnPoint; } - @HypixelEvent(node = EventNodes.PLAYER, requireDataLoaded = false) + @PhasedEvent(node = EventNodes.PLAYER, requireDataLoaded = false, phase = EventPhase.GAMEPLAY) public void onPlayerMove(PlayerMoveEvent event) { Player player = event.getPlayer(); if (player.getPosition().y() < 0) { diff --git a/type.murdermysteryconfigurator/src/main/java/net/swofty/type/murdermysteryconfigurator/events/ActionPlayerBreak.java b/type.murdermysteryconfigurator/src/main/java/net/swofty/type/murdermysteryconfigurator/events/ActionPlayerBreak.java index 82616df2e..cab37927a 100644 --- a/type.murdermysteryconfigurator/src/main/java/net/swofty/type/murdermysteryconfigurator/events/ActionPlayerBreak.java +++ b/type.murdermysteryconfigurator/src/main/java/net/swofty/type/murdermysteryconfigurator/events/ActionPlayerBreak.java @@ -3,13 +3,14 @@ import lombok.SneakyThrows; import net.minestom.server.event.player.PlayerBlockBreakEvent; import net.swofty.type.generic.event.EventNodes; -import net.swofty.type.generic.event.HypixelEvent; import net.swofty.type.generic.event.HypixelEventClass; +import net.swofty.type.generic.event.phase.EventPhase; +import net.swofty.type.generic.event.phase.PhasedEvent; public class ActionPlayerBreak implements HypixelEventClass { @SneakyThrows - @HypixelEvent(node = EventNodes.PLAYER, requireDataLoaded = false) + @PhasedEvent(node = EventNodes.PLAYER, requireDataLoaded = false, phase = EventPhase.GAMEPLAY) public void run(PlayerBlockBreakEvent event) { // Prevent block breaking in configurator mode event.setCancelled(true); diff --git a/type.murdermysteryconfigurator/src/main/java/net/swofty/type/murdermysteryconfigurator/events/ActionPlayerDataSpawn.java b/type.murdermysteryconfigurator/src/main/java/net/swofty/type/murdermysteryconfigurator/events/ActionPlayerDataSpawn.java index 510497ed6..faa418549 100644 --- a/type.murdermysteryconfigurator/src/main/java/net/swofty/type/murdermysteryconfigurator/events/ActionPlayerDataSpawn.java +++ b/type.murdermysteryconfigurator/src/main/java/net/swofty/type/murdermysteryconfigurator/events/ActionPlayerDataSpawn.java @@ -3,13 +3,14 @@ import net.kyori.adventure.text.Component; import net.minestom.server.event.player.PlayerSpawnEvent; import net.swofty.type.generic.event.EventNodes; -import net.swofty.type.generic.event.HypixelEvent; import net.swofty.type.generic.event.HypixelEventClass; +import net.swofty.type.generic.event.phase.EventPhase; +import net.swofty.type.generic.event.phase.PhasedEvent; import net.swofty.type.generic.user.HypixelPlayer; public class ActionPlayerDataSpawn implements HypixelEventClass { - @HypixelEvent(node = EventNodes.PLAYER_DATA, requireDataLoaded = false, isAsync = true) + @PhasedEvent(node = EventNodes.PLAYER_DATA, requireDataLoaded = false, isAsync = true, phase = EventPhase.POST_SPAWN) public void run(PlayerSpawnEvent event) { if (!event.isFirstSpawn()) return; diff --git a/type.murdermysteryconfigurator/src/main/java/net/swofty/type/murdermysteryconfigurator/events/ActionPlayerJoin.java b/type.murdermysteryconfigurator/src/main/java/net/swofty/type/murdermysteryconfigurator/events/ActionPlayerJoin.java index 6fd553c30..6dc60dd87 100644 --- a/type.murdermysteryconfigurator/src/main/java/net/swofty/type/murdermysteryconfigurator/events/ActionPlayerJoin.java +++ b/type.murdermysteryconfigurator/src/main/java/net/swofty/type/murdermysteryconfigurator/events/ActionPlayerJoin.java @@ -4,15 +4,16 @@ import net.minestom.server.event.player.AsyncPlayerConfigurationEvent; import net.swofty.type.generic.HypixelConst; import net.swofty.type.generic.event.EventNodes; -import net.swofty.type.generic.event.HypixelEvent; import net.swofty.type.generic.event.HypixelEventClass; +import net.swofty.type.generic.event.phase.EventPhase; +import net.swofty.type.generic.event.phase.PhasedEvent; import net.swofty.type.generic.user.HypixelPlayer; import org.tinylog.Logger; public class ActionPlayerJoin implements HypixelEventClass { @SneakyThrows - @HypixelEvent(node = EventNodes.PLAYER, requireDataLoaded = false) + @PhasedEvent(node = EventNodes.PLAYER, requireDataLoaded = false, phase = EventPhase.CONNECT) public void run(AsyncPlayerConfigurationEvent event) { final HypixelPlayer player = (HypixelPlayer) event.getPlayer(); diff --git a/type.murdermysterygame/src/main/java/net/swofty/type/murdermysterygame/events/ActionArrowHit.java b/type.murdermysterygame/src/main/java/net/swofty/type/murdermysterygame/events/ActionArrowHit.java index 7be28340f..0a6e15b15 100644 --- a/type.murdermysterygame/src/main/java/net/swofty/type/murdermysterygame/events/ActionArrowHit.java +++ b/type.murdermysterygame/src/main/java/net/swofty/type/murdermysterygame/events/ActionArrowHit.java @@ -5,8 +5,9 @@ import net.swofty.pvp.projectile.AbstractProjectile; import net.swofty.type.generic.achievement.PlayerAchievementHandler; import net.swofty.type.generic.event.EventNodes; -import net.swofty.type.generic.event.HypixelEvent; import net.swofty.type.generic.event.HypixelEventClass; +import net.swofty.type.generic.event.phase.EventPhase; +import net.swofty.type.generic.event.phase.PhasedEvent; import net.swofty.type.murdermysterygame.TypeMurderMysteryGameLoader; import net.swofty.type.murdermysterygame.game.Game; import net.swofty.type.murdermysterygame.game.GameStatus; @@ -15,7 +16,7 @@ public class ActionArrowHit implements HypixelEventClass { - @HypixelEvent(node = EventNodes.ALL, requireDataLoaded = false) + @PhasedEvent(node = EventNodes.ALL, requireDataLoaded = false, phase = EventPhase.GAMEPLAY) public void run(ProjectileCollideWithEntityEvent event) { Entity projectile = event.getEntity(); Entity target = event.getTarget(); diff --git a/type.murdermysterygame/src/main/java/net/swofty/type/murdermysterygame/events/ActionArrowShoot.java b/type.murdermysterygame/src/main/java/net/swofty/type/murdermysterygame/events/ActionArrowShoot.java index 5436ebc7a..5a6cf6b1f 100644 --- a/type.murdermysterygame/src/main/java/net/swofty/type/murdermysterygame/events/ActionArrowShoot.java +++ b/type.murdermysterygame/src/main/java/net/swofty/type/murdermysterygame/events/ActionArrowShoot.java @@ -4,8 +4,9 @@ import net.minestom.server.item.Material; import net.swofty.type.generic.achievement.PlayerAchievementHandler; import net.swofty.type.generic.event.EventNodes; -import net.swofty.type.generic.event.HypixelEvent; import net.swofty.type.generic.event.HypixelEventClass; +import net.swofty.type.generic.event.phase.EventPhase; +import net.swofty.type.generic.event.phase.PhasedEvent; import net.swofty.type.murdermysterygame.TypeMurderMysteryGameLoader; import net.swofty.type.murdermysterygame.game.Game; import net.swofty.type.murdermysterygame.game.GameStatus; @@ -13,7 +14,7 @@ public class ActionArrowShoot implements HypixelEventClass { - @HypixelEvent(node = EventNodes.ALL, requireDataLoaded = false) + @PhasedEvent(node = EventNodes.ALL, requireDataLoaded = false, phase = EventPhase.GAMEPLAY) public void run(PlayerCancelItemUseEvent event) { if (event.getItemStack().material() != Material.BOW) return; if (!(event.getPlayer() instanceof MurderMysteryPlayer player)) return; diff --git a/type.murdermysterygame/src/main/java/net/swofty/type/murdermysterygame/events/ActionBlockInteraction.java b/type.murdermysterygame/src/main/java/net/swofty/type/murdermysterygame/events/ActionBlockInteraction.java index 15a9b01e0..0f481b5e8 100644 --- a/type.murdermysterygame/src/main/java/net/swofty/type/murdermysterygame/events/ActionBlockInteraction.java +++ b/type.murdermysterygame/src/main/java/net/swofty/type/murdermysterygame/events/ActionBlockInteraction.java @@ -3,8 +3,9 @@ import net.minestom.server.coordinate.Point; import net.minestom.server.event.player.PlayerBlockInteractEvent; import net.swofty.type.generic.event.EventNodes; -import net.swofty.type.generic.event.HypixelEvent; import net.swofty.type.generic.event.HypixelEventClass; +import net.swofty.type.generic.event.phase.EventPhase; +import net.swofty.type.generic.event.phase.PhasedEvent; import net.swofty.type.murdermysterygame.TypeMurderMysteryGameLoader; import net.swofty.type.murdermysterygame.game.Game; import net.swofty.type.murdermysterygame.game.GameStatus; @@ -14,7 +15,7 @@ public class ActionBlockInteraction implements HypixelEventClass { - @HypixelEvent(node = EventNodes.PLAYER, requireDataLoaded = false) + @PhasedEvent(node = EventNodes.PLAYER, requireDataLoaded = false, phase = EventPhase.GAMEPLAY) public void run(PlayerBlockInteractEvent event) { Point blockPos = event.getBlockPosition(); diff --git a/type.murdermysterygame/src/main/java/net/swofty/type/murdermysterygame/events/ActionGameCustomItems.java b/type.murdermysterygame/src/main/java/net/swofty/type/murdermysterygame/events/ActionGameCustomItems.java index 99ccdfd6a..69cf1978a 100644 --- a/type.murdermysterygame/src/main/java/net/swofty/type/murdermysterygame/events/ActionGameCustomItems.java +++ b/type.murdermysterygame/src/main/java/net/swofty/type/murdermysterygame/events/ActionGameCustomItems.java @@ -6,27 +6,28 @@ import net.minestom.server.event.player.PlayerUseItemOnBlockEvent; import net.swofty.type.murdermysterygame.TypeMurderMysteryGameLoader; import net.swofty.type.generic.event.EventNodes; -import net.swofty.type.generic.event.HypixelEvent; import net.swofty.type.generic.event.HypixelEventClass; +import net.swofty.type.generic.event.phase.EventPhase; +import net.swofty.type.generic.event.phase.PhasedEvent; public class ActionGameCustomItems implements HypixelEventClass { - @HypixelEvent(node = EventNodes.ALL, requireDataLoaded = false) + @PhasedEvent(node = EventNodes.ALL, requireDataLoaded = false, phase = EventPhase.GAMEPLAY) public void run(PlayerUseItemOnBlockEvent event) { TypeMurderMysteryGameLoader.getItemHandler().onItemUseOnBlock(event); } - @HypixelEvent(node = EventNodes.ALL, requireDataLoaded = false) + @PhasedEvent(node = EventNodes.ALL, requireDataLoaded = false, phase = EventPhase.GAMEPLAY) public void run(PlayerFinishItemUseEvent event) { TypeMurderMysteryGameLoader.getItemHandler().onItemFinishUse(event); } - @HypixelEvent(node = EventNodes.ALL, requireDataLoaded = false) + @PhasedEvent(node = EventNodes.ALL, requireDataLoaded = false, phase = EventPhase.GAMEPLAY) public void run(PlayerUseItemEvent event) { TypeMurderMysteryGameLoader.getItemHandler().onItemUse(event); } - @HypixelEvent(node = EventNodes.ALL, requireDataLoaded = false) + @PhasedEvent(node = EventNodes.ALL, requireDataLoaded = false, phase = EventPhase.GAMEPLAY) public void run(PlayerBlockPlaceEvent event) { TypeMurderMysteryGameLoader.getItemHandler().onBlockPlace(event); } diff --git a/type.murdermysterygame/src/main/java/net/swofty/type/murdermysterygame/events/ActionGoldDrop.java b/type.murdermysterygame/src/main/java/net/swofty/type/murdermysterygame/events/ActionGoldDrop.java index 9345a075b..ee6c70628 100644 --- a/type.murdermysterygame/src/main/java/net/swofty/type/murdermysterygame/events/ActionGoldDrop.java +++ b/type.murdermysterygame/src/main/java/net/swofty/type/murdermysterygame/events/ActionGoldDrop.java @@ -7,12 +7,13 @@ import net.swofty.type.murdermysterygame.game.GameStatus; import net.swofty.type.murdermysterygame.user.MurderMysteryPlayer; import net.swofty.type.generic.event.EventNodes; -import net.swofty.type.generic.event.HypixelEvent; import net.swofty.type.generic.event.HypixelEventClass; +import net.swofty.type.generic.event.phase.EventPhase; +import net.swofty.type.generic.event.phase.PhasedEvent; public class ActionGoldDrop implements HypixelEventClass { - @HypixelEvent(node = EventNodes.PLAYER, requireDataLoaded = false) + @PhasedEvent(node = EventNodes.PLAYER, requireDataLoaded = false, phase = EventPhase.GAMEPLAY) public void run(ItemDropEvent event) { if (!(event.getPlayer() instanceof MurderMysteryPlayer player)) return; diff --git a/type.murdermysterygame/src/main/java/net/swofty/type/murdermysterygame/events/ActionGoldInventoryMove.java b/type.murdermysterygame/src/main/java/net/swofty/type/murdermysterygame/events/ActionGoldInventoryMove.java index ec76002a0..745484234 100644 --- a/type.murdermysterygame/src/main/java/net/swofty/type/murdermysterygame/events/ActionGoldInventoryMove.java +++ b/type.murdermysterygame/src/main/java/net/swofty/type/murdermysterygame/events/ActionGoldInventoryMove.java @@ -8,12 +8,13 @@ import net.swofty.type.murdermysterygame.game.GameStatus; import net.swofty.type.murdermysterygame.user.MurderMysteryPlayer; import net.swofty.type.generic.event.EventNodes; -import net.swofty.type.generic.event.HypixelEvent; import net.swofty.type.generic.event.HypixelEventClass; +import net.swofty.type.generic.event.phase.EventPhase; +import net.swofty.type.generic.event.phase.PhasedEvent; public class ActionGoldInventoryMove implements HypixelEventClass { - @HypixelEvent(node = EventNodes.PLAYER, requireDataLoaded = false) + @PhasedEvent(node = EventNodes.PLAYER, requireDataLoaded = false, phase = EventPhase.GAMEPLAY) public void run(InventoryItemChangeEvent event) { if (event.getInventory().getViewers().isEmpty()) return; MurderMysteryPlayer player = (MurderMysteryPlayer) event.getInventory().getViewers().stream().findFirst().orElse(null); diff --git a/type.murdermysterygame/src/main/java/net/swofty/type/murdermysterygame/events/ActionGoldPickup.java b/type.murdermysterygame/src/main/java/net/swofty/type/murdermysterygame/events/ActionGoldPickup.java index 5bca81a04..42753b0aa 100644 --- a/type.murdermysterygame/src/main/java/net/swofty/type/murdermysterygame/events/ActionGoldPickup.java +++ b/type.murdermysterygame/src/main/java/net/swofty/type/murdermysterygame/events/ActionGoldPickup.java @@ -13,12 +13,13 @@ import net.swofty.type.murdermysterygame.role.GameRole; import net.swofty.type.murdermysterygame.user.MurderMysteryPlayer; import net.swofty.type.generic.event.EventNodes; -import net.swofty.type.generic.event.HypixelEvent; import net.swofty.type.generic.event.HypixelEventClass; +import net.swofty.type.generic.event.phase.EventPhase; +import net.swofty.type.generic.event.phase.PhasedEvent; public class ActionGoldPickup implements HypixelEventClass { - @HypixelEvent(node = EventNodes.ALL, requireDataLoaded = false) + @PhasedEvent(node = EventNodes.ALL, requireDataLoaded = false, phase = EventPhase.GAMEPLAY) public void run(PickupItemEvent event) { if (!(event.getLivingEntity() instanceof MurderMysteryPlayer player)) return; diff --git a/type.murdermysterygame/src/main/java/net/swofty/type/murdermysterygame/events/ActionPlayerChat.java b/type.murdermysterygame/src/main/java/net/swofty/type/murdermysterygame/events/ActionPlayerChat.java index a4daaafe5..c8c9993c1 100644 --- a/type.murdermysterygame/src/main/java/net/swofty/type/murdermysterygame/events/ActionPlayerChat.java +++ b/type.murdermysterygame/src/main/java/net/swofty/type/murdermysterygame/events/ActionPlayerChat.java @@ -7,8 +7,9 @@ import net.swofty.type.generic.chat.StaffChat; import net.swofty.type.generic.data.datapoints.DatapointChatType; import net.swofty.type.generic.event.EventNodes; -import net.swofty.type.generic.event.HypixelEvent; import net.swofty.type.generic.event.HypixelEventClass; +import net.swofty.type.generic.event.phase.EventPhase; +import net.swofty.type.generic.event.phase.PhasedEvent; import net.swofty.type.generic.user.categories.Rank; import net.swofty.type.murdermysterygame.TypeMurderMysteryGameLoader; import net.swofty.type.murdermysterygame.game.Game; @@ -17,7 +18,7 @@ public class ActionPlayerChat implements HypixelEventClass { - @HypixelEvent(node = EventNodes.PLAYER, requireDataLoaded = false) + @PhasedEvent(node = EventNodes.PLAYER, requireDataLoaded = false, phase = EventPhase.GAMEPLAY) public void run(PlayerChatEvent event) { MurderMysteryPlayer player = (MurderMysteryPlayer) event.getPlayer(); event.setCancelled(true); diff --git a/type.murdermysterygame/src/main/java/net/swofty/type/murdermysterygame/events/ActionPlayerCombat.java b/type.murdermysterygame/src/main/java/net/swofty/type/murdermysterygame/events/ActionPlayerCombat.java index 178b397f3..1fed08e47 100644 --- a/type.murdermysterygame/src/main/java/net/swofty/type/murdermysterygame/events/ActionPlayerCombat.java +++ b/type.murdermysterygame/src/main/java/net/swofty/type/murdermysterygame/events/ActionPlayerCombat.java @@ -11,12 +11,13 @@ import net.swofty.type.murdermysterygame.role.GameRole; import net.swofty.type.murdermysterygame.user.MurderMysteryPlayer; import net.swofty.type.generic.event.EventNodes; -import net.swofty.type.generic.event.HypixelEvent; import net.swofty.type.generic.event.HypixelEventClass; +import net.swofty.type.generic.event.phase.EventPhase; +import net.swofty.type.generic.event.phase.PhasedEvent; public class ActionPlayerCombat implements HypixelEventClass { - @HypixelEvent(node = EventNodes.ALL, requireDataLoaded = false) + @PhasedEvent(node = EventNodes.ALL, requireDataLoaded = false, phase = EventPhase.GAMEPLAY) public void run(PrepareAttackEvent event) { if (!(event.getEntity() instanceof MurderMysteryPlayer attacker)) return; if (!(event.getTarget() instanceof MurderMysteryPlayer victim)) return; diff --git a/type.murdermysterygame/src/main/java/net/swofty/type/murdermysterygame/events/ActionPlayerDataSpawn.java b/type.murdermysterygame/src/main/java/net/swofty/type/murdermysterygame/events/ActionPlayerDataSpawn.java index 841fc061a..9ddc274c8 100644 --- a/type.murdermysterygame/src/main/java/net/swofty/type/murdermysterygame/events/ActionPlayerDataSpawn.java +++ b/type.murdermysterygame/src/main/java/net/swofty/type/murdermysterygame/events/ActionPlayerDataSpawn.java @@ -6,12 +6,13 @@ import net.swofty.pvp.projectile.entities.ArrowProjectile; import net.swofty.type.murdermysterygame.user.MurderMysteryPlayer; import net.swofty.type.generic.event.EventNodes; -import net.swofty.type.generic.event.HypixelEvent; import net.swofty.type.generic.event.HypixelEventClass; +import net.swofty.type.generic.event.phase.EventPhase; +import net.swofty.type.generic.event.phase.PhasedEvent; public class ActionPlayerDataSpawn implements HypixelEventClass { - @HypixelEvent(node = EventNodes.PLAYER_DATA, requireDataLoaded = false, isAsync = true) + @PhasedEvent(node = EventNodes.PLAYER_DATA, requireDataLoaded = false, isAsync = true, phase = EventPhase.POST_SPAWN) public void run(PlayerSpawnEvent event) { if (!event.isFirstSpawn()) return; final MurderMysteryPlayer player = (MurderMysteryPlayer) event.getPlayer(); diff --git a/type.murdermysterygame/src/main/java/net/swofty/type/murdermysterygame/events/ActionPlayerDisconnect.java b/type.murdermysterygame/src/main/java/net/swofty/type/murdermysterygame/events/ActionPlayerDisconnect.java index 973f2efcf..09a29bff2 100644 --- a/type.murdermysterygame/src/main/java/net/swofty/type/murdermysterygame/events/ActionPlayerDisconnect.java +++ b/type.murdermysterygame/src/main/java/net/swofty/type/murdermysterygame/events/ActionPlayerDisconnect.java @@ -6,12 +6,13 @@ import net.swofty.type.murdermysterygame.game.Game; import net.swofty.type.murdermysterygame.user.MurderMysteryPlayer; import net.swofty.type.generic.event.EventNodes; -import net.swofty.type.generic.event.HypixelEvent; import net.swofty.type.generic.event.HypixelEventClass; +import net.swofty.type.generic.event.phase.EventPhase; +import net.swofty.type.generic.event.phase.PhasedEvent; public class ActionPlayerDisconnect implements HypixelEventClass { - @HypixelEvent(node = EventNodes.PLAYER, requireDataLoaded = false) + @PhasedEvent(node = EventNodes.PLAYER, requireDataLoaded = false, phase = EventPhase.DISCONNECT) public void run(PlayerDisconnectEvent event) { MurderMysteryPlayer player = (MurderMysteryPlayer) event.getPlayer(); diff --git a/type.murdermysterygame/src/main/java/net/swofty/type/murdermysterygame/events/ActionPlayerJoin.java b/type.murdermysterygame/src/main/java/net/swofty/type/murdermysterygame/events/ActionPlayerJoin.java index d8d13d2ac..d645b8654 100644 --- a/type.murdermysterygame/src/main/java/net/swofty/type/murdermysterygame/events/ActionPlayerJoin.java +++ b/type.murdermysterygame/src/main/java/net/swofty/type/murdermysterygame/events/ActionPlayerJoin.java @@ -9,8 +9,9 @@ import net.swofty.type.murdermysterygame.user.MurderMysteryPlayer; import net.swofty.type.generic.HypixelConst; import net.swofty.type.generic.event.EventNodes; -import net.swofty.type.generic.event.HypixelEvent; import net.swofty.type.generic.event.HypixelEventClass; +import net.swofty.type.generic.event.phase.EventPhase; +import net.swofty.type.generic.event.phase.PhasedEvent; import net.swofty.type.generic.redis.service.TypedGameInformationHandler; import net.swofty.type.generic.utility.MathUtility; import org.tinylog.Logger; @@ -18,7 +19,7 @@ public class ActionPlayerJoin implements HypixelEventClass { @SneakyThrows - @HypixelEvent(node = EventNodes.PLAYER, requireDataLoaded = false) + @PhasedEvent(node = EventNodes.PLAYER, requireDataLoaded = false, phase = EventPhase.CONNECT) public void run(AsyncPlayerConfigurationEvent event) { final MurderMysteryPlayer player = (MurderMysteryPlayer) event.getPlayer(); Logger.info("Player " + player.getUsername() + " joined the server from origin server " + player.getOriginServer()); diff --git a/type.murdermysterygame/src/main/java/net/swofty/type/murdermysterygame/events/ActionPlayerTick.java b/type.murdermysterygame/src/main/java/net/swofty/type/murdermysterygame/events/ActionPlayerTick.java index 57d5c69c0..ec6010dcd 100644 --- a/type.murdermysterygame/src/main/java/net/swofty/type/murdermysterygame/events/ActionPlayerTick.java +++ b/type.murdermysterygame/src/main/java/net/swofty/type/murdermysterygame/events/ActionPlayerTick.java @@ -8,12 +8,13 @@ import net.swofty.type.murdermysterygame.game.GameStatus; import net.swofty.type.murdermysterygame.user.MurderMysteryPlayer; import net.swofty.type.generic.event.EventNodes; -import net.swofty.type.generic.event.HypixelEvent; import net.swofty.type.generic.event.HypixelEventClass; +import net.swofty.type.generic.event.phase.EventPhase; +import net.swofty.type.generic.event.phase.PhasedEvent; public class ActionPlayerTick implements HypixelEventClass { - @HypixelEvent(node = EventNodes.PLAYER, requireDataLoaded = false) + @PhasedEvent(node = EventNodes.PLAYER, requireDataLoaded = false, phase = EventPhase.GAMEPLAY) public void run(PlayerTickEvent event) { if (!(event.getPlayer() instanceof MurderMysteryPlayer player)) return; diff --git a/type.murdermysterygame/src/main/java/net/swofty/type/murdermysterygame/events/ActionPreventBlockModification.java b/type.murdermysterygame/src/main/java/net/swofty/type/murdermysterygame/events/ActionPreventBlockModification.java index a6a7f926a..bd89eecda 100644 --- a/type.murdermysterygame/src/main/java/net/swofty/type/murdermysterygame/events/ActionPreventBlockModification.java +++ b/type.murdermysterygame/src/main/java/net/swofty/type/murdermysterygame/events/ActionPreventBlockModification.java @@ -7,12 +7,13 @@ import net.swofty.type.murdermysterygame.game.Game; import net.swofty.type.murdermysterygame.user.MurderMysteryPlayer; import net.swofty.type.generic.event.EventNodes; -import net.swofty.type.generic.event.HypixelEvent; import net.swofty.type.generic.event.HypixelEventClass; +import net.swofty.type.generic.event.phase.EventPhase; +import net.swofty.type.generic.event.phase.PhasedEvent; public class ActionPreventBlockModification implements HypixelEventClass { - @HypixelEvent(node = EventNodes.PLAYER, requireDataLoaded = false) + @PhasedEvent(node = EventNodes.PLAYER, requireDataLoaded = false, phase = EventPhase.GAMEPLAY) public void onBlockBreak(PlayerBlockBreakEvent event) { if (!(event.getPlayer() instanceof MurderMysteryPlayer player)) return; @@ -25,7 +26,7 @@ public void onBlockBreak(PlayerBlockBreakEvent event) { } } - @HypixelEvent(node = EventNodes.PLAYER, requireDataLoaded = false) + @PhasedEvent(node = EventNodes.PLAYER, requireDataLoaded = false, phase = EventPhase.GAMEPLAY) public void onBlockPlace(PlayerBlockPlaceEvent event) { if (!(event.getPlayer() instanceof MurderMysteryPlayer player)) return; diff --git a/type.murdermysterygame/src/main/java/net/swofty/type/murdermysterygame/events/ActionPreventFallDamage.java b/type.murdermysterygame/src/main/java/net/swofty/type/murdermysterygame/events/ActionPreventFallDamage.java index 91095edee..0dc1b1f69 100644 --- a/type.murdermysterygame/src/main/java/net/swofty/type/murdermysterygame/events/ActionPreventFallDamage.java +++ b/type.murdermysterygame/src/main/java/net/swofty/type/murdermysterygame/events/ActionPreventFallDamage.java @@ -7,12 +7,13 @@ import net.swofty.type.murdermysterygame.game.Game; import net.swofty.type.murdermysterygame.user.MurderMysteryPlayer; import net.swofty.type.generic.event.EventNodes; -import net.swofty.type.generic.event.HypixelEvent; import net.swofty.type.generic.event.HypixelEventClass; +import net.swofty.type.generic.event.phase.EventPhase; +import net.swofty.type.generic.event.phase.PhasedEvent; public class ActionPreventFallDamage implements HypixelEventClass { - @HypixelEvent(node = EventNodes.ALL, requireDataLoaded = false) + @PhasedEvent(node = EventNodes.ALL, requireDataLoaded = false, phase = EventPhase.GAMEPLAY) public void run(FinalDamageEvent event) { if (!(event.getEntity() instanceof MurderMysteryPlayer player)) return; diff --git a/type.murdermysterygame/src/main/java/net/swofty/type/murdermysterygame/events/ActionWaterDeath.java b/type.murdermysterygame/src/main/java/net/swofty/type/murdermysterygame/events/ActionWaterDeath.java index 1e8dc1572..f0a8b679b 100644 --- a/type.murdermysterygame/src/main/java/net/swofty/type/murdermysterygame/events/ActionWaterDeath.java +++ b/type.murdermysterygame/src/main/java/net/swofty/type/murdermysterygame/events/ActionWaterDeath.java @@ -4,8 +4,9 @@ import net.minestom.server.event.player.PlayerMoveEvent; import net.minestom.server.instance.block.Block; import net.swofty.type.generic.event.EventNodes; -import net.swofty.type.generic.event.HypixelEvent; import net.swofty.type.generic.event.HypixelEventClass; +import net.swofty.type.generic.event.phase.EventPhase; +import net.swofty.type.generic.event.phase.PhasedEvent; import net.swofty.type.murdermysterygame.TypeMurderMysteryGameLoader; import net.swofty.type.murdermysterygame.game.Game; import net.swofty.type.murdermysterygame.game.GameStatus; @@ -16,7 +17,7 @@ */ public class ActionWaterDeath implements HypixelEventClass { - @HypixelEvent(node = EventNodes.PLAYER, requireDataLoaded = false) + @PhasedEvent(node = EventNodes.PLAYER, requireDataLoaded = false, phase = EventPhase.GAMEPLAY) public void run(PlayerMoveEvent event) { if (!(event.getPlayer() instanceof MurderMysteryPlayer player)) return; diff --git a/type.murdermysterygame/src/main/java/net/swofty/type/murdermysterygame/events/ActionWeaknessSplash.java b/type.murdermysterygame/src/main/java/net/swofty/type/murdermysterygame/events/ActionWeaknessSplash.java index 2412ac7cf..f128c37ad 100644 --- a/type.murdermysterygame/src/main/java/net/swofty/type/murdermysterygame/events/ActionWeaknessSplash.java +++ b/type.murdermysterygame/src/main/java/net/swofty/type/murdermysterygame/events/ActionWeaknessSplash.java @@ -3,8 +3,9 @@ import net.minestom.server.event.entity.EntityPotionAddEvent; import net.minestom.server.potion.PotionEffect; import net.swofty.type.generic.event.EventNodes; -import net.swofty.type.generic.event.HypixelEvent; import net.swofty.type.generic.event.HypixelEventClass; +import net.swofty.type.generic.event.phase.EventPhase; +import net.swofty.type.generic.event.phase.PhasedEvent; import net.swofty.type.murdermysterygame.TypeMurderMysteryGameLoader; import net.swofty.type.murdermysterygame.game.Game; import net.swofty.type.murdermysterygame.game.GameStatus; @@ -18,7 +19,7 @@ */ public class ActionWeaknessSplash implements HypixelEventClass { - @HypixelEvent(node = EventNodes.ALL, requireDataLoaded = false) + @PhasedEvent(node = EventNodes.ALL, requireDataLoaded = false, phase = EventPhase.GAMEPLAY) public void run(EntityPotionAddEvent event) { if (!(event.getEntity() instanceof MurderMysteryPlayer player)) return; diff --git a/type.murdermysterylobby/src/main/java/net/swofty/type/murdermysterylobby/events/ActionPlayerChat.java b/type.murdermysterylobby/src/main/java/net/swofty/type/murdermysterylobby/events/ActionPlayerChat.java index 9cfe6c720..97c84d2da 100644 --- a/type.murdermysterylobby/src/main/java/net/swofty/type/murdermysterylobby/events/ActionPlayerChat.java +++ b/type.murdermysterylobby/src/main/java/net/swofty/type/murdermysterylobby/events/ActionPlayerChat.java @@ -7,8 +7,9 @@ import net.swofty.type.generic.data.HypixelDataHandler; import net.swofty.type.generic.data.datapoints.DatapointChatType; import net.swofty.type.generic.event.EventNodes; -import net.swofty.type.generic.event.HypixelEvent; import net.swofty.type.generic.event.HypixelEventClass; +import net.swofty.type.generic.event.phase.EventPhase; +import net.swofty.type.generic.event.phase.PhasedEvent; import net.swofty.type.generic.party.PartyManager; import net.swofty.type.generic.user.HypixelPlayer; import net.swofty.type.generic.user.categories.Rank; @@ -17,7 +18,7 @@ public class ActionPlayerChat implements HypixelEventClass { - @HypixelEvent(node = EventNodes.PLAYER, requireDataLoaded = false) + @PhasedEvent(node = EventNodes.PLAYER, requireDataLoaded = false, phase = EventPhase.GAMEPLAY) public void run(PlayerChatEvent event) { final HypixelPlayer player = (HypixelPlayer) event.getPlayer(); event.setCancelled(true); diff --git a/type.murdermysterylobby/src/main/java/net/swofty/type/murdermysterylobby/events/ActionPlayerDataSpawn.java b/type.murdermysterylobby/src/main/java/net/swofty/type/murdermysterylobby/events/ActionPlayerDataSpawn.java index d00e453d2..41f28ea5a 100644 --- a/type.murdermysterylobby/src/main/java/net/swofty/type/murdermysterylobby/events/ActionPlayerDataSpawn.java +++ b/type.murdermysterylobby/src/main/java/net/swofty/type/murdermysterylobby/events/ActionPlayerDataSpawn.java @@ -6,14 +6,15 @@ import net.swofty.type.generic.HypixelConst; import net.swofty.type.generic.HypixelGenericLoader; import net.swofty.type.generic.event.EventNodes; -import net.swofty.type.generic.event.HypixelEvent; import net.swofty.type.generic.event.HypixelEventClass; +import net.swofty.type.generic.event.phase.EventPhase; +import net.swofty.type.generic.event.phase.PhasedEvent; import net.swofty.type.generic.user.HypixelPlayer; import net.swofty.type.generic.user.categories.Rank; public class ActionPlayerDataSpawn implements HypixelEventClass { - @HypixelEvent(node = EventNodes.PLAYER_DATA, requireDataLoaded = false, isAsync = true) + @PhasedEvent(node = EventNodes.PLAYER_DATA, requireDataLoaded = false, isAsync = true, phase = EventPhase.POST_SPAWN) public void run(PlayerSpawnEvent event) { if (!event.isFirstSpawn()) return; if (!(HypixelConst.getTypeLoader().getType() == ServerType.MURDER_MYSTERY_LOBBY)) return; diff --git a/type.murdermysterylobby/src/main/java/net/swofty/type/murdermysterylobby/events/ActionPlayerDisconnect.java b/type.murdermysterylobby/src/main/java/net/swofty/type/murdermysterylobby/events/ActionPlayerDisconnect.java index 18fb6d325..31f6ae9d9 100644 --- a/type.murdermysterylobby/src/main/java/net/swofty/type/murdermysterylobby/events/ActionPlayerDisconnect.java +++ b/type.murdermysterylobby/src/main/java/net/swofty/type/murdermysterylobby/events/ActionPlayerDisconnect.java @@ -2,14 +2,15 @@ import net.minestom.server.event.player.PlayerDisconnectEvent; import net.swofty.type.generic.event.EventNodes; -import net.swofty.type.generic.event.HypixelEvent; import net.swofty.type.generic.event.HypixelEventClass; +import net.swofty.type.generic.event.phase.EventPhase; +import net.swofty.type.generic.event.phase.PhasedEvent; import net.swofty.type.generic.user.HypixelPlayer; import net.swofty.type.murdermysterylobby.MurderMysteryLobbyScoreboard; public class ActionPlayerDisconnect implements HypixelEventClass { - @HypixelEvent(node = EventNodes.PLAYER, requireDataLoaded = false) + @PhasedEvent(node = EventNodes.PLAYER, requireDataLoaded = false, phase = EventPhase.DISCONNECT) public void run(PlayerDisconnectEvent event) { HypixelPlayer player = (HypixelPlayer) event.getPlayer(); MurderMysteryLobbyScoreboard.removeCache(player); diff --git a/type.murdermysterylobby/src/main/java/net/swofty/type/murdermysterylobby/events/ActionPlayerSpawn.java b/type.murdermysterylobby/src/main/java/net/swofty/type/murdermysterylobby/events/ActionPlayerSpawn.java index 9584a31d2..ad89716b7 100644 --- a/type.murdermysterylobby/src/main/java/net/swofty/type/murdermysterylobby/events/ActionPlayerSpawn.java +++ b/type.murdermysterylobby/src/main/java/net/swofty/type/murdermysterylobby/events/ActionPlayerSpawn.java @@ -3,8 +3,9 @@ import lombok.SneakyThrows; import net.minestom.server.event.player.PlayerSpawnEvent; import net.swofty.type.generic.event.EventNodes; -import net.swofty.type.generic.event.HypixelEvent; import net.swofty.type.generic.event.HypixelEventClass; +import net.swofty.type.generic.event.phase.EventPhase; +import net.swofty.type.generic.event.phase.PhasedEvent; import net.swofty.type.generic.user.HypixelPlayer; import net.minestom.server.entity.GameMode; import net.swofty.type.murdermysterylobby.TypeMurderMysteryLobbyLoader; @@ -13,7 +14,7 @@ public class ActionPlayerSpawn implements HypixelEventClass { @SneakyThrows - @HypixelEvent(node = EventNodes.PLAYER, requireDataLoaded = false, isAsync = true) + @PhasedEvent(node = EventNodes.PLAYER, requireDataLoaded = false, isAsync = true, phase = EventPhase.SPAWN) public void run(PlayerSpawnEvent event) { final HypixelPlayer player = (HypixelPlayer) event.getPlayer(); player.setGameMode(GameMode.SURVIVAL); diff --git a/type.prototypelobby/src/main/java/net/swofty/type/prototypelobby/events/ActionPlayerChat.java b/type.prototypelobby/src/main/java/net/swofty/type/prototypelobby/events/ActionPlayerChat.java index ad4b4db48..8a174f572 100644 --- a/type.prototypelobby/src/main/java/net/swofty/type/prototypelobby/events/ActionPlayerChat.java +++ b/type.prototypelobby/src/main/java/net/swofty/type/prototypelobby/events/ActionPlayerChat.java @@ -7,8 +7,9 @@ import net.swofty.type.generic.data.HypixelDataHandler; import net.swofty.type.generic.data.datapoints.DatapointChatType; import net.swofty.type.generic.event.EventNodes; -import net.swofty.type.generic.event.HypixelEvent; import net.swofty.type.generic.event.HypixelEventClass; +import net.swofty.type.generic.event.phase.EventPhase; +import net.swofty.type.generic.event.phase.PhasedEvent; import net.swofty.type.generic.party.PartyManager; import net.swofty.type.generic.user.HypixelPlayer; import net.swofty.type.generic.user.categories.Rank; @@ -17,7 +18,7 @@ public class ActionPlayerChat implements HypixelEventClass { - @HypixelEvent(node = EventNodes.PLAYER, requireDataLoaded = false) + @PhasedEvent(node = EventNodes.PLAYER, requireDataLoaded = false, phase = EventPhase.GAMEPLAY) public void run(PlayerChatEvent event) { final HypixelPlayer player = (HypixelPlayer) event.getPlayer(); event.setCancelled(true); diff --git a/type.prototypelobby/src/main/java/net/swofty/type/prototypelobby/events/ActionPlayerDataSpawn.java b/type.prototypelobby/src/main/java/net/swofty/type/prototypelobby/events/ActionPlayerDataSpawn.java index e2f64118f..829c99196 100644 --- a/type.prototypelobby/src/main/java/net/swofty/type/prototypelobby/events/ActionPlayerDataSpawn.java +++ b/type.prototypelobby/src/main/java/net/swofty/type/prototypelobby/events/ActionPlayerDataSpawn.java @@ -6,14 +6,15 @@ import net.minestom.server.event.player.PlayerSpawnEvent; import net.swofty.type.generic.HypixelGenericLoader; import net.swofty.type.generic.event.EventNodes; -import net.swofty.type.generic.event.HypixelEvent; import net.swofty.type.generic.event.HypixelEventClass; +import net.swofty.type.generic.event.phase.EventPhase; +import net.swofty.type.generic.event.phase.PhasedEvent; import net.swofty.type.generic.user.HypixelPlayer; import net.swofty.type.generic.user.categories.Rank; public class ActionPlayerDataSpawn implements HypixelEventClass { - @HypixelEvent(node = EventNodes.PLAYER_DATA, requireDataLoaded = false, isAsync = true) + @PhasedEvent(node = EventNodes.PLAYER_DATA, requireDataLoaded = false, isAsync = true, phase = EventPhase.POST_SPAWN) public void run(PlayerSpawnEvent event) { if (!event.isFirstSpawn()) return; @@ -34,4 +35,4 @@ public void run(PlayerSpawnEvent event) { .clickEvent(ClickEvent.openUrl("https://hypixel.net/PTL"))); player.sendMessage(Component.empty()); } -} \ No newline at end of file +} diff --git a/type.prototypelobby/src/main/java/net/swofty/type/prototypelobby/events/ActionPlayerDisconnect.java b/type.prototypelobby/src/main/java/net/swofty/type/prototypelobby/events/ActionPlayerDisconnect.java index 0b6566b8d..8d45859dd 100644 --- a/type.prototypelobby/src/main/java/net/swofty/type/prototypelobby/events/ActionPlayerDisconnect.java +++ b/type.prototypelobby/src/main/java/net/swofty/type/prototypelobby/events/ActionPlayerDisconnect.java @@ -2,14 +2,15 @@ import net.minestom.server.event.player.PlayerDisconnectEvent; import net.swofty.type.generic.event.EventNodes; -import net.swofty.type.generic.event.HypixelEvent; import net.swofty.type.generic.event.HypixelEventClass; +import net.swofty.type.generic.event.phase.EventPhase; +import net.swofty.type.generic.event.phase.PhasedEvent; import net.swofty.type.generic.user.HypixelPlayer; import net.swofty.type.prototypelobby.PrototypeLobbyScoreboard; public class ActionPlayerDisconnect implements HypixelEventClass { - @HypixelEvent(node = EventNodes.PLAYER, requireDataLoaded = false) + @PhasedEvent(node = EventNodes.PLAYER, requireDataLoaded = false, phase = EventPhase.DISCONNECT) public void run(PlayerDisconnectEvent event) { HypixelPlayer player = (HypixelPlayer) event.getPlayer(); PrototypeLobbyScoreboard.removeCache(player); diff --git a/type.prototypelobby/src/main/java/net/swofty/type/prototypelobby/events/ActionPlayerSpawn.java b/type.prototypelobby/src/main/java/net/swofty/type/prototypelobby/events/ActionPlayerSpawn.java index 0c5b6c4e2..dee879796 100644 --- a/type.prototypelobby/src/main/java/net/swofty/type/prototypelobby/events/ActionPlayerSpawn.java +++ b/type.prototypelobby/src/main/java/net/swofty/type/prototypelobby/events/ActionPlayerSpawn.java @@ -3,15 +3,16 @@ import lombok.SneakyThrows; import net.minestom.server.event.player.PlayerSpawnEvent; import net.swofty.type.generic.event.EventNodes; -import net.swofty.type.generic.event.HypixelEvent; import net.swofty.type.generic.event.HypixelEventClass; +import net.swofty.type.generic.event.phase.EventPhase; +import net.swofty.type.generic.event.phase.PhasedEvent; import net.swofty.type.generic.user.HypixelPlayer; import net.swofty.type.prototypelobby.util.PrototypeLobbyMap; public class ActionPlayerSpawn implements HypixelEventClass { @SneakyThrows - @HypixelEvent(node = EventNodes.PLAYER, requireDataLoaded = false, isAsync = true) + @PhasedEvent(node = EventNodes.PLAYER, requireDataLoaded = false, isAsync = true, phase = EventPhase.SPAWN) public void run(PlayerSpawnEvent event) { final HypixelPlayer player = (HypixelPlayer) event.getPlayer(); diff --git a/type.ravengardgeneric/src/main/java/net/swofty/type/ravengardgeneric/event/actions/player/ActionPlayerFirstSpawnTexturePack.java b/type.ravengardgeneric/src/main/java/net/swofty/type/ravengardgeneric/event/actions/player/ActionPlayerFirstSpawnTexturePack.java index a8947cbfa..feac0233f 100644 --- a/type.ravengardgeneric/src/main/java/net/swofty/type/ravengardgeneric/event/actions/player/ActionPlayerFirstSpawnTexturePack.java +++ b/type.ravengardgeneric/src/main/java/net/swofty/type/ravengardgeneric/event/actions/player/ActionPlayerFirstSpawnTexturePack.java @@ -3,15 +3,16 @@ import net.minestom.server.event.player.PlayerSpawnEvent; import net.swofty.type.generic.HypixelConst; import net.swofty.type.generic.event.EventNodes; -import net.swofty.type.generic.event.HypixelEvent; import net.swofty.type.generic.event.HypixelEventClass; +import net.swofty.type.generic.event.phase.EventPhase; +import net.swofty.type.generic.event.phase.PhasedEvent; import net.swofty.type.generic.user.HypixelPlayer; import net.swofty.type.ravengardgeneric.texturepack.TexturePackManager; import org.tinylog.Logger; public class ActionPlayerFirstSpawnTexturePack implements HypixelEventClass { - @HypixelEvent(node = EventNodes.PLAYER, requireDataLoaded = false) + @PhasedEvent(node = EventNodes.PLAYER, requireDataLoaded = false, phase = EventPhase.GAMEPLAY) public void run(PlayerSpawnEvent event) { if (!event.isFirstSpawn()) { return; diff --git a/type.ravengardgeneric/src/main/java/net/swofty/type/ravengardgeneric/event/actions/player/ActionPlayerJoin.java b/type.ravengardgeneric/src/main/java/net/swofty/type/ravengardgeneric/event/actions/player/ActionPlayerJoin.java index f3b4cc883..aa026253a 100644 --- a/type.ravengardgeneric/src/main/java/net/swofty/type/ravengardgeneric/event/actions/player/ActionPlayerJoin.java +++ b/type.ravengardgeneric/src/main/java/net/swofty/type/ravengardgeneric/event/actions/player/ActionPlayerJoin.java @@ -4,14 +4,15 @@ import net.minestom.server.instance.Instance; import net.swofty.type.generic.HypixelConst; import net.swofty.type.generic.event.EventNodes; -import net.swofty.type.generic.event.HypixelEvent; import net.swofty.type.generic.event.HypixelEventClass; +import net.swofty.type.generic.event.phase.EventPhase; +import net.swofty.type.generic.event.phase.PhasedEvent; import net.swofty.type.ravengardgeneric.user.RavengardPlayer; import org.tinylog.Logger; public class ActionPlayerJoin implements HypixelEventClass { - @HypixelEvent(node = EventNodes.PLAYER, requireDataLoaded = false) + @PhasedEvent(node = EventNodes.PLAYER, requireDataLoaded = false, phase = EventPhase.CONNECT) public void run(AsyncPlayerConfigurationEvent event) { RavengardPlayer player = (RavengardPlayer) event.getPlayer(); diff --git a/type.ravengardgeneric/src/main/java/net/swofty/type/ravengardgeneric/event/actions/player/data/ActionPlayerClearRavengardCache.java b/type.ravengardgeneric/src/main/java/net/swofty/type/ravengardgeneric/event/actions/player/data/ActionPlayerClearRavengardCache.java index e7adc33e7..b8bae2f8f 100644 --- a/type.ravengardgeneric/src/main/java/net/swofty/type/ravengardgeneric/event/actions/player/data/ActionPlayerClearRavengardCache.java +++ b/type.ravengardgeneric/src/main/java/net/swofty/type/ravengardgeneric/event/actions/player/data/ActionPlayerClearRavengardCache.java @@ -2,12 +2,13 @@ import net.minestom.server.event.player.PlayerDisconnectEvent; import net.swofty.type.generic.event.EventNodes; -import net.swofty.type.generic.event.HypixelEvent; import net.swofty.type.generic.event.HypixelEventClass; +import net.swofty.type.generic.event.phase.EventPhase; +import net.swofty.type.generic.event.phase.PhasedEvent; public class ActionPlayerClearRavengardCache implements HypixelEventClass { - @HypixelEvent(node = EventNodes.PLAYER, requireDataLoaded = false) + @PhasedEvent(node = EventNodes.PLAYER, requireDataLoaded = false, phase = EventPhase.GAMEPLAY) public void run(PlayerDisconnectEvent event) { // Reserved for non-persistent Ravengard runtime caches. } diff --git a/type.ravengardgeneric/src/main/java/net/swofty/type/ravengardgeneric/event/actions/player/data/ActionPlayerRavengardDataLoad.java b/type.ravengardgeneric/src/main/java/net/swofty/type/ravengardgeneric/event/actions/player/data/ActionPlayerRavengardDataLoad.java index 581c5de73..4c0b04a03 100644 --- a/type.ravengardgeneric/src/main/java/net/swofty/type/ravengardgeneric/event/actions/player/data/ActionPlayerRavengardDataLoad.java +++ b/type.ravengardgeneric/src/main/java/net/swofty/type/ravengardgeneric/event/actions/player/data/ActionPlayerRavengardDataLoad.java @@ -4,8 +4,9 @@ import net.minestom.server.event.player.AsyncPlayerConfigurationEvent; import net.swofty.type.generic.data.mongodb.UserDatabase; import net.swofty.type.generic.event.EventNodes; -import net.swofty.type.generic.event.HypixelEvent; import net.swofty.type.generic.event.HypixelEventClass; +import net.swofty.type.generic.event.phase.EventPhase; +import net.swofty.type.generic.event.phase.PhasedEvent; import net.swofty.type.ravengardgeneric.data.RavengardDataHandler; import net.swofty.type.ravengardgeneric.user.RavengardPlayer; import org.bson.Document; @@ -16,7 +17,7 @@ public class ActionPlayerRavengardDataLoad implements HypixelEventClass { @SneakyThrows - @HypixelEvent(node = EventNodes.PLAYER_DATA, requireDataLoaded = false) + @PhasedEvent(node = EventNodes.PLAYER_DATA, requireDataLoaded = false, phase = EventPhase.GAMEPLAY) public void run(AsyncPlayerConfigurationEvent event) { RavengardPlayer player = (RavengardPlayer) event.getPlayer(); UUID playerUuid = player.getUuid(); diff --git a/type.ravengardgeneric/src/main/java/net/swofty/type/ravengardgeneric/event/actions/player/data/ActionPlayerRavengardDataSave.java b/type.ravengardgeneric/src/main/java/net/swofty/type/ravengardgeneric/event/actions/player/data/ActionPlayerRavengardDataSave.java index 2bda33d6d..c637b8b05 100644 --- a/type.ravengardgeneric/src/main/java/net/swofty/type/ravengardgeneric/event/actions/player/data/ActionPlayerRavengardDataSave.java +++ b/type.ravengardgeneric/src/main/java/net/swofty/type/ravengardgeneric/event/actions/player/data/ActionPlayerRavengardDataSave.java @@ -4,8 +4,9 @@ import net.minestom.server.event.player.PlayerDisconnectEvent; import net.swofty.type.generic.data.mongodb.UserDatabase; import net.swofty.type.generic.event.EventNodes; -import net.swofty.type.generic.event.HypixelEvent; import net.swofty.type.generic.event.HypixelEventClass; +import net.swofty.type.generic.event.phase.EventPhase; +import net.swofty.type.generic.event.phase.PhasedEvent; import net.swofty.type.ravengardgeneric.data.RavengardDataHandler; import net.swofty.type.ravengardgeneric.user.RavengardPlayer; import org.tinylog.Logger; @@ -15,7 +16,7 @@ public class ActionPlayerRavengardDataSave implements HypixelEventClass { @SneakyThrows - @HypixelEvent(node = EventNodes.PLAYER, requireDataLoaded = false, isAsync = true) + @PhasedEvent(node = EventNodes.PLAYER, requireDataLoaded = false, isAsync = true, phase = EventPhase.GAMEPLAY) public void run(PlayerDisconnectEvent event) { RavengardPlayer player = (RavengardPlayer) event.getPlayer(); UUID playerUuid = player.getUuid(); diff --git a/type.ravengardgeneric/src/main/java/net/swofty/type/ravengardgeneric/event/actions/player/data/ActionPlayerRavengardDataSpawn.java b/type.ravengardgeneric/src/main/java/net/swofty/type/ravengardgeneric/event/actions/player/data/ActionPlayerRavengardDataSpawn.java index 51a069186..d1e707662 100644 --- a/type.ravengardgeneric/src/main/java/net/swofty/type/ravengardgeneric/event/actions/player/data/ActionPlayerRavengardDataSpawn.java +++ b/type.ravengardgeneric/src/main/java/net/swofty/type/ravengardgeneric/event/actions/player/data/ActionPlayerRavengardDataSpawn.java @@ -2,14 +2,15 @@ import net.minestom.server.event.player.PlayerSpawnEvent; import net.swofty.type.generic.event.EventNodes; -import net.swofty.type.generic.event.HypixelEvent; import net.swofty.type.generic.event.HypixelEventClass; +import net.swofty.type.generic.event.phase.EventPhase; +import net.swofty.type.generic.event.phase.PhasedEvent; import net.swofty.type.ravengardgeneric.data.RavengardDataHandler; import net.swofty.type.ravengardgeneric.user.RavengardPlayer; public class ActionPlayerRavengardDataSpawn implements HypixelEventClass { - @HypixelEvent(node = EventNodes.PLAYER_DATA, requireDataLoaded = false, isAsync = true) + @PhasedEvent(node = EventNodes.PLAYER_DATA, requireDataLoaded = false, isAsync = true, phase = EventPhase.GAMEPLAY) public void run(PlayerSpawnEvent event) { if (!event.isFirstSpawn()) { return; diff --git a/type.ravengardlobby/src/main/java/net/swofty/type/ravengardlobby/events/ActionPlayerVoid.java b/type.ravengardlobby/src/main/java/net/swofty/type/ravengardlobby/events/ActionPlayerVoid.java index 2cd21b2b5..f1eb9cd8e 100644 --- a/type.ravengardlobby/src/main/java/net/swofty/type/ravengardlobby/events/ActionPlayerVoid.java +++ b/type.ravengardlobby/src/main/java/net/swofty/type/ravengardlobby/events/ActionPlayerVoid.java @@ -3,12 +3,13 @@ import net.minestom.server.event.player.PlayerMoveEvent; import net.swofty.type.generic.HypixelConst; import net.swofty.type.generic.event.EventNodes; -import net.swofty.type.generic.event.HypixelEvent; import net.swofty.type.generic.event.HypixelEventClass; +import net.swofty.type.generic.event.phase.EventPhase; +import net.swofty.type.generic.event.phase.PhasedEvent; public class ActionPlayerVoid implements HypixelEventClass { - @HypixelEvent(node = EventNodes.PLAYER, requireDataLoaded = false) + @PhasedEvent(node = EventNodes.PLAYER, requireDataLoaded = false, phase = EventPhase.GAMEPLAY) public void run(PlayerMoveEvent event) { if (event.getPlayer().getPosition().y() < 0) { event.getPlayer().teleport(HypixelConst.getTypeLoader() diff --git a/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/SkyBlockGenericLoader.java b/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/SkyBlockGenericLoader.java index 83675e217..e97cfbe4f 100644 --- a/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/SkyBlockGenericLoader.java +++ b/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/SkyBlockGenericLoader.java @@ -86,7 +86,7 @@ import net.swofty.type.skyblockgeneric.region.SkyBlockRegion; import net.swofty.type.skyblockgeneric.server.attribute.SkyBlockServerAttributes; import net.swofty.type.skyblockgeneric.server.eventcaller.CustomEventCaller; -import net.swofty.type.skyblockgeneric.user.SkyBlockIsland; +import net.swofty.type.skyblockgeneric.user.island.SkyBlockIsland; import net.swofty.type.skyblockgeneric.user.SkyBlockPlayer; import net.swofty.type.skyblockgeneric.user.SkyBlockScoreboard; import net.swofty.type.skyblockgeneric.user.StashReminder; diff --git a/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/event/actions/custom/ActionChangeMiningRegion.java b/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/event/actions/custom/ActionChangeMiningRegion.java index 2098c466e..42bcace7d 100644 --- a/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/event/actions/custom/ActionChangeMiningRegion.java +++ b/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/event/actions/custom/ActionChangeMiningRegion.java @@ -3,13 +3,14 @@ import net.minestom.server.entity.attribute.Attribute; import net.swofty.type.generic.HypixelConst; import net.swofty.type.generic.event.EventNodes; -import net.swofty.type.generic.event.HypixelEvent; import net.swofty.type.generic.event.HypixelEventClass; +import net.swofty.type.generic.event.phase.EventPhase; +import net.swofty.type.generic.event.phase.PhasedEvent; import net.swofty.type.skyblockgeneric.event.custom.PlayerRegionChangeEvent; import net.swofty.type.skyblockgeneric.user.SkyBlockPlayer; public class ActionChangeMiningRegion implements HypixelEventClass { - @HypixelEvent(node = EventNodes.CUSTOM, requireDataLoaded = false) + @PhasedEvent(node = EventNodes.CUSTOM, requireDataLoaded = false, phase = EventPhase.GAMEPLAY) public void run(PlayerRegionChangeEvent event) { SkyBlockPlayer player = event.getPlayer(); diff --git a/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/event/actions/custom/ActionChangeTimeCalender.java b/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/event/actions/custom/ActionChangeTimeCalender.java index 169918357..05e4930c5 100644 --- a/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/event/actions/custom/ActionChangeTimeCalender.java +++ b/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/event/actions/custom/ActionChangeTimeCalender.java @@ -1,13 +1,14 @@ package net.swofty.type.skyblockgeneric.event.actions.custom; import net.swofty.type.generic.event.EventNodes; -import net.swofty.type.generic.event.HypixelEvent; import net.swofty.type.generic.event.HypixelEventClass; +import net.swofty.type.generic.event.phase.EventPhase; +import net.swofty.type.generic.event.phase.PhasedEvent; import net.swofty.type.skyblockgeneric.SkyBlockGenericLoader; import net.swofty.type.skyblockgeneric.event.custom.CalenderHourlyUpdateEvent; public class ActionChangeTimeCalender implements HypixelEventClass { - @HypixelEvent(node = EventNodes.CUSTOM, requireDataLoaded = true) + @PhasedEvent(node = EventNodes.CUSTOM, requireDataLoaded = true, phase = EventPhase.GAMEPLAY) public void run(CalenderHourlyUpdateEvent event) { int hour = event.hour(); long minecraftTime = (hour * 1000L + 6000) % 24000; diff --git a/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/event/actions/custom/ActionDisplayMenu.java b/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/event/actions/custom/ActionDisplayMenu.java index 6ce7d9516..61692a258 100644 --- a/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/event/actions/custom/ActionDisplayMenu.java +++ b/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/event/actions/custom/ActionDisplayMenu.java @@ -1,14 +1,15 @@ package net.swofty.type.skyblockgeneric.event.actions.custom; import net.swofty.type.generic.event.EventNodes; -import net.swofty.type.generic.event.HypixelEvent; import net.swofty.type.generic.event.HypixelEventClass; +import net.swofty.type.generic.event.phase.EventPhase; +import net.swofty.type.generic.event.phase.PhasedEvent; import net.swofty.type.generic.gui.inventory.HypixelInventoryGUI; import net.swofty.type.skyblockgeneric.event.actions.player.ActionPlayerChangeHypixelMenuDisplay; import net.swofty.type.skyblockgeneric.user.SkyBlockPlayer; public class ActionDisplayMenu implements HypixelEventClass { - @HypixelEvent(node = EventNodes.CUSTOM, requireDataLoaded = false) + @PhasedEvent(node = EventNodes.CUSTOM, requireDataLoaded = false, phase = EventPhase.GAMEPLAY) public void run(HypixelInventoryGUI.InventoryGUIOpenEvent event) { SkyBlockPlayer player = (SkyBlockPlayer) event.player(); ActionPlayerChangeHypixelMenuDisplay.setMainMenu(player); diff --git a/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/event/actions/custom/ActionNewZoneDisplay.java b/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/event/actions/custom/ActionNewZoneDisplay.java index 24219ed5f..139e5ebe3 100644 --- a/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/event/actions/custom/ActionNewZoneDisplay.java +++ b/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/event/actions/custom/ActionNewZoneDisplay.java @@ -6,8 +6,9 @@ import net.kyori.adventure.title.Title; import net.swofty.type.generic.data.datapoints.DatapointStringList; import net.swofty.type.generic.event.EventNodes; -import net.swofty.type.generic.event.HypixelEvent; import net.swofty.type.generic.event.HypixelEventClass; +import net.swofty.type.generic.event.phase.EventPhase; +import net.swofty.type.generic.event.phase.PhasedEvent; import net.swofty.type.skyblockgeneric.data.SkyBlockDataHandler; import net.swofty.type.skyblockgeneric.event.custom.PlayerRegionChangeEvent; import net.swofty.type.skyblockgeneric.region.RegionType; @@ -18,7 +19,7 @@ public class ActionNewZoneDisplay implements HypixelEventClass { - @HypixelEvent(node = EventNodes.CUSTOM, requireDataLoaded = false) + @PhasedEvent(node = EventNodes.CUSTOM, requireDataLoaded = false, phase = EventPhase.GAMEPLAY) public void run(PlayerRegionChangeEvent event) { SkyBlockPlayer player = event.getPlayer(); diff --git a/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/event/actions/custom/ActionPlayerDamageBlock.java b/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/event/actions/custom/ActionPlayerDamageBlock.java index a565f83ca..966051f76 100644 --- a/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/event/actions/custom/ActionPlayerDamageBlock.java +++ b/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/event/actions/custom/ActionPlayerDamageBlock.java @@ -7,8 +7,9 @@ import net.minestom.server.network.packet.server.play.BlockBreakAnimationPacket; import net.minestom.server.timer.TaskSchedule; import net.swofty.type.generic.event.EventNodes; -import net.swofty.type.generic.event.HypixelEvent; import net.swofty.type.generic.event.HypixelEventClass; +import net.swofty.type.generic.event.phase.EventPhase; +import net.swofty.type.generic.event.phase.PhasedEvent; import net.swofty.type.skyblockgeneric.event.custom.PlayerDamageSkyBlockBlockEvent; import net.swofty.type.skyblockgeneric.item.SkyBlockItem; import net.swofty.type.skyblockgeneric.region.SkyBlockRegion; @@ -24,7 +25,7 @@ public class ActionPlayerDamageBlock implements HypixelEventClass { public static final Map CLICKING = new HashMap<>(); - @HypixelEvent(node = EventNodes.CUSTOM, requireDataLoaded = true) + @PhasedEvent(node = EventNodes.CUSTOM, requireDataLoaded = true, phase = EventPhase.GAMEPLAY) public void run(PlayerDamageSkyBlockBlockEvent event) { SkyBlockPlayer player = (SkyBlockPlayer) event.getPlayer(); SkyBlockRegion region = SkyBlockRegion.getRegionOfPosition(event.getBlockPosition()); diff --git a/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/event/actions/custom/ActionRegionChangeDisplay.java b/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/event/actions/custom/ActionRegionChangeDisplay.java index ec49f2bf4..b3b6313b5 100644 --- a/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/event/actions/custom/ActionRegionChangeDisplay.java +++ b/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/event/actions/custom/ActionRegionChangeDisplay.java @@ -1,8 +1,9 @@ package net.swofty.type.skyblockgeneric.event.actions.custom; import net.swofty.type.generic.event.EventNodes; -import net.swofty.type.generic.event.HypixelEvent; import net.swofty.type.generic.event.HypixelEventClass; +import net.swofty.type.generic.event.phase.EventPhase; +import net.swofty.type.generic.event.phase.PhasedEvent; import net.swofty.type.skyblockgeneric.event.custom.PlayerRegionChangeEvent; import net.swofty.type.skyblockgeneric.region.RegionType; import net.swofty.type.skyblockgeneric.user.SkyBlockActionBar; @@ -10,7 +11,7 @@ public class ActionRegionChangeDisplay implements HypixelEventClass { - @HypixelEvent(node = EventNodes.CUSTOM, requireDataLoaded = false) + @PhasedEvent(node = EventNodes.CUSTOM, requireDataLoaded = false, phase = EventPhase.GAMEPLAY) public void run(PlayerRegionChangeEvent event) { SkyBlockPlayer player = event.getPlayer(); diff --git a/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/event/actions/custom/ActionRegionPlaySong.java b/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/event/actions/custom/ActionRegionPlaySong.java index c6060cc89..963aa309b 100644 --- a/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/event/actions/custom/ActionRegionPlaySong.java +++ b/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/event/actions/custom/ActionRegionPlaySong.java @@ -5,8 +5,9 @@ import net.swofty.type.generic.HypixelConst; import net.swofty.type.generic.SkyBlockTypeLoader; import net.swofty.type.generic.event.EventNodes; -import net.swofty.type.generic.event.HypixelEvent; import net.swofty.type.generic.event.HypixelEventClass; +import net.swofty.type.generic.event.phase.EventPhase; +import net.swofty.type.generic.event.phase.PhasedEvent; import net.swofty.type.skyblockgeneric.event.custom.PlayerRegionChangeEvent; import net.swofty.type.skyblockgeneric.noteblock.SkyBlockSong; import net.swofty.type.skyblockgeneric.noteblock.SkyBlockSongsHandler; @@ -18,7 +19,7 @@ public class ActionRegionPlaySong implements HypixelEventClass { - @HypixelEvent(node = EventNodes.CUSTOM, requireDataLoaded = false, isAsync = true) + @PhasedEvent(node = EventNodes.CUSTOM, requireDataLoaded = false, isAsync = true, phase = EventPhase.GAMEPLAY) public void run(PlayerRegionChangeEvent event) { SkyBlockPlayer player = event.getPlayer(); SkyBlockSongsHandler songHandler = player.getSongHandler(); diff --git a/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/event/actions/custom/bestiary/ActionBestiaryLevelUp.java b/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/event/actions/custom/bestiary/ActionBestiaryLevelUp.java index 68e190759..a8f0e195c 100644 --- a/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/event/actions/custom/bestiary/ActionBestiaryLevelUp.java +++ b/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/event/actions/custom/bestiary/ActionBestiaryLevelUp.java @@ -4,8 +4,9 @@ import net.swofty.commons.StringUtility; import net.swofty.commons.skyblock.statistics.ItemStatistic; import net.swofty.type.generic.event.EventNodes; -import net.swofty.type.generic.event.HypixelEvent; import net.swofty.type.generic.event.HypixelEventClass; +import net.swofty.type.generic.event.phase.EventPhase; +import net.swofty.type.generic.event.phase.PhasedEvent; import net.swofty.type.skyblockgeneric.bestiary.BestiaryData; import net.swofty.type.skyblockgeneric.entity.mob.BestiaryMob; import net.swofty.type.skyblockgeneric.event.custom.BestiaryUpdateEvent; @@ -20,7 +21,7 @@ public class ActionBestiaryLevelUp implements HypixelEventClass { private final BestiaryData bestiaryData = new BestiaryData(); - @HypixelEvent(node = EventNodes.CUSTOM, requireDataLoaded = false) + @PhasedEvent(node = EventNodes.CUSTOM, requireDataLoaded = false, phase = EventPhase.GAMEPLAY) public void run(BestiaryUpdateEvent event) { SkyBlockPlayer player = event.getPlayer(); BestiaryMob mob = event.getBestiaryMob(); diff --git a/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/event/actions/custom/collection/ActionCollectionAdd.java b/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/event/actions/custom/collection/ActionCollectionAdd.java index 1b1e1b75d..98798a859 100644 --- a/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/event/actions/custom/collection/ActionCollectionAdd.java +++ b/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/event/actions/custom/collection/ActionCollectionAdd.java @@ -4,8 +4,9 @@ import net.swofty.commons.skyblock.item.ItemType; import net.swofty.proxyapi.ProxyPlayerSet; import net.swofty.type.generic.event.EventNodes; -import net.swofty.type.generic.event.HypixelEvent; import net.swofty.type.generic.event.HypixelEventClass; +import net.swofty.type.generic.event.phase.EventPhase; +import net.swofty.type.generic.event.phase.PhasedEvent; import net.swofty.type.generic.event.HypixelEventHandler; import net.swofty.type.generic.utility.MathUtility; import net.swofty.type.skyblockgeneric.SkyBlockGenericLoader; @@ -21,7 +22,7 @@ public class ActionCollectionAdd implements HypixelEventClass { - @HypixelEvent(node = EventNodes.CUSTOM, requireDataLoaded = true) + @PhasedEvent(node = EventNodes.CUSTOM, requireDataLoaded = true, phase = EventPhase.GAMEPLAY) public void run(CustomBlockBreakEvent event) { if (event.getPlayerPlaced()) return; diff --git a/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/event/actions/custom/collection/ActionCollectionDisplay.java b/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/event/actions/custom/collection/ActionCollectionDisplay.java index b7b0c3234..4de3637c6 100644 --- a/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/event/actions/custom/collection/ActionCollectionDisplay.java +++ b/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/event/actions/custom/collection/ActionCollectionDisplay.java @@ -5,8 +5,9 @@ import net.minestom.server.item.ItemStack; import net.swofty.commons.StringUtility; import net.swofty.type.generic.event.EventNodes; -import net.swofty.type.generic.event.HypixelEvent; import net.swofty.type.generic.event.HypixelEventClass; +import net.swofty.type.generic.event.phase.EventPhase; +import net.swofty.type.generic.event.phase.PhasedEvent; import net.swofty.type.skyblockgeneric.collection.CollectionCategories; import net.swofty.type.skyblockgeneric.collection.CollectionCategory; import net.swofty.type.skyblockgeneric.event.custom.CollectionUpdateEvent; @@ -19,7 +20,7 @@ public class ActionCollectionDisplay implements HypixelEventClass { - @HypixelEvent(node = EventNodes.CUSTOM, requireDataLoaded = true) + @PhasedEvent(node = EventNodes.CUSTOM, requireDataLoaded = true, phase = EventPhase.GAMEPLAY) public void run(CollectionUpdateEvent event) { if (event.getOldValue() == 0 && CollectionCategories.getCategory(event.getItemType()) != null) { @@ -92,4 +93,4 @@ public void run(CollectionUpdateEvent event) { player.sendMessage("§e§l▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬"); } } -} \ No newline at end of file +} diff --git a/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/event/actions/custom/collection/ActionCollectionHypixelLevel.java b/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/event/actions/custom/collection/ActionCollectionHypixelLevel.java index 4a4c8f61f..0d59cec11 100644 --- a/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/event/actions/custom/collection/ActionCollectionHypixelLevel.java +++ b/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/event/actions/custom/collection/ActionCollectionHypixelLevel.java @@ -1,8 +1,9 @@ package net.swofty.type.skyblockgeneric.event.actions.custom.collection; import net.swofty.type.generic.event.EventNodes; -import net.swofty.type.generic.event.HypixelEvent; import net.swofty.type.generic.event.HypixelEventClass; +import net.swofty.type.generic.event.phase.EventPhase; +import net.swofty.type.generic.event.phase.PhasedEvent; import net.swofty.type.skyblockgeneric.collection.CollectionCategories; import net.swofty.type.skyblockgeneric.collection.CollectionCategory; import net.swofty.type.skyblockgeneric.event.custom.CollectionUpdateEvent; @@ -11,7 +12,7 @@ public class ActionCollectionHypixelLevel implements HypixelEventClass { - @HypixelEvent(node = EventNodes.CUSTOM, requireDataLoaded = true) + @PhasedEvent(node = EventNodes.CUSTOM, requireDataLoaded = true, phase = EventPhase.GAMEPLAY) public void run(CollectionUpdateEvent event) { if (CollectionCategories.getCategory(event.getItemType()) == null) return; diff --git a/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/event/actions/custom/levels/ActionChangeHypixelXP.java b/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/event/actions/custom/levels/ActionChangeHypixelXP.java index 846d51e12..2f9016ac0 100644 --- a/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/event/actions/custom/levels/ActionChangeHypixelXP.java +++ b/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/event/actions/custom/levels/ActionChangeHypixelXP.java @@ -1,8 +1,9 @@ package net.swofty.type.skyblockgeneric.event.actions.custom.levels; import net.swofty.type.generic.event.EventNodes; -import net.swofty.type.generic.event.HypixelEvent; import net.swofty.type.generic.event.HypixelEventClass; +import net.swofty.type.generic.event.phase.EventPhase; +import net.swofty.type.generic.event.phase.PhasedEvent; import net.swofty.type.skyblockgeneric.event.actions.player.ActionAddSkyBlockXPToNametag; import net.swofty.type.skyblockgeneric.event.custom.SkyBlockXPModificationEvent; import net.swofty.type.skyblockgeneric.levels.SkyBlockLevelCause; @@ -15,7 +16,7 @@ public class ActionChangeHypixelXP implements HypixelEventClass { - @HypixelEvent(node = EventNodes.CUSTOM, requireDataLoaded = true) + @PhasedEvent(node = EventNodes.CUSTOM, requireDataLoaded = true, phase = EventPhase.GAMEPLAY) public void run(SkyBlockXPModificationEvent event) { if (event.getNewXP() <= event.getOldXP()) return; SkyBlockPlayer player = event.getPlayer(); diff --git a/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/event/actions/custom/loot/CoinDropHandler.java b/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/event/actions/custom/loot/CoinDropHandler.java index f5fe26d09..7e0cf0700 100644 --- a/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/event/actions/custom/loot/CoinDropHandler.java +++ b/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/event/actions/custom/loot/CoinDropHandler.java @@ -5,15 +5,16 @@ import net.swofty.type.skyblockgeneric.entity.mob.BestiaryMob; import net.swofty.type.skyblockgeneric.entity.mob.SkyBlockMob; import net.swofty.type.generic.event.EventNodes; -import net.swofty.type.generic.event.HypixelEvent; import net.swofty.type.generic.event.HypixelEventClass; +import net.swofty.type.generic.event.phase.EventPhase; +import net.swofty.type.generic.event.phase.PhasedEvent; import net.swofty.type.skyblockgeneric.event.custom.PlayerKilledSkyBlockMobEvent; import net.swofty.type.skyblockgeneric.user.SkyBlockPlayer; public class CoinDropHandler implements HypixelEventClass { BestiaryData bestiaryData = new BestiaryData(); - @HypixelEvent(node = EventNodes.CUSTOM, requireDataLoaded = true) + @PhasedEvent(node = EventNodes.CUSTOM, requireDataLoaded = true, phase = EventPhase.GAMEPLAY) public void run(PlayerKilledSkyBlockMobEvent event) { SkyBlockPlayer player = event.getPlayer(); diff --git a/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/event/actions/custom/loot/VanillaExperienceHandler.java b/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/event/actions/custom/loot/VanillaExperienceHandler.java index ff91bcdaa..6f18c07e7 100644 --- a/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/event/actions/custom/loot/VanillaExperienceHandler.java +++ b/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/event/actions/custom/loot/VanillaExperienceHandler.java @@ -4,8 +4,9 @@ import net.swofty.type.skyblockgeneric.entity.mob.BestiaryMob; import net.swofty.type.skyblockgeneric.entity.mob.SkyBlockMob; import net.swofty.type.generic.event.EventNodes; -import net.swofty.type.generic.event.HypixelEvent; import net.swofty.type.generic.event.HypixelEventClass; +import net.swofty.type.generic.event.phase.EventPhase; +import net.swofty.type.generic.event.phase.PhasedEvent; import net.swofty.type.skyblockgeneric.enchantment.EnchantmentType; import net.swofty.type.skyblockgeneric.enchantment.SkyBlockEnchantment; import net.swofty.type.skyblockgeneric.enchantment.impl.EnchantmentExperience; @@ -17,7 +18,7 @@ public class VanillaExperienceHandler implements HypixelEventClass { BestiaryData bestiaryData = new BestiaryData(); - @HypixelEvent(node = EventNodes.CUSTOM, requireDataLoaded = true) + @PhasedEvent(node = EventNodes.CUSTOM, requireDataLoaded = true, phase = EventPhase.GAMEPLAY) public void run(PlayerKilledSkyBlockMobEvent event) { SkyBlockPlayer player = event.getPlayer(); diff --git a/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/event/actions/custom/skill/ActionSkillCarpentryGain.java b/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/event/actions/custom/skill/ActionSkillCarpentryGain.java index ee4cdfc1a..08cff1df3 100644 --- a/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/event/actions/custom/skill/ActionSkillCarpentryGain.java +++ b/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/event/actions/custom/skill/ActionSkillCarpentryGain.java @@ -2,8 +2,9 @@ import net.swofty.commons.skyblock.item.ItemType; import net.swofty.type.generic.event.EventNodes; -import net.swofty.type.generic.event.HypixelEvent; import net.swofty.type.generic.event.HypixelEventClass; +import net.swofty.type.generic.event.phase.EventPhase; +import net.swofty.type.generic.event.phase.PhasedEvent; import net.swofty.type.skyblockgeneric.event.custom.ItemCraftEvent; import net.swofty.type.skyblockgeneric.item.SkyBlockItem; import net.swofty.type.skyblockgeneric.item.components.CraftableComponent; @@ -16,7 +17,7 @@ import java.util.Map; public class ActionSkillCarpentryGain implements HypixelEventClass { - @HypixelEvent(node = EventNodes.CUSTOM, requireDataLoaded = true) + @PhasedEvent(node = EventNodes.CUSTOM, requireDataLoaded = true, phase = EventPhase.GAMEPLAY) public void run(ItemCraftEvent event) { SkyBlockPlayer player = event.getPlayer(); if (!player.getMissionData().hasCompleted("give_wool_to_carpenter")) return; diff --git a/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/event/actions/custom/skill/ActionSkillDisplay.java b/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/event/actions/custom/skill/ActionSkillDisplay.java index f91c62d4f..da8e9caa6 100644 --- a/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/event/actions/custom/skill/ActionSkillDisplay.java +++ b/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/event/actions/custom/skill/ActionSkillDisplay.java @@ -1,15 +1,16 @@ package net.swofty.type.skyblockgeneric.event.actions.custom.skill; import net.swofty.type.generic.event.EventNodes; -import net.swofty.type.generic.event.HypixelEvent; import net.swofty.type.generic.event.HypixelEventClass; +import net.swofty.type.generic.event.phase.EventPhase; +import net.swofty.type.generic.event.phase.PhasedEvent; import net.swofty.type.skyblockgeneric.event.custom.SkillUpdateEvent; import net.swofty.type.skyblockgeneric.user.SkyBlockActionBar; public class ActionSkillDisplay implements HypixelEventClass { - @HypixelEvent(node = EventNodes.CUSTOM, requireDataLoaded = true) + @PhasedEvent(node = EventNodes.CUSTOM, requireDataLoaded = true, phase = EventPhase.GAMEPLAY) public void run(SkillUpdateEvent event) { double oldValue = event.getOldValueRaw(); double newValue = event.getNewValueRaw(); diff --git a/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/event/actions/custom/skill/ActionSkillHypixelLevel.java b/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/event/actions/custom/skill/ActionSkillHypixelLevel.java index c0036c6c4..4652a9ccb 100644 --- a/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/event/actions/custom/skill/ActionSkillHypixelLevel.java +++ b/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/event/actions/custom/skill/ActionSkillHypixelLevel.java @@ -1,8 +1,9 @@ package net.swofty.type.skyblockgeneric.event.actions.custom.skill; import net.swofty.type.generic.event.EventNodes; -import net.swofty.type.generic.event.HypixelEvent; import net.swofty.type.generic.event.HypixelEventClass; +import net.swofty.type.generic.event.phase.EventPhase; +import net.swofty.type.generic.event.phase.PhasedEvent; import net.swofty.type.skyblockgeneric.event.custom.SkillUpdateEvent; import net.swofty.type.skyblockgeneric.levels.SkyBlockLevelCause; import net.swofty.type.skyblockgeneric.skill.SkillCategories; @@ -10,7 +11,7 @@ public class ActionSkillHypixelLevel implements HypixelEventClass { - @HypixelEvent(node = EventNodes.CUSTOM, requireDataLoaded = false) + @PhasedEvent(node = EventNodes.CUSTOM, requireDataLoaded = false, phase = EventPhase.GAMEPLAY) public void run(SkillUpdateEvent event) { if (event.getNewValueRaw() <= event.getOldValueRaw()) return; diff --git a/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/event/actions/custom/skill/ActionSkillLevelUp.java b/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/event/actions/custom/skill/ActionSkillLevelUp.java index 502d89904..bbceed0c6 100644 --- a/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/event/actions/custom/skill/ActionSkillLevelUp.java +++ b/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/event/actions/custom/skill/ActionSkillLevelUp.java @@ -5,8 +5,9 @@ import net.swofty.commons.StringUtility; import net.swofty.commons.skyblock.statistics.ItemStatistic; import net.swofty.type.generic.event.EventNodes; -import net.swofty.type.generic.event.HypixelEvent; import net.swofty.type.generic.event.HypixelEventClass; +import net.swofty.type.generic.event.phase.EventPhase; +import net.swofty.type.generic.event.phase.PhasedEvent; import net.swofty.type.skyblockgeneric.event.custom.SkillUpdateEvent; import net.swofty.type.skyblockgeneric.skill.SkillCategories; import net.swofty.type.skyblockgeneric.skill.SkillCategory; @@ -17,7 +18,7 @@ public class ActionSkillLevelUp implements HypixelEventClass { - @HypixelEvent(node = EventNodes.CUSTOM, requireDataLoaded = false) + @PhasedEvent(node = EventNodes.CUSTOM, requireDataLoaded = false, phase = EventPhase.GAMEPLAY) public void run(SkillUpdateEvent event) { if (event.getNewValueRaw() <= event.getOldValueRaw()) return; diff --git a/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/event/actions/custom/skill/ActionSkillMiningHandler.java b/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/event/actions/custom/skill/ActionSkillMiningHandler.java index a018d3a66..92948a21c 100644 --- a/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/event/actions/custom/skill/ActionSkillMiningHandler.java +++ b/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/event/actions/custom/skill/ActionSkillMiningHandler.java @@ -1,8 +1,9 @@ package net.swofty.type.skyblockgeneric.event.actions.custom.skill; import net.swofty.type.generic.event.EventNodes; -import net.swofty.type.generic.event.HypixelEvent; import net.swofty.type.generic.event.HypixelEventClass; +import net.swofty.type.generic.event.phase.EventPhase; +import net.swofty.type.generic.event.phase.PhasedEvent; import net.swofty.type.skyblockgeneric.data.datapoints.DatapointSkills; import net.swofty.type.skyblockgeneric.event.custom.CustomBlockBreakEvent; import net.swofty.type.skyblockgeneric.item.SkyBlockItem; @@ -11,7 +12,7 @@ public class ActionSkillMiningHandler implements HypixelEventClass { - @HypixelEvent(node = EventNodes.CUSTOM, requireDataLoaded = true) + @PhasedEvent(node = EventNodes.CUSTOM, requireDataLoaded = true, phase = EventPhase.GAMEPLAY) public void run(CustomBlockBreakEvent event) { if (event.getPlayerPlaced()) return; diff --git a/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/event/actions/custom/skill/ActionSkillPetLevel.java b/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/event/actions/custom/skill/ActionSkillPetLevel.java index 55f4769eb..57fad6f26 100644 --- a/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/event/actions/custom/skill/ActionSkillPetLevel.java +++ b/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/event/actions/custom/skill/ActionSkillPetLevel.java @@ -2,8 +2,9 @@ import net.swofty.commons.skyblock.item.attribute.attributes.ItemAttributePetData; import net.swofty.type.generic.event.EventNodes; -import net.swofty.type.generic.event.HypixelEvent; import net.swofty.type.generic.event.HypixelEventClass; +import net.swofty.type.generic.event.phase.EventPhase; +import net.swofty.type.generic.event.phase.PhasedEvent; import net.swofty.type.skyblockgeneric.event.custom.SkillUpdateEvent; import net.swofty.type.skyblockgeneric.item.SkyBlockItem; import net.swofty.type.skyblockgeneric.item.components.PetComponent; @@ -11,7 +12,7 @@ public class ActionSkillPetLevel implements HypixelEventClass { - @HypixelEvent(node = EventNodes.CUSTOM, requireDataLoaded = false) + @PhasedEvent(node = EventNodes.CUSTOM, requireDataLoaded = false, phase = EventPhase.GAMEPLAY) public void run(SkillUpdateEvent event) { if (event.getNewValueRaw() <= event.getOldValueRaw()) return; double xp = event.getNewValueRaw() - event.getOldValueRaw(); diff --git a/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/event/actions/custom/skill/ActionSkillUpdateLast.java b/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/event/actions/custom/skill/ActionSkillUpdateLast.java index 48f832b7a..6536a9e4c 100644 --- a/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/event/actions/custom/skill/ActionSkillUpdateLast.java +++ b/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/event/actions/custom/skill/ActionSkillUpdateLast.java @@ -1,14 +1,15 @@ package net.swofty.type.skyblockgeneric.event.actions.custom.skill; import net.swofty.type.generic.event.EventNodes; -import net.swofty.type.generic.event.HypixelEvent; import net.swofty.type.generic.event.HypixelEventClass; +import net.swofty.type.generic.event.phase.EventPhase; +import net.swofty.type.generic.event.phase.PhasedEvent; import net.swofty.type.skyblockgeneric.data.datapoints.DatapointSkillCategory; import net.swofty.type.skyblockgeneric.event.custom.SkillUpdateEvent; public class ActionSkillUpdateLast implements HypixelEventClass { - @HypixelEvent(node = EventNodes.CUSTOM, requireDataLoaded = true) + @PhasedEvent(node = EventNodes.CUSTOM, requireDataLoaded = true, phase = EventPhase.GAMEPLAY) public void run(SkillUpdateEvent event) { double oldValue = event.getOldValueRaw(); double newValue = event.getNewValueRaw(); diff --git a/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/event/actions/entity/ActionAnimateEntityDamage.java b/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/event/actions/entity/ActionAnimateEntityDamage.java index 31730b2a4..c04a1262f 100644 --- a/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/event/actions/entity/ActionAnimateEntityDamage.java +++ b/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/event/actions/entity/ActionAnimateEntityDamage.java @@ -3,12 +3,13 @@ import net.minestom.server.event.entity.EntityDamageEvent; import net.minestom.server.network.packet.server.play.DamageEventPacket; import net.swofty.type.generic.event.EventNodes; -import net.swofty.type.generic.event.HypixelEvent; import net.swofty.type.generic.event.HypixelEventClass; +import net.swofty.type.generic.event.phase.EventPhase; +import net.swofty.type.generic.event.phase.PhasedEvent; public class ActionAnimateEntityDamage implements HypixelEventClass { - @HypixelEvent(node = EventNodes.ENTITY, requireDataLoaded = false) + @PhasedEvent(node = EventNodes.ENTITY, requireDataLoaded = false, phase = EventPhase.GAMEPLAY) public void run(EntityDamageEvent event) { event.setAnimation(true); event.setCancelled(false); diff --git a/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/event/actions/entity/ActionChunkUnload.java b/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/event/actions/entity/ActionChunkUnload.java index fb549b543..84a4d6e30 100644 --- a/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/event/actions/entity/ActionChunkUnload.java +++ b/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/event/actions/entity/ActionChunkUnload.java @@ -4,12 +4,13 @@ import net.minestom.server.instance.Instance; import net.swofty.type.generic.HypixelConst; import net.swofty.type.generic.event.EventNodes; -import net.swofty.type.generic.event.HypixelEvent; import net.swofty.type.generic.event.HypixelEventClass; +import net.swofty.type.generic.event.phase.EventPhase; +import net.swofty.type.generic.event.phase.PhasedEvent; public class ActionChunkUnload implements HypixelEventClass { - @HypixelEvent(node = EventNodes.ENTITY, requireDataLoaded = false, isAsync = true) + @PhasedEvent(node = EventNodes.ENTITY, requireDataLoaded = false, isAsync = true, phase = EventPhase.GAMEPLAY) public void run(InstanceChunkUnloadEvent event) { Instance instance = event.getInstance(); int chunkX = event.getChunkX(); diff --git a/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/event/actions/item/ActionDrinkPotion.java b/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/event/actions/item/ActionDrinkPotion.java index 831c14a0c..76a9c3e7e 100644 --- a/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/event/actions/item/ActionDrinkPotion.java +++ b/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/event/actions/item/ActionDrinkPotion.java @@ -5,8 +5,9 @@ import net.minestom.server.item.Material; import net.swofty.commons.skyblock.item.attribute.attributes.ItemAttributePotionData; import net.swofty.type.generic.event.EventNodes; -import net.swofty.type.generic.event.HypixelEvent; import net.swofty.type.generic.event.HypixelEventClass; +import net.swofty.type.generic.event.phase.EventPhase; +import net.swofty.type.generic.event.phase.PhasedEvent; import net.swofty.type.skyblockgeneric.item.SkyBlockItem; import net.swofty.type.skyblockgeneric.potion.PotionEffectService; import net.swofty.type.skyblockgeneric.user.SkyBlockPlayer; @@ -17,7 +18,7 @@ */ public class ActionDrinkPotion implements HypixelEventClass { - @HypixelEvent(node = EventNodes.PLAYER, requireDataLoaded = true) + @PhasedEvent(node = EventNodes.PLAYER, requireDataLoaded = true, phase = EventPhase.GAMEPLAY) public void run(PlayerFinishItemUseEvent event) { SkyBlockPlayer player = (SkyBlockPlayer) event.getPlayer(); ItemStack itemStack = event.getItemStack(); diff --git a/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/event/actions/item/ActionItemAbilityBlockLeftUse.java b/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/event/actions/item/ActionItemAbilityBlockLeftUse.java index f2fa68b11..19a6ef16f 100644 --- a/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/event/actions/item/ActionItemAbilityBlockLeftUse.java +++ b/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/event/actions/item/ActionItemAbilityBlockLeftUse.java @@ -4,8 +4,9 @@ import net.minestom.server.event.player.PlayerBlockBreakEvent; import net.minestom.server.item.ItemStack; import net.swofty.type.generic.event.EventNodes; -import net.swofty.type.generic.event.HypixelEvent; import net.swofty.type.generic.event.HypixelEventClass; +import net.swofty.type.generic.event.phase.EventPhase; +import net.swofty.type.generic.event.phase.PhasedEvent; import net.swofty.type.skyblockgeneric.item.SkyBlockItem; import net.swofty.type.skyblockgeneric.item.components.AbilityComponent; import net.swofty.type.skyblockgeneric.item.handlers.ability.RegisteredAbility; @@ -14,7 +15,7 @@ public class ActionItemAbilityBlockLeftUse implements HypixelEventClass { @SneakyThrows - @HypixelEvent(node = EventNodes.PLAYER, requireDataLoaded = true) + @PhasedEvent(node = EventNodes.PLAYER, requireDataLoaded = true, phase = EventPhase.GAMEPLAY) public void run(PlayerBlockBreakEvent event) { ItemStack itemStack = event.getPlayer().getItemInMainHand(); SkyBlockItem item = new SkyBlockItem(itemStack); diff --git a/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/event/actions/item/ActionItemAbilityBlockRightUse.java b/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/event/actions/item/ActionItemAbilityBlockRightUse.java index fa9910c26..06e46ddfa 100644 --- a/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/event/actions/item/ActionItemAbilityBlockRightUse.java +++ b/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/event/actions/item/ActionItemAbilityBlockRightUse.java @@ -4,8 +4,9 @@ import net.minestom.server.event.player.PlayerBlockInteractEvent; import net.minestom.server.item.ItemStack; import net.swofty.type.generic.event.EventNodes; -import net.swofty.type.generic.event.HypixelEvent; import net.swofty.type.generic.event.HypixelEventClass; +import net.swofty.type.generic.event.phase.EventPhase; +import net.swofty.type.generic.event.phase.PhasedEvent; import net.swofty.type.skyblockgeneric.item.SkyBlockItem; import net.swofty.type.skyblockgeneric.item.components.AbilityComponent; import net.swofty.type.skyblockgeneric.item.handlers.ability.RegisteredAbility; @@ -14,7 +15,7 @@ public class ActionItemAbilityBlockRightUse implements HypixelEventClass { @SneakyThrows - @HypixelEvent(node = EventNodes.PLAYER, requireDataLoaded = true) + @PhasedEvent(node = EventNodes.PLAYER, requireDataLoaded = true, phase = EventPhase.GAMEPLAY) public void run(PlayerBlockInteractEvent event) { ItemStack itemStack = event.getPlayer().getItemInMainHand(); SkyBlockItem item = new SkyBlockItem(itemStack); diff --git a/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/event/actions/item/ActionItemAbilityLeftUse.java b/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/event/actions/item/ActionItemAbilityLeftUse.java index f73ae3f18..d7b4dfffc 100644 --- a/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/event/actions/item/ActionItemAbilityLeftUse.java +++ b/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/event/actions/item/ActionItemAbilityLeftUse.java @@ -4,8 +4,9 @@ import net.minestom.server.event.player.PlayerHandAnimationEvent; import net.minestom.server.item.ItemStack; import net.swofty.type.generic.event.EventNodes; -import net.swofty.type.generic.event.HypixelEvent; import net.swofty.type.generic.event.HypixelEventClass; +import net.swofty.type.generic.event.phase.EventPhase; +import net.swofty.type.generic.event.phase.PhasedEvent; import net.swofty.type.skyblockgeneric.item.SkyBlockItem; import net.swofty.type.skyblockgeneric.item.components.AbilityComponent; import net.swofty.type.skyblockgeneric.item.handlers.ability.RegisteredAbility; @@ -15,7 +16,7 @@ public class ActionItemAbilityLeftUse implements HypixelEventClass { @SneakyThrows - @HypixelEvent(node = EventNodes.PLAYER, requireDataLoaded = true) + @PhasedEvent(node = EventNodes.PLAYER, requireDataLoaded = true, phase = EventPhase.GAMEPLAY) public void run(PlayerHandAnimationEvent event) { ItemStack itemStack = event.getPlayer().getItemInMainHand(); SkyBlockItem item = new SkyBlockItem(itemStack); diff --git a/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/event/actions/item/ActionItemAbilityRightUse.java b/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/event/actions/item/ActionItemAbilityRightUse.java index a003cedc6..f5927655e 100644 --- a/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/event/actions/item/ActionItemAbilityRightUse.java +++ b/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/event/actions/item/ActionItemAbilityRightUse.java @@ -5,8 +5,9 @@ import net.minestom.server.item.ItemStack; import net.swofty.commons.skyblock.item.UnderstandableSkyBlockItem; import net.swofty.type.generic.event.EventNodes; -import net.swofty.type.generic.event.HypixelEvent; import net.swofty.type.generic.event.HypixelEventClass; +import net.swofty.type.generic.event.phase.EventPhase; +import net.swofty.type.generic.event.phase.PhasedEvent; import net.swofty.type.skyblockgeneric.item.SkyBlockItem; import net.swofty.type.skyblockgeneric.item.components.AbilityComponent; import net.swofty.type.skyblockgeneric.item.handlers.ability.RegisteredAbility; @@ -16,7 +17,7 @@ public class ActionItemAbilityRightUse implements HypixelEventClass { @SneakyThrows - @HypixelEvent(node = EventNodes.PLAYER, requireDataLoaded = true) + @PhasedEvent(node = EventNodes.PLAYER, requireDataLoaded = true, phase = EventPhase.GAMEPLAY) public void run(PlayerUseItemEvent event) { ItemStack itemStack = event.getItemStack(); SkyBlockItem item = new SkyBlockItem(itemStack); diff --git a/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/event/actions/item/ActionItemDisableEatingAnimation.java b/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/event/actions/item/ActionItemDisableEatingAnimation.java index 0c5650dd3..fde5cb3c4 100644 --- a/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/event/actions/item/ActionItemDisableEatingAnimation.java +++ b/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/event/actions/item/ActionItemDisableEatingAnimation.java @@ -2,15 +2,16 @@ import net.minestom.server.event.item.PlayerBeginItemUseEvent; import net.swofty.type.generic.event.EventNodes; -import net.swofty.type.generic.event.HypixelEvent; import net.swofty.type.generic.event.HypixelEventClass; +import net.swofty.type.generic.event.phase.EventPhase; +import net.swofty.type.generic.event.phase.PhasedEvent; import net.swofty.type.skyblockgeneric.item.SkyBlockItem; import net.swofty.type.skyblockgeneric.item.components.DisableAnimationComponent; import net.swofty.type.skyblockgeneric.user.SkyBlockPlayer; public class ActionItemDisableEatingAnimation implements HypixelEventClass { - @HypixelEvent(node = EventNodes.PLAYER, requireDataLoaded = true) + @PhasedEvent(node = EventNodes.PLAYER, requireDataLoaded = true, phase = EventPhase.GAMEPLAY) public void run(PlayerBeginItemUseEvent event) { SkyBlockPlayer player = (SkyBlockPlayer) event.getPlayer(); SkyBlockItem item = new SkyBlockItem(player.getItemInMainHand()); diff --git a/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/event/actions/item/ActionItemDrop.java b/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/event/actions/item/ActionItemDrop.java index 41da19388..0d7b17325 100644 --- a/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/event/actions/item/ActionItemDrop.java +++ b/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/event/actions/item/ActionItemDrop.java @@ -5,15 +5,16 @@ import net.minestom.server.event.item.ItemDropEvent; import net.swofty.type.generic.data.datapoints.DatapointToggles; import net.swofty.type.generic.event.EventNodes; -import net.swofty.type.generic.event.HypixelEvent; import net.swofty.type.generic.event.HypixelEventClass; +import net.swofty.type.generic.event.phase.EventPhase; +import net.swofty.type.generic.event.phase.PhasedEvent; import net.swofty.type.skyblockgeneric.entity.DroppedItemEntityImpl; import net.swofty.type.skyblockgeneric.item.SkyBlockItem; import net.swofty.type.skyblockgeneric.user.SkyBlockPlayer; public class ActionItemDrop implements HypixelEventClass { - @HypixelEvent(node = EventNodes.PLAYER, requireDataLoaded = true) + @PhasedEvent(node = EventNodes.PLAYER, requireDataLoaded = true, phase = EventPhase.GAMEPLAY) public void run(ItemDropEvent event) { SkyBlockPlayer player = (SkyBlockPlayer) event.getPlayer(); diff --git a/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/event/actions/item/ActionItemLeftUse.java b/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/event/actions/item/ActionItemLeftUse.java index 65c8e9e3c..2138e1424 100644 --- a/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/event/actions/item/ActionItemLeftUse.java +++ b/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/event/actions/item/ActionItemLeftUse.java @@ -4,8 +4,9 @@ import net.minestom.server.event.player.PlayerHandAnimationEvent; import net.minestom.server.item.ItemStack; import net.swofty.type.generic.event.EventNodes; -import net.swofty.type.generic.event.HypixelEvent; import net.swofty.type.generic.event.HypixelEventClass; +import net.swofty.type.generic.event.phase.EventPhase; +import net.swofty.type.generic.event.phase.PhasedEvent; import net.swofty.type.skyblockgeneric.item.SkyBlockItem; import net.swofty.type.skyblockgeneric.item.components.InteractableComponent; import net.swofty.type.skyblockgeneric.user.SkyBlockPlayer; @@ -13,7 +14,7 @@ public class ActionItemLeftUse implements HypixelEventClass { @SneakyThrows - @HypixelEvent(node = EventNodes.PLAYER, requireDataLoaded = true) + @PhasedEvent(node = EventNodes.PLAYER, requireDataLoaded = true, phase = EventPhase.GAMEPLAY) public void run(PlayerHandAnimationEvent event) { ItemStack itemStack = event.getPlayer().getItemInMainHand(); SkyBlockItem item = new SkyBlockItem(itemStack); diff --git a/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/event/actions/item/ActionItemPlace.java b/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/event/actions/item/ActionItemPlace.java index f63bed015..041b1c9b8 100644 --- a/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/event/actions/item/ActionItemPlace.java +++ b/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/event/actions/item/ActionItemPlace.java @@ -4,8 +4,9 @@ import net.minestom.server.event.player.PlayerBlockPlaceEvent; import net.minestom.server.item.ItemStack; import net.swofty.type.generic.event.EventNodes; -import net.swofty.type.generic.event.HypixelEvent; import net.swofty.type.generic.event.HypixelEventClass; +import net.swofty.type.generic.event.phase.EventPhase; +import net.swofty.type.generic.event.phase.PhasedEvent; import net.swofty.type.skyblockgeneric.block.SkyBlockBlock; import net.swofty.type.skyblockgeneric.item.SkyBlockItem; import net.swofty.type.skyblockgeneric.item.components.PlaceEventComponent; @@ -15,7 +16,7 @@ public class ActionItemPlace implements HypixelEventClass { @SneakyThrows - @HypixelEvent(node = EventNodes.PLAYER, requireDataLoaded = true) + @PhasedEvent(node = EventNodes.PLAYER, requireDataLoaded = true, phase = EventPhase.GAMEPLAY) public void run(PlayerBlockPlaceEvent event) { ItemStack itemStack = event.getPlayer().getItemInMainHand(); SkyBlockItem item = new SkyBlockItem(itemStack); diff --git a/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/event/actions/item/ActionItemRightUse.java b/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/event/actions/item/ActionItemRightUse.java index 964cf87f1..b6a8915b9 100644 --- a/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/event/actions/item/ActionItemRightUse.java +++ b/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/event/actions/item/ActionItemRightUse.java @@ -4,15 +4,16 @@ import net.minestom.server.event.player.PlayerUseItemEvent; import net.minestom.server.item.ItemStack; import net.swofty.type.generic.event.EventNodes; -import net.swofty.type.generic.event.HypixelEvent; import net.swofty.type.generic.event.HypixelEventClass; +import net.swofty.type.generic.event.phase.EventPhase; +import net.swofty.type.generic.event.phase.PhasedEvent; import net.swofty.type.skyblockgeneric.item.SkyBlockItem; import net.swofty.type.skyblockgeneric.item.components.InteractableComponent; import net.swofty.type.skyblockgeneric.user.SkyBlockPlayer; public class ActionItemRightUse implements HypixelEventClass { @SneakyThrows - @HypixelEvent(node = EventNodes.PLAYER, requireDataLoaded = true) + @PhasedEvent(node = EventNodes.PLAYER, requireDataLoaded = true, phase = EventPhase.GAMEPLAY) public void run(PlayerUseItemEvent event) { ItemStack itemStack = event.getPlayer().getItemInMainHand(); SkyBlockItem item = new SkyBlockItem(itemStack); diff --git a/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/event/actions/item/ActionPlayerItemPickup.java b/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/event/actions/item/ActionPlayerItemPickup.java index 7d65fe0ef..7018957e1 100644 --- a/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/event/actions/item/ActionPlayerItemPickup.java +++ b/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/event/actions/item/ActionPlayerItemPickup.java @@ -4,14 +4,15 @@ import net.minestom.server.network.packet.server.play.CollectItemPacket; import net.swofty.commons.skyblock.item.ItemType; import net.swofty.type.generic.event.EventNodes; -import net.swofty.type.generic.event.HypixelEvent; import net.swofty.type.generic.event.HypixelEventClass; +import net.swofty.type.generic.event.phase.EventPhase; +import net.swofty.type.generic.event.phase.PhasedEvent; import net.swofty.type.skyblockgeneric.entity.DroppedItemEntityImpl; import net.swofty.type.skyblockgeneric.user.SkyBlockPlayer; public class ActionPlayerItemPickup implements HypixelEventClass { - @HypixelEvent(node = EventNodes.PLAYER, requireDataLoaded = false) + @PhasedEvent(node = EventNodes.PLAYER, requireDataLoaded = false, phase = EventPhase.GAMEPLAY) public void run(PlayerMoveEvent event) { final SkyBlockPlayer player = (SkyBlockPlayer) event.getPlayer(); diff --git a/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/event/actions/item/ActionThrowSplashPotion.java b/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/event/actions/item/ActionThrowSplashPotion.java index 44523a8ec..8ee20d44e 100644 --- a/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/event/actions/item/ActionThrowSplashPotion.java +++ b/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/event/actions/item/ActionThrowSplashPotion.java @@ -6,8 +6,9 @@ import net.minestom.server.item.Material; import net.swofty.commons.skyblock.item.attribute.attributes.ItemAttributePotionData; import net.swofty.type.generic.event.EventNodes; -import net.swofty.type.generic.event.HypixelEvent; import net.swofty.type.generic.event.HypixelEventClass; +import net.swofty.type.generic.event.phase.EventPhase; +import net.swofty.type.generic.event.phase.PhasedEvent; import net.swofty.type.skyblockgeneric.entity.SplashPotionEntity; import net.swofty.type.skyblockgeneric.item.SkyBlockItem; import net.swofty.type.skyblockgeneric.user.SkyBlockPlayer; @@ -17,7 +18,7 @@ */ public class ActionThrowSplashPotion implements HypixelEventClass { - @HypixelEvent(node = EventNodes.PLAYER, requireDataLoaded = true) + @PhasedEvent(node = EventNodes.PLAYER, requireDataLoaded = true, phase = EventPhase.GAMEPLAY) public void run(PlayerUseItemEvent event) { SkyBlockPlayer player = (SkyBlockPlayer) event.getPlayer(); ItemStack itemStack = event.getItemStack(); diff --git a/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/event/actions/item/ActionUseBow.java b/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/event/actions/item/ActionUseBow.java index 3a9ef3031..98ed94c63 100644 --- a/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/event/actions/item/ActionUseBow.java +++ b/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/event/actions/item/ActionUseBow.java @@ -4,8 +4,9 @@ import net.minestom.server.event.item.PlayerCancelItemUseEvent; import net.minestom.server.item.Material; import net.swofty.type.generic.event.EventNodes; -import net.swofty.type.generic.event.HypixelEvent; import net.swofty.type.generic.event.HypixelEventClass; +import net.swofty.type.generic.event.phase.EventPhase; +import net.swofty.type.generic.event.phase.PhasedEvent; import net.swofty.type.skyblockgeneric.item.SkyBlockItem; import net.swofty.type.skyblockgeneric.item.components.BowComponent; import net.swofty.type.skyblockgeneric.user.SkyBlockPlayer; @@ -13,7 +14,7 @@ public class ActionUseBow implements HypixelEventClass { private static final double MIN_POWER = 0.1; - @HypixelEvent(node = EventNodes.PLAYER, requireDataLoaded = true) + @PhasedEvent(node = EventNodes.PLAYER, requireDataLoaded = true, phase = EventPhase.GAMEPLAY) public void run(PlayerCancelItemUseEvent event) { SkyBlockPlayer player = (SkyBlockPlayer) event.getPlayer(); SkyBlockItem item = new SkyBlockItem(event.getItemStack()); diff --git a/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/event/actions/item/ActionUseShortBow.java b/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/event/actions/item/ActionUseShortBow.java index cc2d64dfc..565b3ee74 100644 --- a/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/event/actions/item/ActionUseShortBow.java +++ b/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/event/actions/item/ActionUseShortBow.java @@ -3,8 +3,9 @@ import net.minestom.server.event.item.PlayerBeginItemUseEvent; import net.minestom.server.item.ItemAnimation; import net.swofty.type.generic.event.EventNodes; -import net.swofty.type.generic.event.HypixelEvent; import net.swofty.type.generic.event.HypixelEventClass; +import net.swofty.type.generic.event.phase.EventPhase; +import net.swofty.type.generic.event.phase.PhasedEvent; import net.swofty.type.skyblockgeneric.item.SkyBlockItem; import net.swofty.type.skyblockgeneric.item.components.ArrowComponent; import net.swofty.type.skyblockgeneric.item.components.BowComponent; @@ -12,7 +13,7 @@ public class ActionUseShortBow implements HypixelEventClass { - @HypixelEvent(node = EventNodes.PLAYER, requireDataLoaded = true) + @PhasedEvent(node = EventNodes.PLAYER, requireDataLoaded = true, phase = EventPhase.GAMEPLAY) public void run(PlayerBeginItemUseEvent event) { SkyBlockPlayer player = (SkyBlockPlayer) event.getPlayer(); ItemAnimation type = event.getAnimation(); diff --git a/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/event/actions/npc/ActionPlayerInteractNPC.java b/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/event/actions/npc/ActionPlayerInteractNPC.java index fd9e6bf8a..578940961 100644 --- a/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/event/actions/npc/ActionPlayerInteractNPC.java +++ b/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/event/actions/npc/ActionPlayerInteractNPC.java @@ -3,8 +3,9 @@ import net.swofty.type.generic.entity.npc.HypixelNPC; import net.swofty.type.generic.entity.npc.trait.NPCAbiphoneTrait; import net.swofty.type.generic.event.EventNodes; -import net.swofty.type.generic.event.HypixelEvent; import net.swofty.type.generic.event.HypixelEventClass; +import net.swofty.type.generic.event.phase.EventPhase; +import net.swofty.type.generic.event.phase.PhasedEvent; import net.swofty.type.generic.event.custom.NPCInteractEvent; import net.swofty.type.skyblockgeneric.abiphone.AbiphoneNPC; import net.swofty.type.skyblockgeneric.abiphone.AbiphoneRegistry; @@ -15,7 +16,7 @@ public class ActionPlayerInteractNPC implements HypixelEventClass { - @HypixelEvent(node = EventNodes.CUSTOM, requireDataLoaded = false) + @PhasedEvent(node = EventNodes.CUSTOM, requireDataLoaded = false, phase = EventPhase.GAMEPLAY) public void run(NPCInteractEvent event) { final SkyBlockPlayer player = (SkyBlockPlayer) event.getPlayer(); HypixelNPC npc = event.getNpc(); diff --git a/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/event/actions/player/ActionAddSkyBlockXPToNametag.java b/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/event/actions/player/ActionAddSkyBlockXPToNametag.java index b07e0f090..d234a18e2 100644 --- a/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/event/actions/player/ActionAddSkyBlockXPToNametag.java +++ b/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/event/actions/player/ActionAddSkyBlockXPToNametag.java @@ -7,8 +7,9 @@ import net.minestom.server.scoreboard.TeamBuilder; import net.swofty.commons.StringUtility; import net.swofty.type.generic.event.EventNodes; -import net.swofty.type.generic.event.HypixelEvent; import net.swofty.type.generic.event.HypixelEventClass; +import net.swofty.type.generic.event.phase.EventPhase; +import net.swofty.type.generic.event.phase.PhasedEvent; import net.swofty.type.generic.user.categories.Rank; import net.swofty.type.generic.utility.MathUtility; import net.swofty.type.skyblockgeneric.data.datapoints.DatapointSkyBlockExperience; @@ -16,7 +17,7 @@ public class ActionAddSkyBlockXPToNametag implements HypixelEventClass { - @HypixelEvent(node = EventNodes.PLAYER, requireDataLoaded = true) + @PhasedEvent(node = EventNodes.PLAYER, requireDataLoaded = true, phase = EventPhase.GAMEPLAY) public void run(PlayerSpawnEvent event) { SkyBlockPlayer player = (SkyBlockPlayer) event.getPlayer(); if (!event.isFirstSpawn()) return; diff --git a/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/event/actions/player/ActionAnvilClick.java b/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/event/actions/player/ActionAnvilClick.java index 8773d41bb..3f6769d36 100644 --- a/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/event/actions/player/ActionAnvilClick.java +++ b/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/event/actions/player/ActionAnvilClick.java @@ -2,14 +2,15 @@ import net.minestom.server.event.player.PlayerBlockInteractEvent; import net.swofty.type.generic.event.EventNodes; -import net.swofty.type.generic.event.HypixelEvent; import net.swofty.type.generic.event.HypixelEventClass; +import net.swofty.type.generic.event.phase.EventPhase; +import net.swofty.type.generic.event.phase.PhasedEvent; import net.swofty.type.skyblockgeneric.gui.inventories.GUIAnvil; import net.swofty.type.skyblockgeneric.user.SkyBlockPlayer; public class ActionAnvilClick implements HypixelEventClass { - @HypixelEvent(node = EventNodes.PLAYER, requireDataLoaded = true) + @PhasedEvent(node = EventNodes.PLAYER, requireDataLoaded = true, phase = EventPhase.GAMEPLAY) public void run(PlayerBlockInteractEvent event) { SkyBlockPlayer player = (SkyBlockPlayer) event.getPlayer(); diff --git a/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/event/actions/player/ActionClearPendingBazaar.java b/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/event/actions/player/ActionClearPendingBazaar.java index 34018cfd5..45efbc6d5 100644 --- a/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/event/actions/player/ActionClearPendingBazaar.java +++ b/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/event/actions/player/ActionClearPendingBazaar.java @@ -2,13 +2,14 @@ import net.minestom.server.event.player.PlayerSpawnEvent; import net.swofty.type.generic.event.EventNodes; -import net.swofty.type.generic.event.HypixelEvent; import net.swofty.type.generic.event.HypixelEventClass; +import net.swofty.type.generic.event.phase.EventPhase; +import net.swofty.type.generic.event.phase.PhasedEvent; import net.swofty.type.skyblockgeneric.user.SkyBlockPlayer; public class ActionClearPendingBazaar implements HypixelEventClass { - @HypixelEvent(node = EventNodes.PLAYER, requireDataLoaded = true) + @PhasedEvent(node = EventNodes.PLAYER, requireDataLoaded = true, phase = EventPhase.GAMEPLAY) public void run(PlayerSpawnEvent event) { SkyBlockPlayer player = (SkyBlockPlayer) event.getPlayer(); player.getBazaarConnector().processAllPendingTransactions(); diff --git a/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/event/actions/player/ActionCraftingTableClick.java b/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/event/actions/player/ActionCraftingTableClick.java index a57d36039..b2f7bd980 100644 --- a/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/event/actions/player/ActionCraftingTableClick.java +++ b/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/event/actions/player/ActionCraftingTableClick.java @@ -3,14 +3,15 @@ import net.minestom.server.event.player.PlayerBlockInteractEvent; import net.minestom.server.item.Material; import net.swofty.type.generic.event.EventNodes; -import net.swofty.type.generic.event.HypixelEvent; import net.swofty.type.generic.event.HypixelEventClass; +import net.swofty.type.generic.event.phase.EventPhase; +import net.swofty.type.generic.event.phase.PhasedEvent; import net.swofty.type.skyblockgeneric.gui.inventories.sbmenu.GUICrafting; import net.swofty.type.skyblockgeneric.user.SkyBlockPlayer; public class ActionCraftingTableClick implements HypixelEventClass { - @HypixelEvent(node = EventNodes.PLAYER, requireDataLoaded = true) + @PhasedEvent(node = EventNodes.PLAYER, requireDataLoaded = true, phase = EventPhase.GAMEPLAY) public void run(PlayerBlockInteractEvent event) { final SkyBlockPlayer player = (SkyBlockPlayer) event.getPlayer(); diff --git a/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/event/actions/player/ActionEnchantmentTableClick.java b/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/event/actions/player/ActionEnchantmentTableClick.java index 3cc4c50d6..eaec45fad 100644 --- a/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/event/actions/player/ActionEnchantmentTableClick.java +++ b/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/event/actions/player/ActionEnchantmentTableClick.java @@ -4,14 +4,15 @@ import net.minestom.server.event.player.PlayerBlockInteractEvent; import net.minestom.server.item.Material; import net.swofty.type.generic.event.EventNodes; -import net.swofty.type.generic.event.HypixelEvent; import net.swofty.type.generic.event.HypixelEventClass; +import net.swofty.type.generic.event.phase.EventPhase; +import net.swofty.type.generic.event.phase.PhasedEvent; import net.swofty.type.skyblockgeneric.gui.inventories.GUIEnchantmentTable; import net.swofty.type.skyblockgeneric.user.SkyBlockPlayer; public class ActionEnchantmentTableClick implements HypixelEventClass { - @HypixelEvent(node = EventNodes.PLAYER, requireDataLoaded = true) + @PhasedEvent(node = EventNodes.PLAYER, requireDataLoaded = true, phase = EventPhase.GAMEPLAY) public void run(PlayerBlockInteractEvent event) { final SkyBlockPlayer player = (SkyBlockPlayer) event.getPlayer(); diff --git a/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/event/actions/player/ActionPlayerBankAddInterest.java b/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/event/actions/player/ActionPlayerBankAddInterest.java index c2024801a..97b0874bf 100644 --- a/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/event/actions/player/ActionPlayerBankAddInterest.java +++ b/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/event/actions/player/ActionPlayerBankAddInterest.java @@ -4,8 +4,9 @@ import net.swofty.commons.StringUtility; import net.swofty.proxyapi.ProxyPlayer; import net.swofty.type.generic.event.EventNodes; -import net.swofty.type.generic.event.HypixelEvent; import net.swofty.type.generic.event.HypixelEventClass; +import net.swofty.type.generic.event.phase.EventPhase; +import net.swofty.type.generic.event.phase.PhasedEvent; import net.swofty.type.skyblockgeneric.calendar.SkyBlockCalendar; import net.swofty.type.skyblockgeneric.data.datapoints.DatapointBankData; import net.swofty.type.skyblockgeneric.data.monogdb.CoopDatabase; @@ -14,7 +15,7 @@ public class ActionPlayerBankAddInterest implements HypixelEventClass { - @HypixelEvent(node = EventNodes.PLAYER, requireDataLoaded = true) + @PhasedEvent(node = EventNodes.PLAYER, requireDataLoaded = true, phase = EventPhase.GAMEPLAY) public void run(PlayerSpawnEvent event) { if (event.isFirstSpawn()) return; SkyBlockPlayer player = (SkyBlockPlayer) event.getPlayer(); diff --git a/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/event/actions/player/ActionPlayerChangeHypixelMenuDisplay.java b/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/event/actions/player/ActionPlayerChangeHypixelMenuDisplay.java index 0990ac5a4..7e3316a39 100644 --- a/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/event/actions/player/ActionPlayerChangeHypixelMenuDisplay.java +++ b/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/event/actions/player/ActionPlayerChangeHypixelMenuDisplay.java @@ -8,8 +8,9 @@ import net.swofty.commons.StringUtility; import net.swofty.commons.skyblock.item.ItemType; import net.swofty.type.generic.event.EventNodes; -import net.swofty.type.generic.event.HypixelEvent; import net.swofty.type.generic.event.HypixelEventClass; +import net.swofty.type.generic.event.phase.EventPhase; +import net.swofty.type.generic.event.phase.PhasedEvent; import net.swofty.type.generic.gui.inventory.ItemStackCreator; import net.swofty.type.skyblockgeneric.collection.CustomCollectionAward; import net.swofty.type.skyblockgeneric.data.datapoints.DatapointQuiver; @@ -24,7 +25,7 @@ public class ActionPlayerChangeHypixelMenuDisplay implements HypixelEventClass { - @HypixelEvent(node = EventNodes.PLAYER, requireDataLoaded = false) + @PhasedEvent(node = EventNodes.PLAYER, requireDataLoaded = false, phase = EventPhase.GAMEPLAY) public void run(PlayerChangeHeldSlotEvent event) { SkyBlockPlayer player = (SkyBlockPlayer) event.getPlayer(); runCheck(player); diff --git a/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/event/actions/player/ActionPlayerChat.java b/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/event/actions/player/ActionPlayerChat.java index 933283a78..357cd4464 100644 --- a/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/event/actions/player/ActionPlayerChat.java +++ b/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/event/actions/player/ActionPlayerChat.java @@ -8,8 +8,9 @@ import net.swofty.type.generic.data.datapoints.DatapointChatType; import net.swofty.type.generic.data.datapoints.DatapointToggles; import net.swofty.type.generic.event.EventNodes; -import net.swofty.type.generic.event.HypixelEvent; import net.swofty.type.generic.event.HypixelEventClass; +import net.swofty.type.generic.event.phase.EventPhase; +import net.swofty.type.generic.event.phase.PhasedEvent; import net.swofty.type.generic.party.PartyManager; import net.swofty.type.generic.user.categories.Rank; import net.swofty.type.skyblockgeneric.SkyBlockGenericLoader; @@ -20,7 +21,7 @@ public class ActionPlayerChat implements HypixelEventClass { - @HypixelEvent(node = EventNodes.PLAYER, requireDataLoaded = false) + @PhasedEvent(node = EventNodes.PLAYER, requireDataLoaded = false, phase = EventPhase.GAMEPLAY) public void run(PlayerChatEvent event) { final SkyBlockPlayer player = (SkyBlockPlayer) event.getPlayer(); event.setCancelled(true); diff --git a/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/event/actions/player/ActionPlayerInteractFairySoul.java b/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/event/actions/player/ActionPlayerInteractFairySoul.java index 4a6ce7df4..35c82fe89 100644 --- a/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/event/actions/player/ActionPlayerInteractFairySoul.java +++ b/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/event/actions/player/ActionPlayerInteractFairySoul.java @@ -2,15 +2,16 @@ import net.minestom.server.event.player.PlayerEntityInteractEvent; import net.swofty.type.generic.event.EventNodes; -import net.swofty.type.generic.event.HypixelEvent; import net.swofty.type.generic.event.HypixelEventClass; +import net.swofty.type.generic.event.phase.EventPhase; +import net.swofty.type.generic.event.phase.PhasedEvent; import net.swofty.type.skyblockgeneric.entity.EntityFairySoul; import net.swofty.type.skyblockgeneric.user.SkyBlockPlayer; import net.swofty.type.skyblockgeneric.user.fairysouls.FairySoul; public class ActionPlayerInteractFairySoul implements HypixelEventClass { - @HypixelEvent(node = EventNodes.PLAYER, requireDataLoaded = true) + @PhasedEvent(node = EventNodes.PLAYER, requireDataLoaded = true, phase = EventPhase.GAMEPLAY) public void run(PlayerEntityInteractEvent event) { final SkyBlockPlayer player = (SkyBlockPlayer) event.getPlayer(); diff --git a/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/event/actions/player/ActionPlayerJoin.java b/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/event/actions/player/ActionPlayerJoin.java index b4ee11e12..5c09abf4d 100644 --- a/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/event/actions/player/ActionPlayerJoin.java +++ b/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/event/actions/player/ActionPlayerJoin.java @@ -2,13 +2,14 @@ import net.minestom.server.event.player.PlayerSpawnEvent; import net.swofty.type.generic.event.EventNodes; -import net.swofty.type.generic.event.HypixelEvent; import net.swofty.type.generic.event.HypixelEventClass; +import net.swofty.type.generic.event.phase.EventPhase; +import net.swofty.type.generic.event.phase.PhasedEvent; import net.swofty.type.skyblockgeneric.calendar.SkyBlockCalendar; public class ActionPlayerJoin implements HypixelEventClass { - @HypixelEvent(node = EventNodes.PLAYER, requireDataLoaded = false) + @PhasedEvent(node = EventNodes.PLAYER, requireDataLoaded = false, phase = EventPhase.SPAWN) public void onPlayerJoin(PlayerSpawnEvent event) { int hour = SkyBlockCalendar.getHour(); long minecraftTime = (hour * 1000L + 6000) % 24000; diff --git a/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/event/actions/player/ActionPlayerLaunchPads.java b/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/event/actions/player/ActionPlayerLaunchPads.java index 0c73772c6..6d46d764b 100644 --- a/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/event/actions/player/ActionPlayerLaunchPads.java +++ b/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/event/actions/player/ActionPlayerLaunchPads.java @@ -14,8 +14,9 @@ import net.swofty.commons.UnderstandableProxyServer; import net.swofty.proxyapi.ProxyInformation; import net.swofty.type.generic.event.EventNodes; -import net.swofty.type.generic.event.HypixelEvent; import net.swofty.type.generic.event.HypixelEventClass; +import net.swofty.type.generic.event.phase.EventPhase; +import net.swofty.type.generic.event.phase.PhasedEvent; import net.swofty.type.generic.utility.MathUtility; import net.swofty.type.skyblockgeneric.user.SkyBlockPlayer; import net.swofty.type.skyblockgeneric.utility.LaunchPads; @@ -35,7 +36,7 @@ public class ActionPlayerLaunchPads implements HypixelEventClass { private static final ScheduledExecutorService scheduler = Executors.newScheduledThreadPool(1); private static final Set notifiedPlayers = ConcurrentHashMap.newKeySet(); - @HypixelEvent(node = EventNodes.PLAYER, requireDataLoaded = true, isAsync = true) + @PhasedEvent(node = EventNodes.PLAYER, requireDataLoaded = true, isAsync = true, phase = EventPhase.GAMEPLAY) public void run(PlayerMoveEvent event) { SkyBlockPlayer player = (SkyBlockPlayer) event.getPlayer(); diff --git a/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/event/actions/player/ActionPlayerRemoveTab.java b/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/event/actions/player/ActionPlayerRemoveTab.java index 0425b244a..3f779ea8a 100644 --- a/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/event/actions/player/ActionPlayerRemoveTab.java +++ b/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/event/actions/player/ActionPlayerRemoveTab.java @@ -5,8 +5,9 @@ import net.minestom.server.event.player.PlayerSpawnEvent; import net.minestom.server.network.packet.server.play.TeamsPacket; import net.swofty.type.generic.event.EventNodes; -import net.swofty.type.generic.event.HypixelEvent; import net.swofty.type.generic.event.HypixelEventClass; +import net.swofty.type.generic.event.phase.EventPhase; +import net.swofty.type.generic.event.phase.PhasedEvent; import net.swofty.type.generic.user.categories.Rank; import net.swofty.type.skyblockgeneric.SkyBlockGenericLoader; import net.swofty.type.skyblockgeneric.user.SkyBlockPlayer; @@ -16,7 +17,7 @@ public class ActionPlayerRemoveTab implements HypixelEventClass { - @HypixelEvent(node = EventNodes.PLAYER, requireDataLoaded = true) + @PhasedEvent(node = EventNodes.PLAYER, requireDataLoaded = true, phase = EventPhase.GAMEPLAY) public void run(PlayerSpawnEvent event) { Player player = event.getPlayer(); @@ -48,4 +49,4 @@ public void run(PlayerSpawnEvent event) { ))); }); } -} \ No newline at end of file +} diff --git a/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/event/actions/player/ActionPlayerRightClickOnPlayer.java b/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/event/actions/player/ActionPlayerRightClickOnPlayer.java index 487e9138f..ad5af9ad1 100644 --- a/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/event/actions/player/ActionPlayerRightClickOnPlayer.java +++ b/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/event/actions/player/ActionPlayerRightClickOnPlayer.java @@ -3,14 +3,15 @@ import net.minestom.server.event.player.PlayerEntityInteractEvent; import net.swofty.type.generic.event.EventNodes; -import net.swofty.type.generic.event.HypixelEvent; import net.swofty.type.generic.event.HypixelEventClass; +import net.swofty.type.generic.event.phase.EventPhase; +import net.swofty.type.generic.event.phase.PhasedEvent; import net.swofty.type.skyblockgeneric.gui.inventories.GUIViewPlayerProfile; import net.swofty.type.skyblockgeneric.user.SkyBlockPlayer; public class ActionPlayerRightClickOnPlayer implements HypixelEventClass { - @HypixelEvent(node = EventNodes.PLAYER, requireDataLoaded = true) + @PhasedEvent(node = EventNodes.PLAYER, requireDataLoaded = true, phase = EventPhase.GAMEPLAY) public void run(PlayerEntityInteractEvent event) { final SkyBlockPlayer player = (SkyBlockPlayer) event.getPlayer(); diff --git a/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/event/actions/player/ActionPlayerStrayTooFar.java b/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/event/actions/player/ActionPlayerStrayTooFar.java index 896b845e0..2900f35ad 100644 --- a/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/event/actions/player/ActionPlayerStrayTooFar.java +++ b/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/event/actions/player/ActionPlayerStrayTooFar.java @@ -3,8 +3,9 @@ import net.minestom.server.event.player.PlayerMoveEvent; import net.swofty.type.generic.HypixelConst; import net.swofty.type.generic.event.EventNodes; -import net.swofty.type.generic.event.HypixelEvent; import net.swofty.type.generic.event.HypixelEventClass; +import net.swofty.type.generic.event.phase.EventPhase; +import net.swofty.type.generic.event.phase.PhasedEvent; import net.swofty.type.generic.user.categories.Rank; import net.swofty.type.skyblockgeneric.region.SkyBlockRegion; import net.swofty.type.skyblockgeneric.user.SkyBlockPlayer; @@ -17,7 +18,7 @@ public class ActionPlayerStrayTooFar implements HypixelEventClass { public static Map startedStray = new HashMap<>(); - @HypixelEvent(node = EventNodes.PLAYER, requireDataLoaded = true) + @PhasedEvent(node = EventNodes.PLAYER, requireDataLoaded = true, phase = EventPhase.GAMEPLAY) public void run(PlayerMoveEvent event) { SkyBlockPlayer player = (SkyBlockPlayer) event.getPlayer(); SkyBlockRegion region = player.getRegion(); diff --git a/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/event/actions/player/ActionPlayerTransferServerParty.java b/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/event/actions/player/ActionPlayerTransferServerParty.java index 1f1950312..d490d6d15 100644 --- a/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/event/actions/player/ActionPlayerTransferServerParty.java +++ b/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/event/actions/player/ActionPlayerTransferServerParty.java @@ -6,8 +6,9 @@ import net.swofty.proxyapi.ProxyPlayer; import net.swofty.proxyapi.ProxyService; import net.swofty.type.generic.event.EventNodes; -import net.swofty.type.generic.event.HypixelEvent; import net.swofty.type.generic.event.HypixelEventClass; +import net.swofty.type.generic.event.phase.EventPhase; +import net.swofty.type.generic.event.phase.PhasedEvent; import net.swofty.type.generic.party.PartyManager; import net.swofty.type.skyblockgeneric.user.SkyBlockPlayer; import net.swofty.type.generic.utility.MathUtility; @@ -15,7 +16,7 @@ public class ActionPlayerTransferServerParty implements HypixelEventClass { @SneakyThrows - @HypixelEvent(node = EventNodes.PLAYER, requireDataLoaded = false, isAsync = true) + @PhasedEvent(node = EventNodes.PLAYER, requireDataLoaded = false, isAsync = true, phase = EventPhase.GAMEPLAY) public void run(PlayerDisconnectEvent event) { final SkyBlockPlayer player = (SkyBlockPlayer) event.getPlayer(); diff --git a/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/event/actions/player/ActionPlayerTravel.java b/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/event/actions/player/ActionPlayerTravel.java index 13a4e4a24..9721c1999 100644 --- a/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/event/actions/player/ActionPlayerTravel.java +++ b/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/event/actions/player/ActionPlayerTravel.java @@ -9,8 +9,9 @@ import net.swofty.commons.ServerType; import net.swofty.type.generic.HypixelConst; import net.swofty.type.generic.event.EventNodes; -import net.swofty.type.generic.event.HypixelEvent; import net.swofty.type.generic.event.HypixelEventClass; +import net.swofty.type.generic.event.phase.EventPhase; +import net.swofty.type.generic.event.phase.PhasedEvent; import net.swofty.type.skyblockgeneric.mission.MissionData; import net.swofty.type.skyblockgeneric.mission.MissionSet; import net.swofty.type.skyblockgeneric.mission.missions.MissionUseTeleporter; @@ -25,7 +26,7 @@ public class ActionPlayerTravel implements HypixelEventClass { public static List delay = new ArrayList<>(); - @HypixelEvent(node = EventNodes.PLAYER, requireDataLoaded = true) + @PhasedEvent(node = EventNodes.PLAYER, requireDataLoaded = true, phase = EventPhase.GAMEPLAY) public void run(PlayerMoveEvent event) { final SkyBlockPlayer player = (SkyBlockPlayer) event.getPlayer(); diff --git a/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/event/actions/player/blocks/ActionBlockDestroy.java b/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/event/actions/player/blocks/ActionBlockDestroy.java index 8ab63c1b5..c30fd6f96 100644 --- a/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/event/actions/player/blocks/ActionBlockDestroy.java +++ b/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/event/actions/player/blocks/ActionBlockDestroy.java @@ -2,14 +2,15 @@ import net.minestom.server.event.player.PlayerBlockBreakEvent; import net.swofty.type.generic.event.EventNodes; -import net.swofty.type.generic.event.HypixelEvent; import net.swofty.type.generic.event.HypixelEventClass; +import net.swofty.type.generic.event.phase.EventPhase; +import net.swofty.type.generic.event.phase.PhasedEvent; import net.swofty.type.skyblockgeneric.block.SkyBlockBlock; import net.swofty.type.skyblockgeneric.block.impl.BlockBreakable; public class ActionBlockDestroy implements HypixelEventClass { - @HypixelEvent(node = EventNodes.PLAYER, requireDataLoaded = true) + @PhasedEvent(node = EventNodes.PLAYER, requireDataLoaded = true, phase = EventPhase.GAMEPLAY) public void onDestroy(PlayerBlockBreakEvent event) { if (SkyBlockBlock.isSkyBlockBlock(event.getBlock())) { SkyBlockBlock block = new SkyBlockBlock(event.getBlock()); diff --git a/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/event/actions/player/blocks/ActionBlockInteract.java b/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/event/actions/player/blocks/ActionBlockInteract.java index 20a69b1c6..df152fe3d 100644 --- a/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/event/actions/player/blocks/ActionBlockInteract.java +++ b/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/event/actions/player/blocks/ActionBlockInteract.java @@ -3,8 +3,9 @@ import net.minestom.server.event.player.PlayerBlockInteractEvent; import net.minestom.server.item.ItemStack; import net.swofty.type.generic.event.EventNodes; -import net.swofty.type.generic.event.HypixelEvent; import net.swofty.type.generic.event.HypixelEventClass; +import net.swofty.type.generic.event.phase.EventPhase; +import net.swofty.type.generic.event.phase.PhasedEvent; import net.swofty.type.skyblockgeneric.block.SkyBlockBlock; import net.swofty.type.skyblockgeneric.block.impl.BlockInteractable; import net.swofty.type.skyblockgeneric.item.SkyBlockItem; @@ -14,7 +15,7 @@ public class ActionBlockInteract implements HypixelEventClass { - @HypixelEvent(node = EventNodes.PLAYER, requireDataLoaded = true) + @PhasedEvent(node = EventNodes.PLAYER, requireDataLoaded = true, phase = EventPhase.GAMEPLAY) public void onInteract(PlayerBlockInteractEvent event) { SkyBlockPlayer player = (SkyBlockPlayer) event.getPlayer(); ItemStack stack = event.getPlayer().getItemInMainHand(); diff --git a/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/event/actions/player/blocks/ActionBlockPlaceable.java b/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/event/actions/player/blocks/ActionBlockPlaceable.java index bd5cc9c2b..1ba12b6ea 100644 --- a/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/event/actions/player/blocks/ActionBlockPlaceable.java +++ b/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/event/actions/player/blocks/ActionBlockPlaceable.java @@ -3,8 +3,9 @@ import net.minestom.server.event.player.PlayerBlockPlaceEvent; import net.minestom.server.item.ItemStack; import net.swofty.type.generic.event.EventNodes; -import net.swofty.type.generic.event.HypixelEvent; import net.swofty.type.generic.event.HypixelEventClass; +import net.swofty.type.generic.event.phase.EventPhase; +import net.swofty.type.generic.event.phase.PhasedEvent; import net.swofty.type.skyblockgeneric.block.SkyBlockBlock; import net.swofty.type.skyblockgeneric.block.impl.BlockPlaceable; import net.swofty.type.skyblockgeneric.item.SkyBlockItem; @@ -13,7 +14,7 @@ public class ActionBlockPlaceable implements HypixelEventClass { - @HypixelEvent(node = EventNodes.PLAYER, requireDataLoaded = true) + @PhasedEvent(node = EventNodes.PLAYER, requireDataLoaded = true, phase = EventPhase.GAMEPLAY) public void onPlace(PlayerBlockPlaceEvent event) { ItemStack itemStack = event.getPlayer().getItemInMainHand(); SkyBlockItem item = new SkyBlockItem(itemStack); diff --git a/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/event/actions/player/blocks/ActionPlayerSetupMining.java b/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/event/actions/player/blocks/ActionPlayerSetupMining.java index f523935a2..7e51978f5 100644 --- a/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/event/actions/player/blocks/ActionPlayerSetupMining.java +++ b/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/event/actions/player/blocks/ActionPlayerSetupMining.java @@ -4,12 +4,13 @@ import net.minestom.server.event.player.PlayerSpawnEvent; import net.swofty.type.generic.HypixelConst; import net.swofty.type.generic.event.EventNodes; -import net.swofty.type.generic.event.HypixelEvent; import net.swofty.type.generic.event.HypixelEventClass; +import net.swofty.type.generic.event.phase.EventPhase; +import net.swofty.type.generic.event.phase.PhasedEvent; public class ActionPlayerSetupMining implements HypixelEventClass { - @HypixelEvent(node = EventNodes.PLAYER, requireDataLoaded = true) + @PhasedEvent(node = EventNodes.PLAYER, requireDataLoaded = true, phase = EventPhase.GAMEPLAY) public void onSpawn(PlayerSpawnEvent event) { var player = event.getPlayer(); @@ -18,4 +19,4 @@ public void onSpawn(PlayerSpawnEvent event) { player.getAttribute(Attribute.BLOCK_BREAK_SPEED).clearModifiers(); player.getAttribute(Attribute.BLOCK_BREAK_SPEED).setBaseValue(0D); } -} \ No newline at end of file +} diff --git a/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/event/actions/player/data/ActionPlayerClearSkyBlockCache.java b/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/event/actions/player/data/ActionPlayerClearSkyBlockCache.java index b576de21f..261a8da29 100644 --- a/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/event/actions/player/data/ActionPlayerClearSkyBlockCache.java +++ b/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/event/actions/player/data/ActionPlayerClearSkyBlockCache.java @@ -3,8 +3,9 @@ import lombok.SneakyThrows; import net.minestom.server.event.player.PlayerDisconnectEvent; import net.swofty.type.generic.event.EventNodes; -import net.swofty.type.generic.event.HypixelEvent; import net.swofty.type.generic.event.HypixelEventClass; +import net.swofty.type.generic.event.phase.EventPhase; +import net.swofty.type.generic.event.phase.PhasedEvent; import net.swofty.type.generic.packet.packets.client.anticheat.PacketListenerAirJump; import net.swofty.type.skyblockgeneric.event.actions.player.ActionPlayerStrayTooFar; import net.swofty.type.skyblockgeneric.item.updater.PlayerItemOrigin; @@ -15,7 +16,7 @@ public class ActionPlayerClearSkyBlockCache implements HypixelEventClass { @SneakyThrows - @HypixelEvent(node = EventNodes.PLAYER, requireDataLoaded = false) + @PhasedEvent(node = EventNodes.PLAYER, requireDataLoaded = false, phase = EventPhase.DISCONNECT, order = 10) public void run(PlayerDisconnectEvent event) { final SkyBlockPlayer player = (SkyBlockPlayer) event.getPlayer(); @@ -27,4 +28,4 @@ public void run(PlayerDisconnectEvent event) { ActionPlayerStrayTooFar.startedStray.remove(player.getUuid()); CustomEventCaller.clearCache(player); } -} \ No newline at end of file +} diff --git a/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/event/actions/player/data/ActionPlayerDataLoaded.java b/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/event/actions/player/data/ActionPlayerDataLoaded.java index df21b9903..c47ec59bf 100644 --- a/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/event/actions/player/data/ActionPlayerDataLoaded.java +++ b/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/event/actions/player/data/ActionPlayerDataLoaded.java @@ -1,140 +1,23 @@ package net.swofty.type.skyblockgeneric.event.actions.player.data; import lombok.SneakyThrows; -import net.kyori.adventure.text.Component; -import net.kyori.adventure.title.Title; -import net.minestom.server.MinecraftServer; import net.minestom.server.event.player.PlayerSpawnEvent; -import net.minestom.server.network.packet.server.play.UpdateHealthPacket; -import net.swofty.commons.skyblock.SkyBlockPlayerProfiles; -import net.swofty.packer.packs.TestingTexture; -import net.swofty.type.generic.HypixelConst; -import net.swofty.type.generic.data.datapoints.DatapointBoolean; -import net.swofty.type.generic.data.datapoints.DatapointString; -import net.swofty.type.generic.data.datapoints.DatapointStringList; -import net.swofty.type.generic.data.mongodb.ProfilesDatabase; import net.swofty.type.generic.event.EventNodes; -import net.swofty.type.generic.event.HypixelEvent; import net.swofty.type.generic.event.HypixelEventClass; -import net.swofty.type.generic.event.HypixelEventHandler; -import net.swofty.type.generic.user.categories.CustomGroups; -import net.swofty.type.generic.user.categories.Rank; -import net.swofty.type.generic.utility.MathUtility; -import net.swofty.type.skyblockgeneric.SkyBlockGenericLoader; -import net.swofty.type.skyblockgeneric.data.SkyBlockDataHandler; -import net.swofty.type.skyblockgeneric.data.SkyBlockDatapoint; -import net.swofty.type.skyblockgeneric.data.datapoints.DatapointUUID; -import net.swofty.type.skyblockgeneric.data.monogdb.CoopDatabase; -import net.swofty.type.skyblockgeneric.event.custom.PlayerRegionChangeEvent; -import net.swofty.type.skyblockgeneric.region.SkyBlockRegion; +import net.swofty.type.generic.event.phase.EventPhase; +import net.swofty.type.generic.event.phase.PhasedEvent; +import net.swofty.type.generic.user.flow.PlayerFlow; import net.swofty.type.skyblockgeneric.user.SkyBlockPlayer; -import net.swofty.type.skyblockgeneric.warps.TravelScrollIslands; -import org.tinylog.Logger; - -import java.time.Duration; -import java.util.List; -import java.util.UUID; +import net.swofty.type.skyblockgeneric.user.flow.SkyBlockPlayerDataFlow; public class ActionPlayerDataLoaded implements HypixelEventClass { @SneakyThrows - @HypixelEvent(node = EventNodes.PLAYER_DATA, requireDataLoaded = false) + @PhasedEvent(node = EventNodes.PLAYER_DATA, requireDataLoaded = false, phase = EventPhase.POST_SPAWN, order = 10) public void run(PlayerSpawnEvent event) { SkyBlockPlayer player = (SkyBlockPlayer) event.getPlayer(); if (!event.isFirstSpawn()) return; - Logger.info("Loading SkyBlock data for spawned player: " + event.getPlayer().getUsername() + "..."); - - UUID playerUuid = player.getUuid(); - SkyBlockPlayerProfiles profiles = player.getProfiles(); - SkyBlockDataHandler handler = player.getSkyblockDataHandler(); - handler.runOnLoad(player); - - // Handle coop synchronization - if (handler.get(SkyBlockDataHandler.Data.IS_COOP, DatapointBoolean.class).getValue()) { - CoopDatabase.Coop coop = CoopDatabase.getFromMember(playerUuid); - if (coop.members().size() != 1) { - SkyBlockDataHandler data; - - if (SkyBlockGenericLoader.getLoadedPlayers().stream().anyMatch(player1 -> coop.members().contains(player1.getUuid()))) { - // A coop member is online, use their data - SkyBlockPlayer otherCoopMember = SkyBlockGenericLoader.getLoadedPlayers().stream() - .filter(player1 -> coop.members().contains(player1.getUuid())).findFirst().get(); - data = otherCoopMember.getSkyblockDataHandler(); - } else { - // No coop members are online, use the first member's data - UUID finalProfileId = profiles.getCurrentlySelected(); - data = SkyBlockDataHandler.createFromProfileOnly( - new ProfilesDatabase(coop.memberProfiles().stream() - .filter(uuid -> !uuid.equals(finalProfileId)) - .findFirst().get().toString()).getDocument() - ); - } - - data.getCoopValues().forEach((key, value) -> { - SkyBlockDatapoint targetDatapoint = (SkyBlockDatapoint) handler.getSkyBlockDatapoint(key); - targetDatapoint.setValueBypassCoop(value); - }); - } - } - - player.sendMessage(""); - - // Manually call region event with a delay - MathUtility.delay(() -> { - SkyBlockRegion playerRegion = player.getRegion(); - if (playerRegion != null && player.isOnline()) - HypixelEventHandler.callCustomEvent(new PlayerRegionChangeEvent( - player, - null, - playerRegion.getType() - )); - }, 50); - - Logger.info("Successfully loaded SkyBlock data for: " + player.getUsername()); - - Thread.startVirtualThread(() -> { - player.showTitle(Title.title( - Component.text(TestingTexture.FULL_SCREEN_BLACK.toString()), - Component.empty(), - Title.Times.times(Duration.ZERO, Duration.ofMillis(300), Duration.ofSeconds(1)) - )); - - Rank rank = player.getRank(); - if (rank.isStaff()) { - CustomGroups.staffMembers.add(player); - } - - player.sendMessage("§7 "); - player.sendMessage("§aYou are playing on profile: §e" + player.getSkyblockDataHandler().get( - SkyBlockDataHandler.Data.PROFILE_NAME, DatapointString.class).getValue()); - player.sendMessage("§8Profile ID: " + player.getProfiles().getCurrentlySelected()); - - UUID islandUuid = player.getSkyblockDataHandler().get(SkyBlockDataHandler.Data.ISLAND_UUID, DatapointUUID.class).getValue(); - if (islandUuid != player.getProfiles().getCurrentlySelected()) - player.sendMessage("§8Island ID: " + islandUuid); - player.sendMessage(" "); - - player.health = player.getMaxHealth(); - player.sendPacket(new UpdateHealthPacket( - (player.health / player.getMaxHealth()) * 20, - 20, - 20)); - - MinecraftServer.getBossBarManager().removeAllBossBars(player); - MathUtility.delay(() -> { - if (!player.isOnline()) return; - player.getPetData().updatePetEntityImpl(player); - }, 20); - - TravelScrollIslands island = TravelScrollIslands.getFromType(HypixelConst.getTypeLoader().getType()); - if (island != null) { - List visitedIslands = player.getSkyblockDataHandler().get(SkyBlockDataHandler.Data.VISITED_ISLANDS, DatapointStringList.class).getValue(); - if (!visitedIslands.contains(island.getInternalName())) { - visitedIslands.add(island.getInternalName()); - player.getSkyblockDataHandler().get(SkyBlockDataHandler.Data.VISITED_ISLANDS, DatapointStringList.class).setValue(visitedIslands); - } - } - }); + PlayerFlow.run(player, "skyblock-data/post-spawn", () -> SkyBlockPlayerDataFlow.postSpawn(player)); } } diff --git a/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/event/actions/player/data/ActionPlayerSkyBlockDataLoad.java b/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/event/actions/player/data/ActionPlayerSkyBlockDataLoad.java index 1664026e3..d3402c2a0 100644 --- a/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/event/actions/player/data/ActionPlayerSkyBlockDataLoad.java +++ b/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/event/actions/player/data/ActionPlayerSkyBlockDataLoad.java @@ -2,105 +2,20 @@ import lombok.SneakyThrows; import net.minestom.server.event.player.AsyncPlayerConfigurationEvent; -import net.swofty.commons.skyblock.SkyBlockPlayerProfiles; -import net.swofty.type.generic.data.datapoints.DatapointString; -import net.swofty.type.generic.data.mongodb.ProfilesDatabase; -import net.swofty.type.generic.data.mongodb.UserDatabase; import net.swofty.type.generic.event.EventNodes; -import net.swofty.type.generic.event.HypixelEvent; import net.swofty.type.generic.event.HypixelEventClass; -import net.swofty.type.skyblockgeneric.data.SkyBlockDataHandler; -import net.swofty.type.skyblockgeneric.data.datapoints.DatapointUUID; -import net.swofty.type.skyblockgeneric.user.SkyBlockIsland; +import net.swofty.type.generic.event.phase.EventPhase; +import net.swofty.type.generic.event.phase.PhasedEvent; +import net.swofty.type.generic.user.flow.PlayerFlow; import net.swofty.type.skyblockgeneric.user.SkyBlockPlayer; -import org.bson.Document; -import org.tinylog.Logger; - -import java.util.Objects; -import java.util.UUID; +import net.swofty.type.skyblockgeneric.user.flow.SkyBlockPlayerDataFlow; public class ActionPlayerSkyBlockDataLoad implements HypixelEventClass { @SneakyThrows - @HypixelEvent(node = EventNodes.PLAYER_DATA, requireDataLoaded = false) + @PhasedEvent(node = EventNodes.PLAYER_DATA, requireDataLoaded = false, phase = EventPhase.LOAD_DATA, order = 10) public void run(AsyncPlayerConfigurationEvent event) { - Logger.info("Loading SkyBlock data for: " + event.getPlayer().getUsername() + "..."); - - final SkyBlockPlayer player = (SkyBlockPlayer) event.getPlayer(); - UUID playerUuid = player.getUuid(); - - // Check if player has ever joined SkyBlock before - SkyBlockPlayerProfiles profiles = new UserDatabase(playerUuid).getProfiles(); - UUID profileId; - - if (profiles == null) { - // Brand new SkyBlock player - initialize everything - Logger.info("New SkyBlock player detected: " + player.getUsername() + " - initializing..."); - - profileId = UUID.randomUUID(); - // Create new profiles object - profiles = new SkyBlockPlayerProfiles(playerUuid); - profiles.setCurrentlySelected(profileId); - profiles.addProfile(profileId); - - // Save the new profiles to database - UserDatabase userDb = new UserDatabase(playerUuid); - userDb.saveProfiles(profiles); - } else { - // Existing player - profileId = profiles.getCurrentlySelected(); - if (profileId == null) { - // Player has profiles but no selected profile - create new one - profileId = UUID.randomUUID(); - profiles.setCurrentlySelected(profileId); - profiles.addProfile(profileId); - - // Save updated profiles - UserDatabase userDb = new UserDatabase(playerUuid); - userDb.saveProfiles(profiles); - } - } - - // Load SkyBlock profile data - ProfilesDatabase profileDb = new ProfilesDatabase(profileId.toString()); - SkyBlockDataHandler handler; - boolean shouldPersistProfile = false; - - if (profileDb.exists()) { - Document profileDocument = profileDb.getDocument(); - handler = SkyBlockDataHandler.createFromProfile(playerUuid, profileId, profileDocument); - } else { - handler = SkyBlockDataHandler.initUserWithDefaultData(playerUuid, profileId); - shouldPersistProfile = true; - } - - DatapointUUID islandDatapoint = handler.get(SkyBlockDataHandler.Data.ISLAND_UUID, DatapointUUID.class); - UUID islandUUID = islandDatapoint.getValue(); - if (islandUUID == null) { - islandUUID = profileId; - islandDatapoint.setValue(islandUUID); - shouldPersistProfile = true; - } - - DatapointString profileNameDatapoint = handler.get(SkyBlockDataHandler.Data.PROFILE_NAME, DatapointString.class); - if (Objects.equals(profileNameDatapoint.getValue(), "null")) { - profileNameDatapoint.setValue(SkyBlockPlayerProfiles.getRandomName()); - shouldPersistProfile = true; - } - - // Put in SkyBlock cache - SkyBlockDataHandler.skyBlockCache.put(playerUuid, handler); - - if (shouldPersistProfile) { - profileDb.saveDocument(handler.toProfileDocument()); - } - - // Set up the island after the cache is populated so island init can see the player as loaded - SkyBlockIsland island = (SkyBlockIsland.getIsland(islandUUID) == null) - ? new SkyBlockIsland(islandUUID, profileId) - : SkyBlockIsland.getIsland(islandUUID); - player.setSkyBlockIsland(island); - - Logger.info("Successfully loaded SkyBlock (profile " + profileId + ") for: " + player.getUsername()); + SkyBlockPlayer player = (SkyBlockPlayer) event.getPlayer(); + PlayerFlow.run(player, "skyblock-data/load-profile", () -> SkyBlockPlayerDataFlow.load(player)); } } diff --git a/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/event/actions/player/data/ActionPlayerSkyBlockDataSave.java b/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/event/actions/player/data/ActionPlayerSkyBlockDataSave.java index 3d69e46fb..11a165adb 100644 --- a/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/event/actions/player/data/ActionPlayerSkyBlockDataSave.java +++ b/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/event/actions/player/data/ActionPlayerSkyBlockDataSave.java @@ -2,49 +2,20 @@ import lombok.SneakyThrows; import net.minestom.server.event.player.PlayerDisconnectEvent; -import net.swofty.type.generic.data.mongodb.ProfilesDatabase; import net.swofty.type.generic.event.EventNodes; -import net.swofty.type.generic.event.HypixelEvent; import net.swofty.type.generic.event.HypixelEventClass; -import net.swofty.type.skyblockgeneric.data.SkyBlockDataHandler; +import net.swofty.type.generic.event.phase.EventPhase; +import net.swofty.type.generic.event.phase.PhasedEvent; +import net.swofty.type.generic.user.flow.PlayerFlow; import net.swofty.type.skyblockgeneric.user.SkyBlockPlayer; -import org.bson.Document; -import org.tinylog.Logger; - -import java.util.UUID; - -import static com.mongodb.client.model.Filters.eq; +import net.swofty.type.skyblockgeneric.user.flow.SkyBlockPlayerDataFlow; public class ActionPlayerSkyBlockDataSave implements HypixelEventClass { @SneakyThrows - @HypixelEvent(node = EventNodes.PLAYER, requireDataLoaded = false, isAsync = true) + @PhasedEvent(node = EventNodes.PLAYER, requireDataLoaded = false, isAsync = true, phase = EventPhase.PERSIST, order = 10) public void run(PlayerDisconnectEvent event) { SkyBlockPlayer player = (SkyBlockPlayer) event.getPlayer(); - UUID playerUuid = player.getUuid(); - SkyBlockDataHandler handler = SkyBlockDataHandler.skyBlockCache.get(playerUuid); - - if (handler == null) return; - - Logger.info("Saving SkyBlock data for: " + player.getUsername() + "..."); - - // Run onSave for SkyBlock data - handler.runOnSave(player); - - // Save profile-scoped data to ProfilesDatabase - UUID profileId = handler.getCurrentProfileId(); - ProfilesDatabase profileDb = new ProfilesDatabase(profileId.toString()); - Document newDoc = handler.toProfileDocument(); - - if (profileDb.exists()) { - ProfilesDatabase.collection.replaceOne(eq("_id", profileId.toString()), newDoc); - } else { - ProfilesDatabase.collection.insertOne(newDoc); - } - - // Evict from SkyBlock cache - SkyBlockDataHandler.skyBlockCache.remove(playerUuid); - - Logger.info("Successfully saved SkyBlock (profile " + profileId + ") for: " + player.getUsername()); + PlayerFlow.run(player, "skyblock-data/save-profile", () -> SkyBlockPlayerDataFlow.save(player)); } -} \ No newline at end of file +} diff --git a/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/event/actions/player/fall/ActionPlayerFall.java b/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/event/actions/player/fall/ActionPlayerFall.java index 7fe31b18d..6e832cd6a 100644 --- a/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/event/actions/player/fall/ActionPlayerFall.java +++ b/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/event/actions/player/fall/ActionPlayerFall.java @@ -5,14 +5,15 @@ import net.minestom.server.entity.damage.DamageType; import net.minestom.server.event.player.PlayerMoveEvent; import net.swofty.type.generic.event.EventNodes; -import net.swofty.type.generic.event.HypixelEvent; import net.swofty.type.generic.event.HypixelEventClass; +import net.swofty.type.generic.event.phase.EventPhase; +import net.swofty.type.generic.event.phase.PhasedEvent; import net.swofty.type.skyblockgeneric.user.SkyBlockPlayer; public class ActionPlayerFall implements HypixelEventClass { - @HypixelEvent(node = EventNodes.PLAYER, requireDataLoaded = true) + @PhasedEvent(node = EventNodes.PLAYER, requireDataLoaded = true, phase = EventPhase.GAMEPLAY) public void run(PlayerMoveEvent event) { final SkyBlockPlayer player = (SkyBlockPlayer) event.getPlayer(); Pos newPosition = event.getNewPosition(); diff --git a/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/event/actions/player/fall/ActionPlayerVoid.java b/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/event/actions/player/fall/ActionPlayerVoid.java index ce5282c45..040a68a38 100644 --- a/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/event/actions/player/fall/ActionPlayerVoid.java +++ b/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/event/actions/player/fall/ActionPlayerVoid.java @@ -4,13 +4,14 @@ import net.minestom.server.entity.damage.DamageType; import net.minestom.server.event.player.PlayerMoveEvent; import net.swofty.type.generic.event.EventNodes; -import net.swofty.type.generic.event.HypixelEvent; import net.swofty.type.generic.event.HypixelEventClass; +import net.swofty.type.generic.event.phase.EventPhase; +import net.swofty.type.generic.event.phase.PhasedEvent; import net.swofty.type.skyblockgeneric.user.SkyBlockPlayer; public class ActionPlayerVoid implements HypixelEventClass { - @HypixelEvent(node = EventNodes.PLAYER, requireDataLoaded = true) + @PhasedEvent(node = EventNodes.PLAYER, requireDataLoaded = true, phase = EventPhase.GAMEPLAY) public void run(PlayerMoveEvent event) { final SkyBlockPlayer player = (SkyBlockPlayer) event.getPlayer(); diff --git a/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/event/actions/player/gui/ActionPlayerClickItemUpdate.java b/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/event/actions/player/gui/ActionPlayerClickItemUpdate.java index df1cecc4a..6261b1175 100644 --- a/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/event/actions/player/gui/ActionPlayerClickItemUpdate.java +++ b/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/event/actions/player/gui/ActionPlayerClickItemUpdate.java @@ -2,15 +2,16 @@ import net.minestom.server.event.inventory.InventoryItemChangeEvent; import net.swofty.type.generic.event.EventNodes; -import net.swofty.type.generic.event.HypixelEvent; import net.swofty.type.generic.event.HypixelEventClass; +import net.swofty.type.generic.event.phase.EventPhase; +import net.swofty.type.generic.event.phase.PhasedEvent; import net.swofty.type.skyblockgeneric.item.SkyBlockItem; import net.swofty.type.skyblockgeneric.item.updater.PlayerItemUpdater; import net.swofty.type.skyblockgeneric.user.SkyBlockPlayer; public class ActionPlayerClickItemUpdate implements HypixelEventClass { - @HypixelEvent(node = EventNodes.PLAYER, requireDataLoaded = true) + @PhasedEvent(node = EventNodes.PLAYER, requireDataLoaded = true, phase = EventPhase.GAMEPLAY) public void run(InventoryItemChangeEvent event) { final SkyBlockPlayer player = (SkyBlockPlayer) event.getInventory().getViewers().stream().toList().getFirst(); diff --git a/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/event/actions/player/gui/ActionPlayerInteractWithCrafting.java b/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/event/actions/player/gui/ActionPlayerInteractWithCrafting.java index 03586de6b..5327ba823 100644 --- a/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/event/actions/player/gui/ActionPlayerInteractWithCrafting.java +++ b/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/event/actions/player/gui/ActionPlayerInteractWithCrafting.java @@ -4,13 +4,14 @@ import net.minestom.server.inventory.PlayerInventory; import net.minestom.server.item.ItemStack; import net.swofty.type.generic.event.EventNodes; -import net.swofty.type.generic.event.HypixelEvent; import net.swofty.type.generic.event.HypixelEventClass; +import net.swofty.type.generic.event.phase.EventPhase; +import net.swofty.type.generic.event.phase.PhasedEvent; import net.swofty.type.skyblockgeneric.gui.inventories.sbmenu.GUICrafting; import net.swofty.type.skyblockgeneric.user.SkyBlockPlayer; public class ActionPlayerInteractWithCrafting implements HypixelEventClass { - @HypixelEvent(node = EventNodes.PLAYER, requireDataLoaded = true) + @PhasedEvent(node = EventNodes.PLAYER, requireDataLoaded = true, phase = EventPhase.GAMEPLAY) public void run(InventoryPreClickEvent event) { SkyBlockPlayer player = (SkyBlockPlayer) event.getPlayer(); diff --git a/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/event/actions/player/mobdamage/PlayerActionArrowDamageMob.java b/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/event/actions/player/mobdamage/PlayerActionArrowDamageMob.java index 31c932fa8..baa23976c 100644 --- a/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/event/actions/player/mobdamage/PlayerActionArrowDamageMob.java +++ b/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/event/actions/player/mobdamage/PlayerActionArrowDamageMob.java @@ -6,8 +6,9 @@ import net.swofty.commons.skyblock.statistics.ItemStatistic; import net.swofty.commons.skyblock.statistics.ItemStatistics; import net.swofty.type.generic.event.EventNodes; -import net.swofty.type.generic.event.HypixelEvent; import net.swofty.type.generic.event.HypixelEventClass; +import net.swofty.type.generic.event.phase.EventPhase; +import net.swofty.type.generic.event.phase.PhasedEvent; import net.swofty.type.skyblockgeneric.entity.ArrowEntityImpl; import net.swofty.type.skyblockgeneric.entity.mob.SkyBlockMob; import net.swofty.type.skyblockgeneric.item.SkyBlockItem; @@ -19,7 +20,7 @@ public class PlayerActionArrowDamageMob implements HypixelEventClass { - @HypixelEvent(node = EventNodes.ALL, requireDataLoaded = false) + @PhasedEvent(node = EventNodes.ALL, requireDataLoaded = false, phase = EventPhase.GAMEPLAY) public void run(ProjectileCollideWithEntityEvent event) { ArrowEntityImpl arrow; if (event.getEntity() instanceof ArrowEntityImpl arrowEntity) @@ -70,4 +71,4 @@ public void run(ProjectileCollideWithEntityEvent event) { collidedWith.damage(new Damage(DamageType.PLAYER_ATTACK, player, player, player.getPosition(), (float) damage)); } } -} \ No newline at end of file +} diff --git a/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/event/actions/player/mobdamage/PlayerActionDamageMob.java b/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/event/actions/player/mobdamage/PlayerActionDamageMob.java index 494ef25a2..fe5fda5e8 100644 --- a/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/event/actions/player/mobdamage/PlayerActionDamageMob.java +++ b/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/event/actions/player/mobdamage/PlayerActionDamageMob.java @@ -11,8 +11,9 @@ import net.swofty.commons.skyblock.statistics.ItemStatistic; import net.swofty.commons.skyblock.statistics.ItemStatistics; import net.swofty.type.generic.event.EventNodes; -import net.swofty.type.generic.event.HypixelEvent; import net.swofty.type.generic.event.HypixelEventClass; +import net.swofty.type.generic.event.phase.EventPhase; +import net.swofty.type.generic.event.phase.PhasedEvent; import net.swofty.type.generic.utility.MathUtility; import net.swofty.type.skyblockgeneric.entity.mob.SkyBlockMob; import net.swofty.type.skyblockgeneric.enchantment.SkyBlockEnchantment; @@ -33,7 +34,7 @@ public class PlayerActionDamageMob implements HypixelEventClass { private static final Random random = new Random(); private static final Map COOLDOWN = new HashMap<>(); - @HypixelEvent(node = EventNodes.ALL, requireDataLoaded = false) + @PhasedEvent(node = EventNodes.ALL, requireDataLoaded = false, phase = EventPhase.GAMEPLAY) public void run(EntityAttackEvent event) { if (event.getTarget().getEntityType().equals(EntityType.PLAYER)) return; if (!event.getEntity().getEntityType().equals(EntityType.PLAYER)) return; @@ -95,4 +96,4 @@ public void run(EntityAttackEvent event) { } } } -} \ No newline at end of file +} diff --git a/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/event/actions/player/mobdamage/PlayerActionDamagedAttacked.java b/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/event/actions/player/mobdamage/PlayerActionDamagedAttacked.java index 39a5255cc..b712086f4 100644 --- a/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/event/actions/player/mobdamage/PlayerActionDamagedAttacked.java +++ b/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/event/actions/player/mobdamage/PlayerActionDamagedAttacked.java @@ -5,8 +5,9 @@ import net.minestom.server.event.entity.EntityAttackEvent; import net.swofty.commons.skyblock.statistics.ItemStatistics; import net.swofty.type.generic.event.EventNodes; -import net.swofty.type.generic.event.HypixelEvent; import net.swofty.type.generic.event.HypixelEventClass; +import net.swofty.type.generic.event.phase.EventPhase; +import net.swofty.type.generic.event.phase.PhasedEvent; import net.swofty.type.skyblockgeneric.entity.mob.SkyBlockMob; import net.swofty.type.skyblockgeneric.event.value.SkyBlockValueEvent; import net.swofty.type.skyblockgeneric.event.value.events.PlayerDamagedByMobValueUpdateEvent; @@ -18,7 +19,7 @@ public class PlayerActionDamagedAttacked implements HypixelEventClass { - @HypixelEvent(node = EventNodes.ENTITY, requireDataLoaded = false) + @PhasedEvent(node = EventNodes.ENTITY, requireDataLoaded = false, phase = EventPhase.GAMEPLAY) public void run(EntityAttackEvent event) { if (!event.getTarget().getEntityType().equals(EntityType.PLAYER)) return; diff --git a/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/event/actions/player/offhand/ActionOffhandHandClick.java b/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/event/actions/player/offhand/ActionOffhandHandClick.java index afd60d685..d1af0a98b 100644 --- a/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/event/actions/player/offhand/ActionOffhandHandClick.java +++ b/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/event/actions/player/offhand/ActionOffhandHandClick.java @@ -3,12 +3,13 @@ import net.minestom.server.entity.PlayerHand; import net.minestom.server.event.player.PlayerHandAnimationEvent; import net.swofty.type.generic.event.EventNodes; -import net.swofty.type.generic.event.HypixelEvent; import net.swofty.type.generic.event.HypixelEventClass; +import net.swofty.type.generic.event.phase.EventPhase; +import net.swofty.type.generic.event.phase.PhasedEvent; public class ActionOffhandHandClick implements HypixelEventClass { - @HypixelEvent(node = EventNodes.PLAYER, requireDataLoaded = false) + @PhasedEvent(node = EventNodes.PLAYER, requireDataLoaded = false, phase = EventPhase.GAMEPLAY) public void run(PlayerHandAnimationEvent event) { if (event.getHand().equals(PlayerHand.OFF)) { event.getPlayer().sendMessage("§cYou cannot use your offhand!"); diff --git a/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/event/actions/player/offhand/ActionOffhandItemClick.java b/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/event/actions/player/offhand/ActionOffhandItemClick.java index 5ffc38fbc..e90142851 100644 --- a/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/event/actions/player/offhand/ActionOffhandItemClick.java +++ b/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/event/actions/player/offhand/ActionOffhandItemClick.java @@ -2,11 +2,12 @@ import net.minestom.server.event.player.PlayerSwapItemEvent; import net.swofty.type.generic.event.EventNodes; -import net.swofty.type.generic.event.HypixelEvent; import net.swofty.type.generic.event.HypixelEventClass; +import net.swofty.type.generic.event.phase.EventPhase; +import net.swofty.type.generic.event.phase.PhasedEvent; public class ActionOffhandItemClick implements HypixelEventClass { - @HypixelEvent(node = EventNodes.PLAYER, requireDataLoaded = false) + @PhasedEvent(node = EventNodes.PLAYER, requireDataLoaded = false, phase = EventPhase.GAMEPLAY) public void run(PlayerSwapItemEvent event) { event.getPlayer().sendMessage("§cYou cannot use your offhand!"); event.setCancelled(true); diff --git a/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/event/actions/player/region/ActionRegionBlockBreak.java b/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/event/actions/player/region/ActionRegionBlockBreak.java index 346b13229..fa882ad2d 100644 --- a/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/event/actions/player/region/ActionRegionBlockBreak.java +++ b/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/event/actions/player/region/ActionRegionBlockBreak.java @@ -10,8 +10,9 @@ import net.swofty.commons.skyblock.item.ItemType; import net.swofty.type.generic.HypixelConst; import net.swofty.type.generic.event.EventNodes; -import net.swofty.type.generic.event.HypixelEvent; import net.swofty.type.generic.event.HypixelEventClass; +import net.swofty.type.generic.event.phase.EventPhase; +import net.swofty.type.generic.event.phase.PhasedEvent; import net.swofty.type.generic.event.HypixelEventHandler; import net.swofty.type.skyblockgeneric.entity.DroppedItemEntityImpl; import net.swofty.type.skyblockgeneric.event.custom.CustomBlockBreakEvent; @@ -29,7 +30,7 @@ public class ActionRegionBlockBreak implements HypixelEventClass { - @HypixelEvent(node = EventNodes.PLAYER, requireDataLoaded = false) + @PhasedEvent(node = EventNodes.PLAYER, requireDataLoaded = false, phase = EventPhase.GAMEPLAY) public void run(PlayerBlockBreakEvent event) { final SkyBlockPlayer player = (SkyBlockPlayer) event.getPlayer(); final ItemStack stack = event.getPlayer().getItemInMainHand(); diff --git a/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/event/actions/player/region/ActionRegionBlockPlace.java b/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/event/actions/player/region/ActionRegionBlockPlace.java index 7eba8c51a..b28c26386 100644 --- a/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/event/actions/player/region/ActionRegionBlockPlace.java +++ b/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/event/actions/player/region/ActionRegionBlockPlace.java @@ -5,8 +5,9 @@ import net.minestom.server.tag.Tag; import net.swofty.type.generic.HypixelConst; import net.swofty.type.generic.event.EventNodes; -import net.swofty.type.generic.event.HypixelEvent; import net.swofty.type.generic.event.HypixelEventClass; +import net.swofty.type.generic.event.phase.EventPhase; +import net.swofty.type.generic.event.phase.PhasedEvent; import net.swofty.type.skyblockgeneric.user.SkyBlockPlayer; import net.swofty.type.generic.utility.MathUtility; @@ -14,7 +15,7 @@ public class ActionRegionBlockPlace implements HypixelEventClass { private static final int ISLAND_SIZE = 161; private static final Tag PLAYER_PLACED_TAG = Tag.Boolean("player_placed"); - @HypixelEvent(node = EventNodes.PLAYER, requireDataLoaded = false) + @PhasedEvent(node = EventNodes.PLAYER, requireDataLoaded = false, phase = EventPhase.GAMEPLAY) public void run(PlayerBlockPlaceEvent event) { final SkyBlockPlayer player = (SkyBlockPlayer) event.getPlayer(); diff --git a/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/event/actions/race/RaceEvents.java b/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/event/actions/race/RaceEvents.java index 3b76e3c57..8418e1658 100644 --- a/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/event/actions/race/RaceEvents.java +++ b/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/event/actions/race/RaceEvents.java @@ -8,8 +8,9 @@ import net.minestom.server.event.player.PlayerSpawnEvent; import net.swofty.type.generic.HypixelConst; import net.swofty.type.generic.event.EventNodes; -import net.swofty.type.generic.event.HypixelEvent; import net.swofty.type.generic.event.HypixelEventClass; +import net.swofty.type.generic.event.phase.EventPhase; +import net.swofty.type.generic.event.phase.PhasedEvent; import net.swofty.type.skyblockgeneric.race.RaceInstance; import net.swofty.type.skyblockgeneric.race.RaceManager; import net.swofty.type.skyblockgeneric.user.SkyBlockPlayer; @@ -21,7 +22,7 @@ public class RaceEvents implements HypixelEventClass { private final HashMap lastClickedTimes = new HashMap<>(); - @HypixelEvent(node = EventNodes.PLAYER, requireDataLoaded = false) + @PhasedEvent(node = EventNodes.PLAYER, requireDataLoaded = false, phase = EventPhase.GAMEPLAY) public void onPlayerJoin(PlayerSpawnEvent event) { SkyBlockPlayer player = (SkyBlockPlayer) event.getPlayer(); if (!(HypixelConst.getTypeLoader() instanceof RaceInstance raceInstance)) { @@ -33,7 +34,7 @@ public void onPlayerJoin(PlayerSpawnEvent event) { race.updateForPlayer(HypixelConst.getInstanceContainer(), player); } - @HypixelEvent(node = EventNodes.PLAYER, requireDataLoaded = false) + @PhasedEvent(node = EventNodes.PLAYER, requireDataLoaded = false, phase = EventPhase.GAMEPLAY) public void onPlayerDisconnect(PlayerDisconnectEvent event) { SkyBlockPlayer player = (SkyBlockPlayer) event.getPlayer(); if (!(HypixelConst.getTypeLoader() instanceof RaceInstance raceInstance)) { @@ -45,7 +46,7 @@ public void onPlayerDisconnect(PlayerDisconnectEvent event) { race.cancelRace(player); } - @HypixelEvent(node = EventNodes.PLAYER, requireDataLoaded = true) + @PhasedEvent(node = EventNodes.PLAYER, requireDataLoaded = true, phase = EventPhase.GAMEPLAY) public void onPlayerMove(PlayerMoveEvent event) { SkyBlockPlayer player = (SkyBlockPlayer) event.getPlayer(); if (!(HypixelConst.getTypeLoader() instanceof RaceInstance raceInstance)) { diff --git a/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/event/custom/IslandFetchedFromDatabaseEvent.java b/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/event/custom/IslandFetchedFromDatabaseEvent.java deleted file mode 100644 index b10feab42..000000000 --- a/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/event/custom/IslandFetchedFromDatabaseEvent.java +++ /dev/null @@ -1,24 +0,0 @@ -package net.swofty.type.skyblockgeneric.event.custom; - -import lombok.Getter; -import net.minestom.server.event.Event; -import net.swofty.type.skyblockgeneric.user.SkyBlockIsland; -import net.swofty.type.skyblockgeneric.user.SkyBlockPlayer; - -import java.util.List; -import java.util.UUID; - -@Getter -public class IslandFetchedFromDatabaseEvent implements Event { - private final SkyBlockIsland island; - private final boolean isCoop; - private final List membersOnline; - private final List allMembers; - - public IslandFetchedFromDatabaseEvent(SkyBlockIsland island, boolean isCoop, List membersOnline, List allMembers) { - this.island = island; - this.isCoop = isCoop; - this.membersOnline = membersOnline; - this.allMembers = allMembers; - } -} diff --git a/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/event/custom/IslandFirstCreatedEvent.java b/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/event/custom/IslandFirstCreatedEvent.java deleted file mode 100644 index 86c297215..000000000 --- a/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/event/custom/IslandFirstCreatedEvent.java +++ /dev/null @@ -1,21 +0,0 @@ -package net.swofty.type.skyblockgeneric.event.custom; - -import lombok.Getter; -import net.minestom.server.event.Event; -import net.swofty.type.skyblockgeneric.user.SkyBlockIsland; - -import java.util.List; -import java.util.UUID; - -@Getter -public class IslandFirstCreatedEvent implements Event { - private final SkyBlockIsland island; - private final boolean isCoop; - private final List allMembers; - - public IslandFirstCreatedEvent(SkyBlockIsland island, boolean isCoop, List allMembers) { - this.island = island; - this.isCoop = isCoop; - this.allMembers = allMembers; - } -} diff --git a/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/event/custom/IslandPlayerLoadedEvent.java b/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/event/custom/IslandPlayerLoadedEvent.java deleted file mode 100644 index 4d182334d..000000000 --- a/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/event/custom/IslandPlayerLoadedEvent.java +++ /dev/null @@ -1,26 +0,0 @@ -package net.swofty.type.skyblockgeneric.event.custom; - -import lombok.Getter; -import net.minestom.server.event.Event; -import net.swofty.type.skyblockgeneric.user.SkyBlockIsland; -import net.swofty.type.skyblockgeneric.user.SkyBlockPlayer; - -import java.util.List; -import java.util.UUID; - -@Getter -public class IslandPlayerLoadedEvent implements Event { - private final SkyBlockIsland island; - private final SkyBlockPlayer player; - private final boolean isCoop; - private final List membersOnline; - private final List allMembers; - - public IslandPlayerLoadedEvent(SkyBlockIsland island, SkyBlockPlayer player, boolean isCoop, List membersOnline, List allMembers) { - this.island = island; - this.player = player; - this.isCoop = isCoop; - this.membersOnline = membersOnline; - this.allMembers = allMembers; - } -} diff --git a/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/event/custom/IslandSavedIntoDatabaseEvent.java b/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/event/custom/IslandSavedIntoDatabaseEvent.java deleted file mode 100644 index c05c46ae6..000000000 --- a/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/event/custom/IslandSavedIntoDatabaseEvent.java +++ /dev/null @@ -1,21 +0,0 @@ -package net.swofty.type.skyblockgeneric.event.custom; - -import lombok.Getter; -import net.minestom.server.event.Event; -import net.swofty.type.skyblockgeneric.user.SkyBlockIsland; - -import java.util.List; -import java.util.UUID; - -@Getter -public class IslandSavedIntoDatabaseEvent implements Event { - private final SkyBlockIsland island; - private final boolean isCoop; - private final List allMembers; - - public IslandSavedIntoDatabaseEvent(SkyBlockIsland island, boolean isCoop, List allMembers) { - this.island = island; - this.isCoop = isCoop; - this.allMembers = allMembers; - } -} diff --git a/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/item/events/RuneItemEvent.java b/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/item/events/RuneItemEvent.java index 3700ba03e..a35c63598 100644 --- a/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/item/events/RuneItemEvent.java +++ b/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/item/events/RuneItemEvent.java @@ -4,14 +4,15 @@ import net.minestom.server.particle.Particle; import net.swofty.commons.skyblock.item.ItemType; import net.swofty.type.generic.event.EventNodes; -import net.swofty.type.generic.event.HypixelEvent; import net.swofty.type.generic.event.HypixelEventClass; +import net.swofty.type.generic.event.phase.EventPhase; +import net.swofty.type.generic.event.phase.PhasedEvent; import net.swofty.type.skyblockgeneric.event.custom.PlayerKilledSkyBlockMobEvent; import net.swofty.type.skyblockgeneric.item.SkyBlockItem; import net.swofty.type.skyblockgeneric.user.SkyBlockPlayer; public class RuneItemEvent implements HypixelEventClass { - @HypixelEvent(node = EventNodes.CUSTOM, requireDataLoaded = true, isAsync = true) + @PhasedEvent(node = EventNodes.CUSTOM, requireDataLoaded = true, isAsync = true, phase = EventPhase.GAMEPLAY) public void run(PlayerKilledSkyBlockMobEvent event) { SkyBlockPlayer player = event.getPlayer(); diff --git a/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/item/handlers/interactable/InteractableRegistry.java b/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/item/handlers/interactable/InteractableRegistry.java index 55f273779..1379325ec 100644 --- a/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/item/handlers/interactable/InteractableRegistry.java +++ b/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/item/handlers/interactable/InteractableRegistry.java @@ -5,7 +5,7 @@ import net.swofty.type.generic.HypixelConst; import net.swofty.type.generic.entity.hologram.ServerHolograms; import net.swofty.type.skyblockgeneric.gui.inventories.sbmenu.GUISkyBlockMenu; -import net.swofty.type.skyblockgeneric.user.SkyBlockIsland; +import net.swofty.type.skyblockgeneric.user.island.SkyBlockIsland; import net.swofty.type.skyblockgeneric.utility.JerryInformation; import java.util.HashMap; diff --git a/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/minion/IslandMinionData.java b/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/minion/IslandMinionData.java index 178bd400d..8ed0b46bf 100644 --- a/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/minion/IslandMinionData.java +++ b/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/minion/IslandMinionData.java @@ -15,7 +15,7 @@ import net.swofty.type.skyblockgeneric.item.components.MinionUpgradeComponent; import net.swofty.type.skyblockgeneric.minion.extension.MinionExtensionData; import net.swofty.type.skyblockgeneric.minion.extension.extensions.MinionFuelExtension; -import net.swofty.type.skyblockgeneric.user.SkyBlockIsland; +import net.swofty.type.skyblockgeneric.user.island.SkyBlockIsland; import org.tinylog.Logger; import java.util.*; diff --git a/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/mission/missions/MissionBreakLog.java b/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/mission/missions/MissionBreakLog.java index 32fa31055..dc94715df 100644 --- a/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/mission/missions/MissionBreakLog.java +++ b/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/mission/missions/MissionBreakLog.java @@ -2,7 +2,6 @@ import net.minestom.server.event.player.PlayerSpawnEvent; import net.swofty.type.generic.event.EventNodes; -import net.swofty.type.generic.event.HypixelEvent; import net.swofty.type.skyblockgeneric.event.custom.CustomBlockBreakEvent; import net.swofty.type.skyblockgeneric.mission.MissionData; import net.swofty.type.skyblockgeneric.mission.SkyBlockMission; @@ -13,9 +12,11 @@ import java.util.HashMap; import java.util.Map; import java.util.Set; +import net.swofty.type.generic.event.phase.EventPhase; +import net.swofty.type.generic.event.phase.PhasedEvent; public class MissionBreakLog extends SkyBlockMission { - @HypixelEvent(node = EventNodes.CUSTOM, requireDataLoaded = false) + @PhasedEvent(node = EventNodes.CUSTOM, requireDataLoaded = false, phase = EventPhase.GAMEPLAY) public void endMission(CustomBlockBreakEvent event) { if (event.getPlayerPlaced()) return; @@ -27,7 +28,7 @@ public void endMission(CustomBlockBreakEvent event) { data.endMission(MissionBreakLog.class); } - @HypixelEvent(node = EventNodes.PLAYER, requireDataLoaded = true, isAsync = true) + @PhasedEvent(node = EventNodes.PLAYER, requireDataLoaded = true, isAsync = true, phase = EventPhase.GAMEPLAY) public void startMission(PlayerSpawnEvent event) { if (!event.isFirstSpawn()) return; MissionData data = ((SkyBlockPlayer) event.getPlayer()).getMissionData(); diff --git a/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/mission/missions/MissionCraftWoodenPickaxe.java b/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/mission/missions/MissionCraftWoodenPickaxe.java index 58e55d11b..e19db5311 100644 --- a/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/mission/missions/MissionCraftWoodenPickaxe.java +++ b/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/mission/missions/MissionCraftWoodenPickaxe.java @@ -2,7 +2,6 @@ import net.minestom.server.item.Material; import net.swofty.type.generic.event.EventNodes; -import net.swofty.type.generic.event.HypixelEvent; import net.swofty.type.skyblockgeneric.event.custom.ItemCraftEvent; import net.swofty.type.skyblockgeneric.mission.MissionData; import net.swofty.type.skyblockgeneric.mission.SkyBlockMission; @@ -13,9 +12,11 @@ import java.util.HashMap; import java.util.Map; import java.util.Set; +import net.swofty.type.generic.event.phase.EventPhase; +import net.swofty.type.generic.event.phase.PhasedEvent; public class MissionCraftWoodenPickaxe extends SkyBlockMission { - @HypixelEvent(node = EventNodes.CUSTOM, requireDataLoaded = false) + @PhasedEvent(node = EventNodes.CUSTOM, requireDataLoaded = false, phase = EventPhase.GAMEPLAY) public void onCraftEvent(ItemCraftEvent event) { MissionData data = event.getPlayer().getMissionData(); @@ -52,4 +53,4 @@ public void onEnd(SkyBlockPlayer player, Map customData, Mission public Set getValidRegions() { return Collections.singleton(RegionType.PRIVATE_ISLAND); } -} \ No newline at end of file +} diff --git a/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/mission/missions/MissionCraftWorkbench.java b/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/mission/missions/MissionCraftWorkbench.java index b8310562f..a514aec0e 100644 --- a/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/mission/missions/MissionCraftWorkbench.java +++ b/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/mission/missions/MissionCraftWorkbench.java @@ -2,7 +2,6 @@ import net.minestom.server.item.Material; import net.swofty.type.generic.event.EventNodes; -import net.swofty.type.generic.event.HypixelEvent; import net.swofty.type.skyblockgeneric.event.custom.ItemCraftEvent; import net.swofty.type.skyblockgeneric.mission.MissionData; import net.swofty.type.skyblockgeneric.mission.SkyBlockMission; @@ -13,9 +12,11 @@ import java.util.HashMap; import java.util.Map; import java.util.Set; +import net.swofty.type.generic.event.phase.EventPhase; +import net.swofty.type.generic.event.phase.PhasedEvent; public class MissionCraftWorkbench extends SkyBlockMission { - @HypixelEvent(node = EventNodes.CUSTOM, requireDataLoaded = false) + @PhasedEvent(node = EventNodes.CUSTOM, requireDataLoaded = false, phase = EventPhase.GAMEPLAY) public void onCraftEvent(ItemCraftEvent event) { MissionData data = event.getPlayer().getMissionData(); diff --git a/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/mission/missions/MissionKillZombies.java b/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/mission/missions/MissionKillZombies.java index da481f265..86560b0e8 100644 --- a/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/mission/missions/MissionKillZombies.java +++ b/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/mission/missions/MissionKillZombies.java @@ -2,7 +2,6 @@ import net.minestom.server.entity.EntityType; import net.swofty.type.generic.event.EventNodes; -import net.swofty.type.generic.event.HypixelEvent; import net.swofty.type.skyblockgeneric.event.custom.PlayerKilledSkyBlockMobEvent; import net.swofty.type.skyblockgeneric.levels.SkyBlockLevelCause; import net.swofty.type.skyblockgeneric.mission.MissionData; @@ -12,9 +11,11 @@ import net.swofty.type.skyblockgeneric.user.SkyBlockPlayer; import java.util.*; +import net.swofty.type.generic.event.phase.EventPhase; +import net.swofty.type.generic.event.phase.PhasedEvent; public class MissionKillZombies extends SkyBlockProgressMission { - @HypixelEvent(node = EventNodes.CUSTOM, requireDataLoaded = false) + @PhasedEvent(node = EventNodes.CUSTOM, requireDataLoaded = false, phase = EventPhase.GAMEPLAY) public void onKilledZombie(PlayerKilledSkyBlockMobEvent event) { if (event.getKilledMob().getEntityType() != EntityType.ZOMBIE) return; @@ -64,4 +65,4 @@ public Double getAttachedSkyBlockXP() { public int getMaxProgress() { return 10; } -} \ No newline at end of file +} diff --git a/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/mission/missions/MissionTalkJerry.java b/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/mission/missions/MissionTalkJerry.java index 5228d8d5b..a8a7e55e3 100644 --- a/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/mission/missions/MissionTalkJerry.java +++ b/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/mission/missions/MissionTalkJerry.java @@ -5,7 +5,6 @@ import net.minestom.server.timer.TaskSchedule; import net.swofty.type.generic.HypixelConst; import net.swofty.type.generic.event.EventNodes; -import net.swofty.type.generic.event.HypixelEvent; import net.swofty.type.skyblockgeneric.event.custom.JerryClickedEvent; import net.swofty.type.skyblockgeneric.mission.MissionData; import net.swofty.type.skyblockgeneric.mission.SkyBlockMission; @@ -16,10 +15,12 @@ import java.util.HashMap; import java.util.Map; import java.util.Set; +import net.swofty.type.generic.event.phase.EventPhase; +import net.swofty.type.generic.event.phase.PhasedEvent; public class MissionTalkJerry extends SkyBlockMission { - @HypixelEvent(node = EventNodes.CUSTOM, requireDataLoaded = false) + @PhasedEvent(node = EventNodes.CUSTOM, requireDataLoaded = false, phase = EventPhase.GAMEPLAY) public void onJerryClicked(JerryClickedEvent event) { MissionData data = event.getPlayer().getMissionData(); SkyBlockPlayer player = event.getPlayer(); diff --git a/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/mission/missions/MissionTalkToAuctionMaster.java b/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/mission/missions/MissionTalkToAuctionMaster.java index 6d44f3c7f..a192f15dd 100644 --- a/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/mission/missions/MissionTalkToAuctionMaster.java +++ b/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/mission/missions/MissionTalkToAuctionMaster.java @@ -1,7 +1,6 @@ package net.swofty.type.skyblockgeneric.mission.missions; import net.swofty.type.generic.event.EventNodes; -import net.swofty.type.generic.event.HypixelEvent; import net.swofty.type.skyblockgeneric.event.custom.PlayerRegionChangeEvent; import net.swofty.type.skyblockgeneric.mission.MissionData; import net.swofty.type.skyblockgeneric.mission.SkyBlockMission; @@ -12,9 +11,11 @@ import java.util.HashMap; import java.util.Map; import java.util.Set; +import net.swofty.type.generic.event.phase.EventPhase; +import net.swofty.type.generic.event.phase.PhasedEvent; public class MissionTalkToAuctionMaster extends SkyBlockMission { - @HypixelEvent(node = EventNodes.CUSTOM, requireDataLoaded = false) + @PhasedEvent(node = EventNodes.CUSTOM, requireDataLoaded = false, phase = EventPhase.GAMEPLAY) public void onRegionChange(PlayerRegionChangeEvent event) { MissionData data = event.getPlayer().getMissionData(); diff --git a/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/mission/missions/MissionTalkToBanker.java b/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/mission/missions/MissionTalkToBanker.java index ce71c3255..6fbacd0e1 100644 --- a/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/mission/missions/MissionTalkToBanker.java +++ b/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/mission/missions/MissionTalkToBanker.java @@ -1,7 +1,6 @@ package net.swofty.type.skyblockgeneric.mission.missions; import net.swofty.type.generic.event.EventNodes; -import net.swofty.type.generic.event.HypixelEvent; import net.swofty.type.skyblockgeneric.event.custom.PlayerRegionChangeEvent; import net.swofty.type.skyblockgeneric.mission.MissionData; import net.swofty.type.skyblockgeneric.mission.SkyBlockMission; @@ -12,9 +11,11 @@ import java.util.HashMap; import java.util.Map; import java.util.Set; +import net.swofty.type.generic.event.phase.EventPhase; +import net.swofty.type.generic.event.phase.PhasedEvent; public class MissionTalkToBanker extends SkyBlockMission { - @HypixelEvent(node = EventNodes.CUSTOM, requireDataLoaded = false) + @PhasedEvent(node = EventNodes.CUSTOM, requireDataLoaded = false, phase = EventPhase.GAMEPLAY) public void onRegionChange(PlayerRegionChangeEvent event) { MissionData data = event.getPlayer().getMissionData(); diff --git a/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/mission/missions/MissionTalkToLibrarian.java b/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/mission/missions/MissionTalkToLibrarian.java index ccf13dd20..80df6282e 100644 --- a/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/mission/missions/MissionTalkToLibrarian.java +++ b/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/mission/missions/MissionTalkToLibrarian.java @@ -1,7 +1,6 @@ package net.swofty.type.skyblockgeneric.mission.missions; import net.swofty.type.generic.event.EventNodes; -import net.swofty.type.generic.event.HypixelEvent; import net.swofty.type.skyblockgeneric.event.custom.PlayerRegionChangeEvent; import net.swofty.type.skyblockgeneric.mission.MissionData; import net.swofty.type.skyblockgeneric.mission.SkyBlockMission; @@ -12,9 +11,11 @@ import java.util.HashMap; import java.util.Map; import java.util.Set; +import net.swofty.type.generic.event.phase.EventPhase; +import net.swofty.type.generic.event.phase.PhasedEvent; public class MissionTalkToLibrarian extends SkyBlockMission { - @HypixelEvent(node = EventNodes.CUSTOM, requireDataLoaded = false) + @PhasedEvent(node = EventNodes.CUSTOM, requireDataLoaded = false, phase = EventPhase.GAMEPLAY) public void onRegionChange(PlayerRegionChangeEvent event) { MissionData data = event.getPlayer().getMissionData(); diff --git a/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/mission/missions/MissionUseTeleporter.java b/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/mission/missions/MissionUseTeleporter.java index 3fee87900..9ba574a7e 100644 --- a/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/mission/missions/MissionUseTeleporter.java +++ b/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/mission/missions/MissionUseTeleporter.java @@ -2,7 +2,6 @@ import net.swofty.type.generic.data.datapoints.DatapointDouble; import net.swofty.type.generic.event.EventNodes; -import net.swofty.type.generic.event.HypixelEvent; import net.swofty.type.skyblockgeneric.event.custom.PlayerRegionChangeEvent; import net.swofty.type.skyblockgeneric.mission.MissionData; import net.swofty.type.skyblockgeneric.mission.SkyBlockMission; @@ -10,10 +9,12 @@ import net.swofty.type.skyblockgeneric.user.SkyBlockPlayer; import java.util.*; +import net.swofty.type.generic.event.phase.EventPhase; +import net.swofty.type.generic.event.phase.PhasedEvent; public class MissionUseTeleporter extends SkyBlockMission { - @HypixelEvent(node = EventNodes.CUSTOM, requireDataLoaded = false) + @PhasedEvent(node = EventNodes.CUSTOM, requireDataLoaded = false, phase = EventPhase.GAMEPLAY) public void onRegionChange(PlayerRegionChangeEvent event) { if (event.getTo() == null || !event.getTo().equals(RegionType.VILLAGE)) { return; @@ -55,4 +56,4 @@ public void onEnd(SkyBlockPlayer player, Map customData, Mission public Set getValidRegions() { return Collections.singleton(RegionType.PRIVATE_ISLAND); } -} \ No newline at end of file +} diff --git a/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/mission/missions/barn/MissionCraftWheatMinion.java b/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/mission/missions/barn/MissionCraftWheatMinion.java index c82f10e8d..12de1f185 100644 --- a/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/mission/missions/barn/MissionCraftWheatMinion.java +++ b/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/mission/missions/barn/MissionCraftWheatMinion.java @@ -2,7 +2,6 @@ import net.swofty.commons.skyblock.item.ItemType; import net.swofty.type.generic.event.EventNodes; -import net.swofty.type.generic.event.HypixelEvent; import net.swofty.type.skyblockgeneric.event.custom.ItemCraftEvent; import net.swofty.type.skyblockgeneric.mission.MissionData; import net.swofty.type.skyblockgeneric.mission.SkyBlockMission; @@ -11,9 +10,11 @@ import java.util.Map; import java.util.Set; +import net.swofty.type.generic.event.phase.EventPhase; +import net.swofty.type.generic.event.phase.PhasedEvent; public class MissionCraftWheatMinion extends SkyBlockMission { - @HypixelEvent(node = EventNodes.CUSTOM, requireDataLoaded = false) + @PhasedEvent(node = EventNodes.CUSTOM, requireDataLoaded = false, phase = EventPhase.GAMEPLAY) public void onCraftEvent(ItemCraftEvent event) { MissionData data = event.getPlayer().getMissionData(); diff --git a/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/mission/missions/barn/MissionTalkToFarmHand.java b/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/mission/missions/barn/MissionTalkToFarmHand.java index 9a78b086b..1da7c6a90 100644 --- a/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/mission/missions/barn/MissionTalkToFarmHand.java +++ b/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/mission/missions/barn/MissionTalkToFarmHand.java @@ -1,7 +1,6 @@ package net.swofty.type.skyblockgeneric.mission.missions.barn; import net.swofty.type.generic.event.EventNodes; -import net.swofty.type.generic.event.HypixelEvent; import net.swofty.type.skyblockgeneric.event.custom.PlayerRegionChangeEvent; import net.swofty.type.skyblockgeneric.levels.SkyBlockLevelCause; import net.swofty.type.skyblockgeneric.mission.MissionData; @@ -11,9 +10,11 @@ import net.swofty.type.skyblockgeneric.user.SkyBlockPlayer; import java.util.*; +import net.swofty.type.generic.event.phase.EventPhase; +import net.swofty.type.generic.event.phase.PhasedEvent; public class MissionTalkToFarmHand extends SkyBlockMission { - @HypixelEvent(node = EventNodes.CUSTOM, requireDataLoaded = false) + @PhasedEvent(node = EventNodes.CUSTOM, requireDataLoaded = false, phase = EventPhase.GAMEPLAY) public void onRegionChange(PlayerRegionChangeEvent event) { MissionData data = event.getPlayer().getMissionData(); diff --git a/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/mission/missions/blacksmith/MissionMineCoal.java b/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/mission/missions/blacksmith/MissionMineCoal.java index eee49bc0a..0cd0b2bf8 100644 --- a/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/mission/missions/blacksmith/MissionMineCoal.java +++ b/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/mission/missions/blacksmith/MissionMineCoal.java @@ -2,7 +2,6 @@ import net.minestom.server.item.Material; import net.swofty.type.generic.event.EventNodes; -import net.swofty.type.generic.event.HypixelEvent; import net.swofty.type.skyblockgeneric.event.custom.CustomBlockBreakEvent; import net.swofty.type.skyblockgeneric.mission.MissionData; import net.swofty.type.skyblockgeneric.mission.SkyBlockProgressMission; @@ -11,9 +10,11 @@ import net.swofty.type.skyblockgeneric.user.SkyBlockPlayer; import java.util.*; +import net.swofty.type.generic.event.phase.EventPhase; +import net.swofty.type.generic.event.phase.PhasedEvent; public class MissionMineCoal extends SkyBlockProgressMission { - @HypixelEvent(node = EventNodes.CUSTOM, requireDataLoaded = false) + @PhasedEvent(node = EventNodes.CUSTOM, requireDataLoaded = false, phase = EventPhase.GAMEPLAY) public void onBlockBreak(CustomBlockBreakEvent event) { MissionData data = event.getPlayer().getMissionData(); diff --git a/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/mission/missions/blacksmith/MissionTalkToBlacksmith.java b/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/mission/missions/blacksmith/MissionTalkToBlacksmith.java index 786d965ca..50ad2d2be 100644 --- a/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/mission/missions/blacksmith/MissionTalkToBlacksmith.java +++ b/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/mission/missions/blacksmith/MissionTalkToBlacksmith.java @@ -2,7 +2,6 @@ import net.minestom.server.coordinate.Pos; import net.swofty.type.generic.event.EventNodes; -import net.swofty.type.generic.event.HypixelEvent; import net.swofty.type.skyblockgeneric.event.custom.PlayerRegionChangeEvent; import net.swofty.type.skyblockgeneric.mission.LocationAssociatedMission; import net.swofty.type.skyblockgeneric.mission.MissionData; @@ -13,10 +12,12 @@ import java.util.HashMap; import java.util.Map; import java.util.Set; +import net.swofty.type.generic.event.phase.EventPhase; +import net.swofty.type.generic.event.phase.PhasedEvent; public class MissionTalkToBlacksmith extends SkyBlockMission implements LocationAssociatedMission { - @HypixelEvent(node = EventNodes.CUSTOM, requireDataLoaded = true) + @PhasedEvent(node = EventNodes.CUSTOM, requireDataLoaded = true, phase = EventPhase.GAMEPLAY) public void run(PlayerRegionChangeEvent event) { MissionData data = event.getPlayer().getMissionData(); diff --git a/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/mission/missions/farmer/MissionCollectWheat.java b/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/mission/missions/farmer/MissionCollectWheat.java index 420cdbce7..4686be137 100644 --- a/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/mission/missions/farmer/MissionCollectWheat.java +++ b/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/mission/missions/farmer/MissionCollectWheat.java @@ -2,7 +2,6 @@ import net.minestom.server.item.Material; import net.swofty.type.generic.event.EventNodes; -import net.swofty.type.generic.event.HypixelEvent; import net.swofty.type.skyblockgeneric.event.custom.CustomBlockBreakEvent; import net.swofty.type.skyblockgeneric.mission.MissionData; import net.swofty.type.skyblockgeneric.mission.SkyBlockProgressMission; @@ -11,9 +10,11 @@ import net.swofty.type.skyblockgeneric.user.SkyBlockPlayer; import java.util.*; +import net.swofty.type.generic.event.phase.EventPhase; +import net.swofty.type.generic.event.phase.PhasedEvent; public class MissionCollectWheat extends SkyBlockProgressMission { - @HypixelEvent(node = EventNodes.CUSTOM, requireDataLoaded = false) + @PhasedEvent(node = EventNodes.CUSTOM, requireDataLoaded = false, phase = EventPhase.GAMEPLAY) public void onBlockBreak(CustomBlockBreakEvent event) { MissionData data = event.getPlayer().getMissionData(); diff --git a/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/mission/missions/farmer/MissionTalkToFarmer.java b/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/mission/missions/farmer/MissionTalkToFarmer.java index a44c84a9f..cb3d7b33b 100644 --- a/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/mission/missions/farmer/MissionTalkToFarmer.java +++ b/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/mission/missions/farmer/MissionTalkToFarmer.java @@ -1,7 +1,6 @@ package net.swofty.type.skyblockgeneric.mission.missions.farmer; import net.swofty.type.generic.event.EventNodes; -import net.swofty.type.generic.event.HypixelEvent; import net.swofty.type.skyblockgeneric.event.custom.PlayerRegionChangeEvent; import net.swofty.type.skyblockgeneric.mission.MissionData; import net.swofty.type.skyblockgeneric.mission.SkyBlockMission; @@ -11,9 +10,11 @@ import java.util.HashMap; import java.util.Map; import java.util.Set; +import net.swofty.type.generic.event.phase.EventPhase; +import net.swofty.type.generic.event.phase.PhasedEvent; public class MissionTalkToFarmer extends SkyBlockMission { - @HypixelEvent(node = EventNodes.CUSTOM, requireDataLoaded = false) + @PhasedEvent(node = EventNodes.CUSTOM, requireDataLoaded = false, phase = EventPhase.GAMEPLAY) public void onRegionChange(PlayerRegionChangeEvent event) { MissionData data = event.getPlayer().getMissionData(); diff --git a/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/mission/missions/lumber/MissionBreakOaklog.java b/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/mission/missions/lumber/MissionBreakOaklog.java index 25c85720d..072b7db40 100644 --- a/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/mission/missions/lumber/MissionBreakOaklog.java +++ b/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/mission/missions/lumber/MissionBreakOaklog.java @@ -3,7 +3,6 @@ import net.minestom.server.event.player.PlayerTickEvent; import net.minestom.server.item.Material; import net.swofty.type.generic.event.EventNodes; -import net.swofty.type.generic.event.HypixelEvent; import net.swofty.type.skyblockgeneric.item.SkyBlockItem; import net.swofty.type.skyblockgeneric.levels.SkyBlockLevelCause; import net.swofty.type.skyblockgeneric.mission.MissionData; @@ -17,11 +16,13 @@ import java.util.Map; import java.util.Set; import java.util.UUID; +import net.swofty.type.generic.event.phase.EventPhase; +import net.swofty.type.generic.event.phase.PhasedEvent; public class MissionBreakOaklog extends SkyBlockProgressMission { private final Map testTimes = new HashMap<>(); - @HypixelEvent(node = EventNodes.CUSTOM, requireDataLoaded = false) + @PhasedEvent(node = EventNodes.CUSTOM, requireDataLoaded = false, phase = EventPhase.GAMEPLAY) public void onTick(PlayerTickEvent event) { SkyBlockPlayer player = (SkyBlockPlayer) event.getPlayer(); if (testTimes.containsKey(player.getUuid())) { diff --git a/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/mission/missions/lumber/MissionTalkToLumberjack.java b/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/mission/missions/lumber/MissionTalkToLumberjack.java index fb23c9254..b4b91c287 100644 --- a/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/mission/missions/lumber/MissionTalkToLumberjack.java +++ b/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/mission/missions/lumber/MissionTalkToLumberjack.java @@ -1,7 +1,6 @@ package net.swofty.type.skyblockgeneric.mission.missions.lumber; import net.swofty.type.generic.event.EventNodes; -import net.swofty.type.generic.event.HypixelEvent; import net.swofty.type.skyblockgeneric.event.custom.PlayerRegionChangeEvent; import net.swofty.type.skyblockgeneric.mission.MissionData; import net.swofty.type.skyblockgeneric.mission.SkyBlockMission; @@ -11,9 +10,11 @@ import java.util.HashMap; import java.util.Map; import java.util.Set; +import net.swofty.type.generic.event.phase.EventPhase; +import net.swofty.type.generic.event.phase.PhasedEvent; public class MissionTalkToLumberjack extends SkyBlockMission { - @HypixelEvent(node = EventNodes.CUSTOM, requireDataLoaded = false) + @PhasedEvent(node = EventNodes.CUSTOM, requireDataLoaded = false, phase = EventPhase.GAMEPLAY) public void onRegionChange(PlayerRegionChangeEvent event) { MissionData data = event.getPlayer().getMissionData(); diff --git a/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/mission/missions/sheperd/MissionShearSheep.java b/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/mission/missions/sheperd/MissionShearSheep.java index ee7446904..3854c5bc3 100644 --- a/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/mission/missions/sheperd/MissionShearSheep.java +++ b/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/mission/missions/sheperd/MissionShearSheep.java @@ -2,7 +2,6 @@ import net.minestom.server.entity.EntityType; import net.swofty.type.generic.event.EventNodes; -import net.swofty.type.generic.event.HypixelEvent; import net.swofty.type.skyblockgeneric.event.custom.PlayerKilledSkyBlockMobEvent; import net.swofty.type.skyblockgeneric.levels.SkyBlockLevelCause; import net.swofty.type.skyblockgeneric.mission.MissionData; @@ -12,10 +11,12 @@ import net.swofty.type.skyblockgeneric.user.SkyBlockPlayer; import java.util.*; +import net.swofty.type.generic.event.phase.EventPhase; +import net.swofty.type.generic.event.phase.PhasedEvent; public class MissionShearSheep extends SkyBlockProgressMission { - @HypixelEvent(node = EventNodes.CUSTOM, requireDataLoaded = false) + @PhasedEvent(node = EventNodes.CUSTOM, requireDataLoaded = false, phase = EventPhase.GAMEPLAY) public void onKilledSheep(PlayerKilledSkyBlockMobEvent event) { if (event.getKilledMob().getEntityType() != EntityType.SHEEP) return; diff --git a/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/mission/missions/sheperd/MissionTalkToShepherd.java b/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/mission/missions/sheperd/MissionTalkToShepherd.java index bd2f3623f..efafc60c2 100644 --- a/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/mission/missions/sheperd/MissionTalkToShepherd.java +++ b/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/mission/missions/sheperd/MissionTalkToShepherd.java @@ -1,7 +1,6 @@ package net.swofty.type.skyblockgeneric.mission.missions.sheperd; import net.swofty.type.generic.event.EventNodes; -import net.swofty.type.generic.event.HypixelEvent; import net.swofty.type.generic.event.custom.NPCInteractEvent; import net.swofty.type.skyblockgeneric.mission.MissionData; import net.swofty.type.skyblockgeneric.mission.SkyBlockMission; @@ -11,9 +10,11 @@ import java.util.HashMap; import java.util.Map; import java.util.Set; +import net.swofty.type.generic.event.phase.EventPhase; +import net.swofty.type.generic.event.phase.PhasedEvent; public class MissionTalkToShepherd extends SkyBlockMission { - @HypixelEvent(node = EventNodes.CUSTOM, requireDataLoaded = false) + @PhasedEvent(node = EventNodes.CUSTOM, requireDataLoaded = false, phase = EventPhase.GAMEPLAY) public void onVillagerSpokenTo(NPCInteractEvent event) { MissionData data = ((SkyBlockPlayer) event.getPlayer()).getMissionData(); diff --git a/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/mission/missions/thepark/birchpark/MissionCollectBirchLogs.java b/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/mission/missions/thepark/birchpark/MissionCollectBirchLogs.java index 79fe162a6..c10d01ce3 100644 --- a/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/mission/missions/thepark/birchpark/MissionCollectBirchLogs.java +++ b/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/mission/missions/thepark/birchpark/MissionCollectBirchLogs.java @@ -3,7 +3,6 @@ import net.minestom.server.event.player.PlayerTickEvent; import net.minestom.server.item.Material; import net.swofty.type.generic.event.EventNodes; -import net.swofty.type.generic.event.HypixelEvent; import net.swofty.type.skyblockgeneric.item.SkyBlockItem; import net.swofty.type.skyblockgeneric.mission.MissionData; import net.swofty.type.skyblockgeneric.mission.SkyBlockProgressMission; @@ -14,12 +13,14 @@ import java.util.Map; import java.util.Set; import java.util.UUID; +import net.swofty.type.generic.event.phase.EventPhase; +import net.swofty.type.generic.event.phase.PhasedEvent; public class MissionCollectBirchLogs extends SkyBlockProgressMission { private final Map testTimes = new HashMap<>(); - @HypixelEvent(node = EventNodes.CUSTOM, requireDataLoaded = false) + @PhasedEvent(node = EventNodes.CUSTOM, requireDataLoaded = false, phase = EventPhase.GAMEPLAY) public void onTick(PlayerTickEvent event) { SkyBlockPlayer player = (SkyBlockPlayer) event.getPlayer(); if (testTimes.containsKey(player.getUuid())) { diff --git a/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/mission/missions/thepark/darkthicket/MissionCollectDarkOakLogs.java b/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/mission/missions/thepark/darkthicket/MissionCollectDarkOakLogs.java index 029d757d2..96d5732c8 100644 --- a/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/mission/missions/thepark/darkthicket/MissionCollectDarkOakLogs.java +++ b/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/mission/missions/thepark/darkthicket/MissionCollectDarkOakLogs.java @@ -3,7 +3,6 @@ import net.minestom.server.event.player.PlayerTickEvent; import net.minestom.server.item.Material; import net.swofty.type.generic.event.EventNodes; -import net.swofty.type.generic.event.HypixelEvent; import net.swofty.type.skyblockgeneric.item.SkyBlockItem; import net.swofty.type.skyblockgeneric.mission.MissionData; import net.swofty.type.skyblockgeneric.mission.SkyBlockProgressMission; @@ -14,12 +13,14 @@ import java.util.Map; import java.util.Set; import java.util.UUID; +import net.swofty.type.generic.event.phase.EventPhase; +import net.swofty.type.generic.event.phase.PhasedEvent; public class MissionCollectDarkOakLogs extends SkyBlockProgressMission { private final Map testTimes = new HashMap<>(); - @HypixelEvent(node = EventNodes.CUSTOM, requireDataLoaded = false) + @PhasedEvent(node = EventNodes.CUSTOM, requireDataLoaded = false, phase = EventPhase.GAMEPLAY) public void onTick(PlayerTickEvent event) { SkyBlockPlayer player = (SkyBlockPlayer) event.getPlayer(); if (testTimes.containsKey(player.getUuid())) { diff --git a/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/mission/missions/thepark/jungle/MissionCollectJungleLogs.java b/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/mission/missions/thepark/jungle/MissionCollectJungleLogs.java index c3d3743a7..dab93813b 100644 --- a/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/mission/missions/thepark/jungle/MissionCollectJungleLogs.java +++ b/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/mission/missions/thepark/jungle/MissionCollectJungleLogs.java @@ -3,7 +3,6 @@ import net.minestom.server.event.player.PlayerTickEvent; import net.minestom.server.item.Material; import net.swofty.type.generic.event.EventNodes; -import net.swofty.type.generic.event.HypixelEvent; import net.swofty.type.skyblockgeneric.item.SkyBlockItem; import net.swofty.type.skyblockgeneric.mission.MissionData; import net.swofty.type.skyblockgeneric.mission.SkyBlockProgressMission; @@ -14,12 +13,14 @@ import java.util.Map; import java.util.Set; import java.util.UUID; +import net.swofty.type.generic.event.phase.EventPhase; +import net.swofty.type.generic.event.phase.PhasedEvent; public class MissionCollectJungleLogs extends SkyBlockProgressMission { private final Map testTimes = new HashMap<>(); - @HypixelEvent(node = EventNodes.CUSTOM, requireDataLoaded = false) + @PhasedEvent(node = EventNodes.CUSTOM, requireDataLoaded = false, phase = EventPhase.GAMEPLAY) public void onTick(PlayerTickEvent event) { SkyBlockPlayer player = (SkyBlockPlayer) event.getPlayer(); if (testTimes.containsKey(player.getUuid())) { diff --git a/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/mission/missions/thepark/jungle/MissionLeaveTheArea.java b/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/mission/missions/thepark/jungle/MissionLeaveTheArea.java index 545c07638..3c2388e86 100644 --- a/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/mission/missions/thepark/jungle/MissionLeaveTheArea.java +++ b/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/mission/missions/thepark/jungle/MissionLeaveTheArea.java @@ -1,7 +1,6 @@ package net.swofty.type.skyblockgeneric.mission.missions.thepark.jungle; import net.swofty.type.generic.event.EventNodes; -import net.swofty.type.generic.event.HypixelEvent; import net.swofty.type.skyblockgeneric.event.custom.PlayerRegionChangeEvent; import net.swofty.type.skyblockgeneric.mission.MissionData; import net.swofty.type.skyblockgeneric.mission.SkyBlockMission; @@ -10,10 +9,12 @@ import java.util.Map; import java.util.Set; +import net.swofty.type.generic.event.phase.EventPhase; +import net.swofty.type.generic.event.phase.PhasedEvent; public class MissionLeaveTheArea extends SkyBlockMission { - @HypixelEvent(node = EventNodes.CUSTOM, requireDataLoaded = false) + @PhasedEvent(node = EventNodes.CUSTOM, requireDataLoaded = false, phase = EventPhase.GAMEPLAY) public void run(PlayerRegionChangeEvent event) { if (event.getTo() == null) return; MissionData data = event.getPlayer().getMissionData(); diff --git a/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/mission/missions/thepark/jungle/MissionLeaveTheAreaAgain.java b/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/mission/missions/thepark/jungle/MissionLeaveTheAreaAgain.java index ab1c462d1..e43bd6fd0 100644 --- a/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/mission/missions/thepark/jungle/MissionLeaveTheAreaAgain.java +++ b/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/mission/missions/thepark/jungle/MissionLeaveTheAreaAgain.java @@ -1,7 +1,6 @@ package net.swofty.type.skyblockgeneric.mission.missions.thepark.jungle; import net.swofty.type.generic.event.EventNodes; -import net.swofty.type.generic.event.HypixelEvent; import net.swofty.type.skyblockgeneric.event.custom.PlayerRegionChangeEvent; import net.swofty.type.skyblockgeneric.mission.MissionData; import net.swofty.type.skyblockgeneric.mission.SkyBlockMission; @@ -10,10 +9,12 @@ import java.util.Map; import java.util.Set; +import net.swofty.type.generic.event.phase.EventPhase; +import net.swofty.type.generic.event.phase.PhasedEvent; public class MissionLeaveTheAreaAgain extends SkyBlockMission { - @HypixelEvent(node = EventNodes.CUSTOM, requireDataLoaded = false) + @PhasedEvent(node = EventNodes.CUSTOM, requireDataLoaded = false, phase = EventPhase.GAMEPLAY) public void run(PlayerRegionChangeEvent event) { if (event.getTo() == null) return; MissionData data = event.getPlayer().getMissionData(); diff --git a/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/mission/missions/thepark/savanna/MissionCollectAcaciaLogs.java b/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/mission/missions/thepark/savanna/MissionCollectAcaciaLogs.java index 49d5d9c66..82d10edaa 100644 --- a/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/mission/missions/thepark/savanna/MissionCollectAcaciaLogs.java +++ b/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/mission/missions/thepark/savanna/MissionCollectAcaciaLogs.java @@ -3,7 +3,6 @@ import net.minestom.server.event.player.PlayerTickEvent; import net.minestom.server.item.Material; import net.swofty.type.generic.event.EventNodes; -import net.swofty.type.generic.event.HypixelEvent; import net.swofty.type.skyblockgeneric.item.SkyBlockItem; import net.swofty.type.skyblockgeneric.mission.MissionData; import net.swofty.type.skyblockgeneric.mission.SkyBlockProgressMission; @@ -14,12 +13,14 @@ import java.util.Map; import java.util.Set; import java.util.UUID; +import net.swofty.type.generic.event.phase.EventPhase; +import net.swofty.type.generic.event.phase.PhasedEvent; public class MissionCollectAcaciaLogs extends SkyBlockProgressMission { private final Map testTimes = new HashMap<>(); - @HypixelEvent(node = EventNodes.CUSTOM, requireDataLoaded = false) + @PhasedEvent(node = EventNodes.CUSTOM, requireDataLoaded = false, phase = EventPhase.GAMEPLAY) public void onTick(PlayerTickEvent event) { SkyBlockPlayer player = (SkyBlockPlayer) event.getPlayer(); if (testTimes.containsKey(player.getUuid())) { diff --git a/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/mission/missions/thepark/spruce/MissionCollectSpruceLogs.java b/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/mission/missions/thepark/spruce/MissionCollectSpruceLogs.java index b80487da8..f464da797 100644 --- a/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/mission/missions/thepark/spruce/MissionCollectSpruceLogs.java +++ b/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/mission/missions/thepark/spruce/MissionCollectSpruceLogs.java @@ -3,7 +3,6 @@ import net.minestom.server.event.player.PlayerTickEvent; import net.minestom.server.item.Material; import net.swofty.type.generic.event.EventNodes; -import net.swofty.type.generic.event.HypixelEvent; import net.swofty.type.skyblockgeneric.item.SkyBlockItem; import net.swofty.type.skyblockgeneric.mission.MissionData; import net.swofty.type.skyblockgeneric.mission.SkyBlockProgressMission; @@ -14,12 +13,14 @@ import java.util.Map; import java.util.Set; import java.util.UUID; +import net.swofty.type.generic.event.phase.EventPhase; +import net.swofty.type.generic.event.phase.PhasedEvent; public class MissionCollectSpruceLogs extends SkyBlockProgressMission { private final Map testTimes = new HashMap<>(); - @HypixelEvent(node = EventNodes.CUSTOM, requireDataLoaded = false) + @PhasedEvent(node = EventNodes.CUSTOM, requireDataLoaded = false, phase = EventPhase.GAMEPLAY) public void onTick(PlayerTickEvent event) { SkyBlockPlayer player = (SkyBlockPlayer) event.getPlayer(); if (testTimes.containsKey(player.getUuid())) { diff --git a/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/redis/RedisHasIslandLoaded.java b/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/redis/RedisHasIslandLoaded.java index d3ceae626..0623ddb63 100644 --- a/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/redis/RedisHasIslandLoaded.java +++ b/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/redis/RedisHasIslandLoaded.java @@ -3,7 +3,7 @@ import net.swofty.commons.protocol.ProtocolObject; import net.swofty.commons.protocol.objects.proxy.from.DoesServerHaveIslandProtocol; import net.swofty.proxyapi.redis.TypedProxyHandler; -import net.swofty.type.skyblockgeneric.user.SkyBlockIsland; +import net.swofty.type.skyblockgeneric.user.island.SkyBlockIsland; import java.util.UUID; diff --git a/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/user/SkyBlockIsland.java b/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/user/SkyBlockIsland.java deleted file mode 100644 index 4ae326c89..000000000 --- a/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/user/SkyBlockIsland.java +++ /dev/null @@ -1,203 +0,0 @@ -package net.swofty.type.skyblockgeneric.user; - -import lombok.Getter; -import lombok.Setter; -import net.hollowcube.polar.PolarLoader; -import net.hollowcube.polar.PolarReader; -import net.hollowcube.polar.PolarWorld; -import net.hollowcube.polar.PolarWriter; -import net.kyori.adventure.key.Key; -import net.minestom.server.MinecraftServer; -import net.minestom.server.instance.InstanceContainer; -import net.minestom.server.instance.InstanceManager; -import net.minestom.server.instance.SharedInstance; -import net.minestom.server.registry.RegistryKey; -import net.minestom.server.timer.ExecutionType; -import net.minestom.server.timer.Scheduler; -import net.minestom.server.timer.TaskSchedule; -import net.minestom.server.world.DimensionType; -import net.swofty.commons.CustomWorlds; -import net.swofty.type.generic.HypixelConst; -import net.swofty.type.generic.event.HypixelEventHandler; -import net.swofty.type.generic.user.HypixelPlayer; -import net.swofty.type.generic.utility.MathUtility; -import net.swofty.type.skyblockgeneric.SkyBlockGenericLoader; -import net.swofty.type.skyblockgeneric.data.monogdb.CoopDatabase; -import net.swofty.type.skyblockgeneric.data.monogdb.IslandDatabase; -import net.swofty.type.skyblockgeneric.event.custom.IslandFetchedFromDatabaseEvent; -import net.swofty.type.skyblockgeneric.event.custom.IslandFirstCreatedEvent; -import net.swofty.type.skyblockgeneric.event.custom.IslandSavedIntoDatabaseEvent; -import net.swofty.type.skyblockgeneric.minion.IslandMinionData; -import net.swofty.type.skyblockgeneric.utility.JerryInformation; -import org.bson.types.Binary; -import org.jetbrains.annotations.Nullable; -import org.tinylog.Logger; - -import java.io.IOException; -import java.nio.file.Path; -import java.util.HashMap; -import java.util.List; -import java.util.Map; -import java.util.UUID; -import java.util.concurrent.CompletableFuture; - -@Getter -public class SkyBlockIsland { - private static final Path ISLAND_TEMPLATE_PATH = CustomWorlds.SKYBLOCK_ISLAND_TEMPLATE.getPath(); - private static final Map loadedIslands = new HashMap<>(); - - // Internal Island Data - private final IslandDatabase database; - private final CoopDatabase.Coop coop; - private final UUID islandID; - private Boolean created = false; - private SharedInstance islandInstance; - private PolarWorld world; - - // External Island Data - @Setter - private JerryInformation jerryInformation = null; - @Setter - private IslandMinionData minionData = null; - @Setter - private long lastSaved = 0; - @Setter - private Integer islandVersion; - - public SkyBlockIsland(UUID islandID, UUID profileID) { - this.islandID = islandID; - this.database = new IslandDatabase(islandID.toString()); - this.coop = CoopDatabase.getFromMemberProfile(profileID); - - loadedIslands.put(islandID, this); - } - - public CompletableFuture getSharedInstance() { - InstanceManager manager = MinecraftServer.getInstanceManager(); - CompletableFuture future = new CompletableFuture<>(); - - new Thread(() -> { - if (created) { - future.complete(islandInstance); - return; - } - RegistryKey dimensionTypeKey = MinecraftServer.getDimensionTypeRegistry().getKey( - Key.key("skyblock:island") - ); - InstanceContainer temporaryInstance = manager.createInstanceContainer(dimensionTypeKey); - islandInstance = manager.createSharedInstance(temporaryInstance); - - List onlinePlayers; - if (coop != null) { - onlinePlayers = coop.getOnlineMembers(); - } else { - // Island ID will be the same as the profile ID if the island is not a coop - try { - onlinePlayers = List.of(SkyBlockGenericLoader.getPlayerFromProfileUUID(islandID)); - } catch (NullPointerException e) { - // Player doesn't have their data loaded yet - onlinePlayers = List.of(); - } - } - - if (!database.exists()) { - islandVersion = HypixelConst.getCurrentIslandVersion(); - try { - world = new PolarLoader(ISLAND_TEMPLATE_PATH).world(); - } catch (IOException e) { - Logger.error("Failed to create island world", e); - throw new RuntimeException("Failed to create island world", e); - } - - HypixelEventHandler.callCustomEvent(new IslandFirstCreatedEvent( - this, coop != null, coop != null ? coop.memberProfiles() : List.of(islandID) - )); - } else { - if (database.has("version")) - islandVersion = (int) database.get("version", Integer.class); - else islandVersion = 0; - - switch (islandVersion) { - case 0: - lastSaved = System.currentTimeMillis(); - try { - world = new PolarLoader(ISLAND_TEMPLATE_PATH).world(); - } catch (IOException e) { - throw new RuntimeException(e); - } - break; - case 1: - world = PolarReader.read(((Binary) database.get("data", Binary.class)).getData()); - lastSaved = (long) database.get("lastSaved", Long.class); - break; - } - - int oldVersion = islandVersion; - if (islandVersion < HypixelConst.getCurrentIslandVersion()) { - MathUtility.delay(() -> { - SkyBlockGenericLoader.getLoadedPlayers().stream().filter(player -> player.getSkyBlockIsland().getIslandID() == islandID).forEach(player -> { - player.getLogHandler().debug("Your island was migrated from version §c" + oldVersion + " §fto §a" + HypixelConst.getCurrentIslandVersion() + "§f!"); - }); - }, 20); - islandVersion = HypixelConst.getCurrentIslandVersion(); - } - } - temporaryInstance.setChunkLoader(new PolarLoader(world)); - - this.created = true; - - HypixelEventHandler.callCustomEvent(new IslandFetchedFromDatabaseEvent( - this, coop != null, onlinePlayers, coop != null ? coop.memberProfiles() : List.of(islandID)) - ); - - future.complete(islandInstance); - onlinePlayers.forEach(HypixelPlayer::setReadyForEvents); - }).start(); - - return future; - } - - public void runVacantCheck() { - if (islandInstance == null) return; - - if (islandInstance.getPlayers().isEmpty()) { - HypixelEventHandler.callCustomEvent(new IslandSavedIntoDatabaseEvent( - this, coop != null, coop != null ? coop.memberProfiles() : List.of(islandID) - )); - - save(); - this.created = false; - islandInstance.getChunks().forEach(chunk -> { - islandInstance.unloadChunk(chunk); - }); - this.islandInstance = null; - this.world = null; - } - } - - private void save() { - new PolarLoader(world).saveInstance(islandInstance); - database.insertOrUpdate("data", new Binary(PolarWriter.write(world))); - database.insertOrUpdate("lastSaved", System.currentTimeMillis()); - database.insertOrUpdate("version", islandVersion); - } - - public static boolean hasIsland(UUID islandID) { - return loadedIslands.containsKey(islandID); - } - - public static @Nullable SkyBlockIsland getIsland(UUID islandID) { - if (!loadedIslands.containsKey(islandID)) return null; - return loadedIslands.get(islandID); - } - - public static void runVacantLoop(Scheduler scheduler) { - scheduler.submitTask(() -> { - SkyBlockGenericLoader.getLoadedPlayers().forEach(player -> { - if (player.isOnIsland()) - player.getSkyBlockIsland().runVacantCheck(); - }); - return TaskSchedule.tick(4); - }, ExecutionType.TICK_END); - } -} \ No newline at end of file diff --git a/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/user/SkyBlockPlayer.java b/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/user/SkyBlockPlayer.java index e24f2c905..7578e72a2 100644 --- a/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/user/SkyBlockPlayer.java +++ b/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/user/SkyBlockPlayer.java @@ -65,6 +65,7 @@ import net.swofty.type.skyblockgeneric.region.mining.MineableBlock; import net.swofty.type.skyblockgeneric.region.mining.handler.SkyBlockMiningHandler; import net.swofty.type.skyblockgeneric.skill.skills.RunecraftingSkill; +import net.swofty.type.skyblockgeneric.user.island.SkyBlockIsland; import net.swofty.type.skyblockgeneric.user.statistics.PlayerStatistics; import net.swofty.type.skyblockgeneric.utility.DeathMessageCreator; import org.intellij.lang.annotations.MagicConstant; diff --git a/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/user/flow/SkyBlockPlayerDataFlow.java b/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/user/flow/SkyBlockPlayerDataFlow.java new file mode 100644 index 000000000..57b3d65a8 --- /dev/null +++ b/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/user/flow/SkyBlockPlayerDataFlow.java @@ -0,0 +1,226 @@ +package net.swofty.type.skyblockgeneric.user.flow; + +import net.kyori.adventure.text.Component; +import net.kyori.adventure.title.Title; +import net.minestom.server.MinecraftServer; +import net.minestom.server.network.packet.server.play.UpdateHealthPacket; +import net.swofty.commons.skyblock.SkyBlockPlayerProfiles; +import net.swofty.packer.packs.TestingTexture; +import net.swofty.type.generic.HypixelConst; +import net.swofty.type.generic.data.datapoints.DatapointBoolean; +import net.swofty.type.generic.data.datapoints.DatapointString; +import net.swofty.type.generic.data.datapoints.DatapointStringList; +import net.swofty.type.generic.data.mongodb.ProfilesDatabase; +import net.swofty.type.generic.data.mongodb.UserDatabase; +import net.swofty.type.generic.event.HypixelEventHandler; +import net.swofty.type.generic.user.categories.CustomGroups; +import net.swofty.type.generic.user.categories.Rank; +import net.swofty.type.generic.utility.MathUtility; +import net.swofty.type.skyblockgeneric.SkyBlockGenericLoader; +import net.swofty.type.skyblockgeneric.data.SkyBlockDataHandler; +import net.swofty.type.skyblockgeneric.data.SkyBlockDatapoint; +import net.swofty.type.skyblockgeneric.data.datapoints.DatapointUUID; +import net.swofty.type.skyblockgeneric.data.monogdb.CoopDatabase; +import net.swofty.type.skyblockgeneric.event.custom.PlayerRegionChangeEvent; +import net.swofty.type.skyblockgeneric.region.SkyBlockRegion; +import net.swofty.type.skyblockgeneric.user.SkyBlockPlayer; +import net.swofty.type.skyblockgeneric.user.island.SkyBlockIsland; +import net.swofty.type.skyblockgeneric.warps.TravelScrollIslands; +import org.bson.Document; + +import java.time.Duration; +import java.util.List; +import java.util.Objects; +import java.util.UUID; + +public final class SkyBlockPlayerDataFlow { + private SkyBlockPlayerDataFlow() { + } + + public static void load(SkyBlockPlayer player) { + UUID playerUuid = player.getUuid(); + SkyBlockPlayerProfiles profiles = loadProfiles(player); + UUID profileId = profiles.getCurrentlySelected(); + + ProfilesDatabase profileDb = new ProfilesDatabase(profileId.toString()); + SkyBlockDataHandler handler; + boolean shouldPersistProfile = false; + + if (profileDb.exists()) { + Document profileDocument = profileDb.getDocument(); + handler = SkyBlockDataHandler.createFromProfile(playerUuid, profileId, profileDocument); + } else { + handler = SkyBlockDataHandler.initUserWithDefaultData(playerUuid, profileId); + shouldPersistProfile = true; + } + + DatapointUUID islandDatapoint = handler.get(SkyBlockDataHandler.Data.ISLAND_UUID, DatapointUUID.class); + UUID islandUuid = islandDatapoint.getValue(); + if (islandUuid == null) { + islandUuid = profileId; + islandDatapoint.setValue(islandUuid); + shouldPersistProfile = true; + } + + DatapointString profileNameDatapoint = handler.get(SkyBlockDataHandler.Data.PROFILE_NAME, DatapointString.class); + if (Objects.equals(profileNameDatapoint.getValue(), "null")) { + profileNameDatapoint.setValue(SkyBlockPlayerProfiles.getRandomName()); + shouldPersistProfile = true; + } + + SkyBlockDataHandler.skyBlockCache.put(playerUuid, handler); + + if (shouldPersistProfile) { + profileDb.saveDocument(handler.toProfileDocument()); + } + + player.setSkyBlockIsland(SkyBlockIsland.getOrCreate(islandUuid, profileId)); + } + + public static void postSpawn(SkyBlockPlayer player) { + SkyBlockPlayerProfiles profiles = player.getProfiles(); + SkyBlockDataHandler handler = player.getSkyblockDataHandler(); + handler.runOnLoad(player); + + syncCoopValues(player, profiles, handler); + scheduleRegionRefresh(player); + sendProfileIntro(player); + } + + public static void save(SkyBlockPlayer player) { + UUID playerUuid = player.getUuid(); + SkyBlockDataHandler handler = SkyBlockDataHandler.skyBlockCache.get(playerUuid); + + if (handler == null) return; + + handler.runOnSave(player); + + UUID profileId = handler.getCurrentProfileId(); + ProfilesDatabase profileDb = new ProfilesDatabase(profileId.toString()); + Document newDoc = handler.toProfileDocument(); + + if (profileDb.exists()) { + ProfilesDatabase.collection.replaceOne(com.mongodb.client.model.Filters.eq("_id", profileId.toString()), newDoc); + } else { + ProfilesDatabase.collection.insertOne(newDoc); + } + + SkyBlockDataHandler.skyBlockCache.remove(playerUuid); + } + + private static SkyBlockPlayerProfiles loadProfiles(SkyBlockPlayer player) { + UserDatabase userDatabase = new UserDatabase(player.getUuid()); + SkyBlockPlayerProfiles profiles = userDatabase.getProfiles(); + + if (profiles == null) { + UUID profileId = UUID.randomUUID(); + profiles = new SkyBlockPlayerProfiles(player.getUuid()); + profiles.setCurrentlySelected(profileId); + profiles.addProfile(profileId); + userDatabase.saveProfiles(profiles); + return profiles; + } + + if (profiles.getCurrentlySelected() == null) { + UUID profileId = UUID.randomUUID(); + profiles.setCurrentlySelected(profileId); + profiles.addProfile(profileId); + userDatabase.saveProfiles(profiles); + } + + return profiles; + } + + private static void syncCoopValues(SkyBlockPlayer player, SkyBlockPlayerProfiles profiles, SkyBlockDataHandler handler) { + if (!handler.get(SkyBlockDataHandler.Data.IS_COOP, DatapointBoolean.class).getValue()) return; + + CoopDatabase.Coop coop = CoopDatabase.getFromMember(player.getUuid()); + if (coop == null) return; + if (coop.members().size() == 1) return; + + SkyBlockDataHandler sourceData; + if (SkyBlockGenericLoader.getLoadedPlayers().stream() + .anyMatch(player1 -> !player1.getUuid().equals(player.getUuid()) && coop.members().contains(player1.getUuid()))) { + SkyBlockPlayer otherCoopMember = SkyBlockGenericLoader.getLoadedPlayers().stream() + .filter(player1 -> !player1.getUuid().equals(player.getUuid()) && coop.members().contains(player1.getUuid())) + .findFirst() + .get(); + sourceData = otherCoopMember.getSkyblockDataHandler(); + } else { + UUID finalProfileId = profiles.getCurrentlySelected(); + sourceData = SkyBlockDataHandler.createFromProfileOnly( + new ProfilesDatabase(coop.memberProfiles().stream() + .filter(uuid -> !uuid.equals(finalProfileId)) + .findFirst() + .get().toString()).getDocument() + ); + } + + sourceData.getCoopValues().forEach((key, value) -> { + SkyBlockDatapoint targetDatapoint = (SkyBlockDatapoint) handler.getSkyBlockDatapoint(key); + targetDatapoint.setValueBypassCoop(value); + }); + } + + private static void scheduleRegionRefresh(SkyBlockPlayer player) { + MathUtility.delay(() -> { + SkyBlockRegion playerRegion = player.getRegion(); + if (playerRegion != null && player.isOnline()) { + HypixelEventHandler.callCustomEvent(new PlayerRegionChangeEvent( + player, + null, + playerRegion.getType() + )); + } + }, 50); + } + + private static void sendProfileIntro(SkyBlockPlayer player) { + Thread.startVirtualThread(() -> { + player.sendMessage(""); + player.showTitle(Title.title( + Component.text(TestingTexture.FULL_SCREEN_BLACK.toString()), + Component.empty(), + Title.Times.times(Duration.ZERO, Duration.ofMillis(300), Duration.ofSeconds(1)) + )); + + Rank rank = player.getRank(); + if (rank.isStaff()) { + CustomGroups.staffMembers.add(player); + } + + player.sendMessage("§7 "); + player.sendMessage("§aYou are playing on profile: §e" + player.getSkyblockDataHandler().get( + SkyBlockDataHandler.Data.PROFILE_NAME, DatapointString.class).getValue()); + player.sendMessage("§8Profile ID: " + player.getProfiles().getCurrentlySelected()); + + UUID islandUuid = player.getSkyblockDataHandler().get(SkyBlockDataHandler.Data.ISLAND_UUID, DatapointUUID.class).getValue(); + if (!islandUuid.equals(player.getProfiles().getCurrentlySelected())) { + player.sendMessage("§8Island ID: " + islandUuid); + } + player.sendMessage(" "); + + player.health = player.getMaxHealth(); + player.sendPacket(new UpdateHealthPacket((player.health / player.getMaxHealth()) * 20, 20, 20)); + + MinecraftServer.getBossBarManager().removeAllBossBars(player); + MathUtility.delay(() -> { + if (!player.isOnline()) return; + player.getPetData().updatePetEntityImpl(player); + }, 20); + + TravelScrollIslands island = TravelScrollIslands.getFromType(HypixelConst.getTypeLoader().getType()); + if (island != null) { + List visitedIslands = player.getSkyblockDataHandler() + .get(SkyBlockDataHandler.Data.VISITED_ISLANDS, DatapointStringList.class) + .getValue(); + if (!visitedIslands.contains(island.getInternalName())) { + visitedIslands.add(island.getInternalName()); + player.getSkyblockDataHandler() + .get(SkyBlockDataHandler.Data.VISITED_ISLANDS, DatapointStringList.class) + .setValue(visitedIslands); + } + } + }); + } +} diff --git a/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/user/island/IslandLifecycle.java b/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/user/island/IslandLifecycle.java new file mode 100644 index 000000000..85984ac2d --- /dev/null +++ b/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/user/island/IslandLifecycle.java @@ -0,0 +1,47 @@ +package net.swofty.type.skyblockgeneric.user.island; + +import java.util.Comparator; +import java.util.List; +import java.util.concurrent.CopyOnWriteArrayList; +import org.tinylog.Logger; + +public final class IslandLifecycle { + private static final List steps = new CopyOnWriteArrayList<>(); + + private IslandLifecycle() { + } + + public static void register(IslandLifecycleStep step) { + steps.add(step); + steps.sort(Comparator.comparing(IslandLifecycleStep::phase).thenComparingInt(IslandLifecycleStep::order)); + } + + public static void run(IslandLifecyclePhase phase, IslandLifecycleContext context) { + steps.stream() + .filter(step -> step.phase() == phase) + .forEach(step -> runStep(step, context)); + } + + private static void runStep(IslandLifecycleStep step, IslandLifecycleContext context) { + long started = System.currentTimeMillis(); + Logger.info("[{}] Starting island {} step {}", context.island().getIslandID(), step.phase(), step.getClass().getSimpleName()); + + try { + step.run(context); + Logger.info("[{}] Completed island {} step {} in {}ms", + context.island().getIslandID(), + step.phase(), + step.getClass().getSimpleName(), + System.currentTimeMillis() - started); + } catch (Throwable throwable) { + Logger.error(throwable, "[{}] Failed island {} step {} after {}ms", + context.island().getIslandID(), + step.phase(), + step.getClass().getSimpleName(), + System.currentTimeMillis() - started); + if (throwable instanceof RuntimeException runtimeException) throw runtimeException; + if (throwable instanceof Error error) throw error; + throw new RuntimeException(throwable); + } + } +} diff --git a/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/user/island/IslandLifecycleContext.java b/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/user/island/IslandLifecycleContext.java new file mode 100644 index 000000000..10c063954 --- /dev/null +++ b/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/user/island/IslandLifecycleContext.java @@ -0,0 +1,13 @@ +package net.swofty.type.skyblockgeneric.user.island; + +import net.swofty.type.skyblockgeneric.user.SkyBlockPlayer; + +import java.util.List; +import java.util.UUID; + +public record IslandLifecycleContext( + SkyBlockIsland island, + boolean coop, + List onlineMembers, + List memberProfiles) { +} diff --git a/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/user/island/IslandLifecyclePhase.java b/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/user/island/IslandLifecyclePhase.java new file mode 100644 index 000000000..fa3d8dc0d --- /dev/null +++ b/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/user/island/IslandLifecyclePhase.java @@ -0,0 +1,7 @@ +package net.swofty.type.skyblockgeneric.user.island; + +public enum IslandLifecyclePhase { + CREATE, + LOAD, + SAVE +} diff --git a/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/user/island/IslandLifecycleStep.java b/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/user/island/IslandLifecycleStep.java new file mode 100644 index 000000000..b36d5be52 --- /dev/null +++ b/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/user/island/IslandLifecycleStep.java @@ -0,0 +1,11 @@ +package net.swofty.type.skyblockgeneric.user.island; + +public interface IslandLifecycleStep { + IslandLifecyclePhase phase(); + + default int order() { + return 0; + } + + void run(IslandLifecycleContext context); +} diff --git a/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/user/island/IslandMembers.java b/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/user/island/IslandMembers.java new file mode 100644 index 000000000..4ebffbade --- /dev/null +++ b/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/user/island/IslandMembers.java @@ -0,0 +1,29 @@ +package net.swofty.type.skyblockgeneric.user.island; + +import net.swofty.type.skyblockgeneric.SkyBlockGenericLoader; +import net.swofty.type.skyblockgeneric.data.monogdb.CoopDatabase; +import net.swofty.type.skyblockgeneric.user.SkyBlockPlayer; + +import java.util.List; +import java.util.UUID; + +public final class IslandMembers { + private IslandMembers() { + } + + public static List onlineMembers(UUID islandId, CoopDatabase.Coop coop) { + if (coop != null) { + return coop.getOnlineMembers(); + } + + try { + return List.of(SkyBlockGenericLoader.getPlayerFromProfileUUID(islandId)); + } catch (NullPointerException ignored) { + return List.of(); + } + } + + public static List memberProfiles(UUID islandId, CoopDatabase.Coop coop) { + return coop != null ? coop.memberProfiles() : List.of(islandId); + } +} diff --git a/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/user/island/IslandWorldStorage.java b/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/user/island/IslandWorldStorage.java new file mode 100644 index 000000000..cbeb0d2d9 --- /dev/null +++ b/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/user/island/IslandWorldStorage.java @@ -0,0 +1,55 @@ +package net.swofty.type.skyblockgeneric.user.island; + +import net.hollowcube.polar.PolarLoader; +import net.hollowcube.polar.PolarReader; +import net.hollowcube.polar.PolarWorld; +import net.hollowcube.polar.PolarWriter; +import net.swofty.commons.CustomWorlds; +import net.swofty.type.generic.HypixelConst; +import net.swofty.type.skyblockgeneric.data.monogdb.IslandDatabase; +import org.bson.types.Binary; +import org.tinylog.Logger; + +import java.io.IOException; +import java.nio.file.Path; + +public final class IslandWorldStorage { + private static final Path TEMPLATE_PATH = CustomWorlds.SKYBLOCK_ISLAND_TEMPLATE.getPath(); + + private IslandWorldStorage() { + } + + public static LoadedIslandWorld load(IslandDatabase database) { + if (!database.exists()) { + return new LoadedIslandWorld(templateWorld(), HypixelConst.getCurrentIslandVersion(), 0, true); + } + + int version = database.has("version") ? (int) database.get("version", Integer.class) : 0; + + if (version == 0) { + return new LoadedIslandWorld(templateWorld(), version, System.currentTimeMillis(), false); + } + + PolarWorld world = PolarReader.read(((Binary) database.get("data", Binary.class)).getData()); + long lastSaved = (long) database.get("lastSaved", Long.class); + return new LoadedIslandWorld(world, version, lastSaved, false); + } + + public static void save(IslandDatabase database, PolarWorld world, int version) { + database.insertOrUpdate("data", new Binary(PolarWriter.write(world))); + database.insertOrUpdate("lastSaved", System.currentTimeMillis()); + database.insertOrUpdate("version", version); + } + + private static PolarWorld templateWorld() { + try { + return new PolarLoader(TEMPLATE_PATH).world(); + } catch (IOException e) { + Logger.error("Failed to create island world", e); + throw new RuntimeException("Failed to create island world", e); + } + } + + public record LoadedIslandWorld(PolarWorld world, int version, long lastSaved, boolean firstCreated) { + } +} diff --git a/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/user/island/SkyBlockIsland.java b/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/user/island/SkyBlockIsland.java new file mode 100644 index 000000000..1b81a358e --- /dev/null +++ b/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/user/island/SkyBlockIsland.java @@ -0,0 +1,175 @@ +package net.swofty.type.skyblockgeneric.user.island; + +import lombok.Getter; +import lombok.Setter; +import net.hollowcube.polar.PolarLoader; +import net.hollowcube.polar.PolarWorld; +import net.kyori.adventure.key.Key; +import net.minestom.server.MinecraftServer; +import net.minestom.server.instance.InstanceContainer; +import net.minestom.server.instance.SharedInstance; +import net.minestom.server.registry.RegistryKey; +import net.minestom.server.timer.ExecutionType; +import net.minestom.server.timer.Scheduler; +import net.minestom.server.timer.TaskSchedule; +import net.minestom.server.world.DimensionType; +import net.swofty.type.generic.HypixelConst; +import net.swofty.type.generic.user.HypixelPlayer; +import net.swofty.type.generic.utility.MathUtility; +import net.swofty.type.skyblockgeneric.SkyBlockGenericLoader; +import net.swofty.type.skyblockgeneric.data.monogdb.CoopDatabase; +import net.swofty.type.skyblockgeneric.data.monogdb.IslandDatabase; +import net.swofty.type.skyblockgeneric.minion.IslandMinionData; +import net.swofty.type.skyblockgeneric.user.SkyBlockPlayer; +import net.swofty.type.skyblockgeneric.utility.JerryInformation; +import org.jetbrains.annotations.Nullable; +import org.tinylog.Logger; + +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.UUID; +import java.util.concurrent.CompletableFuture; + +@Getter +public class SkyBlockIsland { + private static final Map loadedIslands = new HashMap<>(); + + private final IslandDatabase database; + private final CoopDatabase.Coop coop; + private final UUID islandID; + private Boolean created = false; + private SharedInstance islandInstance; + private PolarWorld world; + + @Setter + private JerryInformation jerryInformation = null; + @Setter + private IslandMinionData minionData = null; + @Setter + private long lastSaved = 0; + @Setter + private Integer islandVersion; + + public SkyBlockIsland(UUID islandID, UUID profileID) { + this.islandID = islandID; + this.database = new IslandDatabase(islandID.toString()); + this.coop = CoopDatabase.getFromMemberProfile(profileID); + + loadedIslands.put(islandID, this); + } + + public CompletableFuture getSharedInstance() { + CompletableFuture future = new CompletableFuture<>(); + + Thread.startVirtualThread(() -> { + try { + if (created) { + future.complete(islandInstance); + return; + } + + Logger.info("[{}] Starting island instance load", islandID); + + InstanceContainer temporaryInstance = createInstanceContainer(); + islandInstance = MinecraftServer.getInstanceManager().createSharedInstance(temporaryInstance); + + IslandWorldStorage.LoadedIslandWorld loadedWorld = IslandWorldStorage.load(database); + world = loadedWorld.world(); + islandVersion = loadedWorld.version(); + lastSaved = loadedWorld.lastSaved(); + IslandLifecycleContext context = lifecycleContext(); + + if (loadedWorld.firstCreated()) { + IslandLifecycle.run(IslandLifecyclePhase.CREATE, context); + } + + migrateIfNeeded(); + temporaryInstance.setChunkLoader(new PolarLoader(world)); + + this.created = true; + IslandLifecycle.run(IslandLifecyclePhase.LOAD, context); + + future.complete(islandInstance); + context.onlineMembers().forEach(HypixelPlayer::setReadyForEvents); + Logger.info("[{}] Completed island instance load", islandID); + } catch (Throwable throwable) { + Logger.error(throwable, "[{}] Failed island instance load", islandID); + future.completeExceptionally(throwable); + } + }); + + return future; + } + + public void runVacantCheck() { + if (islandInstance == null) return; + + if (islandInstance.getPlayers().isEmpty()) { + IslandLifecycle.run(IslandLifecyclePhase.SAVE, lifecycleContext()); + + save(); + this.created = false; + islandInstance.getChunks().forEach(chunk -> { + islandInstance.unloadChunk(chunk); + }); + this.islandInstance = null; + this.world = null; + } + } + + private void save() { + new PolarLoader(world).saveInstance(islandInstance); + IslandWorldStorage.save(database, world, islandVersion); + } + + private InstanceContainer createInstanceContainer() { + RegistryKey dimensionTypeKey = MinecraftServer.getDimensionTypeRegistry().getKey( + Key.key("skyblock:island") + ); + return MinecraftServer.getInstanceManager().createInstanceContainer(dimensionTypeKey); + } + + private IslandLifecycleContext lifecycleContext() { + List onlineMembers = IslandMembers.onlineMembers(islandID, coop); + List memberProfiles = IslandMembers.memberProfiles(islandID, coop); + return new IslandLifecycleContext(this, coop != null, onlineMembers, memberProfiles); + } + + private void migrateIfNeeded() { + int oldVersion = islandVersion; + if (islandVersion >= HypixelConst.getCurrentIslandVersion()) return; + + MathUtility.delay(() -> SkyBlockGenericLoader.getLoadedPlayers().stream() + .filter(player -> player.getSkyBlockIsland().getIslandID() == islandID) + .forEach(player -> player.getLogHandler().debug("Your island was migrated from version §c" + oldVersion + " §fto §a" + HypixelConst.getCurrentIslandVersion() + "§f!")), 20); + + islandVersion = HypixelConst.getCurrentIslandVersion(); + } + + public static boolean hasIsland(UUID islandID) { + return loadedIslands.containsKey(islandID); + } + + public static SkyBlockIsland getOrCreate(UUID islandID, UUID profileID) { + SkyBlockIsland existing = loadedIslands.get(islandID); + if (existing != null) return existing; + + return new SkyBlockIsland(islandID, profileID); + } + + public static @Nullable SkyBlockIsland getIsland(UUID islandID) { + if (!loadedIslands.containsKey(islandID)) return null; + return loadedIslands.get(islandID); + } + + public static void runVacantLoop(Scheduler scheduler) { + scheduler.submitTask(() -> { + SkyBlockGenericLoader.getLoadedPlayers().forEach(player -> { + if (player.isOnIsland()) + player.getSkyBlockIsland().runVacantCheck(); + }); + return TaskSchedule.tick(4); + }, ExecutionType.TICK_END); + } +} diff --git a/type.skywarsconfigurator/src/main/java/net/swofty/type/skywarsconfigurator/events/ActionPlayerDataSpawn.java b/type.skywarsconfigurator/src/main/java/net/swofty/type/skywarsconfigurator/events/ActionPlayerDataSpawn.java index e5fb5d63d..7df38b7be 100644 --- a/type.skywarsconfigurator/src/main/java/net/swofty/type/skywarsconfigurator/events/ActionPlayerDataSpawn.java +++ b/type.skywarsconfigurator/src/main/java/net/swofty/type/skywarsconfigurator/events/ActionPlayerDataSpawn.java @@ -3,13 +3,14 @@ import net.kyori.adventure.text.Component; import net.minestom.server.event.player.PlayerSpawnEvent; import net.swofty.type.generic.event.EventNodes; -import net.swofty.type.generic.event.HypixelEvent; import net.swofty.type.generic.event.HypixelEventClass; +import net.swofty.type.generic.event.phase.EventPhase; +import net.swofty.type.generic.event.phase.PhasedEvent; import net.swofty.type.generic.user.HypixelPlayer; public class ActionPlayerDataSpawn implements HypixelEventClass { - @HypixelEvent(node = EventNodes.PLAYER_DATA, requireDataLoaded = false, isAsync = true) + @PhasedEvent(node = EventNodes.PLAYER_DATA, requireDataLoaded = false, isAsync = true, phase = EventPhase.POST_SPAWN) public void run(PlayerSpawnEvent event) { if (!event.isFirstSpawn()) return; diff --git a/type.skywarsconfigurator/src/main/java/net/swofty/type/skywarsconfigurator/events/ActionPlayerJoin.java b/type.skywarsconfigurator/src/main/java/net/swofty/type/skywarsconfigurator/events/ActionPlayerJoin.java index 617f0801f..4f39ac8d3 100644 --- a/type.skywarsconfigurator/src/main/java/net/swofty/type/skywarsconfigurator/events/ActionPlayerJoin.java +++ b/type.skywarsconfigurator/src/main/java/net/swofty/type/skywarsconfigurator/events/ActionPlayerJoin.java @@ -4,15 +4,16 @@ import net.minestom.server.event.player.AsyncPlayerConfigurationEvent; import net.swofty.type.generic.HypixelConst; import net.swofty.type.generic.event.EventNodes; -import net.swofty.type.generic.event.HypixelEvent; import net.swofty.type.generic.event.HypixelEventClass; +import net.swofty.type.generic.event.phase.EventPhase; +import net.swofty.type.generic.event.phase.PhasedEvent; import net.swofty.type.generic.user.HypixelPlayer; import org.tinylog.Logger; public class ActionPlayerJoin implements HypixelEventClass { @SneakyThrows - @HypixelEvent(node = EventNodes.PLAYER, requireDataLoaded = false) + @PhasedEvent(node = EventNodes.PLAYER, requireDataLoaded = false, phase = EventPhase.CONNECT) public void run(AsyncPlayerConfigurationEvent event) { final HypixelPlayer player = (HypixelPlayer) event.getPlayer(); diff --git a/type.skywarsgame/src/main/java/net/swofty/type/skywarsgame/events/ActionArrowStats.java b/type.skywarsgame/src/main/java/net/swofty/type/skywarsgame/events/ActionArrowStats.java index 4753ea9b5..7c0cf7ea6 100644 --- a/type.skywarsgame/src/main/java/net/swofty/type/skywarsgame/events/ActionArrowStats.java +++ b/type.skywarsgame/src/main/java/net/swofty/type/skywarsgame/events/ActionArrowStats.java @@ -12,15 +12,16 @@ import net.swofty.type.generic.data.datapoints.DatapointSkywarsModeStats; import net.swofty.type.generic.data.handlers.SkywarsDataHandler; import net.swofty.type.generic.event.EventNodes; -import net.swofty.type.generic.event.HypixelEvent; import net.swofty.type.generic.event.HypixelEventClass; +import net.swofty.type.generic.event.phase.EventPhase; +import net.swofty.type.generic.event.phase.PhasedEvent; import net.swofty.type.skywarsgame.TypeSkywarsGameLoader; import net.swofty.type.skywarsgame.game.SkywarsGame; import net.swofty.type.skywarsgame.game.SkywarsGameStatus; import net.swofty.type.skywarsgame.user.SkywarsPlayer; public class ActionArrowStats implements HypixelEventClass { - @HypixelEvent(node = EventNodes.PLAYER, requireDataLoaded = false) + @PhasedEvent(node = EventNodes.PLAYER, requireDataLoaded = false, phase = EventPhase.GAMEPLAY) public void onBowUse(PlayerUseItemEvent event) { if (!(event.getPlayer() instanceof SkywarsPlayer player)) return; if (event.getItemStack().material() != Material.BOW) return; @@ -33,7 +34,7 @@ public void onBowUse(PlayerUseItemEvent event) { recordArrowShot(player, game); } - @HypixelEvent(node = EventNodes.ALL, requireDataLoaded = false) + @PhasedEvent(node = EventNodes.ALL, requireDataLoaded = false, phase = EventPhase.GAMEPLAY) public void onArrowHit(EntityDamageEvent event) { if (!(event.getEntity() instanceof LivingEntity)) return; diff --git a/type.skywarsgame/src/main/java/net/swofty/type/skywarsgame/events/ActionChestClose.java b/type.skywarsgame/src/main/java/net/swofty/type/skywarsgame/events/ActionChestClose.java index ec3142296..7ac281251 100644 --- a/type.skywarsgame/src/main/java/net/swofty/type/skywarsgame/events/ActionChestClose.java +++ b/type.skywarsgame/src/main/java/net/swofty/type/skywarsgame/events/ActionChestClose.java @@ -5,15 +5,16 @@ import net.minestom.server.inventory.AbstractInventory; import net.minestom.server.inventory.Inventory; import net.swofty.type.generic.event.EventNodes; -import net.swofty.type.generic.event.HypixelEvent; import net.swofty.type.generic.event.HypixelEventClass; +import net.swofty.type.generic.event.phase.EventPhase; +import net.swofty.type.generic.event.phase.PhasedEvent; import net.swofty.type.skywarsgame.TypeSkywarsGameLoader; import net.swofty.type.skywarsgame.game.SkywarsGame; import net.swofty.type.skywarsgame.game.SkywarsGameStatus; import net.swofty.type.skywarsgame.user.SkywarsPlayer; public class ActionChestClose implements HypixelEventClass { - @HypixelEvent(node = EventNodes.PLAYER, requireDataLoaded = false) + @PhasedEvent(node = EventNodes.PLAYER, requireDataLoaded = false, phase = EventPhase.GAMEPLAY) public void onInventoryClose(InventoryCloseEvent event) { if (!(event.getPlayer() instanceof SkywarsPlayer player)) return; diff --git a/type.skywarsgame/src/main/java/net/swofty/type/skywarsgame/events/ActionChestOpen.java b/type.skywarsgame/src/main/java/net/swofty/type/skywarsgame/events/ActionChestOpen.java index a9c2560da..e3c100db1 100644 --- a/type.skywarsgame/src/main/java/net/swofty/type/skywarsgame/events/ActionChestOpen.java +++ b/type.skywarsgame/src/main/java/net/swofty/type/skywarsgame/events/ActionChestOpen.java @@ -4,15 +4,16 @@ import net.minestom.server.event.player.PlayerBlockInteractEvent; import net.minestom.server.instance.block.Block; import net.swofty.type.generic.event.EventNodes; -import net.swofty.type.generic.event.HypixelEvent; import net.swofty.type.generic.event.HypixelEventClass; +import net.swofty.type.generic.event.phase.EventPhase; +import net.swofty.type.generic.event.phase.PhasedEvent; import net.swofty.type.skywarsgame.TypeSkywarsGameLoader; import net.swofty.type.skywarsgame.game.SkywarsGame; import net.swofty.type.skywarsgame.game.SkywarsGameStatus; import net.swofty.type.skywarsgame.user.SkywarsPlayer; public class ActionChestOpen implements HypixelEventClass { - @HypixelEvent(node = EventNodes.PLAYER, requireDataLoaded = false) + @PhasedEvent(node = EventNodes.PLAYER, requireDataLoaded = false, phase = EventPhase.GAMEPLAY) public void onBlockInteract(PlayerBlockInteractEvent event) { if (!(event.getPlayer() instanceof SkywarsPlayer player)) return; diff --git a/type.skywarsgame/src/main/java/net/swofty/type/skywarsgame/events/ActionGameCustomItems.java b/type.skywarsgame/src/main/java/net/swofty/type/skywarsgame/events/ActionGameCustomItems.java index 9fd6e91a1..9c4834b54 100644 --- a/type.skywarsgame/src/main/java/net/swofty/type/skywarsgame/events/ActionGameCustomItems.java +++ b/type.skywarsgame/src/main/java/net/swofty/type/skywarsgame/events/ActionGameCustomItems.java @@ -7,12 +7,13 @@ import net.swofty.type.skywarsgame.luckyblock.items.LuckyBlockItemHandler; import net.swofty.type.skywarsgame.user.SkywarsPlayer; import net.swofty.type.generic.event.EventNodes; -import net.swofty.type.generic.event.HypixelEvent; import net.swofty.type.generic.event.HypixelEventClass; +import net.swofty.type.generic.event.phase.EventPhase; +import net.swofty.type.generic.event.phase.PhasedEvent; public class ActionGameCustomItems implements HypixelEventClass { - @HypixelEvent(node = EventNodes.ALL, requireDataLoaded = false) + @PhasedEvent(node = EventNodes.ALL, requireDataLoaded = false, phase = EventPhase.GAMEPLAY) public void run(PlayerUseItemOnBlockEvent event) { TypeSkywarsGameLoader.getItemHandler().onItemUseOnBlock(event); @@ -21,7 +22,7 @@ public void run(PlayerUseItemOnBlockEvent event) { } } - @HypixelEvent(node = EventNodes.ALL, requireDataLoaded = false) + @PhasedEvent(node = EventNodes.ALL, requireDataLoaded = false, phase = EventPhase.GAMEPLAY) public void run(PlayerUseItemEvent event) { TypeSkywarsGameLoader.getItemHandler().onItemUse(event); @@ -30,7 +31,7 @@ public void run(PlayerUseItemEvent event) { } } - @HypixelEvent(node = EventNodes.ALL, requireDataLoaded = false) + @PhasedEvent(node = EventNodes.ALL, requireDataLoaded = false, phase = EventPhase.GAMEPLAY) public void run(PlayerBlockPlaceEvent event) { TypeSkywarsGameLoader.getItemHandler().onBlockPlace(event); } diff --git a/type.skywarsgame/src/main/java/net/swofty/type/skywarsgame/events/ActionLuckyBlockArrows.java b/type.skywarsgame/src/main/java/net/swofty/type/skywarsgame/events/ActionLuckyBlockArrows.java index b9b2de98d..002ea94f8 100644 --- a/type.skywarsgame/src/main/java/net/swofty/type/skywarsgame/events/ActionLuckyBlockArrows.java +++ b/type.skywarsgame/src/main/java/net/swofty/type/skywarsgame/events/ActionLuckyBlockArrows.java @@ -12,8 +12,9 @@ import net.minestom.server.potion.Potion; import net.minestom.server.potion.PotionEffect; import net.swofty.type.generic.event.EventNodes; -import net.swofty.type.generic.event.HypixelEvent; import net.swofty.type.generic.event.HypixelEventClass; +import net.swofty.type.generic.event.phase.EventPhase; +import net.swofty.type.generic.event.phase.PhasedEvent; import net.swofty.type.skywarsgame.luckyblock.items.LuckyBlockItemRegistry; import net.swofty.type.skywarsgame.luckyblock.items.weapons.ExplosiveBow; import net.swofty.type.skywarsgame.luckyblock.items.weapons.Invisibow; @@ -27,7 +28,7 @@ public class ActionLuckyBlockArrows implements HypixelEventClass { private static final Map arrowBowMap = new ConcurrentHashMap<>(); - @HypixelEvent(node = EventNodes.ALL, requireDataLoaded = false) + @PhasedEvent(node = EventNodes.ALL, requireDataLoaded = false, phase = EventPhase.GAMEPLAY) public void onArrowShoot(EntityShootEvent event) { if (!(event.getEntity() instanceof SkywarsPlayer player)) return; @@ -39,7 +40,7 @@ public void onArrowShoot(EntityShootEvent event) { } } - @HypixelEvent(node = EventNodes.ALL, requireDataLoaded = false) + @PhasedEvent(node = EventNodes.ALL, requireDataLoaded = false, phase = EventPhase.GAMEPLAY) public void onArrowHitBlock(ProjectileCollideWithBlockEvent event) { Entity projectile = event.getEntity(); String bowId = arrowBowMap.remove(projectile.getUuid()); @@ -49,7 +50,7 @@ public void onArrowHitBlock(ProjectileCollideWithBlockEvent event) { handleArrowEffect(bowId, projectile, event.getCollisionPosition(), null); } - @HypixelEvent(node = EventNodes.ALL, requireDataLoaded = false) + @PhasedEvent(node = EventNodes.ALL, requireDataLoaded = false, phase = EventPhase.GAMEPLAY) public void onArrowHitEntity(ProjectileCollideWithEntityEvent event) { Entity projectile = event.getEntity(); String bowId = arrowBowMap.get(projectile.getUuid()); diff --git a/type.skywarsgame/src/main/java/net/swofty/type/skywarsgame/events/ActionLuckyBlockBreak.java b/type.skywarsgame/src/main/java/net/swofty/type/skywarsgame/events/ActionLuckyBlockBreak.java index f34236a76..9b14c4d2a 100644 --- a/type.skywarsgame/src/main/java/net/swofty/type/skywarsgame/events/ActionLuckyBlockBreak.java +++ b/type.skywarsgame/src/main/java/net/swofty/type/skywarsgame/events/ActionLuckyBlockBreak.java @@ -5,8 +5,9 @@ import net.minestom.server.instance.block.Block; import net.swofty.commons.skywars.SkywarsGameType; import net.swofty.type.generic.event.EventNodes; -import net.swofty.type.generic.event.HypixelEvent; import net.swofty.type.generic.event.HypixelEventClass; +import net.swofty.type.generic.event.phase.EventPhase; +import net.swofty.type.generic.event.phase.PhasedEvent; import net.swofty.type.skywarsgame.TypeSkywarsGameLoader; import net.swofty.type.skywarsgame.game.SkywarsGame; import net.swofty.type.skywarsgame.game.SkywarsGameStatus; @@ -14,7 +15,7 @@ import net.swofty.type.skywarsgame.user.SkywarsPlayer; public class ActionLuckyBlockBreak implements HypixelEventClass { - @HypixelEvent(node = EventNodes.PLAYER, requireDataLoaded = false) + @PhasedEvent(node = EventNodes.PLAYER, requireDataLoaded = false, phase = EventPhase.GAMEPLAY) public void onBlockBreak(PlayerBlockBreakEvent event) { if (!(event.getPlayer() instanceof SkywarsPlayer player)) return; diff --git a/type.skywarsgame/src/main/java/net/swofty/type/skywarsgame/events/ActionLuckyBlockPlace.java b/type.skywarsgame/src/main/java/net/swofty/type/skywarsgame/events/ActionLuckyBlockPlace.java index f7dc02cf7..936a76882 100644 --- a/type.skywarsgame/src/main/java/net/swofty/type/skywarsgame/events/ActionLuckyBlockPlace.java +++ b/type.skywarsgame/src/main/java/net/swofty/type/skywarsgame/events/ActionLuckyBlockPlace.java @@ -6,8 +6,9 @@ import net.minestom.server.item.Material; import net.swofty.commons.skywars.SkywarsGameType; import net.swofty.type.generic.event.EventNodes; -import net.swofty.type.generic.event.HypixelEvent; import net.swofty.type.generic.event.HypixelEventClass; +import net.swofty.type.generic.event.phase.EventPhase; +import net.swofty.type.generic.event.phase.PhasedEvent; import net.swofty.type.skywarsgame.TypeSkywarsGameLoader; import net.swofty.type.skywarsgame.game.SkywarsGame; import net.swofty.type.skywarsgame.game.SkywarsGameStatus; @@ -16,7 +17,7 @@ import net.swofty.type.skywarsgame.user.SkywarsPlayer; public class ActionLuckyBlockPlace implements HypixelEventClass { - @HypixelEvent(node = EventNodes.PLAYER, requireDataLoaded = false) + @PhasedEvent(node = EventNodes.PLAYER, requireDataLoaded = false, phase = EventPhase.GAMEPLAY) public void onBlockPlace(PlayerBlockPlaceEvent event) { if (!(event.getPlayer() instanceof SkywarsPlayer player)) return; diff --git a/type.skywarsgame/src/main/java/net/swofty/type/skywarsgame/events/ActionMobAttack.java b/type.skywarsgame/src/main/java/net/swofty/type/skywarsgame/events/ActionMobAttack.java index f1406c66f..4bbe3e9de 100644 --- a/type.skywarsgame/src/main/java/net/swofty/type/skywarsgame/events/ActionMobAttack.java +++ b/type.skywarsgame/src/main/java/net/swofty/type/skywarsgame/events/ActionMobAttack.java @@ -7,8 +7,9 @@ import net.minestom.server.entity.damage.DamageType; import net.minestom.server.event.entity.EntityAttackEvent; import net.swofty.type.generic.event.EventNodes; -import net.swofty.type.generic.event.HypixelEvent; import net.swofty.type.generic.event.HypixelEventClass; +import net.swofty.type.generic.event.phase.EventPhase; +import net.swofty.type.generic.event.phase.PhasedEvent; import net.swofty.type.skywarsgame.TypeSkywarsGameLoader; import net.swofty.type.skywarsgame.game.SkywarsGame; import net.swofty.type.skywarsgame.game.SkywarsGameStatus; @@ -16,7 +17,7 @@ public class ActionMobAttack implements HypixelEventClass { - @HypixelEvent(node = EventNodes.ALL, requireDataLoaded = false) + @PhasedEvent(node = EventNodes.ALL, requireDataLoaded = false, phase = EventPhase.GAMEPLAY) public void onMobAttack(EntityAttackEvent event) { Entity attacker = event.getEntity(); Entity target = event.getTarget(); diff --git a/type.skywarsgame/src/main/java/net/swofty/type/skywarsgame/events/ActionMobKill.java b/type.skywarsgame/src/main/java/net/swofty/type/skywarsgame/events/ActionMobKill.java index 7d8762212..89b1d3075 100644 --- a/type.skywarsgame/src/main/java/net/swofty/type/skywarsgame/events/ActionMobKill.java +++ b/type.skywarsgame/src/main/java/net/swofty/type/skywarsgame/events/ActionMobKill.java @@ -7,15 +7,16 @@ import net.swofty.type.generic.data.datapoints.DatapointSkywarsKitStats; import net.swofty.type.generic.data.handlers.SkywarsDataHandler; import net.swofty.type.generic.event.EventNodes; -import net.swofty.type.generic.event.HypixelEvent; import net.swofty.type.generic.event.HypixelEventClass; +import net.swofty.type.generic.event.phase.EventPhase; +import net.swofty.type.generic.event.phase.PhasedEvent; import net.swofty.type.skywarsgame.TypeSkywarsGameLoader; import net.swofty.type.skywarsgame.game.SkywarsGame; import net.swofty.type.skywarsgame.game.SkywarsGameStatus; import net.swofty.type.skywarsgame.user.SkywarsPlayer; public class ActionMobKill implements HypixelEventClass { - @HypixelEvent(node = EventNodes.ALL, requireDataLoaded = false) + @PhasedEvent(node = EventNodes.ALL, requireDataLoaded = false, phase = EventPhase.GAMEPLAY) public void onEntityDeath(EntityDeathEvent event) { Entity entity = event.getEntity(); if (entity instanceof Player) return; diff --git a/type.skywarsgame/src/main/java/net/swofty/type/skywarsgame/events/ActionPlayerChat.java b/type.skywarsgame/src/main/java/net/swofty/type/skywarsgame/events/ActionPlayerChat.java index 4309089a8..1df9dfabb 100644 --- a/type.skywarsgame/src/main/java/net/swofty/type/skywarsgame/events/ActionPlayerChat.java +++ b/type.skywarsgame/src/main/java/net/swofty/type/skywarsgame/events/ActionPlayerChat.java @@ -9,8 +9,9 @@ import net.swofty.type.generic.data.datapoints.DatapointLong; import net.swofty.type.generic.data.handlers.SkywarsDataHandler; import net.swofty.type.generic.event.EventNodes; -import net.swofty.type.generic.event.HypixelEvent; import net.swofty.type.generic.event.HypixelEventClass; +import net.swofty.type.generic.event.phase.EventPhase; +import net.swofty.type.generic.event.phase.PhasedEvent; import net.swofty.type.generic.party.PartyManager; import net.swofty.type.generic.user.categories.Rank; import net.swofty.type.skywarsgame.TypeSkywarsGameLoader; @@ -20,7 +21,7 @@ public class ActionPlayerChat implements HypixelEventClass { - @HypixelEvent(node = EventNodes.PLAYER, requireDataLoaded = false) + @PhasedEvent(node = EventNodes.PLAYER, requireDataLoaded = false, phase = EventPhase.GAMEPLAY) public void run(PlayerChatEvent event) { final SkywarsPlayer player = (SkywarsPlayer) event.getPlayer(); event.setCancelled(true); diff --git a/type.skywarsgame/src/main/java/net/swofty/type/skywarsgame/events/ActionPlayerCombat.java b/type.skywarsgame/src/main/java/net/swofty/type/skywarsgame/events/ActionPlayerCombat.java index 284522537..9a5538a2d 100644 --- a/type.skywarsgame/src/main/java/net/swofty/type/skywarsgame/events/ActionPlayerCombat.java +++ b/type.skywarsgame/src/main/java/net/swofty/type/skywarsgame/events/ActionPlayerCombat.java @@ -3,15 +3,16 @@ import net.minestom.server.entity.damage.DamageType; import net.minestom.server.event.entity.EntityDamageEvent; import net.swofty.type.generic.event.EventNodes; -import net.swofty.type.generic.event.HypixelEvent; import net.swofty.type.generic.event.HypixelEventClass; +import net.swofty.type.generic.event.phase.EventPhase; +import net.swofty.type.generic.event.phase.PhasedEvent; import net.swofty.type.skywarsgame.TypeSkywarsGameLoader; import net.swofty.type.skywarsgame.game.SkywarsGame; import net.swofty.type.skywarsgame.game.SkywarsGameStatus; import net.swofty.type.skywarsgame.user.SkywarsPlayer; public class ActionPlayerCombat implements HypixelEventClass { - @HypixelEvent(node = EventNodes.ALL, requireDataLoaded = false) + @PhasedEvent(node = EventNodes.ALL, requireDataLoaded = false, phase = EventPhase.GAMEPLAY) public void onDamage(EntityDamageEvent event) { if (!(event.getEntity() instanceof SkywarsPlayer victim)) return; diff --git a/type.skywarsgame/src/main/java/net/swofty/type/skywarsgame/events/ActionPlayerDisconnect.java b/type.skywarsgame/src/main/java/net/swofty/type/skywarsgame/events/ActionPlayerDisconnect.java index edcb1214f..ea3dc874b 100644 --- a/type.skywarsgame/src/main/java/net/swofty/type/skywarsgame/events/ActionPlayerDisconnect.java +++ b/type.skywarsgame/src/main/java/net/swofty/type/skywarsgame/events/ActionPlayerDisconnect.java @@ -2,15 +2,16 @@ import net.minestom.server.event.player.PlayerDisconnectEvent; import net.swofty.type.generic.event.EventNodes; -import net.swofty.type.generic.event.HypixelEvent; import net.swofty.type.generic.event.HypixelEventClass; +import net.swofty.type.generic.event.phase.EventPhase; +import net.swofty.type.generic.event.phase.PhasedEvent; import net.swofty.type.skywarsgame.SkywarsGameScoreboard; import net.swofty.type.skywarsgame.TypeSkywarsGameLoader; import net.swofty.type.skywarsgame.game.SkywarsGame; import net.swofty.type.skywarsgame.user.SkywarsPlayer; public class ActionPlayerDisconnect implements HypixelEventClass { - @HypixelEvent(node = EventNodes.PLAYER, requireDataLoaded = false) + @PhasedEvent(node = EventNodes.PLAYER, requireDataLoaded = false, phase = EventPhase.DISCONNECT) public void onDisconnect(PlayerDisconnectEvent event) { SkywarsPlayer player = (SkywarsPlayer) event.getPlayer(); SkywarsGame game = TypeSkywarsGameLoader.getPlayerGame(player); diff --git a/type.skywarsgame/src/main/java/net/swofty/type/skywarsgame/events/ActionPlayerJoin.java b/type.skywarsgame/src/main/java/net/swofty/type/skywarsgame/events/ActionPlayerJoin.java index b2e72c737..505a0c134 100644 --- a/type.skywarsgame/src/main/java/net/swofty/type/skywarsgame/events/ActionPlayerJoin.java +++ b/type.skywarsgame/src/main/java/net/swofty/type/skywarsgame/events/ActionPlayerJoin.java @@ -5,8 +5,9 @@ import net.swofty.commons.ServerType; import net.swofty.type.generic.HypixelConst; import net.swofty.type.generic.event.EventNodes; -import net.swofty.type.generic.event.HypixelEvent; import net.swofty.type.generic.event.HypixelEventClass; +import net.swofty.type.generic.event.phase.EventPhase; +import net.swofty.type.generic.event.phase.PhasedEvent; import net.swofty.type.generic.redis.service.TypedGameInformationHandler; import net.swofty.type.generic.utility.MathUtility; import net.swofty.type.skywarsgame.TypeSkywarsGameLoader; @@ -16,7 +17,7 @@ import org.tinylog.Logger; public class ActionPlayerJoin implements HypixelEventClass { - @HypixelEvent(node = EventNodes.PLAYER, requireDataLoaded = false) + @PhasedEvent(node = EventNodes.PLAYER, requireDataLoaded = false, phase = EventPhase.CONNECT) public void onJoin(AsyncPlayerConfigurationEvent event) { SkywarsPlayer player = (SkywarsPlayer) event.getPlayer(); Logger.info("Player " + player.getUsername() + " joined the server from origin server " + player.getOriginServer()); diff --git a/type.skywarsgame/src/main/java/net/swofty/type/skywarsgame/events/ActionPlayerNameColors.java b/type.skywarsgame/src/main/java/net/swofty/type/skywarsgame/events/ActionPlayerNameColors.java index 77aa51cfb..63284ecab 100644 --- a/type.skywarsgame/src/main/java/net/swofty/type/skywarsgame/events/ActionPlayerNameColors.java +++ b/type.skywarsgame/src/main/java/net/swofty/type/skywarsgame/events/ActionPlayerNameColors.java @@ -5,8 +5,9 @@ import net.minestom.server.event.player.PlayerSpawnEvent; import net.minestom.server.network.packet.server.play.TeamsPacket; import net.swofty.type.generic.event.EventNodes; -import net.swofty.type.generic.event.HypixelEvent; import net.swofty.type.generic.event.HypixelEventClass; +import net.swofty.type.generic.event.phase.EventPhase; +import net.swofty.type.generic.event.phase.PhasedEvent; import net.swofty.type.skywarsgame.TypeSkywarsGameLoader; import net.swofty.type.skywarsgame.user.SkywarsPlayer; @@ -15,7 +16,7 @@ public class ActionPlayerNameColors implements HypixelEventClass { - @HypixelEvent(node = EventNodes.PLAYER, requireDataLoaded = true) + @PhasedEvent(node = EventNodes.PLAYER, requireDataLoaded = true, phase = EventPhase.GAMEPLAY) public void run(PlayerSpawnEvent event) { SkywarsPlayer player = (SkywarsPlayer) event.getPlayer(); diff --git a/type.skywarslobby/src/main/java/net/swofty/type/skywarslobby/events/ActionPlayerChat.java b/type.skywarslobby/src/main/java/net/swofty/type/skywarslobby/events/ActionPlayerChat.java index b9e92be93..d34ac4a0b 100644 --- a/type.skywarslobby/src/main/java/net/swofty/type/skywarslobby/events/ActionPlayerChat.java +++ b/type.skywarslobby/src/main/java/net/swofty/type/skywarslobby/events/ActionPlayerChat.java @@ -11,8 +11,9 @@ import net.swofty.type.generic.data.datapoints.DatapointLong; import net.swofty.type.generic.data.handlers.SkywarsDataHandler; import net.swofty.type.generic.event.EventNodes; -import net.swofty.type.generic.event.HypixelEvent; import net.swofty.type.generic.event.HypixelEventClass; +import net.swofty.type.generic.event.phase.EventPhase; +import net.swofty.type.generic.event.phase.PhasedEvent; import net.swofty.type.generic.party.PartyManager; import net.swofty.type.generic.user.HypixelPlayer; import net.swofty.type.generic.user.categories.Rank; @@ -22,7 +23,7 @@ public class ActionPlayerChat implements HypixelEventClass { - @HypixelEvent(node = EventNodes.PLAYER, requireDataLoaded = false) + @PhasedEvent(node = EventNodes.PLAYER, requireDataLoaded = false, phase = EventPhase.GAMEPLAY) public void run(PlayerChatEvent event) { final HypixelPlayer player = (HypixelPlayer) event.getPlayer(); event.setCancelled(true); diff --git a/type.skywarslobby/src/main/java/net/swofty/type/skywarslobby/events/ActionPlayerDataSpawn.java b/type.skywarslobby/src/main/java/net/swofty/type/skywarslobby/events/ActionPlayerDataSpawn.java index 7be1b3c7c..726aa8e66 100644 --- a/type.skywarslobby/src/main/java/net/swofty/type/skywarslobby/events/ActionPlayerDataSpawn.java +++ b/type.skywarslobby/src/main/java/net/swofty/type/skywarslobby/events/ActionPlayerDataSpawn.java @@ -6,14 +6,15 @@ import net.swofty.type.generic.HypixelConst; import net.swofty.type.generic.HypixelGenericLoader; import net.swofty.type.generic.event.EventNodes; -import net.swofty.type.generic.event.HypixelEvent; import net.swofty.type.generic.event.HypixelEventClass; +import net.swofty.type.generic.event.phase.EventPhase; +import net.swofty.type.generic.event.phase.PhasedEvent; import net.swofty.type.generic.user.HypixelPlayer; import net.swofty.type.generic.user.categories.Rank; public class ActionPlayerDataSpawn implements HypixelEventClass { - @HypixelEvent(node = EventNodes.PLAYER_DATA, requireDataLoaded = false, isAsync = true) + @PhasedEvent(node = EventNodes.PLAYER_DATA, requireDataLoaded = false, isAsync = true, phase = EventPhase.POST_SPAWN) public void run(PlayerSpawnEvent event) { if (!event.isFirstSpawn()) return; if (!(HypixelConst.getTypeLoader().getType() == ServerType.SKYWARS_LOBBY)) return; diff --git a/type.skywarslobby/src/main/java/net/swofty/type/skywarslobby/events/ActionPlayerDisconnect.java b/type.skywarslobby/src/main/java/net/swofty/type/skywarslobby/events/ActionPlayerDisconnect.java index 6d88e4a17..fd8b7d799 100644 --- a/type.skywarslobby/src/main/java/net/swofty/type/skywarslobby/events/ActionPlayerDisconnect.java +++ b/type.skywarslobby/src/main/java/net/swofty/type/skywarslobby/events/ActionPlayerDisconnect.java @@ -2,14 +2,15 @@ import net.minestom.server.event.player.PlayerDisconnectEvent; import net.swofty.type.generic.event.EventNodes; -import net.swofty.type.generic.event.HypixelEvent; import net.swofty.type.generic.event.HypixelEventClass; +import net.swofty.type.generic.event.phase.EventPhase; +import net.swofty.type.generic.event.phase.PhasedEvent; import net.swofty.type.generic.user.HypixelPlayer; import net.swofty.type.skywarslobby.SkyWarsLobbyScoreboard; public class ActionPlayerDisconnect implements HypixelEventClass { - @HypixelEvent(node = EventNodes.PLAYER, requireDataLoaded = false) + @PhasedEvent(node = EventNodes.PLAYER, requireDataLoaded = false, phase = EventPhase.DISCONNECT) public void run(PlayerDisconnectEvent event) { HypixelPlayer player = (HypixelPlayer) event.getPlayer(); SkyWarsLobbyScoreboard.removeCache(player); diff --git a/type.skywarslobby/src/main/java/net/swofty/type/skywarslobby/events/ActionPlayerSpawn.java b/type.skywarslobby/src/main/java/net/swofty/type/skywarslobby/events/ActionPlayerSpawn.java index cf263d087..a16defcde 100644 --- a/type.skywarslobby/src/main/java/net/swofty/type/skywarslobby/events/ActionPlayerSpawn.java +++ b/type.skywarslobby/src/main/java/net/swofty/type/skywarslobby/events/ActionPlayerSpawn.java @@ -4,8 +4,9 @@ import net.minestom.server.entity.GameMode; import net.minestom.server.event.player.PlayerSpawnEvent; import net.swofty.type.generic.event.EventNodes; -import net.swofty.type.generic.event.HypixelEvent; import net.swofty.type.generic.event.HypixelEventClass; +import net.swofty.type.generic.event.phase.EventPhase; +import net.swofty.type.generic.event.phase.PhasedEvent; import net.swofty.type.generic.user.HypixelPlayer; import net.swofty.type.skywarslobby.hologram.LeaderboardHologramManager; import net.swofty.type.skywarslobby.hologram.SoulWellHologramManager; @@ -14,7 +15,7 @@ public class ActionPlayerSpawn implements HypixelEventClass { @SneakyThrows - @HypixelEvent(node = EventNodes.PLAYER, requireDataLoaded = false, isAsync = true) + @PhasedEvent(node = EventNodes.PLAYER, requireDataLoaded = false, isAsync = true, phase = EventPhase.SPAWN) public void run(PlayerSpawnEvent event) { final HypixelPlayer player = (HypixelPlayer) event.getPlayer(); player.setGameMode(GameMode.SURVIVAL); diff --git a/type.skywarslobby/src/main/java/net/swofty/type/skywarslobby/events/ActionSoulWellInteract.java b/type.skywarslobby/src/main/java/net/swofty/type/skywarslobby/events/ActionSoulWellInteract.java index 55bc00b3e..f545b4813 100644 --- a/type.skywarslobby/src/main/java/net/swofty/type/skywarslobby/events/ActionSoulWellInteract.java +++ b/type.skywarslobby/src/main/java/net/swofty/type/skywarslobby/events/ActionSoulWellInteract.java @@ -4,8 +4,9 @@ import net.minestom.server.event.player.PlayerBlockInteractEvent; import net.minestom.server.instance.block.Block; import net.swofty.type.generic.event.EventNodes; -import net.swofty.type.generic.event.HypixelEvent; import net.swofty.type.generic.event.HypixelEventClass; +import net.swofty.type.generic.event.phase.EventPhase; +import net.swofty.type.generic.event.phase.PhasedEvent; import net.swofty.type.generic.user.HypixelPlayer; import net.swofty.type.skywarslobby.gui.GUISoulWell; @@ -14,7 +15,7 @@ public class ActionSoulWellInteract implements HypixelEventClass { private static final int SOUL_WELL_Y = 67; private static final int SOUL_WELL_Z = 0; - @HypixelEvent(node = EventNodes.PLAYER, requireDataLoaded = false) + @PhasedEvent(node = EventNodes.PLAYER, requireDataLoaded = false, phase = EventPhase.GAMEPLAY) public void run(PlayerBlockInteractEvent event) { if (!(event.getPlayer() instanceof HypixelPlayer player)) { return; diff --git a/type.spidersden/src/main/java/net/swofty/type/spidersden/events/ActionPlayerJoin.java b/type.spidersden/src/main/java/net/swofty/type/spidersden/events/ActionPlayerJoin.java index 0625c8b5a..9a6158f7b 100644 --- a/type.spidersden/src/main/java/net/swofty/type/spidersden/events/ActionPlayerJoin.java +++ b/type.spidersden/src/main/java/net/swofty/type/spidersden/events/ActionPlayerJoin.java @@ -4,14 +4,15 @@ import net.minestom.server.event.player.AsyncPlayerConfigurationEvent; import net.swofty.type.generic.HypixelConst; import net.swofty.type.generic.event.EventNodes; -import net.swofty.type.generic.event.HypixelEvent; import net.swofty.type.generic.event.HypixelEventClass; +import net.swofty.type.generic.event.phase.EventPhase; +import net.swofty.type.generic.event.phase.PhasedEvent; import net.swofty.type.skyblockgeneric.user.SkyBlockPlayer; public class ActionPlayerJoin implements HypixelEventClass { @SneakyThrows - @HypixelEvent(node = EventNodes.PLAYER, requireDataLoaded = false) + @PhasedEvent(node = EventNodes.PLAYER, requireDataLoaded = false, phase = EventPhase.CONNECT) public void run(AsyncPlayerConfigurationEvent event) { final SkyBlockPlayer player = (SkyBlockPlayer) event.getPlayer(); diff --git a/type.theend/src/main/java/net/swofty/type/theend/events/ActionPlayerJoin.java b/type.theend/src/main/java/net/swofty/type/theend/events/ActionPlayerJoin.java index 94bc7729c..eeebc2469 100644 --- a/type.theend/src/main/java/net/swofty/type/theend/events/ActionPlayerJoin.java +++ b/type.theend/src/main/java/net/swofty/type/theend/events/ActionPlayerJoin.java @@ -4,14 +4,15 @@ import net.minestom.server.event.player.AsyncPlayerConfigurationEvent; import net.swofty.type.generic.HypixelConst; import net.swofty.type.generic.event.EventNodes; -import net.swofty.type.generic.event.HypixelEvent; import net.swofty.type.generic.event.HypixelEventClass; +import net.swofty.type.generic.event.phase.EventPhase; +import net.swofty.type.generic.event.phase.PhasedEvent; import net.swofty.type.skyblockgeneric.user.SkyBlockPlayer; public class ActionPlayerJoin implements HypixelEventClass { @SneakyThrows - @HypixelEvent(node = EventNodes.PLAYER, requireDataLoaded = false) + @PhasedEvent(node = EventNodes.PLAYER, requireDataLoaded = false, phase = EventPhase.CONNECT) public void run(AsyncPlayerConfigurationEvent event) { final SkyBlockPlayer player = (SkyBlockPlayer) event.getPlayer(); diff --git a/type.thefarmingislands/src/main/java/net/swofty/type/thefarmingislands/events/ActionPlayerJoin.java b/type.thefarmingislands/src/main/java/net/swofty/type/thefarmingislands/events/ActionPlayerJoin.java index 65f198896..6c16e36c3 100644 --- a/type.thefarmingislands/src/main/java/net/swofty/type/thefarmingislands/events/ActionPlayerJoin.java +++ b/type.thefarmingislands/src/main/java/net/swofty/type/thefarmingislands/events/ActionPlayerJoin.java @@ -4,14 +4,15 @@ import net.minestom.server.event.player.AsyncPlayerConfigurationEvent; import net.swofty.type.generic.HypixelConst; import net.swofty.type.generic.event.EventNodes; -import net.swofty.type.generic.event.HypixelEvent; import net.swofty.type.generic.event.HypixelEventClass; +import net.swofty.type.generic.event.phase.EventPhase; +import net.swofty.type.generic.event.phase.PhasedEvent; import net.swofty.type.skyblockgeneric.user.SkyBlockPlayer; public class ActionPlayerJoin implements HypixelEventClass { @SneakyThrows - @HypixelEvent(node = EventNodes.PLAYER, requireDataLoaded = false) + @PhasedEvent(node = EventNodes.PLAYER, requireDataLoaded = false, phase = EventPhase.CONNECT) public void run(AsyncPlayerConfigurationEvent event) { final SkyBlockPlayer player = (SkyBlockPlayer) event.getPlayer(); diff --git a/type.thepark/src/main/java/net/swofty/type/thepark/events/ActionContinueParkMission.java b/type.thepark/src/main/java/net/swofty/type/thepark/events/ActionContinueParkMission.java index 410abe2cc..b6a9c9948 100644 --- a/type.thepark/src/main/java/net/swofty/type/thepark/events/ActionContinueParkMission.java +++ b/type.thepark/src/main/java/net/swofty/type/thepark/events/ActionContinueParkMission.java @@ -3,8 +3,9 @@ import net.minestom.server.entity.Entity; import net.swofty.type.generic.entity.npc.HypixelNPC; import net.swofty.type.generic.event.EventNodes; -import net.swofty.type.generic.event.HypixelEvent; import net.swofty.type.generic.event.HypixelEventClass; +import net.swofty.type.generic.event.phase.EventPhase; +import net.swofty.type.generic.event.phase.PhasedEvent; import net.swofty.type.skyblockgeneric.event.custom.PlayerRegionChangeEvent; import net.swofty.type.skyblockgeneric.mission.MissionData; import net.swofty.type.skyblockgeneric.mission.missions.thepark.birchpark.MissionTravelToThePark; @@ -19,7 +20,7 @@ public class ActionContinueParkMission implements HypixelEventClass { - @HypixelEvent(node = EventNodes.CUSTOM, requireDataLoaded = false) + @PhasedEvent(node = EventNodes.CUSTOM, requireDataLoaded = false, phase = EventPhase.GAMEPLAY) public void run(PlayerRegionChangeEvent event) { if (event.getTo() == null) return; diff --git a/type.thepark/src/main/java/net/swofty/type/thepark/events/ActionPlayerJoin.java b/type.thepark/src/main/java/net/swofty/type/thepark/events/ActionPlayerJoin.java index 32737e368..918d5f66c 100644 --- a/type.thepark/src/main/java/net/swofty/type/thepark/events/ActionPlayerJoin.java +++ b/type.thepark/src/main/java/net/swofty/type/thepark/events/ActionPlayerJoin.java @@ -4,14 +4,15 @@ import net.minestom.server.event.player.AsyncPlayerConfigurationEvent; import net.swofty.type.generic.HypixelConst; import net.swofty.type.generic.event.EventNodes; -import net.swofty.type.generic.event.HypixelEvent; import net.swofty.type.generic.event.HypixelEventClass; +import net.swofty.type.generic.event.phase.EventPhase; +import net.swofty.type.generic.event.phase.PhasedEvent; import net.swofty.type.skyblockgeneric.user.SkyBlockPlayer; public class ActionPlayerJoin implements HypixelEventClass { @SneakyThrows - @HypixelEvent(node = EventNodes.PLAYER, requireDataLoaded = false) + @PhasedEvent(node = EventNodes.PLAYER, requireDataLoaded = false, phase = EventPhase.CONNECT) public void run(AsyncPlayerConfigurationEvent event) { final SkyBlockPlayer player = (SkyBlockPlayer) event.getPlayer(); From 898c86944f01c83016eecea673ed081f5fcbfd11 Mon Sep 17 00:00:00 2001 From: "Jacob Nardella (Swofty)" Date: Fri, 15 May 2026 11:40:07 +1000 Subject: [PATCH 102/113] refactor(redis): standardize protocol and handler contracts --- .../commons/impl/ServiceProxyRequest.java | 32 --------- .../commons/protocol/ProtocolObject.java | 26 -------- .../commons/protocol/RedisProtocol.java | 54 +++++++++++++++ .../commons/protocol/ServicePushProtocol.java | 21 ------ ...gProtocolObject.java => PingProtocol.java} | 8 +-- ....java => APIAuthenticateCodeProtocol.java} | 6 +- ...bject.java => AuctionAddItemProtocol.java} | 8 +-- ...ect.java => AuctionFetchItemProtocol.java} | 8 +-- ...ct.java => AuctionFetchItemsProtocol.java} | 8 +-- ...ocolObject.java => BazaarBuyProtocol.java} | 6 +- ...lObject.java => BazaarCancelProtocol.java} | 8 +-- ...Object.java => BazaarGetItemProtocol.java} | 8 +-- ...va => BazaarGetPendingOrdersProtocol.java} | 10 +-- ...BazaarGetPendingTransactionsProtocol.java} | 8 +-- ...arProcessPendingTransactionsProtocol.java} | 8 +-- ...colObject.java => BazaarSellProtocol.java} | 8 +-- .../bazaar/BazaarTransactionPushProtocol.java | 4 +- .../darkauction/DarkAuctionEventProtocol.java | 4 +- .../DarkAuctionEventPushProtocol.java | 4 +- .../darkauction/GetAuctionStateProtocol.java | 4 +- .../objects/darkauction/PlaceBidProtocol.java | 4 +- .../PlayerLeftAuctionProtocol.java | 4 +- .../TriggerDarkAuctionProtocol.java | 4 +- .../data/GetPlayerDataPushProtocol.java | 4 +- .../data/LockPlayerDataPushProtocol.java | 4 +- .../data/UnlockPlayerDataPushProtocol.java | 4 +- .../data/UpdatePlayerDataPushProtocol.java | 4 +- ...ject.java => SynchronizeDataProtocol.java} | 8 +-- ...colObject.java => UnlockDataProtocol.java} | 8 +-- ...va => UpdateSynchronizedDataProtocol.java} | 8 +-- ...tocolObject.java => CastVoteProtocol.java} | 8 +-- ...Object.java => GetCandidatesProtocol.java} | 8 +-- ...ject.java => GetElectionDataProtocol.java} | 8 +-- ...Object.java => GetPlayerVoteProtocol.java} | 8 +-- ...ject.java => ResolveElectionProtocol.java} | 8 +-- ...Object.java => StartElectionProtocol.java} | 8 +-- ...colObject.java => AreFriendsProtocol.java} | 8 +-- .../friend/FriendEventPushProtocol.java | 4 +- ...Object.java => GetFriendDataProtocol.java} | 8 +-- ... => GetPendingFriendRequestsProtocol.java} | 8 +-- ... => SendFriendEventToServiceProtocol.java} | 8 +-- .../game/GameInformationPushProtocol.java | 4 +- .../game/InstantiateGamePushProtocol.java | 4 +- .../objects/gui/KickFromGUIPushProtocol.java | 4 +- ....java => TrackedItemRetrieveProtocol.java} | 8 +-- ...ct.java => TrackedItemUpdateProtocol.java} | 8 +-- .../messaging/SendMessagePushProtocol.java | 4 +- ...colObject.java => ChooseGameProtocol.java} | 8 +-- ...Object.java => GameHeartbeatProtocol.java} | 8 +-- ...Object.java => GetGameCountsProtocol.java} | 8 +-- ...otocolObject.java => GetMapsProtocol.java} | 8 +-- ...ject.java => GetServerForMapProtocol.java} | 8 +-- ...colObject.java => RejoinGameProtocol.java} | 8 +-- ...tocolObject.java => GetPartyProtocol.java} | 8 +-- ...ject.java => IsPlayerInPartyProtocol.java} | 8 +-- .../party/PartyBroadcastPushProtocol.java | 4 +- ...ject.java => SendPartyActionProtocol.java} | 8 +-- ...ject.java => GetPresenceBulkProtocol.java} | 8 +-- ...bject.java => UpdatePresenceProtocol.java} | 8 +-- .../from/BroadcastStaffChatProtocol.java | 4 +- .../from/DoesServerHaveIslandProtocol.java | 4 +- .../from/GivePlayersOriginTypeProtocol.java | 4 +- .../proxy/from/PingServerProtocol.java | 4 +- .../proxy/from/PlayerSwitchedProtocol.java | 4 +- .../proxy/from/RefreshCoopDataProtocol.java | 4 +- .../objects/proxy/from/RunEventProtocol.java | 4 +- .../objects/proxy/from/TeleportProtocol.java | 4 +- .../proxy/to/FinishedWithPlayerProtocol.java | 4 +- .../objects/proxy/to/PlayerCountProtocol.java | 4 +- .../proxy/to/PlayerHandlerProtocol.java | 4 +- .../proxy/to/ProxyIsOnlineProtocol.java | 4 +- .../proxy/to/PunishPlayerProtocol.java | 4 +- .../proxy/to/RegisterServerProtocol.java | 4 +- .../proxy/to/RegisterTestFlowProtocol.java | 4 +- .../proxy/to/RequestServerNameProtocol.java | 4 +- .../proxy/to/RequestServersProtocol.java | 4 +- .../objects/proxy/to/StaffChatProtocol.java | 4 +- .../proxy/to/TestFlowServerReadyProtocol.java | 4 +- ....java => GetActivePunishmentProtocol.java} | 8 +-- ....java => PunishPlayerServiceProtocol.java} | 8 +-- ...bject.java => UnpunishPlayerProtocol.java} | 8 +-- .../swofty/commons/redis/RedisChannels.java | 25 +++++++ .../swofty/commons/redis/RedisEndpoint.java | 27 ++++++++ .../commons/redis/RedisEndpointType.java | 7 ++ .../commons/redis/RedisMessageContext.java | 55 ++++++++++++++++ .../commons/redis/RedisMessageHandler.java | 9 +++ ...otocolTest.java => RedisProtocolTest.java} | 4 +- .../main/java/net/swofty/loader/Hypixel.java | 39 ++++++----- .../java/net/swofty/proxyapi/ProxyAPI.java | 54 ++++++++++----- .../net/swofty/proxyapi/ProxyService.java | 14 ++-- .../proxyapi/redis/ServerOutboundMessage.java | 44 ++++++------- .../proxyapi/redis/TypedProxyHandler.java | 8 --- .../proxyapi/redis/TypedServiceHandler.java | 8 --- .../net/swofty/service/api/APIService.java | 6 +- .../endpoints/EndpointAuthenticateCode.java | 24 ++++--- .../service/auction/AuctionService.java | 6 +- .../auction/endpoints/EndpointAddItem.java | 20 +++--- .../auction/endpoints/EndpointFetchItem.java | 20 +++--- .../auction/endpoints/EndpointFetchItems.java | 22 +++---- .../swofty/service/bazaar/BazaarService.java | 6 +- .../endpoints/EndpointBazaarBuyOrder.java | 24 ++++--- .../endpoints/EndpointBazaarSellOrder.java | 26 ++++---- .../endpoints/EndpointCancelBazaarOrder.java | 18 ++--- .../endpoints/EndpointGetBazaarItem.java | 24 ++++--- .../endpoints/EndpointGetPendingOrders.java | 24 ++++--- .../EndpointGetPendingTransactions.java | 22 +++---- .../EndpointProcessPendingTransactions.java | 20 +++--- .../darkauction/DarkAuctionService.java | 6 +- .../endpoints/EndpointGetAuctionState.java | 14 ++-- .../endpoints/EndpointPlaceBid.java | 14 ++-- .../endpoints/EndpointPlayerLeftAuction.java | 14 ++-- .../endpoints/EndpointTriggerAuction.java | 14 ++-- .../service/datamutex/DataMutexService.java | 4 +- .../endpoints/SynchronizeDataEndpoint.java | 32 +++++---- .../endpoints/UnlockDataEndpoint.java | 26 ++++---- .../UpdateSynchronizedDataEndpoint.java | 30 ++++----- .../service/election/ElectionService.java | 6 +- .../election/endpoints/CastVoteEndpoint.java | 36 +++++----- .../endpoints/GetCandidatesEndpoint.java | 38 +++++------ .../endpoints/GetElectionDataEndpoint.java | 30 ++++----- .../endpoints/GetPlayerVoteEndpoint.java | 32 +++++---- .../endpoints/ResolveElectionEndpoint.java | 34 +++++----- .../endpoints/StartElectionEndpoint.java | 30 ++++----- .../swofty/service/friend/FriendService.java | 6 +- .../friend/endpoints/AreFriendsEndpoint.java | 22 +++---- .../FriendEventToServiceEndpoint.java | 24 ++++--- .../endpoints/GetFriendDataEndpoint.java | 22 +++---- .../endpoints/GetPendingRequestsEndpoint.java | 22 +++---- .../friend/endpoints/GetPresenceEndpoint.java | 22 +++---- .../endpoints/UpdatePresenceEndpoint.java | 22 +++---- .../service/generic/ServiceInitializer.java | 33 ++++++---- .../service/generic/SkyBlockService.java | 4 +- .../service/generic/redis/PingEndpoint.java | 21 +++--- .../generic/redis/ServiceEndpoint.java | 9 --- .../generic/redis/ServiceToServerManager.java | 21 +++--- .../itemtracker/ItemTrackerService.java | 6 +- .../endpoints/EndpointGetTrackedItem.java | 20 +++--- .../endpoints/EndpointUpdateItem.java | 20 +++--- .../orchestrator/OrchestratorService.java | 6 +- .../endpoints/GameChooseEndpoint.java | 23 ++++--- .../endpoints/GameHeartbeatEndpoint.java | 23 ++++--- .../endpoints/GetGameCountsEndpoint.java | 22 +++---- .../endpoints/GetMapsEndpoint.java | 22 +++---- .../endpoints/GetServerForMapEndpoint.java | 65 +++++++++--------- .../endpoints/RejoinGameEndpoint.java | 33 +++++----- .../swofty/service/party/PartyService.java | 6 +- .../party/endpoints/GetPartyEndpoint.java | 22 +++---- .../endpoints/IsPlayerInPartyEndpoint.java | 20 +++--- .../party/endpoints/PartyActionEndpoint.java | 18 ++--- .../swofty/service/punishment/ProxyRedis.java | 4 +- .../service/punishment/PunishmentService.java | 6 +- .../GetActivePunishmentEndpoint.java | 24 +++---- .../endpoints/PunishPlayerEndpoint.java | 39 ++++++----- .../endpoints/UnpunishPlayerEndpoint.java | 26 ++++---- .../TypeBackwaterBayouLoader.java | 4 +- .../TypeBedWarsConfiguratorLoader.java | 4 +- .../bedwarsgame/TypeBedWarsGameLoader.java | 17 +++-- .../bedwarsgame/events/ActionPlayerJoin.java | 4 +- ...ndler.java => InstantiateGameHandler.java} | 11 ++-- .../bedwarslobby/TypeBedWarsLobbyLoader.java | 9 ++- .../bedwarslobby/commands/RejoinCommand.java | 14 ++-- .../events/ActionRejoinCheck.java | 8 +-- .../bedwarslobby/gui/GUIMapSelection.java | 8 +-- .../crimsonisle/TypeCrimsonIsleLoader.java | 4 +- .../deepcaverns/TypeDeepCavernsLoader.java | 4 +- .../type/dungeonhub/TypeDungeonHubLoader.java | 4 +- .../dwarvenmines/TypeDwarvenMinesLoader.java | 4 +- .../type/galatea/TypeGalateaLoader.java | 4 +- .../type/generic/HypixelTypeLoader.java | 7 +- .../generic/command/commands/BanCommand.java | 10 +-- .../generic/command/commands/MuteCommand.java | 8 +-- .../command/commands/UnBanCommand.java | 6 +- .../command/commands/UnMuteCommand.java | 6 +- .../event/actions/ActionPlayerMute.java | 6 +- .../type/generic/friend/FriendManager.java | 48 +++++++------- .../type/generic/party/PartyManager.java | 24 +++---- .../generic/presence/PresenceHeartbeat.java | 6 +- .../type/generic/redis/RedisOriginServer.java | 11 ++-- .../swofty/type/generic/redis/RedisPing.java | 11 ++-- .../redis/RedisStaffChatBroadcast.java | 11 ++-- .../type/generic/redis/RedisTeleport.java | 11 ++-- .../redis/RedisTransferredFromThisServer.java | 11 ++-- ...ntHandler.java => FriendEventHandler.java} | 11 ++-- ...ndler.java => GameInformationHandler.java} | 11 ++-- ...UIHandler.java => KickFromGUIHandler.java} | 11 ++-- .../redis/service/PartyBroadcastHandler.java | 11 ++-- ...geHandler.java => SendMessageHandler.java} | 11 ++-- .../type/generic/utility/GameCountCache.java | 6 +- .../type/goldmine/TypeGoldMineLoader.java | 4 +- .../net/swofty/type/hub/TypeHubLoader.java | 4 +- .../swofty/type/island/TypeIslandLoader.java | 4 +- .../TypeJerrysWorkshopLoader.java | 4 +- .../lobby/LobbyOrchestratorConnector.java | 18 ++--- .../TypeMurderMysteryConfiguratorLoader.java | 4 +- .../TypeMurderMysteryGameLoader.java | 17 +++-- .../events/ActionPlayerJoin.java | 4 +- .../item/impl/PlayAgainItem.java | 14 ++-- ...ndler.java => InstantiateGameHandler.java} | 11 ++-- .../TypeMurderMysteryLobbyLoader.java | 9 ++- .../gui/GUIMapSelection.java | 8 +-- .../TypePrototypeLobbyLoader.java | 9 ++- .../TypeRavengardLobbyLoader.java | 4 +- .../bazaar/BazaarConnector.java | 42 ++++++------ .../GetTrackedItemInformationCommand.java | 6 +- .../commands/VerifyApiCommand.java | 6 +- .../data/DataMutexService.java | 22 +++---- .../elections/ElectionCandidate.java | 6 +- .../elections/ElectionManager.java | 66 +++++++++---------- .../auction/GUIAuctionBrowser.java | 8 +-- .../auction/GUIAuctionCreateItem.java | 8 +-- .../auction/GUIAuctionViewItem.java | 8 +-- .../auction/GUIManageAuctions.java | 10 +-- .../gui/inventories/auction/GUIViewBids.java | 10 +-- .../auction/view/AuctionViewThirdBin.java | 12 ++-- .../auction/view/AuctionViewThirdNormal.java | 12 ++-- .../museum/GUIMuseumArmorCategory.java | 14 ++-- .../inventories/museum/GUIMuseumCategory.java | 10 +-- .../museum/GUIMuseumEmptyDisplay.java | 6 +- .../museum/GUIMuseumNonEmptyDisplay.java | 10 +-- .../item/ItemAttributeHandler.java | 8 +-- .../redis/RedisHasIslandLoaded.java | 11 ++-- .../redis/RedisRefreshCoopData.java | 11 ++-- .../skyblockgeneric/redis/RedisRunEvent.java | 11 ++-- ...ler.java => BazaarTransactionHandler.java} | 11 ++-- ...dler.java => DarkAuctionEventHandler.java} | 11 ++-- ...Handler.java => GetPlayerDataHandler.java} | 11 ++-- ...andler.java => LockPlayerDataHandler.java} | 11 ++-- ...dler.java => UnlockPlayerDataHandler.java} | 11 ++-- ...dler.java => UpdatePlayerDataHandler.java} | 11 ++-- .../TypeSkyWarsConfiguratorLoader.java | 4 +- .../skywarsgame/TypeSkywarsGameLoader.java | 13 ++-- .../skywarsgame/events/ActionPlayerJoin.java | 4 +- .../skywarsgame/item/impl/PlayAgainItem.java | 14 ++-- ...ndler.java => InstantiateGameHandler.java} | 11 ++-- .../skywarslobby/TypeSkyWarsLobbyLoader.java | 9 ++- .../gui/GUIMapSelectionSkywars.java | 8 +-- .../type/spidersden/TypeSpidersDenLoader.java | 4 +- .../swofty/type/theend/TypeTheEndLoader.java | 4 +- .../TypeTheFarmingIslandsLoader.java | 4 +- .../type/thepark/TypeTheParkLoader.java | 4 +- .../net/swofty/velocity/SkyBlockVelocity.java | 20 +++--- .../velocity/presence/PresencePublisher.java | 6 +- .../swofty/velocity/redis/RedisListener.java | 11 ++-- .../swofty/velocity/redis/RedisMessage.java | 11 ++-- .../redis/listeners/ListenerPlayerCount.java | 4 +- .../listeners/ListenerPlayerHandler.java | 4 +- .../listeners/ListenerPlayerPunished.java | 4 +- .../redis/listeners/ListenerProxyOnline.java | 4 +- .../listeners/ListenerRegisterTestFlow.java | 4 +- .../ListenerServerFinishedWithPlayer.java | 4 +- .../listeners/ListenerServerInitialized.java | 4 +- .../redis/listeners/ListenerServerName.java | 4 +- .../listeners/ListenerServersInformation.java | 4 +- .../redis/listeners/ListenerStaffChat.java | 4 +- .../ListenerTestFlowServerReady.java | 4 +- 255 files changed, 1594 insertions(+), 1542 deletions(-) delete mode 100644 commons/src/main/java/net/swofty/commons/impl/ServiceProxyRequest.java delete mode 100644 commons/src/main/java/net/swofty/commons/protocol/ProtocolObject.java create mode 100644 commons/src/main/java/net/swofty/commons/protocol/RedisProtocol.java delete mode 100644 commons/src/main/java/net/swofty/commons/protocol/ServicePushProtocol.java rename commons/src/main/java/net/swofty/commons/protocol/objects/{PingProtocolObject.java => PingProtocol.java} (77%) rename commons/src/main/java/net/swofty/commons/protocol/objects/api/{APIAuthenticateCodeProtocolObject.java => APIAuthenticateCodeProtocol.java} (79%) rename commons/src/main/java/net/swofty/commons/protocol/objects/auctions/{AuctionAddItemProtocolObject.java => AuctionAddItemProtocol.java} (81%) rename commons/src/main/java/net/swofty/commons/protocol/objects/auctions/{AuctionFetchItemProtocolObject.java => AuctionFetchItemProtocol.java} (79%) rename commons/src/main/java/net/swofty/commons/protocol/objects/auctions/{AuctionFetchItemsProtocolObject.java => AuctionFetchItemsProtocol.java} (83%) rename commons/src/main/java/net/swofty/commons/protocol/objects/bazaar/{BazaarBuyProtocolObject.java => BazaarBuyProtocol.java} (81%) rename commons/src/main/java/net/swofty/commons/protocol/objects/bazaar/{BazaarCancelProtocolObject.java => BazaarCancelProtocol.java} (79%) rename commons/src/main/java/net/swofty/commons/protocol/objects/bazaar/{BazaarGetItemProtocolObject.java => BazaarGetItemProtocol.java} (83%) rename commons/src/main/java/net/swofty/commons/protocol/objects/bazaar/{BazaarGetPendingOrdersProtocolObject.java => BazaarGetPendingOrdersProtocol.java} (81%) rename commons/src/main/java/net/swofty/commons/protocol/objects/bazaar/{BazaarGetPendingTransactionsProtocolObject.java => BazaarGetPendingTransactionsProtocol.java} (81%) rename commons/src/main/java/net/swofty/commons/protocol/objects/bazaar/{BazaarProcessPendingTransactionsProtocolObject.java => BazaarProcessPendingTransactionsProtocol.java} (78%) rename commons/src/main/java/net/swofty/commons/protocol/objects/bazaar/{BazaarSellProtocolObject.java => BazaarSellProtocol.java} (80%) rename commons/src/main/java/net/swofty/commons/protocol/objects/datamutex/{SynchronizeDataProtocolObject.java => SynchronizeDataProtocol.java} (81%) rename commons/src/main/java/net/swofty/commons/protocol/objects/datamutex/{UnlockDataProtocolObject.java => UnlockDataProtocol.java} (81%) rename commons/src/main/java/net/swofty/commons/protocol/objects/datamutex/{UpdateSynchronizedDataProtocolObject.java => UpdateSynchronizedDataProtocol.java} (80%) rename commons/src/main/java/net/swofty/commons/protocol/objects/election/{CastVoteProtocolObject.java => CastVoteProtocol.java} (81%) rename commons/src/main/java/net/swofty/commons/protocol/objects/election/{GetCandidatesProtocolObject.java => GetCandidatesProtocol.java} (83%) rename commons/src/main/java/net/swofty/commons/protocol/objects/election/{GetElectionDataProtocolObject.java => GetElectionDataProtocol.java} (79%) rename commons/src/main/java/net/swofty/commons/protocol/objects/election/{GetPlayerVoteProtocolObject.java => GetPlayerVoteProtocol.java} (79%) rename commons/src/main/java/net/swofty/commons/protocol/objects/election/{ResolveElectionProtocolObject.java => ResolveElectionProtocol.java} (78%) rename commons/src/main/java/net/swofty/commons/protocol/objects/election/{StartElectionProtocolObject.java => StartElectionProtocol.java} (79%) rename commons/src/main/java/net/swofty/commons/protocol/objects/friend/{AreFriendsProtocolObject.java => AreFriendsProtocol.java} (79%) rename commons/src/main/java/net/swofty/commons/protocol/objects/friend/{GetFriendDataProtocolObject.java => GetFriendDataProtocol.java} (79%) rename commons/src/main/java/net/swofty/commons/protocol/objects/friend/{GetPendingFriendRequestsProtocolObject.java => GetPendingFriendRequestsProtocol.java} (78%) rename commons/src/main/java/net/swofty/commons/protocol/objects/friend/{SendFriendEventToServiceProtocolObject.java => SendFriendEventToServiceProtocol.java} (77%) rename commons/src/main/java/net/swofty/commons/protocol/objects/itemtracker/{TrackedItemRetrieveProtocolObject.java => TrackedItemRetrieveProtocol.java} (81%) rename commons/src/main/java/net/swofty/commons/protocol/objects/itemtracker/{TrackedItemUpdateProtocolObject.java => TrackedItemUpdateProtocol.java} (79%) rename commons/src/main/java/net/swofty/commons/protocol/objects/orchestrator/{ChooseGameProtocolObject.java => ChooseGameProtocol.java} (81%) rename commons/src/main/java/net/swofty/commons/protocol/objects/orchestrator/{GameHeartbeatProtocolObject.java => GameHeartbeatProtocol.java} (81%) rename commons/src/main/java/net/swofty/commons/protocol/objects/orchestrator/{GetGameCountsProtocolObject.java => GetGameCountsProtocol.java} (80%) rename commons/src/main/java/net/swofty/commons/protocol/objects/orchestrator/{GetMapsProtocolObject.java => GetMapsProtocol.java} (81%) rename commons/src/main/java/net/swofty/commons/protocol/objects/orchestrator/{GetServerForMapProtocolObject.java => GetServerForMapProtocol.java} (81%) rename commons/src/main/java/net/swofty/commons/protocol/objects/orchestrator/{RejoinGameProtocolObject.java => RejoinGameProtocol.java} (84%) rename commons/src/main/java/net/swofty/commons/protocol/objects/party/{GetPartyProtocolObject.java => GetPartyProtocol.java} (80%) rename commons/src/main/java/net/swofty/commons/protocol/objects/party/{IsPlayerInPartyProtocolObject.java => IsPlayerInPartyProtocol.java} (78%) rename commons/src/main/java/net/swofty/commons/protocol/objects/party/{SendPartyActionProtocolObject.java => SendPartyActionProtocol.java} (82%) rename commons/src/main/java/net/swofty/commons/protocol/objects/presence/{GetPresenceBulkProtocolObject.java => GetPresenceBulkProtocol.java} (80%) rename commons/src/main/java/net/swofty/commons/protocol/objects/presence/{UpdatePresenceProtocolObject.java => UpdatePresenceProtocol.java} (79%) rename commons/src/main/java/net/swofty/commons/protocol/objects/punishment/{GetActivePunishmentProtocolObject.java => GetActivePunishmentProtocol.java} (84%) rename commons/src/main/java/net/swofty/commons/protocol/objects/punishment/{PunishPlayerProtocolObject.java => PunishPlayerServiceProtocol.java} (87%) rename commons/src/main/java/net/swofty/commons/protocol/objects/punishment/{UnpunishPlayerProtocolObject.java => UnpunishPlayerProtocol.java} (81%) create mode 100644 commons/src/main/java/net/swofty/commons/redis/RedisChannels.java create mode 100644 commons/src/main/java/net/swofty/commons/redis/RedisEndpoint.java create mode 100644 commons/src/main/java/net/swofty/commons/redis/RedisEndpointType.java create mode 100644 commons/src/main/java/net/swofty/commons/redis/RedisMessageContext.java create mode 100644 commons/src/main/java/net/swofty/commons/redis/RedisMessageHandler.java rename commons/src/test/java/net/swofty/commons/protocol/{ServicePushProtocolTest.java => RedisProtocolTest.java} (91%) delete mode 100644 proxy.api/src/main/java/net/swofty/proxyapi/redis/TypedProxyHandler.java delete mode 100644 proxy.api/src/main/java/net/swofty/proxyapi/redis/TypedServiceHandler.java delete mode 100644 service.generic/src/main/java/net/swofty/service/generic/redis/ServiceEndpoint.java rename type.bedwarsgame/src/main/java/net/swofty/type/bedwarsgame/redis/service/{TypedInstantiateGameHandler.java => InstantiateGameHandler.java} (85%) rename type.generic/src/main/java/net/swofty/type/generic/redis/service/{TypedFriendEventHandler.java => FriendEventHandler.java} (97%) rename type.generic/src/main/java/net/swofty/type/generic/redis/service/{TypedGameInformationHandler.java => GameInformationHandler.java} (64%) rename type.generic/src/main/java/net/swofty/type/generic/redis/service/{TypedKickFromGUIHandler.java => KickFromGUIHandler.java} (80%) rename type.generic/src/main/java/net/swofty/type/generic/redis/service/{TypedSendMessageHandler.java => SendMessageHandler.java} (75%) rename type.murdermysterygame/src/main/java/net/swofty/type/murdermysterygame/redis/service/{TypedInstantiateGameHandler.java => InstantiateGameHandler.java} (85%) rename type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/redis/service/{TypedBazaarTransactionHandler.java => BazaarTransactionHandler.java} (93%) rename type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/redis/service/{TypedDarkAuctionEventHandler.java => DarkAuctionEventHandler.java} (89%) rename type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/redis/service/{TypedGetPlayerDataHandler.java => GetPlayerDataHandler.java} (80%) rename type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/redis/service/{TypedLockPlayerDataHandler.java => LockPlayerDataHandler.java} (75%) rename type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/redis/service/{TypedUnlockPlayerDataHandler.java => UnlockPlayerDataHandler.java} (66%) rename type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/redis/service/{TypedUpdatePlayerDataHandler.java => UpdatePlayerDataHandler.java} (82%) rename type.skywarsgame/src/main/java/net/swofty/type/skywarsgame/redis/service/{TypedInstantiateGameHandler.java => InstantiateGameHandler.java} (88%) diff --git a/commons/src/main/java/net/swofty/commons/impl/ServiceProxyRequest.java b/commons/src/main/java/net/swofty/commons/impl/ServiceProxyRequest.java deleted file mode 100644 index 5db536e68..000000000 --- a/commons/src/main/java/net/swofty/commons/impl/ServiceProxyRequest.java +++ /dev/null @@ -1,32 +0,0 @@ -package net.swofty.commons.impl; - -import org.json.JSONObject; - -import java.util.UUID; - -public record ServiceProxyRequest(UUID requestId, String requestServer, String endpoint, String message) { - - public JSONObject toJSON() { - return new JSONObject() - .put("requestId", requestId.toString()) - .put("requestServer", requestServer) - .put("endpoint", endpoint) - .put("message", message); - } - - public static ServiceProxyRequest fromJSON(JSONObject json) { - return new ServiceProxyRequest( - UUID.fromString(json.getString("requestId")), - json.getString("requestServer"), - json.getString("endpoint"), - json.getString("message") - ); - } - - // Compatibility accessors so existing call sites that used Lombok-generated - // getters keep compiling — records expose component(), not getComponent(). - public UUID getRequestId() { return requestId; } - public String getRequestServer() { return requestServer; } - public String getEndpoint() { return endpoint; } - public String getMessage() { return message; } -} diff --git a/commons/src/main/java/net/swofty/commons/protocol/ProtocolObject.java b/commons/src/main/java/net/swofty/commons/protocol/ProtocolObject.java deleted file mode 100644 index b60d56f6b..000000000 --- a/commons/src/main/java/net/swofty/commons/protocol/ProtocolObject.java +++ /dev/null @@ -1,26 +0,0 @@ -package net.swofty.commons.protocol; - -public abstract class ProtocolObject { - public abstract Serializer getSerializer(); - public abstract Serializer getReturnSerializer(); - - public String translateToString(T message) { - return getSerializer().serialize(message); - } - - public String translateReturnToString(R message) { - return getReturnSerializer().serialize(message); - } - - public T translateFromString(String string) { - return getSerializer().deserialize(string); - } - - public R translateReturnFromString(String string) { - return getReturnSerializer().deserialize(string); - } - - public String channel() { - return getClass().getSimpleName(); - } -} diff --git a/commons/src/main/java/net/swofty/commons/protocol/RedisProtocol.java b/commons/src/main/java/net/swofty/commons/protocol/RedisProtocol.java new file mode 100644 index 000000000..b5c760173 --- /dev/null +++ b/commons/src/main/java/net/swofty/commons/protocol/RedisProtocol.java @@ -0,0 +1,54 @@ +package net.swofty.commons.protocol; + +public abstract class RedisProtocol { + private final Serializer serializer; + private final Serializer returnSerializer; + + protected RedisProtocol() { + this.serializer = null; + this.returnSerializer = null; + } + + protected RedisProtocol(Class requestType, Class responseType) { + this(new JacksonSerializer<>(requestType), new JacksonSerializer<>(responseType)); + } + + protected RedisProtocol(Serializer serializer, Serializer returnSerializer) { + this.serializer = serializer; + this.returnSerializer = returnSerializer; + } + + public Serializer getSerializer() { + if (serializer == null) { + throw new UnsupportedOperationException("Protocol must provide a request serializer"); + } + return serializer; + } + + public Serializer getReturnSerializer() { + if (returnSerializer == null) { + throw new UnsupportedOperationException("Protocol must provide a response serializer"); + } + return returnSerializer; + } + + public String translateToString(T message) { + return getSerializer().serialize(message); + } + + public String translateReturnToString(R message) { + return getReturnSerializer().serialize(message); + } + + public T translateFromString(String string) { + return getSerializer().deserialize(string); + } + + public R translateReturnFromString(String string) { + return getReturnSerializer().deserialize(string); + } + + public String channel() { + return getClass().getSimpleName(); + } +} diff --git a/commons/src/main/java/net/swofty/commons/protocol/ServicePushProtocol.java b/commons/src/main/java/net/swofty/commons/protocol/ServicePushProtocol.java deleted file mode 100644 index 3cc25f164..000000000 --- a/commons/src/main/java/net/swofty/commons/protocol/ServicePushProtocol.java +++ /dev/null @@ -1,21 +0,0 @@ -package net.swofty.commons.protocol; - -public abstract class ServicePushProtocol extends ProtocolObject { - private final JacksonSerializer requestSerializer; - private final JacksonSerializer responseSerializer; - - protected ServicePushProtocol(Class requestType, Class responseType) { - this.requestSerializer = new JacksonSerializer<>(requestType); - this.responseSerializer = new JacksonSerializer<>(responseType); - } - - @Override - public Serializer getSerializer() { - return requestSerializer; - } - - @Override - public Serializer getReturnSerializer() { - return responseSerializer; - } -} diff --git a/commons/src/main/java/net/swofty/commons/protocol/objects/PingProtocolObject.java b/commons/src/main/java/net/swofty/commons/protocol/objects/PingProtocol.java similarity index 77% rename from commons/src/main/java/net/swofty/commons/protocol/objects/PingProtocolObject.java rename to commons/src/main/java/net/swofty/commons/protocol/objects/PingProtocol.java index 968108879..1ea376f24 100644 --- a/commons/src/main/java/net/swofty/commons/protocol/objects/PingProtocolObject.java +++ b/commons/src/main/java/net/swofty/commons/protocol/objects/PingProtocol.java @@ -1,12 +1,12 @@ package net.swofty.commons.protocol.objects; import net.swofty.commons.protocol.JacksonSerializer; -import net.swofty.commons.protocol.ProtocolObject; +import net.swofty.commons.protocol.RedisProtocol; import net.swofty.commons.protocol.Serializer; -public class PingProtocolObject extends ProtocolObject< - PingProtocolObject.EmptyMessage, - PingProtocolObject.EmptyMessage> { +public class PingProtocol extends RedisProtocol< + PingProtocol.EmptyMessage, + PingProtocol.EmptyMessage> { private static final Serializer SERIALIZER = new JacksonSerializer<>(EmptyMessage.class); private static final Serializer RETURN_SERIALIZER = diff --git a/commons/src/main/java/net/swofty/commons/protocol/objects/api/APIAuthenticateCodeProtocolObject.java b/commons/src/main/java/net/swofty/commons/protocol/objects/api/APIAuthenticateCodeProtocol.java similarity index 79% rename from commons/src/main/java/net/swofty/commons/protocol/objects/api/APIAuthenticateCodeProtocolObject.java rename to commons/src/main/java/net/swofty/commons/protocol/objects/api/APIAuthenticateCodeProtocol.java index 0d6b5c073..8f06f5a3c 100644 --- a/commons/src/main/java/net/swofty/commons/protocol/objects/api/APIAuthenticateCodeProtocolObject.java +++ b/commons/src/main/java/net/swofty/commons/protocol/objects/api/APIAuthenticateCodeProtocol.java @@ -1,14 +1,14 @@ package net.swofty.commons.protocol.objects.api; import net.swofty.commons.protocol.JacksonSerializer; -import net.swofty.commons.protocol.ProtocolObject; +import net.swofty.commons.protocol.RedisProtocol; import net.swofty.commons.protocol.Serializer; import org.jetbrains.annotations.Nullable; import java.util.UUID; -public class APIAuthenticateCodeProtocolObject extends ProtocolObject - { +public class APIAuthenticateCodeProtocol extends RedisProtocol + { private static final Serializer SERIALIZER = new JacksonSerializer<>(AuthenticateCodeMessage.class); private static final Serializer RETURN_SERIALIZER = diff --git a/commons/src/main/java/net/swofty/commons/protocol/objects/auctions/AuctionAddItemProtocolObject.java b/commons/src/main/java/net/swofty/commons/protocol/objects/auctions/AuctionAddItemProtocol.java similarity index 81% rename from commons/src/main/java/net/swofty/commons/protocol/objects/auctions/AuctionAddItemProtocolObject.java rename to commons/src/main/java/net/swofty/commons/protocol/objects/auctions/AuctionAddItemProtocol.java index 6ce3bc468..6ad26f5d9 100644 --- a/commons/src/main/java/net/swofty/commons/protocol/objects/auctions/AuctionAddItemProtocolObject.java +++ b/commons/src/main/java/net/swofty/commons/protocol/objects/auctions/AuctionAddItemProtocol.java @@ -3,15 +3,15 @@ import net.swofty.commons.protocol.JacksonSerializer; import net.swofty.commons.skyblock.auctions.AuctionCategories; import net.swofty.commons.skyblock.auctions.AuctionItem; -import net.swofty.commons.protocol.ProtocolObject; +import net.swofty.commons.protocol.RedisProtocol; import net.swofty.commons.protocol.Serializer; import java.util.UUID; import org.jetbrains.annotations.Nullable; -public class AuctionAddItemProtocolObject extends ProtocolObject - { +public class AuctionAddItemProtocol extends RedisProtocol + { private static final Serializer SERIALIZER = new JacksonSerializer<>(AuctionAddItemMessage.class); private static final Serializer RETURN_SERIALIZER = diff --git a/commons/src/main/java/net/swofty/commons/protocol/objects/auctions/AuctionFetchItemProtocolObject.java b/commons/src/main/java/net/swofty/commons/protocol/objects/auctions/AuctionFetchItemProtocol.java similarity index 79% rename from commons/src/main/java/net/swofty/commons/protocol/objects/auctions/AuctionFetchItemProtocolObject.java rename to commons/src/main/java/net/swofty/commons/protocol/objects/auctions/AuctionFetchItemProtocol.java index 61e99acbf..3529a3af2 100644 --- a/commons/src/main/java/net/swofty/commons/protocol/objects/auctions/AuctionFetchItemProtocolObject.java +++ b/commons/src/main/java/net/swofty/commons/protocol/objects/auctions/AuctionFetchItemProtocol.java @@ -2,15 +2,15 @@ import net.swofty.commons.protocol.JacksonSerializer; import net.swofty.commons.skyblock.auctions.AuctionItem; -import net.swofty.commons.protocol.ProtocolObject; +import net.swofty.commons.protocol.RedisProtocol; import net.swofty.commons.protocol.Serializer; import java.util.UUID; import org.jetbrains.annotations.Nullable; -public class AuctionFetchItemProtocolObject extends ProtocolObject< - AuctionFetchItemProtocolObject.AuctionFetchItemMessage, - AuctionFetchItemProtocolObject.AuctionFetchItemResponse> { +public class AuctionFetchItemProtocol extends RedisProtocol< + AuctionFetchItemProtocol.AuctionFetchItemMessage, + AuctionFetchItemProtocol.AuctionFetchItemResponse> { private static final Serializer SERIALIZER = new JacksonSerializer<>(AuctionFetchItemMessage.class); private static final Serializer RETURN_SERIALIZER = diff --git a/commons/src/main/java/net/swofty/commons/protocol/objects/auctions/AuctionFetchItemsProtocolObject.java b/commons/src/main/java/net/swofty/commons/protocol/objects/auctions/AuctionFetchItemsProtocol.java similarity index 83% rename from commons/src/main/java/net/swofty/commons/protocol/objects/auctions/AuctionFetchItemsProtocolObject.java rename to commons/src/main/java/net/swofty/commons/protocol/objects/auctions/AuctionFetchItemsProtocol.java index 95593a691..b5b43f18b 100644 --- a/commons/src/main/java/net/swofty/commons/protocol/objects/auctions/AuctionFetchItemsProtocolObject.java +++ b/commons/src/main/java/net/swofty/commons/protocol/objects/auctions/AuctionFetchItemsProtocol.java @@ -4,16 +4,16 @@ import net.swofty.commons.skyblock.auctions.AuctionCategories; import net.swofty.commons.skyblock.auctions.AuctionsFilter; import net.swofty.commons.skyblock.auctions.AuctionsSorting; -import net.swofty.commons.protocol.ProtocolObject; +import net.swofty.commons.protocol.RedisProtocol; import net.swofty.commons.protocol.Serializer; import net.swofty.commons.skyblock.auctions.AuctionItem; import java.util.List; import org.jetbrains.annotations.Nullable; -public class AuctionFetchItemsProtocolObject extends ProtocolObject< - AuctionFetchItemsProtocolObject.AuctionFetchItemsMessage, - AuctionFetchItemsProtocolObject.AuctionFetchItemsResponse> { +public class AuctionFetchItemsProtocol extends RedisProtocol< + AuctionFetchItemsProtocol.AuctionFetchItemsMessage, + AuctionFetchItemsProtocol.AuctionFetchItemsResponse> { private static final Serializer SERIALIZER = new JacksonSerializer<>(AuctionFetchItemsMessage.class); private static final Serializer RETURN_SERIALIZER = diff --git a/commons/src/main/java/net/swofty/commons/protocol/objects/bazaar/BazaarBuyProtocolObject.java b/commons/src/main/java/net/swofty/commons/protocol/objects/bazaar/BazaarBuyProtocol.java similarity index 81% rename from commons/src/main/java/net/swofty/commons/protocol/objects/bazaar/BazaarBuyProtocolObject.java rename to commons/src/main/java/net/swofty/commons/protocol/objects/bazaar/BazaarBuyProtocol.java index ed044f548..c026fc4d9 100644 --- a/commons/src/main/java/net/swofty/commons/protocol/objects/bazaar/BazaarBuyProtocolObject.java +++ b/commons/src/main/java/net/swofty/commons/protocol/objects/bazaar/BazaarBuyProtocol.java @@ -1,14 +1,14 @@ package net.swofty.commons.protocol.objects.bazaar; import net.swofty.commons.protocol.JacksonSerializer; -import net.swofty.commons.protocol.ProtocolObject; +import net.swofty.commons.protocol.RedisProtocol; import net.swofty.commons.protocol.Serializer; import org.jetbrains.annotations.Nullable; import java.util.UUID; -public class BazaarBuyProtocolObject extends ProtocolObject - { +public class BazaarBuyProtocol extends RedisProtocol + { private static final Serializer SERIALIZER = new JacksonSerializer<>(BazaarBuyMessage.class); private static final Serializer RETURN_SERIALIZER = diff --git a/commons/src/main/java/net/swofty/commons/protocol/objects/bazaar/BazaarCancelProtocolObject.java b/commons/src/main/java/net/swofty/commons/protocol/objects/bazaar/BazaarCancelProtocol.java similarity index 79% rename from commons/src/main/java/net/swofty/commons/protocol/objects/bazaar/BazaarCancelProtocolObject.java rename to commons/src/main/java/net/swofty/commons/protocol/objects/bazaar/BazaarCancelProtocol.java index 3a514efa0..d73cbad6c 100644 --- a/commons/src/main/java/net/swofty/commons/protocol/objects/bazaar/BazaarCancelProtocolObject.java +++ b/commons/src/main/java/net/swofty/commons/protocol/objects/bazaar/BazaarCancelProtocol.java @@ -1,15 +1,15 @@ package net.swofty.commons.protocol.objects.bazaar; import net.swofty.commons.protocol.JacksonSerializer; -import net.swofty.commons.protocol.ProtocolObject; +import net.swofty.commons.protocol.RedisProtocol; import net.swofty.commons.protocol.Serializer; import org.jetbrains.annotations.Nullable; import java.util.UUID; -public class BazaarCancelProtocolObject extends ProtocolObject< - BazaarCancelProtocolObject.CancelMessage, - BazaarCancelProtocolObject.CancelResponse> { +public class BazaarCancelProtocol extends RedisProtocol< + BazaarCancelProtocol.CancelMessage, + BazaarCancelProtocol.CancelResponse> { private static final Serializer SERIALIZER = new JacksonSerializer<>(CancelMessage.class); private static final Serializer RETURN_SERIALIZER = diff --git a/commons/src/main/java/net/swofty/commons/protocol/objects/bazaar/BazaarGetItemProtocolObject.java b/commons/src/main/java/net/swofty/commons/protocol/objects/bazaar/BazaarGetItemProtocol.java similarity index 83% rename from commons/src/main/java/net/swofty/commons/protocol/objects/bazaar/BazaarGetItemProtocolObject.java rename to commons/src/main/java/net/swofty/commons/protocol/objects/bazaar/BazaarGetItemProtocol.java index 03b0964a2..65a38d7b9 100644 --- a/commons/src/main/java/net/swofty/commons/protocol/objects/bazaar/BazaarGetItemProtocolObject.java +++ b/commons/src/main/java/net/swofty/commons/protocol/objects/bazaar/BazaarGetItemProtocol.java @@ -1,16 +1,16 @@ package net.swofty.commons.protocol.objects.bazaar; import net.swofty.commons.protocol.JacksonSerializer; -import net.swofty.commons.protocol.ProtocolObject; +import net.swofty.commons.protocol.RedisProtocol; import net.swofty.commons.protocol.Serializer; import java.util.List; import java.util.UUID; import org.jetbrains.annotations.Nullable; -public class BazaarGetItemProtocolObject extends ProtocolObject< - BazaarGetItemProtocolObject.BazaarGetItemMessage, - BazaarGetItemProtocolObject.BazaarGetItemResponse> { +public class BazaarGetItemProtocol extends RedisProtocol< + BazaarGetItemProtocol.BazaarGetItemMessage, + BazaarGetItemProtocol.BazaarGetItemResponse> { private static final Serializer SERIALIZER = new JacksonSerializer<>(BazaarGetItemMessage.class); private static final Serializer RETURN_SERIALIZER = diff --git a/commons/src/main/java/net/swofty/commons/protocol/objects/bazaar/BazaarGetPendingOrdersProtocolObject.java b/commons/src/main/java/net/swofty/commons/protocol/objects/bazaar/BazaarGetPendingOrdersProtocol.java similarity index 81% rename from commons/src/main/java/net/swofty/commons/protocol/objects/bazaar/BazaarGetPendingOrdersProtocolObject.java rename to commons/src/main/java/net/swofty/commons/protocol/objects/bazaar/BazaarGetPendingOrdersProtocol.java index 74113dda2..af4070fbc 100644 --- a/commons/src/main/java/net/swofty/commons/protocol/objects/bazaar/BazaarGetPendingOrdersProtocolObject.java +++ b/commons/src/main/java/net/swofty/commons/protocol/objects/bazaar/BazaarGetPendingOrdersProtocol.java @@ -1,17 +1,17 @@ package net.swofty.commons.protocol.objects.bazaar; import net.swofty.commons.protocol.JacksonSerializer; -import net.swofty.commons.protocol.ProtocolObject; +import net.swofty.commons.protocol.RedisProtocol; import net.swofty.commons.protocol.Serializer; import java.util.List; import java.util.UUID; import org.jetbrains.annotations.Nullable; -public class BazaarGetPendingOrdersProtocolObject - extends ProtocolObject< - BazaarGetPendingOrdersProtocolObject.BazaarGetPendingOrdersMessage, - BazaarGetPendingOrdersProtocolObject.BazaarGetPendingOrdersResponse> { +public class BazaarGetPendingOrdersProtocol + extends RedisProtocol< + BazaarGetPendingOrdersProtocol.BazaarGetPendingOrdersMessage, + BazaarGetPendingOrdersProtocol.BazaarGetPendingOrdersResponse> { private static final Serializer SERIALIZER = new JacksonSerializer<>(BazaarGetPendingOrdersMessage.class); private static final Serializer RETURN_SERIALIZER = diff --git a/commons/src/main/java/net/swofty/commons/protocol/objects/bazaar/BazaarGetPendingTransactionsProtocolObject.java b/commons/src/main/java/net/swofty/commons/protocol/objects/bazaar/BazaarGetPendingTransactionsProtocol.java similarity index 81% rename from commons/src/main/java/net/swofty/commons/protocol/objects/bazaar/BazaarGetPendingTransactionsProtocolObject.java rename to commons/src/main/java/net/swofty/commons/protocol/objects/bazaar/BazaarGetPendingTransactionsProtocol.java index b2faa28e4..3a39ab1dd 100644 --- a/commons/src/main/java/net/swofty/commons/protocol/objects/bazaar/BazaarGetPendingTransactionsProtocolObject.java +++ b/commons/src/main/java/net/swofty/commons/protocol/objects/bazaar/BazaarGetPendingTransactionsProtocol.java @@ -1,7 +1,7 @@ package net.swofty.commons.protocol.objects.bazaar; import net.swofty.commons.protocol.JacksonSerializer; -import net.swofty.commons.protocol.ProtocolObject; +import net.swofty.commons.protocol.RedisProtocol; import net.swofty.commons.protocol.Serializer; import java.time.Instant; @@ -10,9 +10,9 @@ import java.util.UUID; import org.jetbrains.annotations.Nullable; -public class BazaarGetPendingTransactionsProtocolObject extends ProtocolObject< - BazaarGetPendingTransactionsProtocolObject.BazaarGetPendingTransactionsMessage, - BazaarGetPendingTransactionsProtocolObject.BazaarGetPendingTransactionsResponse> { +public class BazaarGetPendingTransactionsProtocol extends RedisProtocol< + BazaarGetPendingTransactionsProtocol.BazaarGetPendingTransactionsMessage, + BazaarGetPendingTransactionsProtocol.BazaarGetPendingTransactionsResponse> { private static final Serializer SERIALIZER = new JacksonSerializer<>(BazaarGetPendingTransactionsMessage.class); private static final Serializer RETURN_SERIALIZER = diff --git a/commons/src/main/java/net/swofty/commons/protocol/objects/bazaar/BazaarProcessPendingTransactionsProtocolObject.java b/commons/src/main/java/net/swofty/commons/protocol/objects/bazaar/BazaarProcessPendingTransactionsProtocol.java similarity index 78% rename from commons/src/main/java/net/swofty/commons/protocol/objects/bazaar/BazaarProcessPendingTransactionsProtocolObject.java rename to commons/src/main/java/net/swofty/commons/protocol/objects/bazaar/BazaarProcessPendingTransactionsProtocol.java index 26f686970..74a55c440 100644 --- a/commons/src/main/java/net/swofty/commons/protocol/objects/bazaar/BazaarProcessPendingTransactionsProtocolObject.java +++ b/commons/src/main/java/net/swofty/commons/protocol/objects/bazaar/BazaarProcessPendingTransactionsProtocol.java @@ -1,16 +1,16 @@ package net.swofty.commons.protocol.objects.bazaar; import net.swofty.commons.protocol.JacksonSerializer; -import net.swofty.commons.protocol.ProtocolObject; +import net.swofty.commons.protocol.RedisProtocol; import net.swofty.commons.protocol.Serializer; import java.util.List; import java.util.UUID; import org.jetbrains.annotations.Nullable; -public class BazaarProcessPendingTransactionsProtocolObject extends ProtocolObject< - BazaarProcessPendingTransactionsProtocolObject.BazaarProcessPendingTransactionsMessage, - BazaarProcessPendingTransactionsProtocolObject.BazaarProcessPendingTransactionsResponse> { +public class BazaarProcessPendingTransactionsProtocol extends RedisProtocol< + BazaarProcessPendingTransactionsProtocol.BazaarProcessPendingTransactionsMessage, + BazaarProcessPendingTransactionsProtocol.BazaarProcessPendingTransactionsResponse> { private static final Serializer SERIALIZER = new JacksonSerializer<>(BazaarProcessPendingTransactionsMessage.class); private static final Serializer RETURN_SERIALIZER = diff --git a/commons/src/main/java/net/swofty/commons/protocol/objects/bazaar/BazaarSellProtocolObject.java b/commons/src/main/java/net/swofty/commons/protocol/objects/bazaar/BazaarSellProtocol.java similarity index 80% rename from commons/src/main/java/net/swofty/commons/protocol/objects/bazaar/BazaarSellProtocolObject.java rename to commons/src/main/java/net/swofty/commons/protocol/objects/bazaar/BazaarSellProtocol.java index 4f4485aeb..132cb0ed8 100644 --- a/commons/src/main/java/net/swofty/commons/protocol/objects/bazaar/BazaarSellProtocolObject.java +++ b/commons/src/main/java/net/swofty/commons/protocol/objects/bazaar/BazaarSellProtocol.java @@ -1,15 +1,15 @@ package net.swofty.commons.protocol.objects.bazaar; import net.swofty.commons.protocol.JacksonSerializer; -import net.swofty.commons.protocol.ProtocolObject; +import net.swofty.commons.protocol.RedisProtocol; import net.swofty.commons.protocol.Serializer; import org.jetbrains.annotations.Nullable; import java.util.UUID; -public class BazaarSellProtocolObject extends ProtocolObject< - BazaarSellProtocolObject.BazaarSellMessage, - BazaarSellProtocolObject.BazaarSellResponse> { +public class BazaarSellProtocol extends RedisProtocol< + BazaarSellProtocol.BazaarSellMessage, + BazaarSellProtocol.BazaarSellResponse> { private static final Serializer SERIALIZER = new JacksonSerializer<>(BazaarSellMessage.class); private static final Serializer RETURN_SERIALIZER = diff --git a/commons/src/main/java/net/swofty/commons/protocol/objects/bazaar/BazaarTransactionPushProtocol.java b/commons/src/main/java/net/swofty/commons/protocol/objects/bazaar/BazaarTransactionPushProtocol.java index 311ba02fb..793f6e1d4 100644 --- a/commons/src/main/java/net/swofty/commons/protocol/objects/bazaar/BazaarTransactionPushProtocol.java +++ b/commons/src/main/java/net/swofty/commons/protocol/objects/bazaar/BazaarTransactionPushProtocol.java @@ -1,10 +1,10 @@ package net.swofty.commons.protocol.objects.bazaar; -import net.swofty.commons.protocol.ServicePushProtocol; +import net.swofty.commons.protocol.RedisProtocol; import org.jetbrains.annotations.Nullable; public class BazaarTransactionPushProtocol - extends ServicePushProtocol { + extends RedisProtocol { public BazaarTransactionPushProtocol() { super(Request.class, Response.class); diff --git a/commons/src/main/java/net/swofty/commons/protocol/objects/darkauction/DarkAuctionEventProtocol.java b/commons/src/main/java/net/swofty/commons/protocol/objects/darkauction/DarkAuctionEventProtocol.java index 3152da4fc..c8fd72b94 100644 --- a/commons/src/main/java/net/swofty/commons/protocol/objects/darkauction/DarkAuctionEventProtocol.java +++ b/commons/src/main/java/net/swofty/commons/protocol/objects/darkauction/DarkAuctionEventProtocol.java @@ -1,7 +1,7 @@ package net.swofty.commons.protocol.objects.darkauction; import net.swofty.commons.protocol.JacksonSerializer; -import net.swofty.commons.protocol.ProtocolObject; +import net.swofty.commons.protocol.RedisProtocol; import net.swofty.commons.protocol.Serializer; import net.swofty.commons.skyblock.auctions.DarkAuctionPhase; import org.jetbrains.annotations.Nullable; @@ -9,7 +9,7 @@ import java.util.List; import java.util.UUID; -public class DarkAuctionEventProtocol extends ProtocolObject< +public class DarkAuctionEventProtocol extends RedisProtocol< DarkAuctionEventProtocol.DarkAuctionMessage, DarkAuctionEventProtocol.DarkAuctionResponse> { diff --git a/commons/src/main/java/net/swofty/commons/protocol/objects/darkauction/DarkAuctionEventPushProtocol.java b/commons/src/main/java/net/swofty/commons/protocol/objects/darkauction/DarkAuctionEventPushProtocol.java index 620db6b04..85a3d5f79 100644 --- a/commons/src/main/java/net/swofty/commons/protocol/objects/darkauction/DarkAuctionEventPushProtocol.java +++ b/commons/src/main/java/net/swofty/commons/protocol/objects/darkauction/DarkAuctionEventPushProtocol.java @@ -1,12 +1,12 @@ package net.swofty.commons.protocol.objects.darkauction; -import net.swofty.commons.protocol.ServicePushProtocol; +import net.swofty.commons.protocol.RedisProtocol; import java.util.List; import java.util.UUID; public class DarkAuctionEventPushProtocol - extends ServicePushProtocol { + extends RedisProtocol { public DarkAuctionEventPushProtocol() { super(Request.class, Response.class); diff --git a/commons/src/main/java/net/swofty/commons/protocol/objects/darkauction/GetAuctionStateProtocol.java b/commons/src/main/java/net/swofty/commons/protocol/objects/darkauction/GetAuctionStateProtocol.java index 6ecb8a7fd..4536545e7 100644 --- a/commons/src/main/java/net/swofty/commons/protocol/objects/darkauction/GetAuctionStateProtocol.java +++ b/commons/src/main/java/net/swofty/commons/protocol/objects/darkauction/GetAuctionStateProtocol.java @@ -1,7 +1,7 @@ package net.swofty.commons.protocol.objects.darkauction; import net.swofty.commons.protocol.JacksonSerializer; -import net.swofty.commons.protocol.ProtocolObject; +import net.swofty.commons.protocol.RedisProtocol; import net.swofty.commons.protocol.Serializer; import net.swofty.commons.skyblock.auctions.DarkAuctionPhase; import org.jetbrains.annotations.Nullable; @@ -9,7 +9,7 @@ import java.util.List; import java.util.UUID; -public class GetAuctionStateProtocol extends ProtocolObject< +public class GetAuctionStateProtocol extends RedisProtocol< GetAuctionStateProtocol.GetAuctionStateMessage, GetAuctionStateProtocol.GetAuctionStateResponse> { diff --git a/commons/src/main/java/net/swofty/commons/protocol/objects/darkauction/PlaceBidProtocol.java b/commons/src/main/java/net/swofty/commons/protocol/objects/darkauction/PlaceBidProtocol.java index 22fbc9386..fc50f7f27 100644 --- a/commons/src/main/java/net/swofty/commons/protocol/objects/darkauction/PlaceBidProtocol.java +++ b/commons/src/main/java/net/swofty/commons/protocol/objects/darkauction/PlaceBidProtocol.java @@ -1,13 +1,13 @@ package net.swofty.commons.protocol.objects.darkauction; import net.swofty.commons.protocol.JacksonSerializer; -import net.swofty.commons.protocol.ProtocolObject; +import net.swofty.commons.protocol.RedisProtocol; import net.swofty.commons.protocol.Serializer; import org.jetbrains.annotations.Nullable; import java.util.UUID; -public class PlaceBidProtocol extends ProtocolObject< +public class PlaceBidProtocol extends RedisProtocol< PlaceBidProtocol.PlaceBidMessage, PlaceBidProtocol.PlaceBidResponse> { diff --git a/commons/src/main/java/net/swofty/commons/protocol/objects/darkauction/PlayerLeftAuctionProtocol.java b/commons/src/main/java/net/swofty/commons/protocol/objects/darkauction/PlayerLeftAuctionProtocol.java index 15b250d00..1eeaaac15 100644 --- a/commons/src/main/java/net/swofty/commons/protocol/objects/darkauction/PlayerLeftAuctionProtocol.java +++ b/commons/src/main/java/net/swofty/commons/protocol/objects/darkauction/PlayerLeftAuctionProtocol.java @@ -1,13 +1,13 @@ package net.swofty.commons.protocol.objects.darkauction; import net.swofty.commons.protocol.JacksonSerializer; -import net.swofty.commons.protocol.ProtocolObject; +import net.swofty.commons.protocol.RedisProtocol; import net.swofty.commons.protocol.Serializer; import org.jetbrains.annotations.Nullable; import java.util.UUID; -public class PlayerLeftAuctionProtocol extends ProtocolObject< +public class PlayerLeftAuctionProtocol extends RedisProtocol< PlayerLeftAuctionProtocol.PlayerLeftMessage, PlayerLeftAuctionProtocol.PlayerLeftResponse> { diff --git a/commons/src/main/java/net/swofty/commons/protocol/objects/darkauction/TriggerDarkAuctionProtocol.java b/commons/src/main/java/net/swofty/commons/protocol/objects/darkauction/TriggerDarkAuctionProtocol.java index 7318f40d9..92299ef4b 100644 --- a/commons/src/main/java/net/swofty/commons/protocol/objects/darkauction/TriggerDarkAuctionProtocol.java +++ b/commons/src/main/java/net/swofty/commons/protocol/objects/darkauction/TriggerDarkAuctionProtocol.java @@ -1,11 +1,11 @@ package net.swofty.commons.protocol.objects.darkauction; import net.swofty.commons.protocol.JacksonSerializer; -import net.swofty.commons.protocol.ProtocolObject; +import net.swofty.commons.protocol.RedisProtocol; import net.swofty.commons.protocol.Serializer; import org.jetbrains.annotations.Nullable; -public class TriggerDarkAuctionProtocol extends ProtocolObject< +public class TriggerDarkAuctionProtocol extends RedisProtocol< TriggerDarkAuctionProtocol.TriggerMessage, TriggerDarkAuctionProtocol.TriggerResponse> { diff --git a/commons/src/main/java/net/swofty/commons/protocol/objects/data/GetPlayerDataPushProtocol.java b/commons/src/main/java/net/swofty/commons/protocol/objects/data/GetPlayerDataPushProtocol.java index 9b6eb3b30..24b8c739e 100644 --- a/commons/src/main/java/net/swofty/commons/protocol/objects/data/GetPlayerDataPushProtocol.java +++ b/commons/src/main/java/net/swofty/commons/protocol/objects/data/GetPlayerDataPushProtocol.java @@ -1,11 +1,11 @@ package net.swofty.commons.protocol.objects.data; -import net.swofty.commons.protocol.ServicePushProtocol; +import net.swofty.commons.protocol.RedisProtocol; import java.util.UUID; public class GetPlayerDataPushProtocol - extends ServicePushProtocol { + extends RedisProtocol { public GetPlayerDataPushProtocol() { super(Request.class, Response.class); diff --git a/commons/src/main/java/net/swofty/commons/protocol/objects/data/LockPlayerDataPushProtocol.java b/commons/src/main/java/net/swofty/commons/protocol/objects/data/LockPlayerDataPushProtocol.java index a21928e82..02479ab0e 100644 --- a/commons/src/main/java/net/swofty/commons/protocol/objects/data/LockPlayerDataPushProtocol.java +++ b/commons/src/main/java/net/swofty/commons/protocol/objects/data/LockPlayerDataPushProtocol.java @@ -1,11 +1,11 @@ package net.swofty.commons.protocol.objects.data; -import net.swofty.commons.protocol.ServicePushProtocol; +import net.swofty.commons.protocol.RedisProtocol; import java.util.UUID; public class LockPlayerDataPushProtocol - extends ServicePushProtocol { + extends RedisProtocol { public LockPlayerDataPushProtocol() { super(Request.class, Response.class); diff --git a/commons/src/main/java/net/swofty/commons/protocol/objects/data/UnlockPlayerDataPushProtocol.java b/commons/src/main/java/net/swofty/commons/protocol/objects/data/UnlockPlayerDataPushProtocol.java index 7230fa030..bdc14c9d0 100644 --- a/commons/src/main/java/net/swofty/commons/protocol/objects/data/UnlockPlayerDataPushProtocol.java +++ b/commons/src/main/java/net/swofty/commons/protocol/objects/data/UnlockPlayerDataPushProtocol.java @@ -1,12 +1,12 @@ package net.swofty.commons.protocol.objects.data; -import net.swofty.commons.protocol.ServicePushProtocol; +import net.swofty.commons.protocol.RedisProtocol; import java.util.UUID; import org.jetbrains.annotations.Nullable; public class UnlockPlayerDataPushProtocol - extends ServicePushProtocol { + extends RedisProtocol { public UnlockPlayerDataPushProtocol() { super(Request.class, Response.class); diff --git a/commons/src/main/java/net/swofty/commons/protocol/objects/data/UpdatePlayerDataPushProtocol.java b/commons/src/main/java/net/swofty/commons/protocol/objects/data/UpdatePlayerDataPushProtocol.java index 88b7f623c..996ce2287 100644 --- a/commons/src/main/java/net/swofty/commons/protocol/objects/data/UpdatePlayerDataPushProtocol.java +++ b/commons/src/main/java/net/swofty/commons/protocol/objects/data/UpdatePlayerDataPushProtocol.java @@ -1,11 +1,11 @@ package net.swofty.commons.protocol.objects.data; -import net.swofty.commons.protocol.ServicePushProtocol; +import net.swofty.commons.protocol.RedisProtocol; import java.util.UUID; public class UpdatePlayerDataPushProtocol - extends ServicePushProtocol { + extends RedisProtocol { public UpdatePlayerDataPushProtocol() { super(Request.class, Response.class); diff --git a/commons/src/main/java/net/swofty/commons/protocol/objects/datamutex/SynchronizeDataProtocolObject.java b/commons/src/main/java/net/swofty/commons/protocol/objects/datamutex/SynchronizeDataProtocol.java similarity index 81% rename from commons/src/main/java/net/swofty/commons/protocol/objects/datamutex/SynchronizeDataProtocolObject.java rename to commons/src/main/java/net/swofty/commons/protocol/objects/datamutex/SynchronizeDataProtocol.java index bf279a39e..507f5214c 100644 --- a/commons/src/main/java/net/swofty/commons/protocol/objects/datamutex/SynchronizeDataProtocolObject.java +++ b/commons/src/main/java/net/swofty/commons/protocol/objects/datamutex/SynchronizeDataProtocol.java @@ -1,16 +1,16 @@ package net.swofty.commons.protocol.objects.datamutex; import net.swofty.commons.protocol.JacksonSerializer; -import net.swofty.commons.protocol.ProtocolObject; +import net.swofty.commons.protocol.RedisProtocol; import net.swofty.commons.protocol.Serializer; import java.util.List; import java.util.UUID; import org.jetbrains.annotations.Nullable; -public class SynchronizeDataProtocolObject extends ProtocolObject< - SynchronizeDataProtocolObject.SynchronizeDataRequest, - SynchronizeDataProtocolObject.SynchronizeDataResponse> { +public class SynchronizeDataProtocol extends RedisProtocol< + SynchronizeDataProtocol.SynchronizeDataRequest, + SynchronizeDataProtocol.SynchronizeDataResponse> { private static final Serializer SERIALIZER = new JacksonSerializer<>(SynchronizeDataRequest.class); private static final Serializer RETURN_SERIALIZER = diff --git a/commons/src/main/java/net/swofty/commons/protocol/objects/datamutex/UnlockDataProtocolObject.java b/commons/src/main/java/net/swofty/commons/protocol/objects/datamutex/UnlockDataProtocol.java similarity index 81% rename from commons/src/main/java/net/swofty/commons/protocol/objects/datamutex/UnlockDataProtocolObject.java rename to commons/src/main/java/net/swofty/commons/protocol/objects/datamutex/UnlockDataProtocol.java index 56d67791e..ee4885ebf 100644 --- a/commons/src/main/java/net/swofty/commons/protocol/objects/datamutex/UnlockDataProtocolObject.java +++ b/commons/src/main/java/net/swofty/commons/protocol/objects/datamutex/UnlockDataProtocol.java @@ -1,16 +1,16 @@ package net.swofty.commons.protocol.objects.datamutex; import net.swofty.commons.protocol.JacksonSerializer; -import net.swofty.commons.protocol.ProtocolObject; +import net.swofty.commons.protocol.RedisProtocol; import net.swofty.commons.protocol.Serializer; import java.util.List; import java.util.UUID; import org.jetbrains.annotations.Nullable; -public class UnlockDataProtocolObject extends ProtocolObject< - UnlockDataProtocolObject.UnlockDataRequest, - UnlockDataProtocolObject.UnlockDataResponse> { +public class UnlockDataProtocol extends RedisProtocol< + UnlockDataProtocol.UnlockDataRequest, + UnlockDataProtocol.UnlockDataResponse> { private static final Serializer SERIALIZER = new JacksonSerializer<>(UnlockDataRequest.class); private static final Serializer RETURN_SERIALIZER = diff --git a/commons/src/main/java/net/swofty/commons/protocol/objects/datamutex/UpdateSynchronizedDataProtocolObject.java b/commons/src/main/java/net/swofty/commons/protocol/objects/datamutex/UpdateSynchronizedDataProtocol.java similarity index 80% rename from commons/src/main/java/net/swofty/commons/protocol/objects/datamutex/UpdateSynchronizedDataProtocolObject.java rename to commons/src/main/java/net/swofty/commons/protocol/objects/datamutex/UpdateSynchronizedDataProtocol.java index a5408d645..c5f63bbc4 100644 --- a/commons/src/main/java/net/swofty/commons/protocol/objects/datamutex/UpdateSynchronizedDataProtocolObject.java +++ b/commons/src/main/java/net/swofty/commons/protocol/objects/datamutex/UpdateSynchronizedDataProtocol.java @@ -1,16 +1,16 @@ package net.swofty.commons.protocol.objects.datamutex; import net.swofty.commons.protocol.JacksonSerializer; -import net.swofty.commons.protocol.ProtocolObject; +import net.swofty.commons.protocol.RedisProtocol; import net.swofty.commons.protocol.Serializer; import java.util.List; import java.util.UUID; import org.jetbrains.annotations.Nullable; -public class UpdateSynchronizedDataProtocolObject extends ProtocolObject< - UpdateSynchronizedDataProtocolObject.UpdateDataRequest, - UpdateSynchronizedDataProtocolObject.UpdateDataResponse> { +public class UpdateSynchronizedDataProtocol extends RedisProtocol< + UpdateSynchronizedDataProtocol.UpdateDataRequest, + UpdateSynchronizedDataProtocol.UpdateDataResponse> { private static final Serializer SERIALIZER = new JacksonSerializer<>(UpdateDataRequest.class); private static final Serializer RETURN_SERIALIZER = diff --git a/commons/src/main/java/net/swofty/commons/protocol/objects/election/CastVoteProtocolObject.java b/commons/src/main/java/net/swofty/commons/protocol/objects/election/CastVoteProtocol.java similarity index 81% rename from commons/src/main/java/net/swofty/commons/protocol/objects/election/CastVoteProtocolObject.java rename to commons/src/main/java/net/swofty/commons/protocol/objects/election/CastVoteProtocol.java index 54503347e..140c0d09b 100644 --- a/commons/src/main/java/net/swofty/commons/protocol/objects/election/CastVoteProtocolObject.java +++ b/commons/src/main/java/net/swofty/commons/protocol/objects/election/CastVoteProtocol.java @@ -1,16 +1,16 @@ package net.swofty.commons.protocol.objects.election; import net.swofty.commons.protocol.JacksonSerializer; -import net.swofty.commons.protocol.ProtocolObject; +import net.swofty.commons.protocol.RedisProtocol; import net.swofty.commons.protocol.Serializer; import java.util.Map; import java.util.UUID; import org.jetbrains.annotations.Nullable; -public class CastVoteProtocolObject - extends ProtocolObject { +public class CastVoteProtocol + extends RedisProtocol { private static final Serializer SERIALIZER = new JacksonSerializer<>(CastVoteMessage.class); private static final Serializer RETURN_SERIALIZER = diff --git a/commons/src/main/java/net/swofty/commons/protocol/objects/election/GetCandidatesProtocolObject.java b/commons/src/main/java/net/swofty/commons/protocol/objects/election/GetCandidatesProtocol.java similarity index 83% rename from commons/src/main/java/net/swofty/commons/protocol/objects/election/GetCandidatesProtocolObject.java rename to commons/src/main/java/net/swofty/commons/protocol/objects/election/GetCandidatesProtocol.java index 03e322c06..8f586c067 100644 --- a/commons/src/main/java/net/swofty/commons/protocol/objects/election/GetCandidatesProtocolObject.java +++ b/commons/src/main/java/net/swofty/commons/protocol/objects/election/GetCandidatesProtocol.java @@ -1,15 +1,15 @@ package net.swofty.commons.protocol.objects.election; import net.swofty.commons.protocol.JacksonSerializer; -import net.swofty.commons.protocol.ProtocolObject; +import net.swofty.commons.protocol.RedisProtocol; import net.swofty.commons.protocol.Serializer; import java.util.List; import org.jetbrains.annotations.Nullable; -public class GetCandidatesProtocolObject - extends ProtocolObject { +public class GetCandidatesProtocol + extends RedisProtocol { private static final Serializer SERIALIZER = new JacksonSerializer<>(GetCandidatesMessage.class); private static final Serializer RETURN_SERIALIZER = diff --git a/commons/src/main/java/net/swofty/commons/protocol/objects/election/GetElectionDataProtocolObject.java b/commons/src/main/java/net/swofty/commons/protocol/objects/election/GetElectionDataProtocol.java similarity index 79% rename from commons/src/main/java/net/swofty/commons/protocol/objects/election/GetElectionDataProtocolObject.java rename to commons/src/main/java/net/swofty/commons/protocol/objects/election/GetElectionDataProtocol.java index 1fcc8af61..429c321f3 100644 --- a/commons/src/main/java/net/swofty/commons/protocol/objects/election/GetElectionDataProtocolObject.java +++ b/commons/src/main/java/net/swofty/commons/protocol/objects/election/GetElectionDataProtocol.java @@ -1,13 +1,13 @@ package net.swofty.commons.protocol.objects.election; import net.swofty.commons.protocol.JacksonSerializer; -import net.swofty.commons.protocol.ProtocolObject; +import net.swofty.commons.protocol.RedisProtocol; import net.swofty.commons.protocol.Serializer; import org.jetbrains.annotations.Nullable; -public class GetElectionDataProtocolObject - extends ProtocolObject { +public class GetElectionDataProtocol + extends RedisProtocol { private static final Serializer SERIALIZER = new JacksonSerializer<>(GetElectionDataMessage.class); private static final Serializer RETURN_SERIALIZER = diff --git a/commons/src/main/java/net/swofty/commons/protocol/objects/election/GetPlayerVoteProtocolObject.java b/commons/src/main/java/net/swofty/commons/protocol/objects/election/GetPlayerVoteProtocol.java similarity index 79% rename from commons/src/main/java/net/swofty/commons/protocol/objects/election/GetPlayerVoteProtocolObject.java rename to commons/src/main/java/net/swofty/commons/protocol/objects/election/GetPlayerVoteProtocol.java index 0dc04afd1..d5a8d46ad 100644 --- a/commons/src/main/java/net/swofty/commons/protocol/objects/election/GetPlayerVoteProtocolObject.java +++ b/commons/src/main/java/net/swofty/commons/protocol/objects/election/GetPlayerVoteProtocol.java @@ -1,15 +1,15 @@ package net.swofty.commons.protocol.objects.election; import net.swofty.commons.protocol.JacksonSerializer; -import net.swofty.commons.protocol.ProtocolObject; +import net.swofty.commons.protocol.RedisProtocol; import net.swofty.commons.protocol.Serializer; import java.util.UUID; import org.jetbrains.annotations.Nullable; -public class GetPlayerVoteProtocolObject - extends ProtocolObject { +public class GetPlayerVoteProtocol + extends RedisProtocol { private static final Serializer SERIALIZER = new JacksonSerializer<>(GetPlayerVoteMessage.class); private static final Serializer RETURN_SERIALIZER = diff --git a/commons/src/main/java/net/swofty/commons/protocol/objects/election/ResolveElectionProtocolObject.java b/commons/src/main/java/net/swofty/commons/protocol/objects/election/ResolveElectionProtocol.java similarity index 78% rename from commons/src/main/java/net/swofty/commons/protocol/objects/election/ResolveElectionProtocolObject.java rename to commons/src/main/java/net/swofty/commons/protocol/objects/election/ResolveElectionProtocol.java index 6ad01b750..32a779c66 100644 --- a/commons/src/main/java/net/swofty/commons/protocol/objects/election/ResolveElectionProtocolObject.java +++ b/commons/src/main/java/net/swofty/commons/protocol/objects/election/ResolveElectionProtocol.java @@ -1,13 +1,13 @@ package net.swofty.commons.protocol.objects.election; import net.swofty.commons.protocol.JacksonSerializer; -import net.swofty.commons.protocol.ProtocolObject; +import net.swofty.commons.protocol.RedisProtocol; import net.swofty.commons.protocol.Serializer; import org.jetbrains.annotations.Nullable; -public class ResolveElectionProtocolObject - extends ProtocolObject { +public class ResolveElectionProtocol + extends RedisProtocol { private static final Serializer SERIALIZER = new JacksonSerializer<>(ResolveElectionMessage.class); private static final Serializer RETURN_SERIALIZER = diff --git a/commons/src/main/java/net/swofty/commons/protocol/objects/election/StartElectionProtocolObject.java b/commons/src/main/java/net/swofty/commons/protocol/objects/election/StartElectionProtocol.java similarity index 79% rename from commons/src/main/java/net/swofty/commons/protocol/objects/election/StartElectionProtocolObject.java rename to commons/src/main/java/net/swofty/commons/protocol/objects/election/StartElectionProtocol.java index d6ed27009..234fcb984 100644 --- a/commons/src/main/java/net/swofty/commons/protocol/objects/election/StartElectionProtocolObject.java +++ b/commons/src/main/java/net/swofty/commons/protocol/objects/election/StartElectionProtocol.java @@ -1,13 +1,13 @@ package net.swofty.commons.protocol.objects.election; import net.swofty.commons.protocol.JacksonSerializer; -import net.swofty.commons.protocol.ProtocolObject; +import net.swofty.commons.protocol.RedisProtocol; import net.swofty.commons.protocol.Serializer; import org.jetbrains.annotations.Nullable; -public class StartElectionProtocolObject - extends ProtocolObject { +public class StartElectionProtocol + extends RedisProtocol { private static final Serializer SERIALIZER = new JacksonSerializer<>(StartElectionMessage.class); private static final Serializer RETURN_SERIALIZER = diff --git a/commons/src/main/java/net/swofty/commons/protocol/objects/friend/AreFriendsProtocolObject.java b/commons/src/main/java/net/swofty/commons/protocol/objects/friend/AreFriendsProtocol.java similarity index 79% rename from commons/src/main/java/net/swofty/commons/protocol/objects/friend/AreFriendsProtocolObject.java rename to commons/src/main/java/net/swofty/commons/protocol/objects/friend/AreFriendsProtocol.java index 030037dd8..c9c8995eb 100644 --- a/commons/src/main/java/net/swofty/commons/protocol/objects/friend/AreFriendsProtocolObject.java +++ b/commons/src/main/java/net/swofty/commons/protocol/objects/friend/AreFriendsProtocol.java @@ -1,15 +1,15 @@ package net.swofty.commons.protocol.objects.friend; import net.swofty.commons.protocol.JacksonSerializer; -import net.swofty.commons.protocol.ProtocolObject; +import net.swofty.commons.protocol.RedisProtocol; import net.swofty.commons.protocol.Serializer; import java.util.UUID; import org.jetbrains.annotations.Nullable; -public class AreFriendsProtocolObject extends ProtocolObject - { +public class AreFriendsProtocol extends RedisProtocol + { private static final Serializer SERIALIZER = new JacksonSerializer<>(AreFriendsMessage.class); private static final Serializer RETURN_SERIALIZER = diff --git a/commons/src/main/java/net/swofty/commons/protocol/objects/friend/FriendEventPushProtocol.java b/commons/src/main/java/net/swofty/commons/protocol/objects/friend/FriendEventPushProtocol.java index c544e891b..3e3071a20 100644 --- a/commons/src/main/java/net/swofty/commons/protocol/objects/friend/FriendEventPushProtocol.java +++ b/commons/src/main/java/net/swofty/commons/protocol/objects/friend/FriendEventPushProtocol.java @@ -1,12 +1,12 @@ package net.swofty.commons.protocol.objects.friend; -import net.swofty.commons.protocol.ServicePushProtocol; +import net.swofty.commons.protocol.RedisProtocol; import java.util.List; import java.util.UUID; public class FriendEventPushProtocol - extends ServicePushProtocol { + extends RedisProtocol { public FriendEventPushProtocol() { super(Request.class, Response.class); diff --git a/commons/src/main/java/net/swofty/commons/protocol/objects/friend/GetFriendDataProtocolObject.java b/commons/src/main/java/net/swofty/commons/protocol/objects/friend/GetFriendDataProtocol.java similarity index 79% rename from commons/src/main/java/net/swofty/commons/protocol/objects/friend/GetFriendDataProtocolObject.java rename to commons/src/main/java/net/swofty/commons/protocol/objects/friend/GetFriendDataProtocol.java index d04ac2c20..760b65a2d 100644 --- a/commons/src/main/java/net/swofty/commons/protocol/objects/friend/GetFriendDataProtocolObject.java +++ b/commons/src/main/java/net/swofty/commons/protocol/objects/friend/GetFriendDataProtocol.java @@ -2,15 +2,15 @@ import net.swofty.commons.friend.FriendData; import net.swofty.commons.protocol.JacksonSerializer; -import net.swofty.commons.protocol.ProtocolObject; +import net.swofty.commons.protocol.RedisProtocol; import net.swofty.commons.protocol.Serializer; import java.util.UUID; import org.jetbrains.annotations.Nullable; -public class GetFriendDataProtocolObject extends ProtocolObject - { +public class GetFriendDataProtocol extends RedisProtocol + { private static final Serializer SERIALIZER = new JacksonSerializer<>(GetFriendDataMessage.class); private static final Serializer RETURN_SERIALIZER = diff --git a/commons/src/main/java/net/swofty/commons/protocol/objects/friend/GetPendingFriendRequestsProtocolObject.java b/commons/src/main/java/net/swofty/commons/protocol/objects/friend/GetPendingFriendRequestsProtocol.java similarity index 78% rename from commons/src/main/java/net/swofty/commons/protocol/objects/friend/GetPendingFriendRequestsProtocolObject.java rename to commons/src/main/java/net/swofty/commons/protocol/objects/friend/GetPendingFriendRequestsProtocol.java index 3fc310f48..98d06b128 100644 --- a/commons/src/main/java/net/swofty/commons/protocol/objects/friend/GetPendingFriendRequestsProtocolObject.java +++ b/commons/src/main/java/net/swofty/commons/protocol/objects/friend/GetPendingFriendRequestsProtocol.java @@ -2,16 +2,16 @@ import net.swofty.commons.friend.PendingFriendRequest; import net.swofty.commons.protocol.JacksonSerializer; -import net.swofty.commons.protocol.ProtocolObject; +import net.swofty.commons.protocol.RedisProtocol; import net.swofty.commons.protocol.Serializer; import java.util.List; import java.util.UUID; import org.jetbrains.annotations.Nullable; -public class GetPendingFriendRequestsProtocolObject extends ProtocolObject - { +public class GetPendingFriendRequestsProtocol extends RedisProtocol + { private static final Serializer SERIALIZER = new JacksonSerializer<>(GetPendingRequestsMessage.class); private static final Serializer RETURN_SERIALIZER = diff --git a/commons/src/main/java/net/swofty/commons/protocol/objects/friend/SendFriendEventToServiceProtocolObject.java b/commons/src/main/java/net/swofty/commons/protocol/objects/friend/SendFriendEventToServiceProtocol.java similarity index 77% rename from commons/src/main/java/net/swofty/commons/protocol/objects/friend/SendFriendEventToServiceProtocolObject.java rename to commons/src/main/java/net/swofty/commons/protocol/objects/friend/SendFriendEventToServiceProtocol.java index b8da5c202..6bb88a7a6 100644 --- a/commons/src/main/java/net/swofty/commons/protocol/objects/friend/SendFriendEventToServiceProtocolObject.java +++ b/commons/src/main/java/net/swofty/commons/protocol/objects/friend/SendFriendEventToServiceProtocol.java @@ -2,13 +2,13 @@ import net.swofty.commons.friend.FriendEvent; import net.swofty.commons.protocol.JacksonSerializer; -import net.swofty.commons.protocol.ProtocolObject; +import net.swofty.commons.protocol.RedisProtocol; import net.swofty.commons.protocol.Serializer; import org.jetbrains.annotations.Nullable; -public class SendFriendEventToServiceProtocolObject extends ProtocolObject - { +public class SendFriendEventToServiceProtocol extends RedisProtocol + { private static final Serializer SERIALIZER = new JacksonSerializer<>(SendFriendEventToServiceMessage.class); private static final Serializer RETURN_SERIALIZER = diff --git a/commons/src/main/java/net/swofty/commons/protocol/objects/game/GameInformationPushProtocol.java b/commons/src/main/java/net/swofty/commons/protocol/objects/game/GameInformationPushProtocol.java index 0eeff3986..0d2904931 100644 --- a/commons/src/main/java/net/swofty/commons/protocol/objects/game/GameInformationPushProtocol.java +++ b/commons/src/main/java/net/swofty/commons/protocol/objects/game/GameInformationPushProtocol.java @@ -1,11 +1,11 @@ package net.swofty.commons.protocol.objects.game; -import net.swofty.commons.protocol.ServicePushProtocol; +import net.swofty.commons.protocol.RedisProtocol; import java.util.UUID; public class GameInformationPushProtocol - extends ServicePushProtocol { + extends RedisProtocol { public GameInformationPushProtocol() { super(Request.class, Response.class); diff --git a/commons/src/main/java/net/swofty/commons/protocol/objects/game/InstantiateGamePushProtocol.java b/commons/src/main/java/net/swofty/commons/protocol/objects/game/InstantiateGamePushProtocol.java index 356b11048..e4b02f157 100644 --- a/commons/src/main/java/net/swofty/commons/protocol/objects/game/InstantiateGamePushProtocol.java +++ b/commons/src/main/java/net/swofty/commons/protocol/objects/game/InstantiateGamePushProtocol.java @@ -1,9 +1,9 @@ package net.swofty.commons.protocol.objects.game; -import net.swofty.commons.protocol.ServicePushProtocol; +import net.swofty.commons.protocol.RedisProtocol; public class InstantiateGamePushProtocol - extends ServicePushProtocol { + extends RedisProtocol { public InstantiateGamePushProtocol() { super(Request.class, Response.class); diff --git a/commons/src/main/java/net/swofty/commons/protocol/objects/gui/KickFromGUIPushProtocol.java b/commons/src/main/java/net/swofty/commons/protocol/objects/gui/KickFromGUIPushProtocol.java index be143e9d9..967857f3f 100644 --- a/commons/src/main/java/net/swofty/commons/protocol/objects/gui/KickFromGUIPushProtocol.java +++ b/commons/src/main/java/net/swofty/commons/protocol/objects/gui/KickFromGUIPushProtocol.java @@ -1,13 +1,13 @@ package net.swofty.commons.protocol.objects.gui; -import net.swofty.commons.protocol.ServicePushProtocol; +import net.swofty.commons.protocol.RedisProtocol; import java.util.List; import java.util.UUID; import org.jetbrains.annotations.Nullable; public class KickFromGUIPushProtocol - extends ServicePushProtocol { + extends RedisProtocol { public KickFromGUIPushProtocol() { super(Request.class, Response.class); diff --git a/commons/src/main/java/net/swofty/commons/protocol/objects/itemtracker/TrackedItemRetrieveProtocolObject.java b/commons/src/main/java/net/swofty/commons/protocol/objects/itemtracker/TrackedItemRetrieveProtocol.java similarity index 81% rename from commons/src/main/java/net/swofty/commons/protocol/objects/itemtracker/TrackedItemRetrieveProtocolObject.java rename to commons/src/main/java/net/swofty/commons/protocol/objects/itemtracker/TrackedItemRetrieveProtocol.java index d06eb7dcb..76558e242 100644 --- a/commons/src/main/java/net/swofty/commons/protocol/objects/itemtracker/TrackedItemRetrieveProtocolObject.java +++ b/commons/src/main/java/net/swofty/commons/protocol/objects/itemtracker/TrackedItemRetrieveProtocol.java @@ -2,15 +2,15 @@ import net.swofty.commons.TrackedItem; import net.swofty.commons.protocol.JacksonSerializer; -import net.swofty.commons.protocol.ProtocolObject; +import net.swofty.commons.protocol.RedisProtocol; import net.swofty.commons.protocol.Serializer; import java.util.UUID; import org.jetbrains.annotations.Nullable; -public class TrackedItemRetrieveProtocolObject extends ProtocolObject - { +public class TrackedItemRetrieveProtocol extends RedisProtocol + { private static final Serializer SERIALIZER = new JacksonSerializer<>(TrackedItemRetrieveMessage.class); private static final Serializer RETURN_SERIALIZER = diff --git a/commons/src/main/java/net/swofty/commons/protocol/objects/itemtracker/TrackedItemUpdateProtocolObject.java b/commons/src/main/java/net/swofty/commons/protocol/objects/itemtracker/TrackedItemUpdateProtocol.java similarity index 79% rename from commons/src/main/java/net/swofty/commons/protocol/objects/itemtracker/TrackedItemUpdateProtocolObject.java rename to commons/src/main/java/net/swofty/commons/protocol/objects/itemtracker/TrackedItemUpdateProtocol.java index 739acc36f..9c159a483 100644 --- a/commons/src/main/java/net/swofty/commons/protocol/objects/itemtracker/TrackedItemUpdateProtocolObject.java +++ b/commons/src/main/java/net/swofty/commons/protocol/objects/itemtracker/TrackedItemUpdateProtocol.java @@ -1,14 +1,14 @@ package net.swofty.commons.protocol.objects.itemtracker; import net.swofty.commons.protocol.JacksonSerializer; -import net.swofty.commons.protocol.ProtocolObject; +import net.swofty.commons.protocol.RedisProtocol; import net.swofty.commons.protocol.Serializer; import java.util.UUID; -public class TrackedItemUpdateProtocolObject extends ProtocolObject< - TrackedItemUpdateProtocolObject.TrackedItemUpdateMessage, - TrackedItemUpdateProtocolObject.TrackedItemUpdateResponse> { +public class TrackedItemUpdateProtocol extends RedisProtocol< + TrackedItemUpdateProtocol.TrackedItemUpdateMessage, + TrackedItemUpdateProtocol.TrackedItemUpdateResponse> { private static final Serializer SERIALIZER = new JacksonSerializer<>(TrackedItemUpdateMessage.class); private static final Serializer RETURN_SERIALIZER = diff --git a/commons/src/main/java/net/swofty/commons/protocol/objects/messaging/SendMessagePushProtocol.java b/commons/src/main/java/net/swofty/commons/protocol/objects/messaging/SendMessagePushProtocol.java index ca89b6c66..816c3f931 100644 --- a/commons/src/main/java/net/swofty/commons/protocol/objects/messaging/SendMessagePushProtocol.java +++ b/commons/src/main/java/net/swofty/commons/protocol/objects/messaging/SendMessagePushProtocol.java @@ -1,12 +1,12 @@ package net.swofty.commons.protocol.objects.messaging; -import net.swofty.commons.protocol.ServicePushProtocol; +import net.swofty.commons.protocol.RedisProtocol; import java.util.UUID; import org.jetbrains.annotations.Nullable; public class SendMessagePushProtocol - extends ServicePushProtocol { + extends RedisProtocol { public SendMessagePushProtocol() { super(Request.class, Response.class); diff --git a/commons/src/main/java/net/swofty/commons/protocol/objects/orchestrator/ChooseGameProtocolObject.java b/commons/src/main/java/net/swofty/commons/protocol/objects/orchestrator/ChooseGameProtocol.java similarity index 81% rename from commons/src/main/java/net/swofty/commons/protocol/objects/orchestrator/ChooseGameProtocolObject.java rename to commons/src/main/java/net/swofty/commons/protocol/objects/orchestrator/ChooseGameProtocol.java index 188448ae5..db9553353 100644 --- a/commons/src/main/java/net/swofty/commons/protocol/objects/orchestrator/ChooseGameProtocolObject.java +++ b/commons/src/main/java/net/swofty/commons/protocol/objects/orchestrator/ChooseGameProtocol.java @@ -2,15 +2,15 @@ import net.swofty.commons.UnderstandableProxyServer; import net.swofty.commons.protocol.JacksonSerializer; -import net.swofty.commons.protocol.ProtocolObject; +import net.swofty.commons.protocol.RedisProtocol; import net.swofty.commons.protocol.Serializer; import java.util.UUID; import org.jetbrains.annotations.Nullable; -public class ChooseGameProtocolObject extends ProtocolObject - { +public class ChooseGameProtocol extends RedisProtocol + { private static final Serializer SERIALIZER = new JacksonSerializer<>(ChooseGameMessage.class); private static final Serializer RETURN_SERIALIZER = diff --git a/commons/src/main/java/net/swofty/commons/protocol/objects/orchestrator/GameHeartbeatProtocolObject.java b/commons/src/main/java/net/swofty/commons/protocol/objects/orchestrator/GameHeartbeatProtocol.java similarity index 81% rename from commons/src/main/java/net/swofty/commons/protocol/objects/orchestrator/GameHeartbeatProtocolObject.java rename to commons/src/main/java/net/swofty/commons/protocol/objects/orchestrator/GameHeartbeatProtocol.java index 22846481c..4268edd36 100644 --- a/commons/src/main/java/net/swofty/commons/protocol/objects/orchestrator/GameHeartbeatProtocolObject.java +++ b/commons/src/main/java/net/swofty/commons/protocol/objects/orchestrator/GameHeartbeatProtocol.java @@ -3,16 +3,16 @@ import net.swofty.commons.ServerType; import net.swofty.commons.game.Game; import net.swofty.commons.protocol.JacksonSerializer; -import net.swofty.commons.protocol.ProtocolObject; +import net.swofty.commons.protocol.RedisProtocol; import net.swofty.commons.protocol.Serializer; import java.util.List; import java.util.UUID; import org.jetbrains.annotations.Nullable; -public class GameHeartbeatProtocolObject extends ProtocolObject - { +public class GameHeartbeatProtocol extends RedisProtocol + { private static final Serializer SERIALIZER = new JacksonSerializer<>(HeartbeatMessage.class); private static final Serializer RETURN_SERIALIZER = diff --git a/commons/src/main/java/net/swofty/commons/protocol/objects/orchestrator/GetGameCountsProtocolObject.java b/commons/src/main/java/net/swofty/commons/protocol/objects/orchestrator/GetGameCountsProtocol.java similarity index 80% rename from commons/src/main/java/net/swofty/commons/protocol/objects/orchestrator/GetGameCountsProtocolObject.java rename to commons/src/main/java/net/swofty/commons/protocol/objects/orchestrator/GetGameCountsProtocol.java index d392db796..05799c63b 100644 --- a/commons/src/main/java/net/swofty/commons/protocol/objects/orchestrator/GetGameCountsProtocolObject.java +++ b/commons/src/main/java/net/swofty/commons/protocol/objects/orchestrator/GetGameCountsProtocol.java @@ -2,13 +2,13 @@ import net.swofty.commons.ServerType; import net.swofty.commons.protocol.JacksonSerializer; -import net.swofty.commons.protocol.ProtocolObject; +import net.swofty.commons.protocol.RedisProtocol; import net.swofty.commons.protocol.Serializer; import org.jetbrains.annotations.Nullable; -public class GetGameCountsProtocolObject extends ProtocolObject - { +public class GetGameCountsProtocol extends RedisProtocol + { private static final Serializer SERIALIZER = new JacksonSerializer<>(GetGameCountsMessage.class); private static final Serializer RETURN_SERIALIZER = diff --git a/commons/src/main/java/net/swofty/commons/protocol/objects/orchestrator/GetMapsProtocolObject.java b/commons/src/main/java/net/swofty/commons/protocol/objects/orchestrator/GetMapsProtocol.java similarity index 81% rename from commons/src/main/java/net/swofty/commons/protocol/objects/orchestrator/GetMapsProtocolObject.java rename to commons/src/main/java/net/swofty/commons/protocol/objects/orchestrator/GetMapsProtocol.java index 0d2776ccf..6586fc792 100644 --- a/commons/src/main/java/net/swofty/commons/protocol/objects/orchestrator/GetMapsProtocolObject.java +++ b/commons/src/main/java/net/swofty/commons/protocol/objects/orchestrator/GetMapsProtocol.java @@ -2,15 +2,15 @@ import net.swofty.commons.ServerType; import net.swofty.commons.protocol.JacksonSerializer; -import net.swofty.commons.protocol.ProtocolObject; +import net.swofty.commons.protocol.RedisProtocol; import net.swofty.commons.protocol.Serializer; import java.util.List; import org.jetbrains.annotations.Nullable; -public class GetMapsProtocolObject extends ProtocolObject - { +public class GetMapsProtocol extends RedisProtocol + { private static final Serializer SERIALIZER = new JacksonSerializer<>(GetMapsMessage.class); private static final Serializer RETURN_SERIALIZER = diff --git a/commons/src/main/java/net/swofty/commons/protocol/objects/orchestrator/GetServerForMapProtocolObject.java b/commons/src/main/java/net/swofty/commons/protocol/objects/orchestrator/GetServerForMapProtocol.java similarity index 81% rename from commons/src/main/java/net/swofty/commons/protocol/objects/orchestrator/GetServerForMapProtocolObject.java rename to commons/src/main/java/net/swofty/commons/protocol/objects/orchestrator/GetServerForMapProtocol.java index debeec02c..9bfeafcbb 100644 --- a/commons/src/main/java/net/swofty/commons/protocol/objects/orchestrator/GetServerForMapProtocolObject.java +++ b/commons/src/main/java/net/swofty/commons/protocol/objects/orchestrator/GetServerForMapProtocol.java @@ -3,13 +3,13 @@ import net.swofty.commons.ServerType; import net.swofty.commons.UnderstandableProxyServer; import net.swofty.commons.protocol.JacksonSerializer; -import net.swofty.commons.protocol.ProtocolObject; +import net.swofty.commons.protocol.RedisProtocol; import net.swofty.commons.protocol.Serializer; import org.jetbrains.annotations.Nullable; -public class GetServerForMapProtocolObject extends ProtocolObject - { +public class GetServerForMapProtocol extends RedisProtocol + { private static final Serializer SERIALIZER = new JacksonSerializer<>(GetServerForMapMessage.class); private static final Serializer RETURN_SERIALIZER = diff --git a/commons/src/main/java/net/swofty/commons/protocol/objects/orchestrator/RejoinGameProtocolObject.java b/commons/src/main/java/net/swofty/commons/protocol/objects/orchestrator/RejoinGameProtocol.java similarity index 84% rename from commons/src/main/java/net/swofty/commons/protocol/objects/orchestrator/RejoinGameProtocolObject.java rename to commons/src/main/java/net/swofty/commons/protocol/objects/orchestrator/RejoinGameProtocol.java index 0bee52952..89baad8f1 100644 --- a/commons/src/main/java/net/swofty/commons/protocol/objects/orchestrator/RejoinGameProtocolObject.java +++ b/commons/src/main/java/net/swofty/commons/protocol/objects/orchestrator/RejoinGameProtocol.java @@ -2,15 +2,15 @@ import net.swofty.commons.UnderstandableProxyServer; import net.swofty.commons.protocol.JacksonSerializer; -import net.swofty.commons.protocol.ProtocolObject; +import net.swofty.commons.protocol.RedisProtocol; import net.swofty.commons.protocol.Serializer; import org.jetbrains.annotations.Nullable; import java.util.UUID; -public class RejoinGameProtocolObject extends ProtocolObject< - RejoinGameProtocolObject.RejoinGameRequest, - RejoinGameProtocolObject.RejoinGameResponse> { +public class RejoinGameProtocol extends RedisProtocol< + RejoinGameProtocol.RejoinGameRequest, + RejoinGameProtocol.RejoinGameResponse> { private static final Serializer SERIALIZER = new JacksonSerializer<>(RejoinGameRequest.class); private static final Serializer RETURN_SERIALIZER = diff --git a/commons/src/main/java/net/swofty/commons/protocol/objects/party/GetPartyProtocolObject.java b/commons/src/main/java/net/swofty/commons/protocol/objects/party/GetPartyProtocol.java similarity index 80% rename from commons/src/main/java/net/swofty/commons/protocol/objects/party/GetPartyProtocolObject.java rename to commons/src/main/java/net/swofty/commons/protocol/objects/party/GetPartyProtocol.java index 218f99627..f70172bde 100644 --- a/commons/src/main/java/net/swofty/commons/protocol/objects/party/GetPartyProtocolObject.java +++ b/commons/src/main/java/net/swofty/commons/protocol/objects/party/GetPartyProtocol.java @@ -2,15 +2,15 @@ import net.swofty.commons.party.Party; import net.swofty.commons.protocol.JacksonSerializer; -import net.swofty.commons.protocol.ProtocolObject; +import net.swofty.commons.protocol.RedisProtocol; import net.swofty.commons.protocol.Serializer; import java.util.UUID; import org.jetbrains.annotations.Nullable; -public class GetPartyProtocolObject extends ProtocolObject - { +public class GetPartyProtocol extends RedisProtocol + { private static final Serializer SERIALIZER = new JacksonSerializer<>(GetPartyMessage.class); private static final Serializer RETURN_SERIALIZER = diff --git a/commons/src/main/java/net/swofty/commons/protocol/objects/party/IsPlayerInPartyProtocolObject.java b/commons/src/main/java/net/swofty/commons/protocol/objects/party/IsPlayerInPartyProtocol.java similarity index 78% rename from commons/src/main/java/net/swofty/commons/protocol/objects/party/IsPlayerInPartyProtocolObject.java rename to commons/src/main/java/net/swofty/commons/protocol/objects/party/IsPlayerInPartyProtocol.java index 3e093db1c..65c691464 100644 --- a/commons/src/main/java/net/swofty/commons/protocol/objects/party/IsPlayerInPartyProtocolObject.java +++ b/commons/src/main/java/net/swofty/commons/protocol/objects/party/IsPlayerInPartyProtocol.java @@ -1,15 +1,15 @@ package net.swofty.commons.protocol.objects.party; import net.swofty.commons.protocol.JacksonSerializer; -import net.swofty.commons.protocol.ProtocolObject; +import net.swofty.commons.protocol.RedisProtocol; import net.swofty.commons.protocol.Serializer; import java.util.UUID; import org.jetbrains.annotations.Nullable; -public class IsPlayerInPartyProtocolObject extends ProtocolObject - { +public class IsPlayerInPartyProtocol extends RedisProtocol + { private static final Serializer SERIALIZER = new JacksonSerializer<>(IsPlayerInPartyMessage.class); private static final Serializer RETURN_SERIALIZER = diff --git a/commons/src/main/java/net/swofty/commons/protocol/objects/party/PartyBroadcastPushProtocol.java b/commons/src/main/java/net/swofty/commons/protocol/objects/party/PartyBroadcastPushProtocol.java index 80be1efb3..c6f8ea0cd 100644 --- a/commons/src/main/java/net/swofty/commons/protocol/objects/party/PartyBroadcastPushProtocol.java +++ b/commons/src/main/java/net/swofty/commons/protocol/objects/party/PartyBroadcastPushProtocol.java @@ -1,14 +1,14 @@ package net.swofty.commons.protocol.objects.party; import net.swofty.commons.party.PartyBroadcast; -import net.swofty.commons.protocol.ServicePushProtocol; +import net.swofty.commons.protocol.RedisProtocol; import java.util.List; import java.util.Map; import java.util.UUID; public class PartyBroadcastPushProtocol - extends ServicePushProtocol { + extends RedisProtocol { public PartyBroadcastPushProtocol() { super(Request.class, Response.class); diff --git a/commons/src/main/java/net/swofty/commons/protocol/objects/party/SendPartyActionProtocolObject.java b/commons/src/main/java/net/swofty/commons/protocol/objects/party/SendPartyActionProtocol.java similarity index 82% rename from commons/src/main/java/net/swofty/commons/protocol/objects/party/SendPartyActionProtocolObject.java rename to commons/src/main/java/net/swofty/commons/protocol/objects/party/SendPartyActionProtocol.java index 49243bdee..cbce1045b 100644 --- a/commons/src/main/java/net/swofty/commons/protocol/objects/party/SendPartyActionProtocolObject.java +++ b/commons/src/main/java/net/swofty/commons/protocol/objects/party/SendPartyActionProtocol.java @@ -2,13 +2,13 @@ import net.swofty.commons.party.PartyAction; import net.swofty.commons.protocol.JacksonSerializer; -import net.swofty.commons.protocol.ProtocolObject; +import net.swofty.commons.protocol.RedisProtocol; import net.swofty.commons.protocol.Serializer; import org.jetbrains.annotations.Nullable; -public class SendPartyActionProtocolObject extends ProtocolObject< - SendPartyActionProtocolObject.Request, - SendPartyActionProtocolObject.Response> { +public class SendPartyActionProtocol extends RedisProtocol< + SendPartyActionProtocol.Request, + SendPartyActionProtocol.Response> { private static final Serializer SERIALIZER = new JacksonSerializer<>(Request.class); private static final Serializer RETURN_SERIALIZER = diff --git a/commons/src/main/java/net/swofty/commons/protocol/objects/presence/GetPresenceBulkProtocolObject.java b/commons/src/main/java/net/swofty/commons/protocol/objects/presence/GetPresenceBulkProtocol.java similarity index 80% rename from commons/src/main/java/net/swofty/commons/protocol/objects/presence/GetPresenceBulkProtocolObject.java rename to commons/src/main/java/net/swofty/commons/protocol/objects/presence/GetPresenceBulkProtocol.java index c6a18e376..376cca867 100644 --- a/commons/src/main/java/net/swofty/commons/protocol/objects/presence/GetPresenceBulkProtocolObject.java +++ b/commons/src/main/java/net/swofty/commons/protocol/objects/presence/GetPresenceBulkProtocol.java @@ -2,16 +2,16 @@ import net.swofty.commons.presence.PresenceInfo; import net.swofty.commons.protocol.JacksonSerializer; -import net.swofty.commons.protocol.ProtocolObject; +import net.swofty.commons.protocol.RedisProtocol; import net.swofty.commons.protocol.Serializer; import java.util.List; import java.util.UUID; import org.jetbrains.annotations.Nullable; -public class GetPresenceBulkProtocolObject extends ProtocolObject< - GetPresenceBulkProtocolObject.GetPresenceBulkMessage, - GetPresenceBulkProtocolObject.GetPresenceBulkResponse> { +public class GetPresenceBulkProtocol extends RedisProtocol< + GetPresenceBulkProtocol.GetPresenceBulkMessage, + GetPresenceBulkProtocol.GetPresenceBulkResponse> { private static final Serializer SERIALIZER = new JacksonSerializer<>(GetPresenceBulkMessage.class); private static final Serializer RETURN_SERIALIZER = diff --git a/commons/src/main/java/net/swofty/commons/protocol/objects/presence/UpdatePresenceProtocolObject.java b/commons/src/main/java/net/swofty/commons/protocol/objects/presence/UpdatePresenceProtocol.java similarity index 79% rename from commons/src/main/java/net/swofty/commons/protocol/objects/presence/UpdatePresenceProtocolObject.java rename to commons/src/main/java/net/swofty/commons/protocol/objects/presence/UpdatePresenceProtocol.java index c1555daf0..2b0dee5a8 100644 --- a/commons/src/main/java/net/swofty/commons/protocol/objects/presence/UpdatePresenceProtocolObject.java +++ b/commons/src/main/java/net/swofty/commons/protocol/objects/presence/UpdatePresenceProtocol.java @@ -2,13 +2,13 @@ import net.swofty.commons.presence.PresenceInfo; import net.swofty.commons.protocol.JacksonSerializer; -import net.swofty.commons.protocol.ProtocolObject; +import net.swofty.commons.protocol.RedisProtocol; import net.swofty.commons.protocol.Serializer; import org.jetbrains.annotations.Nullable; -public class UpdatePresenceProtocolObject extends ProtocolObject< - UpdatePresenceProtocolObject.UpdatePresenceMessage, - UpdatePresenceProtocolObject.UpdatePresenceResponse> { +public class UpdatePresenceProtocol extends RedisProtocol< + UpdatePresenceProtocol.UpdatePresenceMessage, + UpdatePresenceProtocol.UpdatePresenceResponse> { private static final Serializer SERIALIZER = new JacksonSerializer<>(UpdatePresenceMessage.class); private static final Serializer RETURN_SERIALIZER = diff --git a/commons/src/main/java/net/swofty/commons/protocol/objects/proxy/from/BroadcastStaffChatProtocol.java b/commons/src/main/java/net/swofty/commons/protocol/objects/proxy/from/BroadcastStaffChatProtocol.java index 26e70b0bc..0fff58285 100644 --- a/commons/src/main/java/net/swofty/commons/protocol/objects/proxy/from/BroadcastStaffChatProtocol.java +++ b/commons/src/main/java/net/swofty/commons/protocol/objects/proxy/from/BroadcastStaffChatProtocol.java @@ -1,10 +1,10 @@ package net.swofty.commons.protocol.objects.proxy.from; import net.swofty.commons.protocol.JacksonSerializer; -import net.swofty.commons.protocol.ProtocolObject; +import net.swofty.commons.protocol.RedisProtocol; import net.swofty.commons.protocol.Serializer; -public class BroadcastStaffChatProtocol extends ProtocolObject< +public class BroadcastStaffChatProtocol extends RedisProtocol< BroadcastStaffChatProtocol.Request, BroadcastStaffChatProtocol.Response> { private static final Serializer SERIALIZER = diff --git a/commons/src/main/java/net/swofty/commons/protocol/objects/proxy/from/DoesServerHaveIslandProtocol.java b/commons/src/main/java/net/swofty/commons/protocol/objects/proxy/from/DoesServerHaveIslandProtocol.java index e67ef28bf..c1def2cd2 100644 --- a/commons/src/main/java/net/swofty/commons/protocol/objects/proxy/from/DoesServerHaveIslandProtocol.java +++ b/commons/src/main/java/net/swofty/commons/protocol/objects/proxy/from/DoesServerHaveIslandProtocol.java @@ -1,11 +1,11 @@ package net.swofty.commons.protocol.objects.proxy.from; import net.swofty.commons.protocol.JacksonSerializer; -import net.swofty.commons.protocol.ProtocolObject; +import net.swofty.commons.protocol.RedisProtocol; import net.swofty.commons.protocol.Serializer; import org.jetbrains.annotations.Nullable; -public class DoesServerHaveIslandProtocol extends ProtocolObject< +public class DoesServerHaveIslandProtocol extends RedisProtocol< DoesServerHaveIslandProtocol.Request, DoesServerHaveIslandProtocol.Response> { private static final Serializer SERIALIZER = diff --git a/commons/src/main/java/net/swofty/commons/protocol/objects/proxy/from/GivePlayersOriginTypeProtocol.java b/commons/src/main/java/net/swofty/commons/protocol/objects/proxy/from/GivePlayersOriginTypeProtocol.java index 4683b21e6..b86ccf856 100644 --- a/commons/src/main/java/net/swofty/commons/protocol/objects/proxy/from/GivePlayersOriginTypeProtocol.java +++ b/commons/src/main/java/net/swofty/commons/protocol/objects/proxy/from/GivePlayersOriginTypeProtocol.java @@ -1,10 +1,10 @@ package net.swofty.commons.protocol.objects.proxy.from; import net.swofty.commons.protocol.JacksonSerializer; -import net.swofty.commons.protocol.ProtocolObject; +import net.swofty.commons.protocol.RedisProtocol; import net.swofty.commons.protocol.Serializer; -public class GivePlayersOriginTypeProtocol extends ProtocolObject< +public class GivePlayersOriginTypeProtocol extends RedisProtocol< GivePlayersOriginTypeProtocol.Request, GivePlayersOriginTypeProtocol.Response> { private static final Serializer SERIALIZER = diff --git a/commons/src/main/java/net/swofty/commons/protocol/objects/proxy/from/PingServerProtocol.java b/commons/src/main/java/net/swofty/commons/protocol/objects/proxy/from/PingServerProtocol.java index 67662c0c2..588f859f3 100644 --- a/commons/src/main/java/net/swofty/commons/protocol/objects/proxy/from/PingServerProtocol.java +++ b/commons/src/main/java/net/swofty/commons/protocol/objects/proxy/from/PingServerProtocol.java @@ -1,10 +1,10 @@ package net.swofty.commons.protocol.objects.proxy.from; import net.swofty.commons.protocol.JacksonSerializer; -import net.swofty.commons.protocol.ProtocolObject; +import net.swofty.commons.protocol.RedisProtocol; import net.swofty.commons.protocol.Serializer; -public class PingServerProtocol extends ProtocolObject< +public class PingServerProtocol extends RedisProtocol< PingServerProtocol.Request, PingServerProtocol.Response> { private static final Serializer SERIALIZER = diff --git a/commons/src/main/java/net/swofty/commons/protocol/objects/proxy/from/PlayerSwitchedProtocol.java b/commons/src/main/java/net/swofty/commons/protocol/objects/proxy/from/PlayerSwitchedProtocol.java index 75d9527a5..330eecb50 100644 --- a/commons/src/main/java/net/swofty/commons/protocol/objects/proxy/from/PlayerSwitchedProtocol.java +++ b/commons/src/main/java/net/swofty/commons/protocol/objects/proxy/from/PlayerSwitchedProtocol.java @@ -1,10 +1,10 @@ package net.swofty.commons.protocol.objects.proxy.from; import net.swofty.commons.protocol.JacksonSerializer; -import net.swofty.commons.protocol.ProtocolObject; +import net.swofty.commons.protocol.RedisProtocol; import net.swofty.commons.protocol.Serializer; -public class PlayerSwitchedProtocol extends ProtocolObject< +public class PlayerSwitchedProtocol extends RedisProtocol< PlayerSwitchedProtocol.Request, PlayerSwitchedProtocol.Response> { private static final Serializer SERIALIZER = diff --git a/commons/src/main/java/net/swofty/commons/protocol/objects/proxy/from/RefreshCoopDataProtocol.java b/commons/src/main/java/net/swofty/commons/protocol/objects/proxy/from/RefreshCoopDataProtocol.java index c7d3de5d8..99544e3c3 100644 --- a/commons/src/main/java/net/swofty/commons/protocol/objects/proxy/from/RefreshCoopDataProtocol.java +++ b/commons/src/main/java/net/swofty/commons/protocol/objects/proxy/from/RefreshCoopDataProtocol.java @@ -1,10 +1,10 @@ package net.swofty.commons.protocol.objects.proxy.from; import net.swofty.commons.protocol.JacksonSerializer; -import net.swofty.commons.protocol.ProtocolObject; +import net.swofty.commons.protocol.RedisProtocol; import net.swofty.commons.protocol.Serializer; -public class RefreshCoopDataProtocol extends ProtocolObject< +public class RefreshCoopDataProtocol extends RedisProtocol< RefreshCoopDataProtocol.Request, RefreshCoopDataProtocol.Response> { private static final Serializer SERIALIZER = diff --git a/commons/src/main/java/net/swofty/commons/protocol/objects/proxy/from/RunEventProtocol.java b/commons/src/main/java/net/swofty/commons/protocol/objects/proxy/from/RunEventProtocol.java index 8aa8f61e1..1e8d807d8 100644 --- a/commons/src/main/java/net/swofty/commons/protocol/objects/proxy/from/RunEventProtocol.java +++ b/commons/src/main/java/net/swofty/commons/protocol/objects/proxy/from/RunEventProtocol.java @@ -1,10 +1,10 @@ package net.swofty.commons.protocol.objects.proxy.from; import net.swofty.commons.protocol.JacksonSerializer; -import net.swofty.commons.protocol.ProtocolObject; +import net.swofty.commons.protocol.RedisProtocol; import net.swofty.commons.protocol.Serializer; -public class RunEventProtocol extends ProtocolObject< +public class RunEventProtocol extends RedisProtocol< RunEventProtocol.Request, RunEventProtocol.Response> { private static final Serializer SERIALIZER = diff --git a/commons/src/main/java/net/swofty/commons/protocol/objects/proxy/from/TeleportProtocol.java b/commons/src/main/java/net/swofty/commons/protocol/objects/proxy/from/TeleportProtocol.java index a6c22e620..edb5bc107 100644 --- a/commons/src/main/java/net/swofty/commons/protocol/objects/proxy/from/TeleportProtocol.java +++ b/commons/src/main/java/net/swofty/commons/protocol/objects/proxy/from/TeleportProtocol.java @@ -1,10 +1,10 @@ package net.swofty.commons.protocol.objects.proxy.from; import net.swofty.commons.protocol.JacksonSerializer; -import net.swofty.commons.protocol.ProtocolObject; +import net.swofty.commons.protocol.RedisProtocol; import net.swofty.commons.protocol.Serializer; -public class TeleportProtocol extends ProtocolObject< +public class TeleportProtocol extends RedisProtocol< TeleportProtocol.Request, TeleportProtocol.Response> { private static final Serializer SERIALIZER = diff --git a/commons/src/main/java/net/swofty/commons/protocol/objects/proxy/to/FinishedWithPlayerProtocol.java b/commons/src/main/java/net/swofty/commons/protocol/objects/proxy/to/FinishedWithPlayerProtocol.java index 754e0325b..157107cb0 100644 --- a/commons/src/main/java/net/swofty/commons/protocol/objects/proxy/to/FinishedWithPlayerProtocol.java +++ b/commons/src/main/java/net/swofty/commons/protocol/objects/proxy/to/FinishedWithPlayerProtocol.java @@ -1,10 +1,10 @@ package net.swofty.commons.protocol.objects.proxy.to; import net.swofty.commons.protocol.JacksonSerializer; -import net.swofty.commons.protocol.ProtocolObject; +import net.swofty.commons.protocol.RedisProtocol; import net.swofty.commons.protocol.Serializer; -public class FinishedWithPlayerProtocol extends ProtocolObject< +public class FinishedWithPlayerProtocol extends RedisProtocol< FinishedWithPlayerProtocol.Request, FinishedWithPlayerProtocol.Response> { private static final Serializer SERIALIZER = diff --git a/commons/src/main/java/net/swofty/commons/protocol/objects/proxy/to/PlayerCountProtocol.java b/commons/src/main/java/net/swofty/commons/protocol/objects/proxy/to/PlayerCountProtocol.java index 33a372983..87cfdb0f7 100644 --- a/commons/src/main/java/net/swofty/commons/protocol/objects/proxy/to/PlayerCountProtocol.java +++ b/commons/src/main/java/net/swofty/commons/protocol/objects/proxy/to/PlayerCountProtocol.java @@ -1,11 +1,11 @@ package net.swofty.commons.protocol.objects.proxy.to; import net.swofty.commons.protocol.JacksonSerializer; -import net.swofty.commons.protocol.ProtocolObject; +import net.swofty.commons.protocol.RedisProtocol; import net.swofty.commons.protocol.Serializer; import org.jetbrains.annotations.Nullable; -public class PlayerCountProtocol extends ProtocolObject< +public class PlayerCountProtocol extends RedisProtocol< PlayerCountProtocol.Request, PlayerCountProtocol.Response> { private static final Serializer SERIALIZER = diff --git a/commons/src/main/java/net/swofty/commons/protocol/objects/proxy/to/PlayerHandlerProtocol.java b/commons/src/main/java/net/swofty/commons/protocol/objects/proxy/to/PlayerHandlerProtocol.java index 082b8de7e..3905af367 100644 --- a/commons/src/main/java/net/swofty/commons/protocol/objects/proxy/to/PlayerHandlerProtocol.java +++ b/commons/src/main/java/net/swofty/commons/protocol/objects/proxy/to/PlayerHandlerProtocol.java @@ -1,13 +1,13 @@ package net.swofty.commons.protocol.objects.proxy.to; import net.swofty.commons.protocol.JacksonSerializer; -import net.swofty.commons.protocol.ProtocolObject; +import net.swofty.commons.protocol.RedisProtocol; import net.swofty.commons.protocol.Serializer; import java.util.Map; import org.jetbrains.annotations.Nullable; -public class PlayerHandlerProtocol extends ProtocolObject< +public class PlayerHandlerProtocol extends RedisProtocol< PlayerHandlerProtocol.Request, PlayerHandlerProtocol.Response> { private static final Serializer SERIALIZER = diff --git a/commons/src/main/java/net/swofty/commons/protocol/objects/proxy/to/ProxyIsOnlineProtocol.java b/commons/src/main/java/net/swofty/commons/protocol/objects/proxy/to/ProxyIsOnlineProtocol.java index 2401fea1c..140f5f37d 100644 --- a/commons/src/main/java/net/swofty/commons/protocol/objects/proxy/to/ProxyIsOnlineProtocol.java +++ b/commons/src/main/java/net/swofty/commons/protocol/objects/proxy/to/ProxyIsOnlineProtocol.java @@ -1,11 +1,11 @@ package net.swofty.commons.protocol.objects.proxy.to; import net.swofty.commons.protocol.JacksonSerializer; -import net.swofty.commons.protocol.ProtocolObject; +import net.swofty.commons.protocol.RedisProtocol; import net.swofty.commons.protocol.Serializer; import org.jetbrains.annotations.Nullable; -public class ProxyIsOnlineProtocol extends ProtocolObject< +public class ProxyIsOnlineProtocol extends RedisProtocol< ProxyIsOnlineProtocol.Request, ProxyIsOnlineProtocol.Response> { private static final Serializer SERIALIZER = diff --git a/commons/src/main/java/net/swofty/commons/protocol/objects/proxy/to/PunishPlayerProtocol.java b/commons/src/main/java/net/swofty/commons/protocol/objects/proxy/to/PunishPlayerProtocol.java index 87cc89751..a2d85c110 100644 --- a/commons/src/main/java/net/swofty/commons/protocol/objects/proxy/to/PunishPlayerProtocol.java +++ b/commons/src/main/java/net/swofty/commons/protocol/objects/proxy/to/PunishPlayerProtocol.java @@ -1,10 +1,10 @@ package net.swofty.commons.protocol.objects.proxy.to; import net.swofty.commons.protocol.JacksonSerializer; -import net.swofty.commons.protocol.ProtocolObject; +import net.swofty.commons.protocol.RedisProtocol; import net.swofty.commons.protocol.Serializer; -public class PunishPlayerProtocol extends ProtocolObject< +public class PunishPlayerProtocol extends RedisProtocol< PunishPlayerProtocol.Request, PunishPlayerProtocol.Response> { private static final Serializer SERIALIZER = diff --git a/commons/src/main/java/net/swofty/commons/protocol/objects/proxy/to/RegisterServerProtocol.java b/commons/src/main/java/net/swofty/commons/protocol/objects/proxy/to/RegisterServerProtocol.java index fd69e6c20..f06ffb34b 100644 --- a/commons/src/main/java/net/swofty/commons/protocol/objects/proxy/to/RegisterServerProtocol.java +++ b/commons/src/main/java/net/swofty/commons/protocol/objects/proxy/to/RegisterServerProtocol.java @@ -1,11 +1,11 @@ package net.swofty.commons.protocol.objects.proxy.to; import net.swofty.commons.protocol.JacksonSerializer; -import net.swofty.commons.protocol.ProtocolObject; +import net.swofty.commons.protocol.RedisProtocol; import net.swofty.commons.protocol.Serializer; import org.jetbrains.annotations.Nullable; -public class RegisterServerProtocol extends ProtocolObject< +public class RegisterServerProtocol extends RedisProtocol< RegisterServerProtocol.Request, RegisterServerProtocol.Response> { private static final Serializer SERIALIZER = diff --git a/commons/src/main/java/net/swofty/commons/protocol/objects/proxy/to/RegisterTestFlowProtocol.java b/commons/src/main/java/net/swofty/commons/protocol/objects/proxy/to/RegisterTestFlowProtocol.java index 61cb2f7e5..fd586dfec 100644 --- a/commons/src/main/java/net/swofty/commons/protocol/objects/proxy/to/RegisterTestFlowProtocol.java +++ b/commons/src/main/java/net/swofty/commons/protocol/objects/proxy/to/RegisterTestFlowProtocol.java @@ -1,13 +1,13 @@ package net.swofty.commons.protocol.objects.proxy.to; import net.swofty.commons.protocol.JacksonSerializer; -import net.swofty.commons.protocol.ProtocolObject; +import net.swofty.commons.protocol.RedisProtocol; import net.swofty.commons.protocol.Serializer; import java.util.List; import java.util.Map; -public class RegisterTestFlowProtocol extends ProtocolObject< +public class RegisterTestFlowProtocol extends RedisProtocol< RegisterTestFlowProtocol.Request, RegisterTestFlowProtocol.Response> { private static final Serializer SERIALIZER = diff --git a/commons/src/main/java/net/swofty/commons/protocol/objects/proxy/to/RequestServerNameProtocol.java b/commons/src/main/java/net/swofty/commons/protocol/objects/proxy/to/RequestServerNameProtocol.java index 33fe1646b..b6696005c 100644 --- a/commons/src/main/java/net/swofty/commons/protocol/objects/proxy/to/RequestServerNameProtocol.java +++ b/commons/src/main/java/net/swofty/commons/protocol/objects/proxy/to/RequestServerNameProtocol.java @@ -1,11 +1,11 @@ package net.swofty.commons.protocol.objects.proxy.to; import net.swofty.commons.protocol.JacksonSerializer; -import net.swofty.commons.protocol.ProtocolObject; +import net.swofty.commons.protocol.RedisProtocol; import net.swofty.commons.protocol.Serializer; import org.jetbrains.annotations.Nullable; -public class RequestServerNameProtocol extends ProtocolObject< +public class RequestServerNameProtocol extends RedisProtocol< RequestServerNameProtocol.Request, RequestServerNameProtocol.Response> { private static final Serializer SERIALIZER = diff --git a/commons/src/main/java/net/swofty/commons/protocol/objects/proxy/to/RequestServersProtocol.java b/commons/src/main/java/net/swofty/commons/protocol/objects/proxy/to/RequestServersProtocol.java index d8f341555..13ad3aa31 100644 --- a/commons/src/main/java/net/swofty/commons/protocol/objects/proxy/to/RequestServersProtocol.java +++ b/commons/src/main/java/net/swofty/commons/protocol/objects/proxy/to/RequestServersProtocol.java @@ -1,11 +1,11 @@ package net.swofty.commons.protocol.objects.proxy.to; import net.swofty.commons.protocol.JacksonSerializer; -import net.swofty.commons.protocol.ProtocolObject; +import net.swofty.commons.protocol.RedisProtocol; import net.swofty.commons.protocol.Serializer; import org.jetbrains.annotations.Nullable; -public class RequestServersProtocol extends ProtocolObject< +public class RequestServersProtocol extends RedisProtocol< RequestServersProtocol.Request, RequestServersProtocol.Response> { private static final Serializer SERIALIZER = diff --git a/commons/src/main/java/net/swofty/commons/protocol/objects/proxy/to/StaffChatProtocol.java b/commons/src/main/java/net/swofty/commons/protocol/objects/proxy/to/StaffChatProtocol.java index 105b61f0b..158403783 100644 --- a/commons/src/main/java/net/swofty/commons/protocol/objects/proxy/to/StaffChatProtocol.java +++ b/commons/src/main/java/net/swofty/commons/protocol/objects/proxy/to/StaffChatProtocol.java @@ -1,10 +1,10 @@ package net.swofty.commons.protocol.objects.proxy.to; import net.swofty.commons.protocol.JacksonSerializer; -import net.swofty.commons.protocol.ProtocolObject; +import net.swofty.commons.protocol.RedisProtocol; import net.swofty.commons.protocol.Serializer; -public class StaffChatProtocol extends ProtocolObject< +public class StaffChatProtocol extends RedisProtocol< StaffChatProtocol.Request, StaffChatProtocol.Response> { private static final Serializer SERIALIZER = diff --git a/commons/src/main/java/net/swofty/commons/protocol/objects/proxy/to/TestFlowServerReadyProtocol.java b/commons/src/main/java/net/swofty/commons/protocol/objects/proxy/to/TestFlowServerReadyProtocol.java index 984dd3d8e..74d253946 100644 --- a/commons/src/main/java/net/swofty/commons/protocol/objects/proxy/to/TestFlowServerReadyProtocol.java +++ b/commons/src/main/java/net/swofty/commons/protocol/objects/proxy/to/TestFlowServerReadyProtocol.java @@ -1,10 +1,10 @@ package net.swofty.commons.protocol.objects.proxy.to; import net.swofty.commons.protocol.JacksonSerializer; -import net.swofty.commons.protocol.ProtocolObject; +import net.swofty.commons.protocol.RedisProtocol; import net.swofty.commons.protocol.Serializer; -public class TestFlowServerReadyProtocol extends ProtocolObject< +public class TestFlowServerReadyProtocol extends RedisProtocol< TestFlowServerReadyProtocol.Request, TestFlowServerReadyProtocol.Response> { private static final Serializer SERIALIZER = diff --git a/commons/src/main/java/net/swofty/commons/protocol/objects/punishment/GetActivePunishmentProtocolObject.java b/commons/src/main/java/net/swofty/commons/protocol/objects/punishment/GetActivePunishmentProtocol.java similarity index 84% rename from commons/src/main/java/net/swofty/commons/protocol/objects/punishment/GetActivePunishmentProtocolObject.java rename to commons/src/main/java/net/swofty/commons/protocol/objects/punishment/GetActivePunishmentProtocol.java index dbd4b276e..124a01ee4 100644 --- a/commons/src/main/java/net/swofty/commons/protocol/objects/punishment/GetActivePunishmentProtocolObject.java +++ b/commons/src/main/java/net/swofty/commons/protocol/objects/punishment/GetActivePunishmentProtocol.java @@ -1,7 +1,7 @@ package net.swofty.commons.protocol.objects.punishment; import net.swofty.commons.protocol.JacksonSerializer; -import net.swofty.commons.protocol.ProtocolObject; +import net.swofty.commons.protocol.RedisProtocol; import net.swofty.commons.protocol.Serializer; import net.swofty.commons.punishment.PunishmentReason; import net.swofty.commons.punishment.PunishmentTag; @@ -11,9 +11,9 @@ import java.util.List; import java.util.UUID; -public class GetActivePunishmentProtocolObject - extends ProtocolObject { +public class GetActivePunishmentProtocol + extends RedisProtocol { private static final Serializer SERIALIZER = new JacksonSerializer<>(GetActivePunishmentMessage.class); private static final Serializer RETURN_SERIALIZER = diff --git a/commons/src/main/java/net/swofty/commons/protocol/objects/punishment/PunishPlayerProtocolObject.java b/commons/src/main/java/net/swofty/commons/protocol/objects/punishment/PunishPlayerServiceProtocol.java similarity index 87% rename from commons/src/main/java/net/swofty/commons/protocol/objects/punishment/PunishPlayerProtocolObject.java rename to commons/src/main/java/net/swofty/commons/protocol/objects/punishment/PunishPlayerServiceProtocol.java index 5074c5440..334e9acf1 100644 --- a/commons/src/main/java/net/swofty/commons/protocol/objects/punishment/PunishPlayerProtocolObject.java +++ b/commons/src/main/java/net/swofty/commons/protocol/objects/punishment/PunishPlayerServiceProtocol.java @@ -1,7 +1,7 @@ package net.swofty.commons.protocol.objects.punishment; import net.swofty.commons.protocol.JacksonSerializer; -import net.swofty.commons.protocol.ProtocolObject; +import net.swofty.commons.protocol.RedisProtocol; import net.swofty.commons.protocol.Serializer; import net.swofty.commons.punishment.PunishmentReason; import net.swofty.commons.punishment.PunishmentTag; @@ -11,9 +11,9 @@ import java.util.List; import java.util.UUID; -public class PunishPlayerProtocolObject - extends ProtocolObject { +public class PunishPlayerServiceProtocol + extends RedisProtocol { private static final Serializer SERIALIZER = new JacksonSerializer<>(PunishPlayerMessage.class); private static final Serializer RETURN_SERIALIZER = diff --git a/commons/src/main/java/net/swofty/commons/protocol/objects/punishment/UnpunishPlayerProtocolObject.java b/commons/src/main/java/net/swofty/commons/protocol/objects/punishment/UnpunishPlayerProtocol.java similarity index 81% rename from commons/src/main/java/net/swofty/commons/protocol/objects/punishment/UnpunishPlayerProtocolObject.java rename to commons/src/main/java/net/swofty/commons/protocol/objects/punishment/UnpunishPlayerProtocol.java index bb7979c51..e50c273ee 100644 --- a/commons/src/main/java/net/swofty/commons/protocol/objects/punishment/UnpunishPlayerProtocolObject.java +++ b/commons/src/main/java/net/swofty/commons/protocol/objects/punishment/UnpunishPlayerProtocol.java @@ -1,16 +1,16 @@ package net.swofty.commons.protocol.objects.punishment; import net.swofty.commons.protocol.JacksonSerializer; -import net.swofty.commons.protocol.ProtocolObject; +import net.swofty.commons.protocol.RedisProtocol; import net.swofty.commons.protocol.Serializer; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import java.util.UUID; -public class UnpunishPlayerProtocolObject - extends ProtocolObject { +public class UnpunishPlayerProtocol + extends RedisProtocol { private static final Serializer SERIALIZER = new JacksonSerializer<>(UnpunishPlayerMessage.class); private static final Serializer RETURN_SERIALIZER = diff --git a/commons/src/main/java/net/swofty/commons/redis/RedisChannels.java b/commons/src/main/java/net/swofty/commons/redis/RedisChannels.java new file mode 100644 index 000000000..b67ca10b2 --- /dev/null +++ b/commons/src/main/java/net/swofty/commons/redis/RedisChannels.java @@ -0,0 +1,25 @@ +package net.swofty.commons.redis; + +import net.swofty.commons.protocol.RedisProtocol; + +public final class RedisChannels { + public static final String PROXY_RESPONSE = "proxy"; + public static final String SERVICE_RESPONSE = "service_response"; + public static final String SERVICE_BROADCAST_RESPONSE = "service_broadcast_response"; + public static final String ALL_SERVERS = "all"; + + private RedisChannels() { + } + + public static String protocol(RedisProtocol protocol) { + return protocol.channel(); + } + + public static String serviceRequest(RedisProtocol protocol) { + return "service_" + protocol.channel(); + } + + public static String serviceBroadcast(RedisProtocol protocol) { + return "service_broadcast_" + protocol.channel(); + } +} diff --git a/commons/src/main/java/net/swofty/commons/redis/RedisEndpoint.java b/commons/src/main/java/net/swofty/commons/redis/RedisEndpoint.java new file mode 100644 index 000000000..e55956a63 --- /dev/null +++ b/commons/src/main/java/net/swofty/commons/redis/RedisEndpoint.java @@ -0,0 +1,27 @@ +package net.swofty.commons.redis; + +import net.swofty.commons.ServiceType; + +import java.util.UUID; + +public record RedisEndpoint(RedisEndpointType type, String id) { + public static RedisEndpoint proxy() { + return new RedisEndpoint(RedisEndpointType.PROXY, "proxy"); + } + + public static RedisEndpoint service(ServiceType type) { + return new RedisEndpoint(RedisEndpointType.SERVICE, type.name()); + } + + public static RedisEndpoint service(String id) { + return new RedisEndpoint(RedisEndpointType.SERVICE, id); + } + + public static RedisEndpoint server(UUID uuid) { + return new RedisEndpoint(RedisEndpointType.SERVER, uuid.toString()); + } + + public static RedisEndpoint server(String uuid) { + return new RedisEndpoint(RedisEndpointType.SERVER, uuid); + } +} diff --git a/commons/src/main/java/net/swofty/commons/redis/RedisEndpointType.java b/commons/src/main/java/net/swofty/commons/redis/RedisEndpointType.java new file mode 100644 index 000000000..594b6f1a6 --- /dev/null +++ b/commons/src/main/java/net/swofty/commons/redis/RedisEndpointType.java @@ -0,0 +1,7 @@ +package net.swofty.commons.redis; + +public enum RedisEndpointType { + PROXY, + SERVER, + SERVICE +} diff --git a/commons/src/main/java/net/swofty/commons/redis/RedisMessageContext.java b/commons/src/main/java/net/swofty/commons/redis/RedisMessageContext.java new file mode 100644 index 000000000..603c7579e --- /dev/null +++ b/commons/src/main/java/net/swofty/commons/redis/RedisMessageContext.java @@ -0,0 +1,55 @@ +package net.swofty.commons.redis; + +import java.util.UUID; + +public record RedisMessageContext( + UUID requestId, + RedisEndpoint origin, + RedisEndpoint destination, + String channel, + boolean broadcast +) { + public static RedisMessageContext proxyToServer(UUID requestId, String proxyId, String serverId, String channel) { + return new RedisMessageContext( + requestId, + RedisEndpoint.proxy(), + RedisEndpoint.server(serverId), + channel, + false + ); + } + + public static RedisMessageContext serverToProxy(UUID requestId, String serverId, String channel) { + return new RedisMessageContext( + requestId, + RedisEndpoint.server(serverId), + RedisEndpoint.proxy(), + channel, + false + ); + } + + public static RedisMessageContext serverToService(UUID requestId, String serverId, String serviceId, String channel) { + return new RedisMessageContext( + requestId, + RedisEndpoint.server(serverId), + RedisEndpoint.service(serviceId), + channel, + false + ); + } + + public static RedisMessageContext serviceToServer(UUID requestId, String serviceId, String serverId, String channel) { + return new RedisMessageContext( + requestId, + RedisEndpoint.service(serviceId), + RedisEndpoint.server(serverId), + channel, + false + ); + } + + public RedisMessageContext asBroadcast() { + return new RedisMessageContext(requestId, origin, destination, channel, true); + } +} diff --git a/commons/src/main/java/net/swofty/commons/redis/RedisMessageHandler.java b/commons/src/main/java/net/swofty/commons/redis/RedisMessageHandler.java new file mode 100644 index 000000000..91f1c8ec8 --- /dev/null +++ b/commons/src/main/java/net/swofty/commons/redis/RedisMessageHandler.java @@ -0,0 +1,9 @@ +package net.swofty.commons.redis; + +import net.swofty.commons.protocol.RedisProtocol; + +public interface RedisMessageHandler { + RedisProtocol protocol(); + + R handle(T message, RedisMessageContext context); +} diff --git a/commons/src/test/java/net/swofty/commons/protocol/ServicePushProtocolTest.java b/commons/src/test/java/net/swofty/commons/protocol/RedisProtocolTest.java similarity index 91% rename from commons/src/test/java/net/swofty/commons/protocol/ServicePushProtocolTest.java rename to commons/src/test/java/net/swofty/commons/protocol/RedisProtocolTest.java index a6d4e8828..42a908815 100644 --- a/commons/src/test/java/net/swofty/commons/protocol/ServicePushProtocolTest.java +++ b/commons/src/test/java/net/swofty/commons/protocol/RedisProtocolTest.java @@ -4,12 +4,12 @@ import java.util.UUID; import static org.junit.jupiter.api.Assertions.*; -class ServicePushProtocolTest { +class RedisProtocolTest { public record TestPushRequest(UUID playerId, String item, int amount) {} public record TestPushResponse(boolean handled) {} - static class TestPush extends ServicePushProtocol { + static class TestPush extends RedisProtocol { public TestPush() { super(TestPushRequest.class, TestPushResponse.class); } diff --git a/loader/src/main/java/net/swofty/loader/Hypixel.java b/loader/src/main/java/net/swofty/loader/Hypixel.java index 6b852965c..13e84accb 100644 --- a/loader/src/main/java/net/swofty/loader/Hypixel.java +++ b/loader/src/main/java/net/swofty/loader/Hypixel.java @@ -20,13 +20,12 @@ import net.swofty.commons.ServerType; import net.swofty.commons.TestFlow; import net.swofty.commons.config.ConfigProvider; -import net.swofty.commons.protocol.ProtocolObject; +import net.swofty.commons.protocol.RedisProtocol; import net.swofty.commons.protocol.objects.proxy.to.*; import net.swofty.proxyapi.ProxyAPI; import net.swofty.proxyapi.ProxyService; import net.swofty.proxyapi.redis.ServerOutboundMessage; -import net.swofty.proxyapi.redis.TypedProxyHandler; -import net.swofty.proxyapi.redis.TypedServiceHandler; +import net.swofty.commons.redis.RedisMessageHandler; import net.swofty.spark.Spark; import net.swofty.type.generic.HypixelConst; import net.swofty.type.generic.HypixelGenericLoader; @@ -155,22 +154,22 @@ static void main(String[] args) { // Initialize proxy support ProxyAPI proxyAPI = new ProxyAPI(ConfigProvider.settings().getRedisUri(), serverUUID); - SkyBlockGenericLoader.loopThroughPackage("net.swofty.type.generic.redis", TypedProxyHandler.class) - .forEach(proxyAPI::registerTypedProxyHandler); - SkyBlockGenericLoader.loopThroughPackage("net.swofty.type.generic.redis.service", TypedServiceHandler.class) - .forEach(proxyAPI::registerTypedServiceHandler); - typeLoader.getTypedProxyHandlers().forEach(proxyAPI::registerTypedProxyHandler); - typeLoader.getTypedServiceHandlers().forEach(proxyAPI::registerTypedServiceHandler); + SkyBlockGenericLoader.loopThroughPackage("net.swofty.type.generic.redis", RedisMessageHandler.class) + .forEach(proxyAPI::registerProxyHandler); + SkyBlockGenericLoader.loopThroughPackage("net.swofty.type.generic.redis.service", RedisMessageHandler.class) + .forEach(proxyAPI::registerServiceHandler); + typeLoader.getProxyHandlers().forEach(proxyAPI::registerProxyHandler); + typeLoader.getServiceHandlers().forEach(proxyAPI::registerServiceHandler); if (typeLoader instanceof SkyBlockTypeLoader) { - SkyBlockGenericLoader.loopThroughPackage("net.swofty.type.skyblockgeneric.redis", TypedProxyHandler.class) - .forEach(proxyAPI::registerTypedProxyHandler); - SkyBlockGenericLoader.loopThroughPackage("net.swofty.type.skyblockgeneric.redis.service", TypedServiceHandler.class) - .forEach(proxyAPI::registerTypedServiceHandler); + SkyBlockGenericLoader.loopThroughPackage("net.swofty.type.skyblockgeneric.redis", RedisMessageHandler.class) + .forEach(proxyAPI::registerProxyHandler); + SkyBlockGenericLoader.loopThroughPackage("net.swofty.type.skyblockgeneric.redis.service", RedisMessageHandler.class) + .forEach(proxyAPI::registerServiceHandler); } else if (typeLoader instanceof RavengardTypeLoader) { - SkyBlockGenericLoader.loopThroughPackage("net.swofty.type.ravengardgeneric.redis", TypedProxyHandler.class) - .forEach(proxyAPI::registerTypedProxyHandler); + SkyBlockGenericLoader.loopThroughPackage("net.swofty.type.ravengardgeneric.redis", RedisMessageHandler.class) + .forEach(proxyAPI::registerProxyHandler); } - ProtocolObject[] toProxyProtocols = { + RedisProtocol[] toProxyProtocols = { new RequestServerNameProtocol(), new PlayerCountProtocol(), new PlayerHandlerProtocol(), new ProxyIsOnlineProtocol(), new RegisterServerProtocol(), new FinishedWithPlayerProtocol(), @@ -178,14 +177,14 @@ static void main(String[] args) { new TestFlowServerReadyProtocol(), new StaffChatProtocol(), new PunishPlayerProtocol() }; - for (ProtocolObject protocol : toProxyProtocols) { + for (RedisProtocol protocol : toProxyProtocols) { ServerOutboundMessage.registerToProxyProtocol(protocol); } - List protocolObjects = SkyBlockGenericLoader.loopThroughPackage( - "net.swofty.commons.protocol.objects", ProtocolObject.class) + List protocols = SkyBlockGenericLoader.loopThroughPackage( + "net.swofty.commons.protocol.objects", RedisProtocol.class) .filter(obj -> !obj.getClass().getPackageName().startsWith("net.swofty.commons.protocol.objects.proxy")) .toList(); - protocolObjects.forEach(ServerOutboundMessage::registerFromProtocolObject); + protocols.forEach(ServerOutboundMessage::registerResponseProtocol); proxyAPI.start(); // Start spark if enabled diff --git a/proxy.api/src/main/java/net/swofty/proxyapi/ProxyAPI.java b/proxy.api/src/main/java/net/swofty/proxyapi/ProxyAPI.java index 3e99ec7b4..1920f6c74 100644 --- a/proxy.api/src/main/java/net/swofty/proxyapi/ProxyAPI.java +++ b/proxy.api/src/main/java/net/swofty/proxyapi/ProxyAPI.java @@ -1,10 +1,10 @@ package net.swofty.proxyapi; -import net.swofty.commons.protocol.ProtocolObject; -import net.swofty.commons.protocol.ServicePushProtocol; +import net.swofty.commons.protocol.RedisProtocol; +import net.swofty.commons.redis.RedisChannels; import net.swofty.commons.redis.RedisEnvelope; -import net.swofty.proxyapi.redis.TypedProxyHandler; -import net.swofty.proxyapi.redis.TypedServiceHandler; +import net.swofty.commons.redis.RedisMessageContext; +import net.swofty.commons.redis.RedisMessageHandler; import net.swofty.redisapi.api.ChannelRegistry; import net.swofty.redisapi.api.RedisAPI; @@ -20,29 +20,35 @@ public ProxyAPI(String URI, UUID serverUUID) { RedisAPI.getInstance().setFilterId(serverUUID.toString()); } - public void registerTypedProxyHandler(TypedProxyHandler handler) { - ProtocolObject protocol = handler.getProtocol(); + public void registerProxyHandler(RedisMessageHandler handler) { + RedisProtocol protocol = handler.protocol(); - RedisAPI.getInstance().registerChannel(protocol.channel(), (event) -> { + RedisAPI.getInstance().registerChannel(RedisChannels.protocol(protocol), (event) -> { String messageWithoutFilter = event.message.substring(event.message.indexOf(";") + 1); RedisEnvelope envelope = RedisEnvelope.deserialize(messageWithoutFilter); String rawMessage = envelope.payload(); T typedMessage = protocol.translateFromString(rawMessage); - R response = handler.onMessage(typedMessage); + RedisMessageContext context = RedisMessageContext.proxyToServer( + UUID.fromString(envelope.id()), + envelope.from(), + serverUUID.toString(), + protocol.channel() + ); + R response = handler.handle(typedMessage, context); String serializedResponse = protocol.translateReturnToString(response); RedisAPI.getInstance().publishMessage( - "proxy", - ChannelRegistry.getFromName(protocol.channel()), + RedisChannels.PROXY_RESPONSE, + ChannelRegistry.getFromName(RedisChannels.protocol(protocol)), new RedisEnvelope(envelope.id(), serverUUID.toString(), serializedResponse).serialize()); }); } - public void registerTypedServiceHandler(TypedServiceHandler handler) { - ServicePushProtocol protocol = handler.getProtocol(); - String channelName = "service_" + protocol.channel(); + public void registerServiceHandler(RedisMessageHandler handler) { + RedisProtocol protocol = handler.protocol(); + String channelName = RedisChannels.serviceRequest(protocol); RedisAPI.getInstance().registerChannel(channelName, (event) -> { String messageWithoutFilter = event.message.substring(event.message.indexOf(";") + 1); @@ -52,18 +58,24 @@ public void registerTypedServiceHandler(TypedServiceHandler handler Thread.startVirtualThread(() -> { T typedMessage = protocol.translateFromString(rawMessage); - R response = handler.onMessage(typedMessage); + RedisMessageContext context = RedisMessageContext.serviceToServer( + UUID.fromString(envelope.id()), + serviceId, + serverUUID.toString(), + protocol.channel() + ); + R response = handler.handle(typedMessage, context); String serializedResponse = protocol.translateReturnToString(response); RedisAPI.getInstance().publishMessage( serviceId, - ChannelRegistry.getFromName("service_response"), + ChannelRegistry.getFromName(RedisChannels.SERVICE_RESPONSE), new RedisEnvelope(envelope.id(), serverUUID.toString(), serializedResponse).serialize()); }); }); - RedisAPI.getInstance().registerChannel("service_broadcast_" + protocol.channel(), (event) -> { + RedisAPI.getInstance().registerChannel(RedisChannels.serviceBroadcast(protocol), (event) -> { String messageWithoutFilter = event.message.substring(event.message.indexOf(";") + 1); RedisEnvelope envelope = RedisEnvelope.deserialize(messageWithoutFilter); String serviceId = envelope.from(); @@ -71,7 +83,13 @@ public void registerTypedServiceHandler(TypedServiceHandler handler Thread.startVirtualThread(() -> { T typedMessage = protocol.translateFromString(rawMessage); - R response = handler.onMessage(typedMessage); + RedisMessageContext context = RedisMessageContext.serviceToServer( + UUID.fromString(envelope.id()), + serviceId, + serverUUID.toString(), + protocol.channel() + ).asBroadcast(); + R response = handler.handle(typedMessage, context); if (response == null) return; @@ -79,7 +97,7 @@ public void registerTypedServiceHandler(TypedServiceHandler handler RedisAPI.getInstance().publishMessage( serviceId, - ChannelRegistry.getFromName("service_broadcast_response"), + ChannelRegistry.getFromName(RedisChannels.SERVICE_BROADCAST_RESPONSE), new RedisEnvelope(envelope.id(), serverUUID.toString(), serializedResponse).serialize()); }); }); diff --git a/proxy.api/src/main/java/net/swofty/proxyapi/ProxyService.java b/proxy.api/src/main/java/net/swofty/proxyapi/ProxyService.java index 4ab62136a..d4fa0047a 100644 --- a/proxy.api/src/main/java/net/swofty/proxyapi/ProxyService.java +++ b/proxy.api/src/main/java/net/swofty/proxyapi/ProxyService.java @@ -1,8 +1,8 @@ package net.swofty.proxyapi; import net.swofty.commons.ServiceType; -import net.swofty.commons.protocol.ProtocolObject; -import net.swofty.commons.protocol.objects.PingProtocolObject; +import net.swofty.commons.protocol.RedisProtocol; +import net.swofty.commons.protocol.objects.PingProtocol; import net.swofty.proxyapi.redis.ServerOutboundMessage; import java.util.concurrent.CompletableFuture; @@ -14,8 +14,8 @@ public CompletableFuture isOnline() { CompletableFuture future = new CompletableFuture<>(); AtomicBoolean hasReceivedResponse = new AtomicBoolean(false); - ServerOutboundMessage.sendMessageToService(type, new PingProtocolObject(), - new PingProtocolObject.EmptyMessage(), (s) -> { + ServerOutboundMessage.sendMessageToService(type, new PingProtocol(), + new PingProtocol.EmptyMessage(), (s) -> { future.complete(true); hasReceivedResponse.set(true); }); @@ -31,16 +31,16 @@ public CompletableFuture isOnline() { } public CompletableFuture handleRequest(T request) { - ProtocolObject protocolObject = ServerOutboundMessage.protocolObjects.get(request.getClass().getSimpleName()); + RedisProtocol protocol = ServerOutboundMessage.protocols.get(request.getClass().getSimpleName()); CompletableFuture future = new CompletableFuture<>(); Thread.startVirtualThread(() -> ServerOutboundMessage.sendMessageToService( type, - protocolObject, + protocol, request, (s) -> Thread.startVirtualThread( - () -> future.complete(protocolObject.translateReturnFromString(s)) + () -> future.complete(protocol.translateReturnFromString(s)) ) )); return future; diff --git a/proxy.api/src/main/java/net/swofty/proxyapi/redis/ServerOutboundMessage.java b/proxy.api/src/main/java/net/swofty/proxyapi/redis/ServerOutboundMessage.java index 13c61c008..05b847ecf 100644 --- a/proxy.api/src/main/java/net/swofty/proxyapi/redis/ServerOutboundMessage.java +++ b/proxy.api/src/main/java/net/swofty/proxyapi/redis/ServerOutboundMessage.java @@ -1,8 +1,8 @@ package net.swofty.proxyapi.redis; import net.swofty.commons.ServiceType; -import net.swofty.commons.impl.ServiceProxyRequest; -import net.swofty.commons.protocol.ProtocolObject; +import net.swofty.commons.protocol.RedisProtocol; +import net.swofty.commons.redis.RedisChannels; import net.swofty.commons.redis.RedisEnvelope; import net.swofty.redisapi.api.ChannelRegistry; import net.swofty.redisapi.api.RedisAPI; @@ -17,9 +17,9 @@ public class ServerOutboundMessage { private static final Map> redisMessageListeners = new HashMap<>(); - public static final Map protocolObjects = new HashMap<>(); + public static final Map protocols = new HashMap<>(); - public static void sendToProxy(ProtocolObject protocol, T request, Consumer response) { + public static void sendToProxy(RedisProtocol protocol, T request, Consumer response) { UUID uuid = UUID.randomUUID(); UUID filterID = UUID.fromString(RedisAPI.getInstance().getFilterId()); @@ -30,13 +30,13 @@ public static void sendToProxy(ProtocolObject protocol, T request, redisMessageListeners.put(uuid, consumer); String serialized = protocol.translateToString(request); - RedisAPI.getInstance().publishMessage("proxy", - ChannelRegistry.getFromName(protocol.channel()), + RedisAPI.getInstance().publishMessage(RedisChannels.PROXY_RESPONSE, + ChannelRegistry.getFromName(RedisChannels.protocol(protocol)), new RedisEnvelope(uuid.toString(), filterID.toString(), serialized).serialize()); } - public static void registerToProxyProtocol(ProtocolObject protocol) { - RedisAPI.getInstance().registerChannel(protocol.channel(), (event) -> { + public static void registerToProxyProtocol(RedisProtocol protocol) { + RedisAPI.getInstance().registerChannel(RedisChannels.protocol(protocol), (event) -> { String messageWithoutFilter = event.message.substring(event.message.indexOf(";") + 1); RedisEnvelope envelope = RedisEnvelope.deserialize(messageWithoutFilter); @@ -47,11 +47,11 @@ public static void registerToProxyProtocol(ProtocolObject protocol) { }); } - public static void registerFromProtocolObject(ProtocolObject object) { - String requestTypeName = getRequestTypeName(object); - protocolObjects.put(requestTypeName, object); + public static void registerResponseProtocol(RedisProtocol protocol) { + String requestTypeName = getRequestTypeName(protocol); + protocols.put(requestTypeName, protocol); - RedisAPI.getInstance().registerChannel(object.channel(), (event) -> { + RedisAPI.getInstance().registerChannel(RedisChannels.protocol(protocol), (event) -> { String messageWithoutFilter = event.message.substring(event.message.indexOf(";") + 1); RedisEnvelope envelope = RedisEnvelope.deserialize(messageWithoutFilter); @@ -68,7 +68,7 @@ public static void registerFromProtocolObject(ProtocolObject object) { } public static void sendMessageToService(ServiceType service, - ProtocolObject specification, + RedisProtocol specification, Object rawMessage, Consumer response) { UUID requestId = UUID.randomUUID(); @@ -81,12 +81,11 @@ public static void sendMessageToService(ServiceType service, RedisAPI.getInstance().publishMessage(service.name(), ChannelRegistry.getFromName(specification.channel()), - new ServiceProxyRequest(requestId, callbackId, - specification.channel(), message).toJSON().toString()); + new RedisEnvelope(requestId.toString(), callbackId, message).serialize()); } public static void sendMessageToServiceFireAndForget(ServiceType service, - ProtocolObject specification, + RedisProtocol specification, Object rawMessage) { UUID requestId = UUID.randomUUID(); String callback = null; @@ -99,23 +98,18 @@ public static void sendMessageToServiceFireAndForget(ServiceType service, RedisAPI.getInstance().publishMessage( service.name(), ChannelRegistry.getFromName(specification.channel()), - new ServiceProxyRequest( - requestId, - callback != null ? callback : "proxy", - specification.channel(), - message - ).toJSON().toString() + new RedisEnvelope(requestId.toString(), callback != null ? callback : "proxy", message).serialize() ); } - public static void sendMessageToAllServicesFireAndForget(ProtocolObject specification, + public static void sendMessageToAllServicesFireAndForget(RedisProtocol specification, Object rawMessage) { for (ServiceType serviceType : ServiceType.values()) { sendMessageToServiceFireAndForget(serviceType, specification, rawMessage); } } - private static String getRequestTypeName(ProtocolObject protocolObject) { + private static String getRequestTypeName(RedisProtocol protocolObject) { Class clazz = protocolObject.getClass(); Type genericSuperclass = clazz.getGenericSuperclass(); @@ -131,6 +125,6 @@ private static String getRequestTypeName(ProtocolObject protocolObject) { } } - throw new IllegalArgumentException("Could not determine the type T for the given ProtocolObject"); + throw new IllegalArgumentException("Could not determine the type T for the given RedisProtocol"); } } diff --git a/proxy.api/src/main/java/net/swofty/proxyapi/redis/TypedProxyHandler.java b/proxy.api/src/main/java/net/swofty/proxyapi/redis/TypedProxyHandler.java deleted file mode 100644 index e61dc1e5c..000000000 --- a/proxy.api/src/main/java/net/swofty/proxyapi/redis/TypedProxyHandler.java +++ /dev/null @@ -1,8 +0,0 @@ -package net.swofty.proxyapi.redis; - -import net.swofty.commons.protocol.ProtocolObject; - -public interface TypedProxyHandler { - ProtocolObject getProtocol(); - R onMessage(T message); -} diff --git a/proxy.api/src/main/java/net/swofty/proxyapi/redis/TypedServiceHandler.java b/proxy.api/src/main/java/net/swofty/proxyapi/redis/TypedServiceHandler.java deleted file mode 100644 index dbac08ec0..000000000 --- a/proxy.api/src/main/java/net/swofty/proxyapi/redis/TypedServiceHandler.java +++ /dev/null @@ -1,8 +0,0 @@ -package net.swofty.proxyapi.redis; - -import net.swofty.commons.protocol.ServicePushProtocol; - -public interface TypedServiceHandler { - ServicePushProtocol getProtocol(); - R onMessage(T message); -} diff --git a/service.api/src/main/java/net/swofty/service/api/APIService.java b/service.api/src/main/java/net/swofty/service/api/APIService.java index 35fe4f06a..4db4bb334 100644 --- a/service.api/src/main/java/net/swofty/service/api/APIService.java +++ b/service.api/src/main/java/net/swofty/service/api/APIService.java @@ -9,7 +9,7 @@ import net.swofty.service.api.http.APIResponse; import net.swofty.service.api.http.SkyBlockEndpoint; import net.swofty.service.generic.SkyBlockService; -import net.swofty.service.generic.redis.ServiceEndpoint; +import net.swofty.commons.redis.RedisMessageHandler; import net.swofty.type.generic.data.mongodb.ProfilesDatabase; import net.swofty.type.generic.data.mongodb.UserDatabase; import org.jetbrains.annotations.Nullable; @@ -140,8 +140,8 @@ public ServiceType getType() { } @Override - public List getEndpoints() { - return loopThroughPackage("net.swofty.service.api.endpoints", ServiceEndpoint.class).toList(); + public List getEndpoints() { + return loopThroughPackage("net.swofty.service.api.endpoints", RedisMessageHandler.class).toList(); } } diff --git a/service.api/src/main/java/net/swofty/service/api/endpoints/EndpointAuthenticateCode.java b/service.api/src/main/java/net/swofty/service/api/endpoints/EndpointAuthenticateCode.java index 15e1d7c30..e633d4bbf 100644 --- a/service.api/src/main/java/net/swofty/service/api/endpoints/EndpointAuthenticateCode.java +++ b/service.api/src/main/java/net/swofty/service/api/endpoints/EndpointAuthenticateCode.java @@ -1,29 +1,27 @@ package net.swofty.service.api.endpoints; -import net.swofty.commons.impl.ServiceProxyRequest; -import net.swofty.commons.protocol.objects.api.APIAuthenticateCodeProtocolObject; +import net.swofty.commons.protocol.objects.api.APIAuthenticateCodeProtocol; import net.swofty.service.api.APIAdminDatabase; import net.swofty.service.api.APIAdminDatabaseObject; -import net.swofty.service.generic.redis.ServiceEndpoint; +import net.swofty.commons.redis.RedisMessageHandler; import org.jetbrains.annotations.Nullable; +import net.swofty.commons.redis.RedisMessageContext; -public class EndpointAuthenticateCode implements ServiceEndpoint< - APIAuthenticateCodeProtocolObject.AuthenticateCodeMessage, - APIAuthenticateCodeProtocolObject.AuthenticateCodeResponse> { +public class EndpointAuthenticateCode implements RedisMessageHandler< + APIAuthenticateCodeProtocol.AuthenticateCodeMessage, + APIAuthenticateCodeProtocol.AuthenticateCodeResponse> { @Override - public APIAuthenticateCodeProtocolObject associatedProtocolObject() { - return new APIAuthenticateCodeProtocolObject(); + public APIAuthenticateCodeProtocol protocol() { + return new APIAuthenticateCodeProtocol(); } @Override - public APIAuthenticateCodeProtocolObject.AuthenticateCodeResponse onMessage( - ServiceProxyRequest message, - APIAuthenticateCodeProtocolObject.AuthenticateCodeMessage messageObject) { + public APIAuthenticateCodeProtocol.AuthenticateCodeResponse handle(APIAuthenticateCodeProtocol.AuthenticateCodeMessage messageObject, RedisMessageContext context) { @Nullable APIAdminDatabaseObject document = APIAdminDatabase.getFromCode(messageObject.authCode()); if (document == null) { - return new APIAuthenticateCodeProtocolObject.AuthenticateCodeResponse(false, "Authentication failed"); + return new APIAuthenticateCodeProtocol.AuthenticateCodeResponse(false, "Authentication failed"); } document.setAuthenticatorName(messageObject.playerName()); @@ -31,6 +29,6 @@ public APIAuthenticateCodeProtocolObject.AuthenticateCodeResponse onMessage( APIAdminDatabase.replaceOrInsert(document); - return new APIAuthenticateCodeProtocolObject.AuthenticateCodeResponse(true, null); + return new APIAuthenticateCodeProtocol.AuthenticateCodeResponse(true, null); } } diff --git a/service.auctionhouse/src/main/java/net/swofty/service/auction/AuctionService.java b/service.auctionhouse/src/main/java/net/swofty/service/auction/AuctionService.java index 3e558eb52..390689b9a 100644 --- a/service.auctionhouse/src/main/java/net/swofty/service/auction/AuctionService.java +++ b/service.auctionhouse/src/main/java/net/swofty/service/auction/AuctionService.java @@ -3,7 +3,7 @@ import net.swofty.commons.ServiceType; import net.swofty.commons.config.ConfigProvider; import net.swofty.service.generic.SkyBlockService; -import net.swofty.service.generic.redis.ServiceEndpoint; +import net.swofty.commons.redis.RedisMessageHandler; import java.util.List; @@ -25,7 +25,7 @@ public ServiceType getType() { } @Override - public List getEndpoints() { - return loopThroughPackage("net.swofty.service.auction.endpoints", ServiceEndpoint.class).toList(); + public List getEndpoints() { + return loopThroughPackage("net.swofty.service.auction.endpoints", RedisMessageHandler.class).toList(); } } diff --git a/service.auctionhouse/src/main/java/net/swofty/service/auction/endpoints/EndpointAddItem.java b/service.auctionhouse/src/main/java/net/swofty/service/auction/endpoints/EndpointAddItem.java index 3034246f2..03c8bca94 100644 --- a/service.auctionhouse/src/main/java/net/swofty/service/auction/endpoints/EndpointAddItem.java +++ b/service.auctionhouse/src/main/java/net/swofty/service/auction/endpoints/EndpointAddItem.java @@ -2,26 +2,26 @@ import net.swofty.commons.skyblock.auctions.AuctionCategories; import net.swofty.commons.skyblock.auctions.AuctionItem; -import net.swofty.commons.impl.ServiceProxyRequest; import net.swofty.commons.skyblock.item.UnderstandableSkyBlockItem; -import net.swofty.commons.protocol.objects.auctions.AuctionAddItemProtocolObject; +import net.swofty.commons.protocol.objects.auctions.AuctionAddItemProtocol; import net.swofty.service.auction.AuctionActiveDatabase; -import net.swofty.service.generic.redis.ServiceEndpoint; +import net.swofty.commons.redis.RedisMessageHandler; import org.bson.Document; import java.util.UUID; +import net.swofty.commons.redis.RedisMessageContext; -public class EndpointAddItem implements ServiceEndpoint< - AuctionAddItemProtocolObject.AuctionAddItemMessage, - AuctionAddItemProtocolObject.AuctionAddItemResponse> { +public class EndpointAddItem implements RedisMessageHandler< + AuctionAddItemProtocol.AuctionAddItemMessage, + AuctionAddItemProtocol.AuctionAddItemResponse> { @Override - public AuctionAddItemProtocolObject associatedProtocolObject() { - return new AuctionAddItemProtocolObject(); + public AuctionAddItemProtocol protocol() { + return new AuctionAddItemProtocol(); } @Override - public AuctionAddItemProtocolObject.AuctionAddItemResponse onMessage(ServiceProxyRequest message, AuctionAddItemProtocolObject.AuctionAddItemMessage messageObject) { + public AuctionAddItemProtocol.AuctionAddItemResponse handle(AuctionAddItemProtocol.AuctionAddItemMessage messageObject, RedisMessageContext context) { AuctionItem auctionItem = messageObject.item(); UnderstandableSkyBlockItem item = auctionItem.getItem(); item.getAttribute("item_type").setValue("HYPERION"); @@ -41,6 +41,6 @@ public AuctionAddItemProtocolObject.AuctionAddItemResponse onMessage(ServiceProx } }); - return new AuctionAddItemProtocolObject.AuctionAddItemResponse(UUID.fromString((String) document.get("_id")), true, null); + return new AuctionAddItemProtocol.AuctionAddItemResponse(UUID.fromString((String) document.get("_id")), true, null); } } diff --git a/service.auctionhouse/src/main/java/net/swofty/service/auction/endpoints/EndpointFetchItem.java b/service.auctionhouse/src/main/java/net/swofty/service/auction/endpoints/EndpointFetchItem.java index 7b69b8e81..8c99f9536 100644 --- a/service.auctionhouse/src/main/java/net/swofty/service/auction/endpoints/EndpointFetchItem.java +++ b/service.auctionhouse/src/main/java/net/swofty/service/auction/endpoints/EndpointFetchItem.java @@ -1,26 +1,26 @@ package net.swofty.service.auction.endpoints; import net.swofty.commons.skyblock.auctions.AuctionItem; -import net.swofty.commons.impl.ServiceProxyRequest; -import net.swofty.commons.protocol.objects.auctions.AuctionFetchItemProtocolObject; +import net.swofty.commons.protocol.objects.auctions.AuctionFetchItemProtocol; import net.swofty.service.auction.AuctionActiveDatabase; import net.swofty.service.auction.AuctionInactiveDatabase; -import net.swofty.service.generic.redis.ServiceEndpoint; +import net.swofty.commons.redis.RedisMessageHandler; import org.bson.Document; import java.util.UUID; +import net.swofty.commons.redis.RedisMessageContext; -public class EndpointFetchItem implements ServiceEndpoint< - AuctionFetchItemProtocolObject.AuctionFetchItemMessage, - AuctionFetchItemProtocolObject.AuctionFetchItemResponse> { +public class EndpointFetchItem implements RedisMessageHandler< + AuctionFetchItemProtocol.AuctionFetchItemMessage, + AuctionFetchItemProtocol.AuctionFetchItemResponse> { @Override - public AuctionFetchItemProtocolObject associatedProtocolObject() { - return new AuctionFetchItemProtocolObject(); + public AuctionFetchItemProtocol protocol() { + return new AuctionFetchItemProtocol(); } @Override - public AuctionFetchItemProtocolObject.AuctionFetchItemResponse onMessage(ServiceProxyRequest message, AuctionFetchItemProtocolObject.AuctionFetchItemMessage messageObject) { + public AuctionFetchItemProtocol.AuctionFetchItemResponse handle(AuctionFetchItemProtocol.AuctionFetchItemMessage messageObject, RedisMessageContext context) { UUID uuidToFetch = messageObject.uuid(); AuctionItem toReturn = new AuctionItem(); @@ -35,6 +35,6 @@ public AuctionFetchItemProtocolObject.AuctionFetchItemResponse onMessage(Service toReturn = AuctionItem.fromDocument(inactiveItem); } - return new AuctionFetchItemProtocolObject.AuctionFetchItemResponse(toReturn, true, null); + return new AuctionFetchItemProtocol.AuctionFetchItemResponse(toReturn, true, null); } } diff --git a/service.auctionhouse/src/main/java/net/swofty/service/auction/endpoints/EndpointFetchItems.java b/service.auctionhouse/src/main/java/net/swofty/service/auction/endpoints/EndpointFetchItems.java index 09c5de06c..07ff7d5c7 100644 --- a/service.auctionhouse/src/main/java/net/swofty/service/auction/endpoints/EndpointFetchItems.java +++ b/service.auctionhouse/src/main/java/net/swofty/service/auction/endpoints/EndpointFetchItems.java @@ -3,27 +3,27 @@ import net.swofty.commons.skyblock.auctions.AuctionCategories; import net.swofty.commons.skyblock.auctions.AuctionsFilter; import net.swofty.commons.skyblock.auctions.AuctionsSorting; -import net.swofty.commons.impl.ServiceProxyRequest; -import net.swofty.commons.protocol.objects.auctions.AuctionFetchItemsProtocolObject; +import net.swofty.commons.protocol.objects.auctions.AuctionFetchItemsProtocol; import net.swofty.service.auction.AuctionService; -import net.swofty.service.generic.redis.ServiceEndpoint; +import net.swofty.commons.redis.RedisMessageHandler; import net.swofty.commons.skyblock.auctions.AuctionItem; import org.bson.Document; import java.util.ArrayList; import java.util.List; +import net.swofty.commons.redis.RedisMessageContext; -public class EndpointFetchItems implements ServiceEndpoint< - AuctionFetchItemsProtocolObject.AuctionFetchItemsMessage, - AuctionFetchItemsProtocolObject.AuctionFetchItemsResponse> { +public class EndpointFetchItems implements RedisMessageHandler< + AuctionFetchItemsProtocol.AuctionFetchItemsMessage, + AuctionFetchItemsProtocol.AuctionFetchItemsResponse> { @Override - public AuctionFetchItemsProtocolObject associatedProtocolObject() { - return new AuctionFetchItemsProtocolObject(); + public AuctionFetchItemsProtocol protocol() { + return new AuctionFetchItemsProtocol(); } @Override - public AuctionFetchItemsProtocolObject.AuctionFetchItemsResponse onMessage(ServiceProxyRequest message, AuctionFetchItemsProtocolObject.AuctionFetchItemsMessage messageObject) { + public AuctionFetchItemsProtocol.AuctionFetchItemsResponse handle(AuctionFetchItemsProtocol.AuctionFetchItemsMessage messageObject, RedisMessageContext context) { AuctionsSorting sorting = messageObject.sorting(); AuctionsFilter filter = messageObject.filter(); AuctionCategories category = messageObject.category(); @@ -31,7 +31,7 @@ public AuctionFetchItemsProtocolObject.AuctionFetchItemsResponse onMessage(Servi List results = AuctionService.cacheService.getAuctions(category.toString(), filter); if (results.isEmpty()) { - return new AuctionFetchItemsProtocolObject.AuctionFetchItemsResponse(new ArrayList<>(), true, null); + return new AuctionFetchItemsProtocol.AuctionFetchItemsResponse(new ArrayList<>(), true, null); } // Sort according to sorting @@ -66,6 +66,6 @@ public AuctionFetchItemsProtocolObject.AuctionFetchItemsResponse onMessage(Servi break; } - return new AuctionFetchItemsProtocolObject.AuctionFetchItemsResponse(results.stream().map(AuctionItem::fromDocument).toList(), true, null); + return new AuctionFetchItemsProtocol.AuctionFetchItemsResponse(results.stream().map(AuctionItem::fromDocument).toList(), true, null); } } diff --git a/service.bazaar/src/main/java/net/swofty/service/bazaar/BazaarService.java b/service.bazaar/src/main/java/net/swofty/service/bazaar/BazaarService.java index 00b07feb5..db6d0f007 100644 --- a/service.bazaar/src/main/java/net/swofty/service/bazaar/BazaarService.java +++ b/service.bazaar/src/main/java/net/swofty/service/bazaar/BazaarService.java @@ -3,7 +3,7 @@ import net.swofty.commons.ServiceType; import net.swofty.commons.config.ConfigProvider; import net.swofty.service.generic.SkyBlockService; -import net.swofty.service.generic.redis.ServiceEndpoint; +import net.swofty.commons.redis.RedisMessageHandler; import java.util.List; @@ -27,7 +27,7 @@ public ServiceType getType() { } @Override - public List getEndpoints() { - return loopThroughPackage("net.swofty.service.bazaar.endpoints", ServiceEndpoint.class).toList(); + public List getEndpoints() { + return loopThroughPackage("net.swofty.service.bazaar.endpoints", RedisMessageHandler.class).toList(); } } \ No newline at end of file diff --git a/service.bazaar/src/main/java/net/swofty/service/bazaar/endpoints/EndpointBazaarBuyOrder.java b/service.bazaar/src/main/java/net/swofty/service/bazaar/endpoints/EndpointBazaarBuyOrder.java index ef5b3e594..6e4f49717 100644 --- a/service.bazaar/src/main/java/net/swofty/service/bazaar/endpoints/EndpointBazaarBuyOrder.java +++ b/service.bazaar/src/main/java/net/swofty/service/bazaar/endpoints/EndpointBazaarBuyOrder.java @@ -1,26 +1,24 @@ package net.swofty.service.bazaar.endpoints; -import net.swofty.commons.impl.ServiceProxyRequest; -import net.swofty.commons.protocol.objects.bazaar.BazaarBuyProtocolObject; +import net.swofty.commons.protocol.objects.bazaar.BazaarBuyProtocol; import net.swofty.service.bazaar.BazaarMarket; -import net.swofty.service.generic.redis.ServiceEndpoint; +import net.swofty.commons.redis.RedisMessageHandler; import org.tinylog.Logger; import java.util.UUID; +import net.swofty.commons.redis.RedisMessageContext; -public class EndpointBazaarBuyOrder implements ServiceEndpoint< - BazaarBuyProtocolObject.BazaarBuyMessage, - BazaarBuyProtocolObject.BazaarBuyResponse> { +public class EndpointBazaarBuyOrder implements RedisMessageHandler< + BazaarBuyProtocol.BazaarBuyMessage, + BazaarBuyProtocol.BazaarBuyResponse> { @Override - public BazaarBuyProtocolObject associatedProtocolObject() { - return new BazaarBuyProtocolObject(); + public BazaarBuyProtocol protocol() { + return new BazaarBuyProtocol(); } @Override - public BazaarBuyProtocolObject.BazaarBuyResponse onMessage( - ServiceProxyRequest message, - BazaarBuyProtocolObject.BazaarBuyMessage msg) { + public BazaarBuyProtocol.BazaarBuyResponse handle(BazaarBuyProtocol.BazaarBuyMessage msg, RedisMessageContext context) { String itemName = msg.itemName(); UUID playerUUID = msg.playerUUID(); @@ -32,10 +30,10 @@ public BazaarBuyProtocolObject.BazaarBuyResponse onMessage( BazaarMarket.get().submitBuy(itemName, playerUUID, profileUUID, price, amount); Logger.info("Buy order submitted for {} by {} (profile: {}) — price={}, amount={}", itemName, playerUUID, profileUUID, price, amount); - return new BazaarBuyProtocolObject.BazaarBuyResponse(true, null); + return new BazaarBuyProtocol.BazaarBuyResponse(true, null); } catch (Exception e) { Logger.error(e, "Failed to submit buy order for {} by {}", itemName, playerUUID); - return new BazaarBuyProtocolObject.BazaarBuyResponse(false, "Buy order failed"); + return new BazaarBuyProtocol.BazaarBuyResponse(false, "Buy order failed"); } } } diff --git a/service.bazaar/src/main/java/net/swofty/service/bazaar/endpoints/EndpointBazaarSellOrder.java b/service.bazaar/src/main/java/net/swofty/service/bazaar/endpoints/EndpointBazaarSellOrder.java index afc2decac..8ba8afece 100644 --- a/service.bazaar/src/main/java/net/swofty/service/bazaar/endpoints/EndpointBazaarSellOrder.java +++ b/service.bazaar/src/main/java/net/swofty/service/bazaar/endpoints/EndpointBazaarSellOrder.java @@ -1,27 +1,25 @@ package net.swofty.service.bazaar.endpoints; -import net.swofty.commons.impl.ServiceProxyRequest; -import net.swofty.commons.protocol.ProtocolObject; -import net.swofty.commons.protocol.objects.bazaar.BazaarSellProtocolObject; +import net.swofty.commons.protocol.RedisProtocol; +import net.swofty.commons.protocol.objects.bazaar.BazaarSellProtocol; import net.swofty.service.bazaar.BazaarMarket; -import net.swofty.service.generic.redis.ServiceEndpoint; +import net.swofty.commons.redis.RedisMessageHandler; import org.tinylog.Logger; import java.util.UUID; +import net.swofty.commons.redis.RedisMessageContext; -public class EndpointBazaarSellOrder implements ServiceEndpoint< - BazaarSellProtocolObject.BazaarSellMessage, - BazaarSellProtocolObject.BazaarSellResponse> { +public class EndpointBazaarSellOrder implements RedisMessageHandler< + BazaarSellProtocol.BazaarSellMessage, + BazaarSellProtocol.BazaarSellResponse> { @Override - public ProtocolObject associatedProtocolObject() { - return new BazaarSellProtocolObject(); + public RedisProtocol protocol() { + return new BazaarSellProtocol(); } @Override - public BazaarSellProtocolObject.BazaarSellResponse onMessage( - ServiceProxyRequest message, - BazaarSellProtocolObject.BazaarSellMessage msg) { + public BazaarSellProtocol.BazaarSellResponse handle(BazaarSellProtocol.BazaarSellMessage msg, RedisMessageContext context) { String itemName = msg.itemName(); UUID playerUUID = msg.playerUUID(); @@ -33,10 +31,10 @@ public BazaarSellProtocolObject.BazaarSellResponse onMessage( BazaarMarket.get().submitSell(itemName, playerUUID, profileUUID, price, amount); Logger.info("Sell order submitted for {} by {} (profile: {}) — price={}, amount={}", itemName, playerUUID, profileUUID, price, amount); - return new BazaarSellProtocolObject.BazaarSellResponse(true, null); + return new BazaarSellProtocol.BazaarSellResponse(true, null); } catch (Exception e) { Logger.error(e, "Failed to submit sell order for {} by {}", itemName, playerUUID); - return new BazaarSellProtocolObject.BazaarSellResponse(false, "Sell order failed"); + return new BazaarSellProtocol.BazaarSellResponse(false, "Sell order failed"); } } } diff --git a/service.bazaar/src/main/java/net/swofty/service/bazaar/endpoints/EndpointCancelBazaarOrder.java b/service.bazaar/src/main/java/net/swofty/service/bazaar/endpoints/EndpointCancelBazaarOrder.java index ed9c201bb..65dbc6882 100644 --- a/service.bazaar/src/main/java/net/swofty/service/bazaar/endpoints/EndpointCancelBazaarOrder.java +++ b/service.bazaar/src/main/java/net/swofty/service/bazaar/endpoints/EndpointCancelBazaarOrder.java @@ -1,25 +1,25 @@ package net.swofty.service.bazaar.endpoints; import com.mongodb.client.model.Filters; -import net.swofty.commons.impl.ServiceProxyRequest; -import net.swofty.commons.protocol.objects.bazaar.BazaarCancelProtocolObject; -import net.swofty.commons.protocol.objects.bazaar.BazaarCancelProtocolObject.CancelMessage; -import net.swofty.commons.protocol.objects.bazaar.BazaarCancelProtocolObject.CancelResponse; +import net.swofty.commons.protocol.objects.bazaar.BazaarCancelProtocol; +import net.swofty.commons.protocol.objects.bazaar.BazaarCancelProtocol.CancelMessage; +import net.swofty.commons.protocol.objects.bazaar.BazaarCancelProtocol.CancelResponse; import net.swofty.service.bazaar.BazaarMarket; import net.swofty.service.bazaar.OrderDatabase; -import net.swofty.service.generic.redis.ServiceEndpoint; +import net.swofty.commons.redis.RedisMessageHandler; import org.tinylog.Logger; +import net.swofty.commons.redis.RedisMessageContext; -public class EndpointCancelBazaarOrder implements ServiceEndpoint< +public class EndpointCancelBazaarOrder implements RedisMessageHandler< CancelMessage, CancelResponse> { @Override - public BazaarCancelProtocolObject associatedProtocolObject() { - return new BazaarCancelProtocolObject(); + public BazaarCancelProtocol protocol() { + return new BazaarCancelProtocol(); } @Override - public CancelResponse onMessage(ServiceProxyRequest _msg, CancelMessage msg) { + public CancelResponse handle(CancelMessage msg, RedisMessageContext context) { var result = OrderDatabase.ordersCollection.deleteOne( Filters.and( Filters.eq("_id", msg.orderId().toString()), diff --git a/service.bazaar/src/main/java/net/swofty/service/bazaar/endpoints/EndpointGetBazaarItem.java b/service.bazaar/src/main/java/net/swofty/service/bazaar/endpoints/EndpointGetBazaarItem.java index a4b670d8e..a8aae0dc3 100644 --- a/service.bazaar/src/main/java/net/swofty/service/bazaar/endpoints/EndpointGetBazaarItem.java +++ b/service.bazaar/src/main/java/net/swofty/service/bazaar/endpoints/EndpointGetBazaarItem.java @@ -1,27 +1,25 @@ package net.swofty.service.bazaar.endpoints; -import net.swofty.commons.impl.ServiceProxyRequest; -import net.swofty.commons.protocol.objects.bazaar.BazaarGetItemProtocolObject; -import net.swofty.commons.protocol.objects.bazaar.BazaarGetItemProtocolObject.OrderRecord; +import net.swofty.commons.protocol.objects.bazaar.BazaarGetItemProtocol; +import net.swofty.commons.protocol.objects.bazaar.BazaarGetItemProtocol.OrderRecord; import net.swofty.service.bazaar.BazaarMarket; -import net.swofty.service.generic.redis.ServiceEndpoint; +import net.swofty.commons.redis.RedisMessageHandler; import java.util.List; import java.util.stream.Collectors; +import net.swofty.commons.redis.RedisMessageContext; -public class EndpointGetBazaarItem implements ServiceEndpoint< - BazaarGetItemProtocolObject.BazaarGetItemMessage, - BazaarGetItemProtocolObject.BazaarGetItemResponse> { +public class EndpointGetBazaarItem implements RedisMessageHandler< + BazaarGetItemProtocol.BazaarGetItemMessage, + BazaarGetItemProtocol.BazaarGetItemResponse> { @Override - public BazaarGetItemProtocolObject associatedProtocolObject() { - return new BazaarGetItemProtocolObject(); + public BazaarGetItemProtocol protocol() { + return new BazaarGetItemProtocol(); } @Override - public BazaarGetItemProtocolObject.BazaarGetItemResponse onMessage( - ServiceProxyRequest message, - BazaarGetItemProtocolObject.BazaarGetItemMessage msg) { + public BazaarGetItemProtocol.BazaarGetItemResponse handle(BazaarGetItemProtocol.BazaarGetItemMessage msg, RedisMessageContext context) { String itemName = msg.itemName(); @@ -48,7 +46,7 @@ public BazaarGetItemProtocolObject.BazaarGetItemResponse onMessage( )) .collect(Collectors.toList()); - return new BazaarGetItemProtocolObject.BazaarGetItemResponse( + return new BazaarGetItemProtocol.BazaarGetItemResponse( itemName, buyOrderRecords, sellOrderRecords, diff --git a/service.bazaar/src/main/java/net/swofty/service/bazaar/endpoints/EndpointGetPendingOrders.java b/service.bazaar/src/main/java/net/swofty/service/bazaar/endpoints/EndpointGetPendingOrders.java index afb92d37f..6040162fc 100644 --- a/service.bazaar/src/main/java/net/swofty/service/bazaar/endpoints/EndpointGetPendingOrders.java +++ b/service.bazaar/src/main/java/net/swofty/service/bazaar/endpoints/EndpointGetPendingOrders.java @@ -1,30 +1,28 @@ package net.swofty.service.bazaar.endpoints; import com.mongodb.client.model.Filters; -import net.swofty.commons.protocol.objects.bazaar.BazaarGetPendingOrdersProtocolObject; -import net.swofty.commons.protocol.objects.bazaar.BazaarGetPendingOrdersProtocolObject.PendingOrder; -import net.swofty.commons.impl.ServiceProxyRequest; +import net.swofty.commons.protocol.objects.bazaar.BazaarGetPendingOrdersProtocol; +import net.swofty.commons.protocol.objects.bazaar.BazaarGetPendingOrdersProtocol.PendingOrder; import net.swofty.service.bazaar.OrderDatabase; -import net.swofty.service.generic.redis.ServiceEndpoint; +import net.swofty.commons.redis.RedisMessageHandler; import org.bson.Document; import java.util.ArrayList; import java.util.List; import java.util.UUID; +import net.swofty.commons.redis.RedisMessageContext; -public class EndpointGetPendingOrders implements ServiceEndpoint< - BazaarGetPendingOrdersProtocolObject.BazaarGetPendingOrdersMessage, - BazaarGetPendingOrdersProtocolObject.BazaarGetPendingOrdersResponse> { +public class EndpointGetPendingOrders implements RedisMessageHandler< + BazaarGetPendingOrdersProtocol.BazaarGetPendingOrdersMessage, + BazaarGetPendingOrdersProtocol.BazaarGetPendingOrdersResponse> { @Override - public BazaarGetPendingOrdersProtocolObject associatedProtocolObject() { - return new BazaarGetPendingOrdersProtocolObject(); + public BazaarGetPendingOrdersProtocol protocol() { + return new BazaarGetPendingOrdersProtocol(); } @Override - public BazaarGetPendingOrdersProtocolObject.BazaarGetPendingOrdersResponse onMessage( - ServiceProxyRequest message, - BazaarGetPendingOrdersProtocolObject.BazaarGetPendingOrdersMessage msg) { + public BazaarGetPendingOrdersProtocol.BazaarGetPendingOrdersResponse handle(BazaarGetPendingOrdersProtocol.BazaarGetPendingOrdersMessage msg, RedisMessageContext context) { UUID player = msg.playerUUID(); UUID profile = msg.profileUUID(); @@ -48,6 +46,6 @@ public BazaarGetPendingOrdersProtocolObject.BazaarGetPendingOrdersResponse onMes )); } - return new BazaarGetPendingOrdersProtocolObject.BazaarGetPendingOrdersResponse(out, true, null); + return new BazaarGetPendingOrdersProtocol.BazaarGetPendingOrdersResponse(out, true, null); } } diff --git a/service.bazaar/src/main/java/net/swofty/service/bazaar/endpoints/EndpointGetPendingTransactions.java b/service.bazaar/src/main/java/net/swofty/service/bazaar/endpoints/EndpointGetPendingTransactions.java index 9e227226d..bd6918583 100644 --- a/service.bazaar/src/main/java/net/swofty/service/bazaar/endpoints/EndpointGetPendingTransactions.java +++ b/service.bazaar/src/main/java/net/swofty/service/bazaar/endpoints/EndpointGetPendingTransactions.java @@ -1,29 +1,27 @@ package net.swofty.service.bazaar.endpoints; -import net.swofty.commons.impl.ServiceProxyRequest; -import net.swofty.commons.protocol.objects.bazaar.BazaarGetPendingTransactionsProtocolObject; -import net.swofty.commons.protocol.objects.bazaar.BazaarGetPendingTransactionsProtocolObject.BazaarGetPendingTransactionsMessage; -import net.swofty.commons.protocol.objects.bazaar.BazaarGetPendingTransactionsProtocolObject.BazaarGetPendingTransactionsResponse; -import net.swofty.commons.protocol.objects.bazaar.BazaarGetPendingTransactionsProtocolObject.PendingTransactionInfo; +import net.swofty.commons.protocol.objects.bazaar.BazaarGetPendingTransactionsProtocol; +import net.swofty.commons.protocol.objects.bazaar.BazaarGetPendingTransactionsProtocol.BazaarGetPendingTransactionsMessage; +import net.swofty.commons.protocol.objects.bazaar.BazaarGetPendingTransactionsProtocol.BazaarGetPendingTransactionsResponse; +import net.swofty.commons.protocol.objects.bazaar.BazaarGetPendingTransactionsProtocol.PendingTransactionInfo; import net.swofty.service.bazaar.PendingTransactionsDatabase; -import net.swofty.service.generic.redis.ServiceEndpoint; +import net.swofty.commons.redis.RedisMessageHandler; import org.tinylog.Logger; import java.util.List; +import net.swofty.commons.redis.RedisMessageContext; -public class EndpointGetPendingTransactions implements ServiceEndpoint< +public class EndpointGetPendingTransactions implements RedisMessageHandler< BazaarGetPendingTransactionsMessage, BazaarGetPendingTransactionsResponse> { @Override - public BazaarGetPendingTransactionsProtocolObject associatedProtocolObject() { - return new BazaarGetPendingTransactionsProtocolObject(); + public BazaarGetPendingTransactionsProtocol protocol() { + return new BazaarGetPendingTransactionsProtocol(); } @Override - public BazaarGetPendingTransactionsResponse onMessage( - ServiceProxyRequest message, - BazaarGetPendingTransactionsMessage msg) { + public BazaarGetPendingTransactionsResponse handle(BazaarGetPendingTransactionsMessage msg, RedisMessageContext context) { List pendingTransactions = PendingTransactionsDatabase.getPendingTransactions(msg.playerUUID(), msg.profileUUID()); diff --git a/service.bazaar/src/main/java/net/swofty/service/bazaar/endpoints/EndpointProcessPendingTransactions.java b/service.bazaar/src/main/java/net/swofty/service/bazaar/endpoints/EndpointProcessPendingTransactions.java index 1d2ab15ac..d0afc207b 100644 --- a/service.bazaar/src/main/java/net/swofty/service/bazaar/endpoints/EndpointProcessPendingTransactions.java +++ b/service.bazaar/src/main/java/net/swofty/service/bazaar/endpoints/EndpointProcessPendingTransactions.java @@ -1,29 +1,27 @@ package net.swofty.service.bazaar.endpoints; -import net.swofty.commons.impl.ServiceProxyRequest; -import net.swofty.commons.protocol.objects.bazaar.BazaarProcessPendingTransactionsProtocolObject; -import net.swofty.commons.protocol.objects.bazaar.BazaarProcessPendingTransactionsProtocolObject.BazaarProcessPendingTransactionsMessage; -import net.swofty.commons.protocol.objects.bazaar.BazaarProcessPendingTransactionsProtocolObject.BazaarProcessPendingTransactionsResponse; +import net.swofty.commons.protocol.objects.bazaar.BazaarProcessPendingTransactionsProtocol; +import net.swofty.commons.protocol.objects.bazaar.BazaarProcessPendingTransactionsProtocol.BazaarProcessPendingTransactionsMessage; +import net.swofty.commons.protocol.objects.bazaar.BazaarProcessPendingTransactionsProtocol.BazaarProcessPendingTransactionsResponse; import net.swofty.service.bazaar.PendingTransactionsDatabase; -import net.swofty.service.generic.redis.ServiceEndpoint; +import net.swofty.commons.redis.RedisMessageHandler; import org.tinylog.Logger; import java.util.ArrayList; import java.util.List; +import net.swofty.commons.redis.RedisMessageContext; -public class EndpointProcessPendingTransactions implements ServiceEndpoint< +public class EndpointProcessPendingTransactions implements RedisMessageHandler< BazaarProcessPendingTransactionsMessage, BazaarProcessPendingTransactionsResponse> { @Override - public BazaarProcessPendingTransactionsProtocolObject associatedProtocolObject() { - return new BazaarProcessPendingTransactionsProtocolObject(); + public BazaarProcessPendingTransactionsProtocol protocol() { + return new BazaarProcessPendingTransactionsProtocol(); } @Override - public BazaarProcessPendingTransactionsResponse onMessage( - ServiceProxyRequest message, - BazaarProcessPendingTransactionsMessage msg) { + public BazaarProcessPendingTransactionsResponse handle(BazaarProcessPendingTransactionsMessage msg, RedisMessageContext context) { List successfulIds = new ArrayList<>(); List failedIds = new ArrayList<>(); diff --git a/service.darkauction/src/main/java/net/swofty/service/darkauction/DarkAuctionService.java b/service.darkauction/src/main/java/net/swofty/service/darkauction/DarkAuctionService.java index 4d705382e..b03276ddb 100644 --- a/service.darkauction/src/main/java/net/swofty/service/darkauction/DarkAuctionService.java +++ b/service.darkauction/src/main/java/net/swofty/service/darkauction/DarkAuctionService.java @@ -2,7 +2,7 @@ import net.swofty.commons.ServiceType; import net.swofty.service.generic.SkyBlockService; -import net.swofty.service.generic.redis.ServiceEndpoint; +import net.swofty.commons.redis.RedisMessageHandler; import org.tinylog.Logger; import java.util.List; @@ -24,8 +24,8 @@ public ServiceType getType() { } @Override - public List getEndpoints() { - return loopThroughPackage("net.swofty.service.darkauction.endpoints", ServiceEndpoint.class).toList(); + public List getEndpoints() { + return loopThroughPackage("net.swofty.service.darkauction.endpoints", RedisMessageHandler.class).toList(); } public static DarkAuctionState getCurrentAuction() { diff --git a/service.darkauction/src/main/java/net/swofty/service/darkauction/endpoints/EndpointGetAuctionState.java b/service.darkauction/src/main/java/net/swofty/service/darkauction/endpoints/EndpointGetAuctionState.java index 2ca9495d8..ab2396296 100644 --- a/service.darkauction/src/main/java/net/swofty/service/darkauction/endpoints/EndpointGetAuctionState.java +++ b/service.darkauction/src/main/java/net/swofty/service/darkauction/endpoints/EndpointGetAuctionState.java @@ -1,27 +1,25 @@ package net.swofty.service.darkauction.endpoints; -import net.swofty.commons.impl.ServiceProxyRequest; -import net.swofty.commons.protocol.ProtocolObject; +import net.swofty.commons.protocol.RedisProtocol; import net.swofty.commons.protocol.objects.darkauction.GetAuctionStateProtocol; import net.swofty.service.darkauction.DarkAuctionService; import net.swofty.service.darkauction.DarkAuctionState; -import net.swofty.service.generic.redis.ServiceEndpoint; +import net.swofty.commons.redis.RedisMessageHandler; import java.util.List; +import net.swofty.commons.redis.RedisMessageContext; -public class EndpointGetAuctionState implements ServiceEndpoint< +public class EndpointGetAuctionState implements RedisMessageHandler< GetAuctionStateProtocol.GetAuctionStateMessage, GetAuctionStateProtocol.GetAuctionStateResponse> { @Override - public ProtocolObject associatedProtocolObject() { + public RedisProtocol protocol() { return new GetAuctionStateProtocol(); } @Override - public GetAuctionStateProtocol.GetAuctionStateResponse onMessage( - ServiceProxyRequest request, - GetAuctionStateProtocol.GetAuctionStateMessage msg) { + public GetAuctionStateProtocol.GetAuctionStateResponse handle(GetAuctionStateProtocol.GetAuctionStateMessage msg, RedisMessageContext context) { DarkAuctionState auction = DarkAuctionService.getCurrentAuction(); diff --git a/service.darkauction/src/main/java/net/swofty/service/darkauction/endpoints/EndpointPlaceBid.java b/service.darkauction/src/main/java/net/swofty/service/darkauction/endpoints/EndpointPlaceBid.java index d853af378..55013886b 100644 --- a/service.darkauction/src/main/java/net/swofty/service/darkauction/endpoints/EndpointPlaceBid.java +++ b/service.darkauction/src/main/java/net/swofty/service/darkauction/endpoints/EndpointPlaceBid.java @@ -1,30 +1,28 @@ package net.swofty.service.darkauction.endpoints; import net.swofty.commons.skyblock.auctions.DarkAuctionPhase; -import net.swofty.commons.impl.ServiceProxyRequest; -import net.swofty.commons.protocol.ProtocolObject; +import net.swofty.commons.protocol.RedisProtocol; import net.swofty.commons.protocol.objects.darkauction.PlaceBidProtocol; import net.swofty.service.darkauction.DarkAuctionScheduler; import net.swofty.service.darkauction.DarkAuctionService; import net.swofty.service.darkauction.DarkAuctionState; -import net.swofty.service.generic.redis.ServiceEndpoint; +import net.swofty.commons.redis.RedisMessageHandler; import org.tinylog.Logger; import java.util.UUID; +import net.swofty.commons.redis.RedisMessageContext; -public class EndpointPlaceBid implements ServiceEndpoint< +public class EndpointPlaceBid implements RedisMessageHandler< PlaceBidProtocol.PlaceBidMessage, PlaceBidProtocol.PlaceBidResponse> { @Override - public ProtocolObject associatedProtocolObject() { + public RedisProtocol protocol() { return new PlaceBidProtocol(); } @Override - public PlaceBidProtocol.PlaceBidResponse onMessage( - ServiceProxyRequest request, - PlaceBidProtocol.PlaceBidMessage msg) { + public PlaceBidProtocol.PlaceBidResponse handle(PlaceBidProtocol.PlaceBidMessage msg, RedisMessageContext context) { DarkAuctionState auction = DarkAuctionService.getCurrentAuction(); diff --git a/service.darkauction/src/main/java/net/swofty/service/darkauction/endpoints/EndpointPlayerLeftAuction.java b/service.darkauction/src/main/java/net/swofty/service/darkauction/endpoints/EndpointPlayerLeftAuction.java index 6dab429b1..da9b4d0bb 100644 --- a/service.darkauction/src/main/java/net/swofty/service/darkauction/endpoints/EndpointPlayerLeftAuction.java +++ b/service.darkauction/src/main/java/net/swofty/service/darkauction/endpoints/EndpointPlayerLeftAuction.java @@ -1,30 +1,28 @@ package net.swofty.service.darkauction.endpoints; import net.swofty.commons.skyblock.auctions.DarkAuctionPhase; -import net.swofty.commons.impl.ServiceProxyRequest; -import net.swofty.commons.protocol.ProtocolObject; +import net.swofty.commons.protocol.RedisProtocol; import net.swofty.commons.protocol.objects.darkauction.PlayerLeftAuctionProtocol; import net.swofty.service.darkauction.DarkAuctionScheduler; import net.swofty.service.darkauction.DarkAuctionService; import net.swofty.service.darkauction.DarkAuctionState; -import net.swofty.service.generic.redis.ServiceEndpoint; +import net.swofty.commons.redis.RedisMessageHandler; import org.tinylog.Logger; import java.util.UUID; +import net.swofty.commons.redis.RedisMessageContext; -public class EndpointPlayerLeftAuction implements ServiceEndpoint< +public class EndpointPlayerLeftAuction implements RedisMessageHandler< PlayerLeftAuctionProtocol.PlayerLeftMessage, PlayerLeftAuctionProtocol.PlayerLeftResponse> { @Override - public ProtocolObject associatedProtocolObject() { + public RedisProtocol protocol() { return new PlayerLeftAuctionProtocol(); } @Override - public PlayerLeftAuctionProtocol.PlayerLeftResponse onMessage( - ServiceProxyRequest request, - PlayerLeftAuctionProtocol.PlayerLeftMessage msg) { + public PlayerLeftAuctionProtocol.PlayerLeftResponse handle(PlayerLeftAuctionProtocol.PlayerLeftMessage msg, RedisMessageContext context) { DarkAuctionState auction = DarkAuctionService.getCurrentAuction(); diff --git a/service.darkauction/src/main/java/net/swofty/service/darkauction/endpoints/EndpointTriggerAuction.java b/service.darkauction/src/main/java/net/swofty/service/darkauction/endpoints/EndpointTriggerAuction.java index c2a8e4540..17aa6404b 100644 --- a/service.darkauction/src/main/java/net/swofty/service/darkauction/endpoints/EndpointTriggerAuction.java +++ b/service.darkauction/src/main/java/net/swofty/service/darkauction/endpoints/EndpointTriggerAuction.java @@ -1,26 +1,24 @@ package net.swofty.service.darkauction.endpoints; -import net.swofty.commons.impl.ServiceProxyRequest; -import net.swofty.commons.protocol.ProtocolObject; +import net.swofty.commons.protocol.RedisProtocol; import net.swofty.commons.protocol.objects.darkauction.TriggerDarkAuctionProtocol; import net.swofty.service.darkauction.DarkAuctionScheduler; import net.swofty.service.darkauction.DarkAuctionService; -import net.swofty.service.generic.redis.ServiceEndpoint; +import net.swofty.commons.redis.RedisMessageHandler; import org.tinylog.Logger; +import net.swofty.commons.redis.RedisMessageContext; -public class EndpointTriggerAuction implements ServiceEndpoint< +public class EndpointTriggerAuction implements RedisMessageHandler< TriggerDarkAuctionProtocol.TriggerMessage, TriggerDarkAuctionProtocol.TriggerResponse> { @Override - public ProtocolObject associatedProtocolObject() { + public RedisProtocol protocol() { return new TriggerDarkAuctionProtocol(); } @Override - public TriggerDarkAuctionProtocol.TriggerResponse onMessage( - ServiceProxyRequest request, - TriggerDarkAuctionProtocol.TriggerMessage msg) { + public TriggerDarkAuctionProtocol.TriggerResponse handle(TriggerDarkAuctionProtocol.TriggerMessage msg, RedisMessageContext context) { Logger.info("Received trigger request - calendarTime: {}, forced: {}", msg.calendarTime(), msg.forced()); diff --git a/service.datamutex/src/main/java/net/swofty/service/datamutex/DataMutexService.java b/service.datamutex/src/main/java/net/swofty/service/datamutex/DataMutexService.java index dbcbfddd4..ceea2af84 100644 --- a/service.datamutex/src/main/java/net/swofty/service/datamutex/DataMutexService.java +++ b/service.datamutex/src/main/java/net/swofty/service/datamutex/DataMutexService.java @@ -5,7 +5,7 @@ import net.swofty.service.datamutex.endpoints.UnlockDataEndpoint; import net.swofty.service.datamutex.endpoints.UpdateSynchronizedDataEndpoint; import net.swofty.service.generic.SkyBlockService; -import net.swofty.service.generic.redis.ServiceEndpoint; +import net.swofty.commons.redis.RedisMessageHandler; import java.util.List; @@ -16,7 +16,7 @@ public ServiceType getType() { } @Override - public List getEndpoints() { + public List getEndpoints() { return List.of( new SynchronizeDataEndpoint(), new UpdateSynchronizedDataEndpoint(), diff --git a/service.datamutex/src/main/java/net/swofty/service/datamutex/endpoints/SynchronizeDataEndpoint.java b/service.datamutex/src/main/java/net/swofty/service/datamutex/endpoints/SynchronizeDataEndpoint.java index 6b8c64abe..ce91b2f03 100644 --- a/service.datamutex/src/main/java/net/swofty/service/datamutex/endpoints/SynchronizeDataEndpoint.java +++ b/service.datamutex/src/main/java/net/swofty/service/datamutex/endpoints/SynchronizeDataEndpoint.java @@ -2,12 +2,11 @@ import org.tinylog.Logger; -import net.swofty.commons.impl.ServiceProxyRequest; import net.swofty.commons.protocol.objects.data.GetPlayerDataPushProtocol; import net.swofty.commons.protocol.objects.data.LockPlayerDataPushProtocol; -import net.swofty.commons.protocol.objects.datamutex.SynchronizeDataProtocolObject; +import net.swofty.commons.protocol.objects.datamutex.SynchronizeDataProtocol; import net.swofty.service.datamutex.DataLockManager; -import net.swofty.service.generic.redis.ServiceEndpoint; +import net.swofty.commons.redis.RedisMessageHandler; import net.swofty.service.generic.redis.ServiceToServerManager; import java.util.HashMap; @@ -15,25 +14,24 @@ import java.util.Map; import java.util.UUID; import java.util.concurrent.CompletableFuture; +import net.swofty.commons.redis.RedisMessageContext; -public class SynchronizeDataEndpoint implements ServiceEndpoint< - SynchronizeDataProtocolObject.SynchronizeDataRequest, - SynchronizeDataProtocolObject.SynchronizeDataResponse> { +public class SynchronizeDataEndpoint implements RedisMessageHandler< + SynchronizeDataProtocol.SynchronizeDataRequest, + SynchronizeDataProtocol.SynchronizeDataResponse> { @Override - public SynchronizeDataProtocolObject associatedProtocolObject() { - return new SynchronizeDataProtocolObject(); + public SynchronizeDataProtocol protocol() { + return new SynchronizeDataProtocol(); } @Override - public SynchronizeDataProtocolObject.SynchronizeDataResponse onMessage( - ServiceProxyRequest request, - SynchronizeDataProtocolObject.SynchronizeDataRequest messageObject) { + public SynchronizeDataProtocol.SynchronizeDataResponse handle(SynchronizeDataProtocol.SynchronizeDataRequest messageObject, RedisMessageContext context) { List serverUUIDs = messageObject.serverUUIDs(); UUID playerUUID = messageObject.playerUUID(); String dataKey = messageObject.dataKey(); - String requesterId = request.getRequestServer(); + String requesterId = context.origin().id(); String lockKey = playerUUID + ":" + dataKey; Logger.debug("sync: requester={} player={} key={} servers={} lockKey={}", @@ -42,7 +40,7 @@ public SynchronizeDataProtocolObject.SynchronizeDataResponse onMessage( try { if (!DataLockManager.acquireLock(lockKey, requesterId)) { Logger.debug("sync: service lock {} already held", lockKey); - return new SynchronizeDataProtocolObject.SynchronizeDataResponse( + return new SynchronizeDataProtocol.SynchronizeDataResponse( false, null, "Data is currently locked by another operation"); } @@ -58,7 +56,7 @@ public SynchronizeDataProtocolObject.SynchronizeDataResponse onMessage( lockResults); DataLockManager.releaseLock(lockKey, requesterId); ServiceToServerManager.unlockPlayerData(serverUUIDs, playerUUID, dataKey); - return new SynchronizeDataProtocolObject.SynchronizeDataResponse( + return new SynchronizeDataProtocol.SynchronizeDataResponse( false, null, "Failed to acquire locks on all servers"); } @@ -86,19 +84,19 @@ public SynchronizeDataProtocolObject.SynchronizeDataResponse onMessage( Logger.debug("sync: no valid data among {} responses, rolling back", allData.size()); DataLockManager.releaseLock(lockKey, requesterId); ServiceToServerManager.unlockPlayerData(serverUUIDs, playerUUID, dataKey); - return new SynchronizeDataProtocolObject.SynchronizeDataResponse( + return new SynchronizeDataProtocol.SynchronizeDataResponse( false, null, "No valid data found on any server"); } Logger.debug("sync: settled on timestamp={}", latestTimestamp); - return new SynchronizeDataProtocolObject.SynchronizeDataResponse( + return new SynchronizeDataProtocol.SynchronizeDataResponse( true, latestData.data(), null); } catch (Exception e) { Logger.error(e, "Error occurred in data mutex endpoint (lockKey={})", lockKey); DataLockManager.releaseLock(lockKey, requesterId); ServiceToServerManager.unlockPlayerData(serverUUIDs, playerUUID, dataKey); - return new SynchronizeDataProtocolObject.SynchronizeDataResponse( + return new SynchronizeDataProtocol.SynchronizeDataResponse( false, null, "Error during synchronization: " + e.getMessage()); } } diff --git a/service.datamutex/src/main/java/net/swofty/service/datamutex/endpoints/UnlockDataEndpoint.java b/service.datamutex/src/main/java/net/swofty/service/datamutex/endpoints/UnlockDataEndpoint.java index 082f1df6d..21c855ef9 100644 --- a/service.datamutex/src/main/java/net/swofty/service/datamutex/endpoints/UnlockDataEndpoint.java +++ b/service.datamutex/src/main/java/net/swofty/service/datamutex/endpoints/UnlockDataEndpoint.java @@ -1,33 +1,31 @@ package net.swofty.service.datamutex.endpoints; -import net.swofty.commons.impl.ServiceProxyRequest; -import net.swofty.commons.protocol.objects.datamutex.UnlockDataProtocolObject; +import net.swofty.commons.protocol.objects.datamutex.UnlockDataProtocol; import net.swofty.service.datamutex.DataLockManager; -import net.swofty.service.generic.redis.ServiceEndpoint; +import net.swofty.commons.redis.RedisMessageHandler; import net.swofty.service.generic.redis.ServiceToServerManager; import org.tinylog.Logger; import java.util.List; import java.util.UUID; +import net.swofty.commons.redis.RedisMessageContext; -public class UnlockDataEndpoint implements ServiceEndpoint< - UnlockDataProtocolObject.UnlockDataRequest, - UnlockDataProtocolObject.UnlockDataResponse> { +public class UnlockDataEndpoint implements RedisMessageHandler< + UnlockDataProtocol.UnlockDataRequest, + UnlockDataProtocol.UnlockDataResponse> { @Override - public UnlockDataProtocolObject associatedProtocolObject() { - return new UnlockDataProtocolObject(); + public UnlockDataProtocol protocol() { + return new UnlockDataProtocol(); } @Override - public UnlockDataProtocolObject.UnlockDataResponse onMessage( - ServiceProxyRequest request, - UnlockDataProtocolObject.UnlockDataRequest messageObject) { + public UnlockDataProtocol.UnlockDataResponse handle(UnlockDataProtocol.UnlockDataRequest messageObject, RedisMessageContext context) { List serverUUIDs = messageObject.serverUUIDs(); UUID playerUUID = messageObject.playerUUID(); String dataKey = messageObject.dataKey(); - String requesterId = request.getRequestServer(); + String requesterId = context.origin().id(); String lockKey = playerUUID + ":" + dataKey; @@ -47,11 +45,11 @@ public UnlockDataProtocolObject.UnlockDataResponse onMessage( return null; }); - return new UnlockDataProtocolObject.UnlockDataResponse( + return new UnlockDataProtocol.UnlockDataResponse( true, null); } catch (Exception e) { - return new UnlockDataProtocolObject.UnlockDataResponse( + return new UnlockDataProtocol.UnlockDataResponse( false, "Error during unlock: " + e.getMessage()); } } diff --git a/service.datamutex/src/main/java/net/swofty/service/datamutex/endpoints/UpdateSynchronizedDataEndpoint.java b/service.datamutex/src/main/java/net/swofty/service/datamutex/endpoints/UpdateSynchronizedDataEndpoint.java index 8a5f32fd3..5263521e1 100644 --- a/service.datamutex/src/main/java/net/swofty/service/datamutex/endpoints/UpdateSynchronizedDataEndpoint.java +++ b/service.datamutex/src/main/java/net/swofty/service/datamutex/endpoints/UpdateSynchronizedDataEndpoint.java @@ -2,11 +2,10 @@ import org.tinylog.Logger; -import net.swofty.commons.impl.ServiceProxyRequest; import net.swofty.commons.protocol.objects.data.UpdatePlayerDataPushProtocol; -import net.swofty.commons.protocol.objects.datamutex.UpdateSynchronizedDataProtocolObject; +import net.swofty.commons.protocol.objects.datamutex.UpdateSynchronizedDataProtocol; import net.swofty.service.datamutex.DataLockManager; -import net.swofty.service.generic.redis.ServiceEndpoint; +import net.swofty.commons.redis.RedisMessageHandler; import net.swofty.service.generic.redis.ServiceToServerManager; import java.util.HashMap; @@ -14,26 +13,25 @@ import java.util.Map; import java.util.UUID; import java.util.concurrent.CompletableFuture; +import net.swofty.commons.redis.RedisMessageContext; -public class UpdateSynchronizedDataEndpoint implements ServiceEndpoint< - UpdateSynchronizedDataProtocolObject.UpdateDataRequest, - UpdateSynchronizedDataProtocolObject.UpdateDataResponse> { +public class UpdateSynchronizedDataEndpoint implements RedisMessageHandler< + UpdateSynchronizedDataProtocol.UpdateDataRequest, + UpdateSynchronizedDataProtocol.UpdateDataResponse> { @Override - public UpdateSynchronizedDataProtocolObject associatedProtocolObject() { - return new UpdateSynchronizedDataProtocolObject(); + public UpdateSynchronizedDataProtocol protocol() { + return new UpdateSynchronizedDataProtocol(); } @Override - public UpdateSynchronizedDataProtocolObject.UpdateDataResponse onMessage( - ServiceProxyRequest request, - UpdateSynchronizedDataProtocolObject.UpdateDataRequest messageObject) { + public UpdateSynchronizedDataProtocol.UpdateDataResponse handle(UpdateSynchronizedDataProtocol.UpdateDataRequest messageObject, RedisMessageContext context) { List serverUUIDs = messageObject.serverUUIDs(); UUID playerUUID = messageObject.playerUUID(); String dataKey = messageObject.dataKey(); String newData = messageObject.newData(); - String requesterId = request.getRequestServer(); + String requesterId = context.origin().id(); String lockKey = playerUUID + ":" + dataKey; Logger.debug("update: requester={} player={} key={} servers={} bytes={} lockKey={}", @@ -44,7 +42,7 @@ public UpdateSynchronizedDataProtocolObject.UpdateDataResponse onMessage( if (lockInfo == null || !lockInfo.requesterId().equals(requesterId)) { Logger.debug("update: lock check failed (held by {})", lockInfo == null ? "" : lockInfo.requesterId()); - return new UpdateSynchronizedDataProtocolObject.UpdateDataResponse( + return new UpdateSynchronizedDataProtocol.UpdateDataResponse( false, "Lock has expired or is held by another requester"); } @@ -64,15 +62,15 @@ public UpdateSynchronizedDataProtocolObject.UpdateDataResponse onMessage( if (!allUpdated) { Logger.warn("update: partial failure (results={})", updateResults); - return new UpdateSynchronizedDataProtocolObject.UpdateDataResponse( + return new UpdateSynchronizedDataProtocol.UpdateDataResponse( false, "Failed to update data on all servers"); } - return new UpdateSynchronizedDataProtocolObject.UpdateDataResponse(true, null); + return new UpdateSynchronizedDataProtocol.UpdateDataResponse(true, null); } catch (Exception e) { Logger.error(e, "Error occurred in data mutex update endpoint (lockKey={})", lockKey); - return new UpdateSynchronizedDataProtocolObject.UpdateDataResponse( + return new UpdateSynchronizedDataProtocol.UpdateDataResponse( false, "Error during data update: " + e.getMessage()); } finally { DataLockManager.releaseLock(lockKey, requesterId); diff --git a/service.elections/src/main/java/net/swofty/service/election/ElectionService.java b/service.elections/src/main/java/net/swofty/service/election/ElectionService.java index ba20b9026..7541c7c61 100644 --- a/service.elections/src/main/java/net/swofty/service/election/ElectionService.java +++ b/service.elections/src/main/java/net/swofty/service/election/ElectionService.java @@ -3,7 +3,7 @@ import net.swofty.commons.ServiceType; import net.swofty.commons.config.ConfigProvider; import net.swofty.service.generic.SkyBlockService; -import net.swofty.service.generic.redis.ServiceEndpoint; +import net.swofty.commons.redis.RedisMessageHandler; import java.util.List; @@ -21,7 +21,7 @@ public ServiceType getType() { } @Override - public List getEndpoints() { - return loopThroughPackage("net.swofty.service.election.endpoints", ServiceEndpoint.class).toList(); + public List getEndpoints() { + return loopThroughPackage("net.swofty.service.election.endpoints", RedisMessageHandler.class).toList(); } } diff --git a/service.elections/src/main/java/net/swofty/service/election/endpoints/CastVoteEndpoint.java b/service.elections/src/main/java/net/swofty/service/election/endpoints/CastVoteEndpoint.java index e1bee4dc1..658d6e8c3 100644 --- a/service.elections/src/main/java/net/swofty/service/election/endpoints/CastVoteEndpoint.java +++ b/service.elections/src/main/java/net/swofty/service/election/endpoints/CastVoteEndpoint.java @@ -1,54 +1,52 @@ package net.swofty.service.election.endpoints; import com.google.gson.Gson; -import net.swofty.commons.impl.ServiceProxyRequest; -import net.swofty.commons.protocol.ProtocolObject; -import net.swofty.commons.protocol.objects.election.CastVoteProtocolObject; +import net.swofty.commons.protocol.RedisProtocol; +import net.swofty.commons.protocol.objects.election.CastVoteProtocol; import net.swofty.service.election.ElectionDatabase; -import net.swofty.service.generic.redis.ServiceEndpoint; +import net.swofty.commons.redis.RedisMessageHandler; import org.tinylog.Logger; import java.util.List; import java.util.Map; +import net.swofty.commons.redis.RedisMessageContext; -public class CastVoteEndpoint implements ServiceEndpoint - { +public class CastVoteEndpoint implements RedisMessageHandler + { @Override - public ProtocolObject associatedProtocolObject() { - return new CastVoteProtocolObject(); + public RedisProtocol protocol() { + return new CastVoteProtocol(); } @Override @SuppressWarnings("unchecked") - public CastVoteProtocolObject.CastVoteResponse onMessage( - ServiceProxyRequest message, - CastVoteProtocolObject.CastVoteMessage messageObject) { + public CastVoteProtocol.CastVoteResponse handle(CastVoteProtocol.CastVoteMessage messageObject, RedisMessageContext context) { try { String rawData = ElectionDatabase.loadElectionData(); if (rawData == null) { - return new CastVoteProtocolObject.CastVoteResponse(false, null, "Vote failed"); + return new CastVoteProtocol.CastVoteResponse(false, null, "Vote failed"); } Map data = new Gson().fromJson(rawData, Map.class); Boolean electionOpen = (Boolean) data.get("electionOpen"); if (electionOpen == null || !electionOpen) { - return new CastVoteProtocolObject.CastVoteResponse(false, null, "Vote failed"); + return new CastVoteProtocol.CastVoteResponse(false, null, "Vote failed"); } int electionYear = ((Number) data.get("electionYear")).intValue(); List> candidates = (List>) data.get("candidates"); if (candidates == null) { - return new CastVoteProtocolObject.CastVoteResponse(false, null, "Vote failed"); + return new CastVoteProtocol.CastVoteResponse(false, null, "Vote failed"); } boolean validCandidate = candidates.stream() .anyMatch(c -> messageObject.candidateName().equals(c.get("mayorName"))); if (!validCandidate) { - return new CastVoteProtocolObject.CastVoteResponse(false, null, "Vote failed"); + return new CastVoteProtocol.CastVoteResponse(false, null, "Vote failed"); } ElectionDatabase.castVote( @@ -58,10 +56,10 @@ public CastVoteProtocolObject.CastVoteResponse onMessage( ); Map tallies = ElectionDatabase.getTallies(electionYear); - return new CastVoteProtocolObject.CastVoteResponse(true, tallies, null); + return new CastVoteProtocol.CastVoteResponse(true, tallies, null); } catch (Exception e) { Logger.error(e, "Failed to cast vote"); - return new CastVoteProtocolObject.CastVoteResponse(false, null, "Vote failed"); + return new CastVoteProtocol.CastVoteResponse(false, null, "Vote failed"); } } } diff --git a/service.elections/src/main/java/net/swofty/service/election/endpoints/GetCandidatesEndpoint.java b/service.elections/src/main/java/net/swofty/service/election/endpoints/GetCandidatesEndpoint.java index 52b043171..9df3ec42f 100644 --- a/service.elections/src/main/java/net/swofty/service/election/endpoints/GetCandidatesEndpoint.java +++ b/service.elections/src/main/java/net/swofty/service/election/endpoints/GetCandidatesEndpoint.java @@ -1,70 +1,68 @@ package net.swofty.service.election.endpoints; import com.google.gson.Gson; -import net.swofty.commons.impl.ServiceProxyRequest; -import net.swofty.commons.protocol.ProtocolObject; -import net.swofty.commons.protocol.objects.election.GetCandidatesProtocolObject; +import net.swofty.commons.protocol.RedisProtocol; +import net.swofty.commons.protocol.objects.election.GetCandidatesProtocol; import net.swofty.service.election.ElectionDatabase; -import net.swofty.service.generic.redis.ServiceEndpoint; +import net.swofty.commons.redis.RedisMessageHandler; import org.tinylog.Logger; import java.util.ArrayList; import java.util.List; import java.util.Map; +import net.swofty.commons.redis.RedisMessageContext; -public class GetCandidatesEndpoint implements ServiceEndpoint - { +public class GetCandidatesEndpoint implements RedisMessageHandler + { private static final Gson GSON = new Gson(); @Override - public ProtocolObject associatedProtocolObject() { - return new GetCandidatesProtocolObject(); + public RedisProtocol protocol() { + return new GetCandidatesProtocol(); } @Override @SuppressWarnings("unchecked") - public GetCandidatesProtocolObject.GetCandidatesResponse onMessage( - ServiceProxyRequest message, - GetCandidatesProtocolObject.GetCandidatesMessage messageObject) { + public GetCandidatesProtocol.GetCandidatesResponse handle(GetCandidatesProtocol.GetCandidatesMessage messageObject, RedisMessageContext context) { try { String rawData = ElectionDatabase.loadElectionData(); if (rawData == null) { - return new GetCandidatesProtocolObject.GetCandidatesResponse(false, List.of(), true, null); + return new GetCandidatesProtocol.GetCandidatesResponse(false, List.of(), true, null); } Map data = GSON.fromJson(rawData, Map.class); Boolean electionOpen = (Boolean) data.get("electionOpen"); if (electionOpen == null || !electionOpen) { - return new GetCandidatesProtocolObject.GetCandidatesResponse(false, List.of(), true, null); + return new GetCandidatesProtocol.GetCandidatesResponse(false, List.of(), true, null); } int electionYear = ((Number) data.get("electionYear")).intValue(); List> candidates = (List>) data.get("candidates"); if (candidates == null || candidates.isEmpty()) { - return new GetCandidatesProtocolObject.GetCandidatesResponse(true, List.of(), true, null); + return new GetCandidatesProtocol.GetCandidatesResponse(true, List.of(), true, null); } Map tallies = ElectionDatabase.getTallies(electionYear); long totalVotes = tallies.values().stream().mapToLong(Long::longValue).sum(); - List infos = new ArrayList<>(); + List infos = new ArrayList<>(); for (Map c : candidates) { String name = (String) c.get("mayorName"); List perks = (List) c.get("activePerks"); if (perks == null) perks = List.of(); long voteCount = tallies.getOrDefault(name, 0L); double pct = totalVotes > 0 ? (voteCount * 100.0) / totalVotes : 0; - infos.add(new GetCandidatesProtocolObject.CandidateInfo(name, perks, voteCount, pct)); + infos.add(new GetCandidatesProtocol.CandidateInfo(name, perks, voteCount, pct)); } - return new GetCandidatesProtocolObject.GetCandidatesResponse(true, infos, true, null); + return new GetCandidatesProtocol.GetCandidatesResponse(true, infos, true, null); } catch (Exception e) { Logger.error(e, "Failed to get candidates"); - return new GetCandidatesProtocolObject.GetCandidatesResponse(false, List.of(), true, null); + return new GetCandidatesProtocol.GetCandidatesResponse(false, List.of(), true, null); } } } diff --git a/service.elections/src/main/java/net/swofty/service/election/endpoints/GetElectionDataEndpoint.java b/service.elections/src/main/java/net/swofty/service/election/endpoints/GetElectionDataEndpoint.java index ff1107d1e..acae98839 100644 --- a/service.elections/src/main/java/net/swofty/service/election/endpoints/GetElectionDataEndpoint.java +++ b/service.elections/src/main/java/net/swofty/service/election/endpoints/GetElectionDataEndpoint.java @@ -1,36 +1,34 @@ package net.swofty.service.election.endpoints; import com.google.gson.Gson; -import net.swofty.commons.impl.ServiceProxyRequest; -import net.swofty.commons.protocol.ProtocolObject; -import net.swofty.commons.protocol.objects.election.GetElectionDataProtocolObject; +import net.swofty.commons.protocol.RedisProtocol; +import net.swofty.commons.protocol.objects.election.GetElectionDataProtocol; import net.swofty.service.election.ElectionDatabase; -import net.swofty.service.generic.redis.ServiceEndpoint; +import net.swofty.commons.redis.RedisMessageHandler; import org.tinylog.Logger; import java.util.List; import java.util.Map; +import net.swofty.commons.redis.RedisMessageContext; -public class GetElectionDataEndpoint implements ServiceEndpoint - { +public class GetElectionDataEndpoint implements RedisMessageHandler + { private static final Gson GSON = new Gson(); @Override - public ProtocolObject associatedProtocolObject() { - return new GetElectionDataProtocolObject(); + public RedisProtocol protocol() { + return new GetElectionDataProtocol(); } @Override @SuppressWarnings("unchecked") - public GetElectionDataProtocolObject.GetElectionDataResponse onMessage( - ServiceProxyRequest message, - GetElectionDataProtocolObject.GetElectionDataMessage messageObject) { + public GetElectionDataProtocol.GetElectionDataResponse handle(GetElectionDataProtocol.GetElectionDataMessage messageObject, RedisMessageContext context) { String data = ElectionDatabase.loadElectionData(); if (data == null) { - return new GetElectionDataProtocolObject.GetElectionDataResponse(false, null, true, null); + return new GetElectionDataProtocol.GetElectionDataResponse(false, null, true, null); } try { @@ -45,10 +43,10 @@ public GetElectionDataProtocolObject.GetElectionDataResponse onMessage( parsed.put("voteTallies", tallies); } - return new GetElectionDataProtocolObject.GetElectionDataResponse(true, GSON.toJson(parsed), true, null); + return new GetElectionDataProtocol.GetElectionDataResponse(true, GSON.toJson(parsed), true, null); } catch (Exception e) { Logger.error(e, "Failed to parse election data"); - return new GetElectionDataProtocolObject.GetElectionDataResponse(false, null, true, null); + return new GetElectionDataProtocol.GetElectionDataResponse(false, null, true, null); } } } diff --git a/service.elections/src/main/java/net/swofty/service/election/endpoints/GetPlayerVoteEndpoint.java b/service.elections/src/main/java/net/swofty/service/election/endpoints/GetPlayerVoteEndpoint.java index 31ac3814e..a807cc711 100644 --- a/service.elections/src/main/java/net/swofty/service/election/endpoints/GetPlayerVoteEndpoint.java +++ b/service.elections/src/main/java/net/swofty/service/election/endpoints/GetPlayerVoteEndpoint.java @@ -1,52 +1,50 @@ package net.swofty.service.election.endpoints; import com.google.gson.Gson; -import net.swofty.commons.impl.ServiceProxyRequest; -import net.swofty.commons.protocol.ProtocolObject; -import net.swofty.commons.protocol.objects.election.GetPlayerVoteProtocolObject; +import net.swofty.commons.protocol.RedisProtocol; +import net.swofty.commons.protocol.objects.election.GetPlayerVoteProtocol; import net.swofty.service.election.ElectionDatabase; -import net.swofty.service.generic.redis.ServiceEndpoint; +import net.swofty.commons.redis.RedisMessageHandler; import org.tinylog.Logger; import java.util.Map; +import net.swofty.commons.redis.RedisMessageContext; -public class GetPlayerVoteEndpoint implements ServiceEndpoint - { +public class GetPlayerVoteEndpoint implements RedisMessageHandler + { private static final Gson GSON = new Gson(); @Override - public ProtocolObject associatedProtocolObject() { - return new GetPlayerVoteProtocolObject(); + public RedisProtocol protocol() { + return new GetPlayerVoteProtocol(); } @Override @SuppressWarnings("unchecked") - public GetPlayerVoteProtocolObject.GetPlayerVoteResponse onMessage( - ServiceProxyRequest message, - GetPlayerVoteProtocolObject.GetPlayerVoteMessage messageObject) { + public GetPlayerVoteProtocol.GetPlayerVoteResponse handle(GetPlayerVoteProtocol.GetPlayerVoteMessage messageObject, RedisMessageContext context) { try { String rawData = ElectionDatabase.loadElectionData(); if (rawData == null) { - return new GetPlayerVoteProtocolObject.GetPlayerVoteResponse(null, true, null); + return new GetPlayerVoteProtocol.GetPlayerVoteResponse(null, true, null); } Map data = GSON.fromJson(rawData, Map.class); Number yearNum = (Number) data.get("electionYear"); if (yearNum == null) { - return new GetPlayerVoteProtocolObject.GetPlayerVoteResponse(null, true, null); + return new GetPlayerVoteProtocol.GetPlayerVoteResponse(null, true, null); } String vote = ElectionDatabase.getPlayerVote( messageObject.accountId().toString(), yearNum.intValue() ); - return new GetPlayerVoteProtocolObject.GetPlayerVoteResponse(vote, true, null); + return new GetPlayerVoteProtocol.GetPlayerVoteResponse(vote, true, null); } catch (Exception e) { Logger.error(e, "Failed to get player vote"); - return new GetPlayerVoteProtocolObject.GetPlayerVoteResponse(null, true, null); + return new GetPlayerVoteProtocol.GetPlayerVoteResponse(null, true, null); } } } diff --git a/service.elections/src/main/java/net/swofty/service/election/endpoints/ResolveElectionEndpoint.java b/service.elections/src/main/java/net/swofty/service/election/endpoints/ResolveElectionEndpoint.java index 863d89f68..2ec2ffac6 100644 --- a/service.elections/src/main/java/net/swofty/service/election/endpoints/ResolveElectionEndpoint.java +++ b/service.elections/src/main/java/net/swofty/service/election/endpoints/ResolveElectionEndpoint.java @@ -1,11 +1,10 @@ package net.swofty.service.election.endpoints; import com.google.gson.Gson; -import net.swofty.commons.impl.ServiceProxyRequest; -import net.swofty.commons.protocol.ProtocolObject; -import net.swofty.commons.protocol.objects.election.ResolveElectionProtocolObject; +import net.swofty.commons.protocol.RedisProtocol; +import net.swofty.commons.protocol.objects.election.ResolveElectionProtocol; import net.swofty.service.election.ElectionDatabase; -import net.swofty.service.generic.redis.ServiceEndpoint; +import net.swofty.commons.redis.RedisMessageHandler; import org.tinylog.Logger; import java.util.ArrayList; @@ -13,30 +12,29 @@ import java.util.List; import java.util.Map; import java.util.concurrent.ThreadLocalRandom; +import net.swofty.commons.redis.RedisMessageContext; -public class ResolveElectionEndpoint implements ServiceEndpoint - { +public class ResolveElectionEndpoint implements RedisMessageHandler + { private static final Gson GSON = new Gson(); private static final List SPECIAL_MAYORS = List.of("SCORPIUS", "DERPY", "JERRY"); @Override - public ProtocolObject associatedProtocolObject() { - return new ResolveElectionProtocolObject(); + public RedisProtocol protocol() { + return new ResolveElectionProtocol(); } @Override @SuppressWarnings("unchecked") - public ResolveElectionProtocolObject.ResolveElectionResponse onMessage( - ServiceProxyRequest message, - ResolveElectionProtocolObject.ResolveElectionMessage messageObject) { + public ResolveElectionProtocol.ResolveElectionResponse handle(ResolveElectionProtocol.ResolveElectionMessage messageObject, RedisMessageContext context) { try { String rawData = ElectionDatabase.loadElectionData(); if (rawData == null) { - return new ResolveElectionProtocolObject.ResolveElectionResponse(false, null, true, null); + return new ResolveElectionProtocol.ResolveElectionResponse(false, null, true, null); } Map data = GSON.fromJson(rawData, Map.class); @@ -44,7 +42,7 @@ public ResolveElectionProtocolObject.ResolveElectionResponse onMessage( if (electionOpen == null || !electionOpen) { data.remove("votes"); - return new ResolveElectionProtocolObject.ResolveElectionResponse(false, GSON.toJson(data), true, null); + return new ResolveElectionProtocol.ResolveElectionResponse(false, GSON.toJson(data), true, null); } int electionYear = messageObject.year(); @@ -62,7 +60,7 @@ public ResolveElectionProtocolObject.ResolveElectionResponse onMessage( sorted.sort((a, b) -> Long.compare(b.getValue(), a.getValue())); if (sorted.isEmpty()) { - return new ResolveElectionProtocolObject.ResolveElectionResponse(false, GSON.toJson(data), true, null); + return new ResolveElectionProtocol.ResolveElectionResponse(false, GSON.toJson(data), true, null); } long topVotes = sorted.getFirst().getValue(); @@ -154,10 +152,10 @@ public ResolveElectionProtocolObject.ResolveElectionResponse onMessage( ElectionDatabase.saveElectionData(GSON.toJson(data)); - return new ResolveElectionProtocolObject.ResolveElectionResponse(true, GSON.toJson(data), true, null); + return new ResolveElectionProtocol.ResolveElectionResponse(true, GSON.toJson(data), true, null); } catch (Exception e) { Logger.error(e, "Failed to resolve election"); - return new ResolveElectionProtocolObject.ResolveElectionResponse(false, null, true, null); + return new ResolveElectionProtocol.ResolveElectionResponse(false, null, true, null); } } diff --git a/service.elections/src/main/java/net/swofty/service/election/endpoints/StartElectionEndpoint.java b/service.elections/src/main/java/net/swofty/service/election/endpoints/StartElectionEndpoint.java index dc4d3008d..9b541ce78 100644 --- a/service.elections/src/main/java/net/swofty/service/election/endpoints/StartElectionEndpoint.java +++ b/service.elections/src/main/java/net/swofty/service/election/endpoints/StartElectionEndpoint.java @@ -1,34 +1,32 @@ package net.swofty.service.election.endpoints; import com.google.gson.Gson; -import net.swofty.commons.impl.ServiceProxyRequest; -import net.swofty.commons.protocol.ProtocolObject; -import net.swofty.commons.protocol.objects.election.StartElectionProtocolObject; +import net.swofty.commons.protocol.RedisProtocol; +import net.swofty.commons.protocol.objects.election.StartElectionProtocol; import net.swofty.service.election.ElectionDatabase; -import net.swofty.service.generic.redis.ServiceEndpoint; +import net.swofty.commons.redis.RedisMessageHandler; import org.tinylog.Logger; import java.util.ArrayList; import java.util.List; import java.util.Map; +import net.swofty.commons.redis.RedisMessageContext; -public class StartElectionEndpoint implements ServiceEndpoint - { +public class StartElectionEndpoint implements RedisMessageHandler + { private static final Gson GSON = new Gson(); @Override - public ProtocolObject associatedProtocolObject() { - return new StartElectionProtocolObject(); + public RedisProtocol protocol() { + return new StartElectionProtocol(); } @Override @SuppressWarnings("unchecked") - public StartElectionProtocolObject.StartElectionResponse onMessage( - ServiceProxyRequest message, - StartElectionProtocolObject.StartElectionMessage messageObject) { + public StartElectionProtocol.StartElectionResponse handle(StartElectionProtocol.StartElectionMessage messageObject, RedisMessageContext context) { try { String rawData = ElectionDatabase.loadElectionData(); @@ -42,7 +40,7 @@ public StartElectionProtocolObject.StartElectionResponse onMessage( Map tallies = ElectionDatabase.getTallies(messageObject.year()); existing.put("voteTallies", tallies); existing.remove("votes"); - return new StartElectionProtocolObject.StartElectionResponse(false, GSON.toJson(existing), true, null); + return new StartElectionProtocol.StartElectionResponse(false, GSON.toJson(existing), true, null); } } @@ -62,10 +60,10 @@ public StartElectionProtocolObject.StartElectionResponse onMessage( ElectionDatabase.initTallies(messageObject.year(), candidateNames); electionData.remove("votes"); - return new StartElectionProtocolObject.StartElectionResponse(true, GSON.toJson(electionData), true, null); + return new StartElectionProtocol.StartElectionResponse(true, GSON.toJson(electionData), true, null); } catch (Exception e) { Logger.error(e, "Failed to start election"); - return new StartElectionProtocolObject.StartElectionResponse(false, null, true, null); + return new StartElectionProtocol.StartElectionResponse(false, null, true, null); } } } diff --git a/service.friend/src/main/java/net/swofty/service/friend/FriendService.java b/service.friend/src/main/java/net/swofty/service/friend/FriendService.java index c19bee4b1..7949d0d6d 100644 --- a/service.friend/src/main/java/net/swofty/service/friend/FriendService.java +++ b/service.friend/src/main/java/net/swofty/service/friend/FriendService.java @@ -3,7 +3,7 @@ import net.swofty.commons.ServiceType; import net.swofty.commons.config.ConfigProvider; import net.swofty.service.generic.SkyBlockService; -import net.swofty.service.generic.redis.ServiceEndpoint; +import net.swofty.commons.redis.RedisMessageHandler; import java.util.List; @@ -24,7 +24,7 @@ public ServiceType getType() { } @Override - public List getEndpoints() { - return loopThroughPackage("net.swofty.service.friend.endpoints", ServiceEndpoint.class).toList(); + public List getEndpoints() { + return loopThroughPackage("net.swofty.service.friend.endpoints", RedisMessageHandler.class).toList(); } } diff --git a/service.friend/src/main/java/net/swofty/service/friend/endpoints/AreFriendsEndpoint.java b/service.friend/src/main/java/net/swofty/service/friend/endpoints/AreFriendsEndpoint.java index a379cef85..185740141 100644 --- a/service.friend/src/main/java/net/swofty/service/friend/endpoints/AreFriendsEndpoint.java +++ b/service.friend/src/main/java/net/swofty/service/friend/endpoints/AreFriendsEndpoint.java @@ -1,25 +1,23 @@ package net.swofty.service.friend.endpoints; -import net.swofty.commons.impl.ServiceProxyRequest; -import net.swofty.commons.protocol.objects.friend.AreFriendsProtocolObject; +import net.swofty.commons.protocol.objects.friend.AreFriendsProtocol; import net.swofty.service.friend.FriendCache; -import net.swofty.service.generic.redis.ServiceEndpoint; +import net.swofty.commons.redis.RedisMessageHandler; +import net.swofty.commons.redis.RedisMessageContext; -public class AreFriendsEndpoint implements ServiceEndpoint< - AreFriendsProtocolObject.AreFriendsMessage, - AreFriendsProtocolObject.AreFriendsResponse> { +public class AreFriendsEndpoint implements RedisMessageHandler< + AreFriendsProtocol.AreFriendsMessage, + AreFriendsProtocol.AreFriendsResponse> { @Override - public AreFriendsProtocolObject associatedProtocolObject() { - return new AreFriendsProtocolObject(); + public AreFriendsProtocol protocol() { + return new AreFriendsProtocol(); } @Override - public AreFriendsProtocolObject.AreFriendsResponse onMessage( - ServiceProxyRequest message, - AreFriendsProtocolObject.AreFriendsMessage messageObject) { + public AreFriendsProtocol.AreFriendsResponse handle(AreFriendsProtocol.AreFriendsMessage messageObject, RedisMessageContext context) { boolean areFriends = FriendCache.areFriends(messageObject.player(), messageObject.other()); - return new AreFriendsProtocolObject.AreFriendsResponse(areFriends, true, null); + return new AreFriendsProtocol.AreFriendsResponse(areFriends, true, null); } } diff --git a/service.friend/src/main/java/net/swofty/service/friend/endpoints/FriendEventToServiceEndpoint.java b/service.friend/src/main/java/net/swofty/service/friend/endpoints/FriendEventToServiceEndpoint.java index 1b95dfd01..9c8cc1e11 100644 --- a/service.friend/src/main/java/net/swofty/service/friend/endpoints/FriendEventToServiceEndpoint.java +++ b/service.friend/src/main/java/net/swofty/service/friend/endpoints/FriendEventToServiceEndpoint.java @@ -1,26 +1,24 @@ package net.swofty.service.friend.endpoints; -import net.swofty.commons.impl.ServiceProxyRequest; import net.swofty.commons.friend.FriendEvent; import net.swofty.commons.friend.events.*; -import net.swofty.commons.protocol.objects.friend.SendFriendEventToServiceProtocolObject; +import net.swofty.commons.protocol.objects.friend.SendFriendEventToServiceProtocol; import net.swofty.service.friend.FriendCache; -import net.swofty.service.generic.redis.ServiceEndpoint; +import net.swofty.commons.redis.RedisMessageHandler; import org.tinylog.Logger; +import net.swofty.commons.redis.RedisMessageContext; -public class FriendEventToServiceEndpoint implements ServiceEndpoint< - SendFriendEventToServiceProtocolObject.SendFriendEventToServiceMessage, - SendFriendEventToServiceProtocolObject.SendFriendEventToServiceResponse> { +public class FriendEventToServiceEndpoint implements RedisMessageHandler< + SendFriendEventToServiceProtocol.SendFriendEventToServiceMessage, + SendFriendEventToServiceProtocol.SendFriendEventToServiceResponse> { @Override - public SendFriendEventToServiceProtocolObject associatedProtocolObject() { - return new SendFriendEventToServiceProtocolObject(); + public SendFriendEventToServiceProtocol protocol() { + return new SendFriendEventToServiceProtocol(); } @Override - public SendFriendEventToServiceProtocolObject.SendFriendEventToServiceResponse onMessage( - ServiceProxyRequest message, - SendFriendEventToServiceProtocolObject.SendFriendEventToServiceMessage messageObject) { + public SendFriendEventToServiceProtocol.SendFriendEventToServiceResponse handle(SendFriendEventToServiceProtocol.SendFriendEventToServiceMessage messageObject, RedisMessageContext context) { try { FriendEvent event = messageObject.event(); @@ -61,10 +59,10 @@ public SendFriendEventToServiceProtocolObject.SendFriendEventToServiceResponse o default -> Logger.warn("Unknown friend event type: " + event.getClass().getSimpleName()); } - return new SendFriendEventToServiceProtocolObject.SendFriendEventToServiceResponse(true, null); + return new SendFriendEventToServiceProtocol.SendFriendEventToServiceResponse(true, null); } catch (Exception e) { Logger.error(e, "Failed to process friend event in service endpoint"); - return new SendFriendEventToServiceProtocolObject.SendFriendEventToServiceResponse(false, "Event processing failed"); + return new SendFriendEventToServiceProtocol.SendFriendEventToServiceResponse(false, "Event processing failed"); } } } diff --git a/service.friend/src/main/java/net/swofty/service/friend/endpoints/GetFriendDataEndpoint.java b/service.friend/src/main/java/net/swofty/service/friend/endpoints/GetFriendDataEndpoint.java index 438fae9d5..836a13c31 100644 --- a/service.friend/src/main/java/net/swofty/service/friend/endpoints/GetFriendDataEndpoint.java +++ b/service.friend/src/main/java/net/swofty/service/friend/endpoints/GetFriendDataEndpoint.java @@ -1,26 +1,24 @@ package net.swofty.service.friend.endpoints; import net.swofty.commons.friend.FriendData; -import net.swofty.commons.impl.ServiceProxyRequest; -import net.swofty.commons.protocol.objects.friend.GetFriendDataProtocolObject; +import net.swofty.commons.protocol.objects.friend.GetFriendDataProtocol; import net.swofty.service.friend.FriendCache; -import net.swofty.service.generic.redis.ServiceEndpoint; +import net.swofty.commons.redis.RedisMessageHandler; +import net.swofty.commons.redis.RedisMessageContext; -public class GetFriendDataEndpoint implements ServiceEndpoint< - GetFriendDataProtocolObject.GetFriendDataMessage, - GetFriendDataProtocolObject.GetFriendDataResponse> { +public class GetFriendDataEndpoint implements RedisMessageHandler< + GetFriendDataProtocol.GetFriendDataMessage, + GetFriendDataProtocol.GetFriendDataResponse> { @Override - public GetFriendDataProtocolObject associatedProtocolObject() { - return new GetFriendDataProtocolObject(); + public GetFriendDataProtocol protocol() { + return new GetFriendDataProtocol(); } @Override - public GetFriendDataProtocolObject.GetFriendDataResponse onMessage( - ServiceProxyRequest message, - GetFriendDataProtocolObject.GetFriendDataMessage messageObject) { + public GetFriendDataProtocol.GetFriendDataResponse handle(GetFriendDataProtocol.GetFriendDataMessage messageObject, RedisMessageContext context) { FriendData data = FriendCache.getFriendData(messageObject.playerUuid()); - return new GetFriendDataProtocolObject.GetFriendDataResponse(data, true, null); + return new GetFriendDataProtocol.GetFriendDataResponse(data, true, null); } } diff --git a/service.friend/src/main/java/net/swofty/service/friend/endpoints/GetPendingRequestsEndpoint.java b/service.friend/src/main/java/net/swofty/service/friend/endpoints/GetPendingRequestsEndpoint.java index e823184c3..81a983ebc 100644 --- a/service.friend/src/main/java/net/swofty/service/friend/endpoints/GetPendingRequestsEndpoint.java +++ b/service.friend/src/main/java/net/swofty/service/friend/endpoints/GetPendingRequestsEndpoint.java @@ -1,28 +1,26 @@ package net.swofty.service.friend.endpoints; import net.swofty.commons.friend.PendingFriendRequest; -import net.swofty.commons.impl.ServiceProxyRequest; -import net.swofty.commons.protocol.objects.friend.GetPendingFriendRequestsProtocolObject; +import net.swofty.commons.protocol.objects.friend.GetPendingFriendRequestsProtocol; import net.swofty.service.friend.FriendCache; -import net.swofty.service.generic.redis.ServiceEndpoint; +import net.swofty.commons.redis.RedisMessageHandler; import java.util.List; +import net.swofty.commons.redis.RedisMessageContext; -public class GetPendingRequestsEndpoint implements ServiceEndpoint< - GetPendingFriendRequestsProtocolObject.GetPendingRequestsMessage, - GetPendingFriendRequestsProtocolObject.GetPendingRequestsResponse> { +public class GetPendingRequestsEndpoint implements RedisMessageHandler< + GetPendingFriendRequestsProtocol.GetPendingRequestsMessage, + GetPendingFriendRequestsProtocol.GetPendingRequestsResponse> { @Override - public GetPendingFriendRequestsProtocolObject associatedProtocolObject() { - return new GetPendingFriendRequestsProtocolObject(); + public GetPendingFriendRequestsProtocol protocol() { + return new GetPendingFriendRequestsProtocol(); } @Override - public GetPendingFriendRequestsProtocolObject.GetPendingRequestsResponse onMessage( - ServiceProxyRequest message, - GetPendingFriendRequestsProtocolObject.GetPendingRequestsMessage messageObject) { + public GetPendingFriendRequestsProtocol.GetPendingRequestsResponse handle(GetPendingFriendRequestsProtocol.GetPendingRequestsMessage messageObject, RedisMessageContext context) { List requests = FriendCache.getPendingRequestsFor(messageObject.playerUuid()); - return new GetPendingFriendRequestsProtocolObject.GetPendingRequestsResponse(requests, true, null); + return new GetPendingFriendRequestsProtocol.GetPendingRequestsResponse(requests, true, null); } } diff --git a/service.friend/src/main/java/net/swofty/service/friend/endpoints/GetPresenceEndpoint.java b/service.friend/src/main/java/net/swofty/service/friend/endpoints/GetPresenceEndpoint.java index 2385ae98a..bf1402185 100644 --- a/service.friend/src/main/java/net/swofty/service/friend/endpoints/GetPresenceEndpoint.java +++ b/service.friend/src/main/java/net/swofty/service/friend/endpoints/GetPresenceEndpoint.java @@ -1,29 +1,27 @@ package net.swofty.service.friend.endpoints; -import net.swofty.commons.impl.ServiceProxyRequest; import net.swofty.commons.presence.PresenceInfo; -import net.swofty.commons.protocol.objects.presence.GetPresenceBulkProtocolObject; +import net.swofty.commons.protocol.objects.presence.GetPresenceBulkProtocol; import net.swofty.service.friend.PresenceStorage; -import net.swofty.service.generic.redis.ServiceEndpoint; +import net.swofty.commons.redis.RedisMessageHandler; import java.util.List; +import net.swofty.commons.redis.RedisMessageContext; -public class GetPresenceEndpoint implements ServiceEndpoint< - GetPresenceBulkProtocolObject.GetPresenceBulkMessage, - GetPresenceBulkProtocolObject.GetPresenceBulkResponse> { +public class GetPresenceEndpoint implements RedisMessageHandler< + GetPresenceBulkProtocol.GetPresenceBulkMessage, + GetPresenceBulkProtocol.GetPresenceBulkResponse> { @Override - public GetPresenceBulkProtocolObject associatedProtocolObject() { - return new GetPresenceBulkProtocolObject(); + public GetPresenceBulkProtocol protocol() { + return new GetPresenceBulkProtocol(); } @Override - public GetPresenceBulkProtocolObject.GetPresenceBulkResponse onMessage( - ServiceProxyRequest message, - GetPresenceBulkProtocolObject.GetPresenceBulkMessage messageObject) { + public GetPresenceBulkProtocol.GetPresenceBulkResponse handle(GetPresenceBulkProtocol.GetPresenceBulkMessage messageObject, RedisMessageContext context) { List presence = PresenceStorage.getBulk(messageObject.uuids()); - return new GetPresenceBulkProtocolObject.GetPresenceBulkResponse(presence, true, null); + return new GetPresenceBulkProtocol.GetPresenceBulkResponse(presence, true, null); } } diff --git a/service.friend/src/main/java/net/swofty/service/friend/endpoints/UpdatePresenceEndpoint.java b/service.friend/src/main/java/net/swofty/service/friend/endpoints/UpdatePresenceEndpoint.java index ce678d89f..186bf5c72 100644 --- a/service.friend/src/main/java/net/swofty/service/friend/endpoints/UpdatePresenceEndpoint.java +++ b/service.friend/src/main/java/net/swofty/service/friend/endpoints/UpdatePresenceEndpoint.java @@ -1,25 +1,23 @@ package net.swofty.service.friend.endpoints; -import net.swofty.commons.impl.ServiceProxyRequest; import net.swofty.commons.presence.PresenceInfo; -import net.swofty.commons.protocol.objects.presence.UpdatePresenceProtocolObject; +import net.swofty.commons.protocol.objects.presence.UpdatePresenceProtocol; import net.swofty.service.friend.FriendCache; import net.swofty.service.friend.PresenceStorage; -import net.swofty.service.generic.redis.ServiceEndpoint; +import net.swofty.commons.redis.RedisMessageHandler; +import net.swofty.commons.redis.RedisMessageContext; -public class UpdatePresenceEndpoint implements ServiceEndpoint< - UpdatePresenceProtocolObject.UpdatePresenceMessage, - UpdatePresenceProtocolObject.UpdatePresenceResponse> { +public class UpdatePresenceEndpoint implements RedisMessageHandler< + UpdatePresenceProtocol.UpdatePresenceMessage, + UpdatePresenceProtocol.UpdatePresenceResponse> { @Override - public UpdatePresenceProtocolObject associatedProtocolObject() { - return new UpdatePresenceProtocolObject(); + public UpdatePresenceProtocol protocol() { + return new UpdatePresenceProtocol(); } @Override - public UpdatePresenceProtocolObject.UpdatePresenceResponse onMessage( - ServiceProxyRequest message, - UpdatePresenceProtocolObject.UpdatePresenceMessage messageObject) { + public UpdatePresenceProtocol.UpdatePresenceResponse handle(UpdatePresenceProtocol.UpdatePresenceMessage messageObject, RedisMessageContext context) { PresenceInfo incoming = messageObject.presence(); PresenceInfo previous = PresenceStorage.upsertPreservingServer(incoming); @@ -35,7 +33,7 @@ public UpdatePresenceProtocolObject.UpdatePresenceResponse onMessage( } } - return new UpdatePresenceProtocolObject.UpdatePresenceResponse(true, null); + return new UpdatePresenceProtocol.UpdatePresenceResponse(true, null); } } diff --git a/service.generic/src/main/java/net/swofty/service/generic/ServiceInitializer.java b/service.generic/src/main/java/net/swofty/service/generic/ServiceInitializer.java index 62de978ae..6677af125 100644 --- a/service.generic/src/main/java/net/swofty/service/generic/ServiceInitializer.java +++ b/service.generic/src/main/java/net/swofty/service/generic/ServiceInitializer.java @@ -2,21 +2,22 @@ import lombok.RequiredArgsConstructor; import net.swofty.commons.config.ConfigProvider; -import net.swofty.commons.impl.ServiceProxyRequest; +import net.swofty.commons.protocol.RedisProtocol; +import net.swofty.commons.redis.RedisChannels; import net.swofty.commons.redis.RedisEnvelope; +import net.swofty.commons.redis.RedisMessageContext; +import net.swofty.commons.redis.RedisMessageHandler; import net.swofty.commons.skyblock.item.attribute.ItemAttribute; -import net.swofty.commons.protocol.ProtocolObject; import net.swofty.redisapi.api.ChannelRegistry; import net.swofty.redisapi.api.RedisAPI; import net.swofty.service.generic.redis.PingEndpoint; -import net.swofty.service.generic.redis.ServiceEndpoint; import net.swofty.service.generic.redis.ServiceRedisManager; import net.swofty.service.generic.redis.ServiceToServerManager; -import org.json.JSONObject; import org.tinylog.Logger; import java.util.ArrayList; import java.util.List; +import java.util.UUID; import java.util.concurrent.CountDownLatch; @RequiredArgsConstructor @@ -34,27 +35,33 @@ public void init() { // Initialize service-to-server communication ServiceToServerManager.initialize(service.getType()); - List endpoints = new ArrayList<>(service.getEndpoints()); + List endpoints = new ArrayList<>(service.getEndpoints()); endpoints.add(new PingEndpoint()); endpoints.forEach(endpoint -> { - ProtocolObject protocolObject = endpoint.associatedProtocolObject(); + RedisProtocol protocolObject = endpoint.protocol(); Logger.debug("Registering channel {}", protocolObject.channel()); - RedisAPI.getInstance().registerChannel(protocolObject.channel(), message -> { + RedisAPI.getInstance().registerChannel(RedisChannels.protocol(protocolObject), message -> { // Everything after the first semicolon is the actual message String realMessage = message.message.substring(message.message.indexOf(";") + 1); - ServiceProxyRequest request = ServiceProxyRequest.fromJSON(new JSONObject(realMessage)); + RedisEnvelope envelope = RedisEnvelope.deserialize(realMessage); - Object messageData = protocolObject.translateFromString(request.getMessage()); + Object messageData = protocolObject.translateFromString(envelope.payload()); Thread.startVirtualThread(() -> { - Object rawResponse = endpoint.onMessage(request, messageData); + RedisMessageContext context = RedisMessageContext.serverToService( + UUID.fromString(envelope.id()), + envelope.from(), + service.getType().name(), + protocolObject.channel() + ); + Object rawResponse = endpoint.handle(messageData, context); String response = protocolObject.translateReturnToString(rawResponse); - RedisAPI.getInstance().publishMessage(request.getRequestServer(), - ChannelRegistry.getFromName(request.getEndpoint()), - new RedisEnvelope(request.getRequestId().toString(), service.getType().name(), response).serialize()).join(); + RedisAPI.getInstance().publishMessage(envelope.from(), + ChannelRegistry.getFromName(protocolObject.channel()), + new RedisEnvelope(envelope.id(), service.getType().name(), response).serialize()).join(); }); }); }); diff --git a/service.generic/src/main/java/net/swofty/service/generic/SkyBlockService.java b/service.generic/src/main/java/net/swofty/service/generic/SkyBlockService.java index c34684d9d..3722b54ac 100644 --- a/service.generic/src/main/java/net/swofty/service/generic/SkyBlockService.java +++ b/service.generic/src/main/java/net/swofty/service/generic/SkyBlockService.java @@ -1,7 +1,7 @@ package net.swofty.service.generic; import net.swofty.commons.ServiceType; -import net.swofty.service.generic.redis.ServiceEndpoint; +import net.swofty.commons.redis.RedisMessageHandler; import org.reflections.Reflections; import java.lang.reflect.InvocationTargetException; @@ -13,7 +13,7 @@ public interface SkyBlockService { ServiceType getType(); - List getEndpoints(); + List getEndpoints(); static void init(SkyBlockService service) { new ServiceInitializer(service).init(); diff --git a/service.generic/src/main/java/net/swofty/service/generic/redis/PingEndpoint.java b/service.generic/src/main/java/net/swofty/service/generic/redis/PingEndpoint.java index 6e6b829f8..4d46cddbc 100644 --- a/service.generic/src/main/java/net/swofty/service/generic/redis/PingEndpoint.java +++ b/service.generic/src/main/java/net/swofty/service/generic/redis/PingEndpoint.java @@ -1,19 +1,20 @@ package net.swofty.service.generic.redis; -import net.swofty.commons.impl.ServiceProxyRequest; -import net.swofty.commons.protocol.ProtocolObject; -import net.swofty.commons.protocol.objects.PingProtocolObject; +import net.swofty.commons.protocol.RedisProtocol; +import net.swofty.commons.protocol.objects.PingProtocol; +import net.swofty.commons.redis.RedisMessageContext; +import net.swofty.commons.redis.RedisMessageHandler; -public class PingEndpoint implements ServiceEndpoint< - PingProtocolObject.EmptyMessage, - PingProtocolObject.EmptyMessage> { +public class PingEndpoint implements RedisMessageHandler< + PingProtocol.EmptyMessage, + PingProtocol.EmptyMessage> { @Override - public ProtocolObject associatedProtocolObject() { - return new PingProtocolObject(); + public RedisProtocol protocol() { + return new PingProtocol(); } @Override - public PingProtocolObject.EmptyMessage onMessage(ServiceProxyRequest message, PingProtocolObject.EmptyMessage messageObject) { - return new PingProtocolObject.EmptyMessage(); + public PingProtocol.EmptyMessage handle(PingProtocol.EmptyMessage messageObject, RedisMessageContext context) { + return new PingProtocol.EmptyMessage(); } } diff --git a/service.generic/src/main/java/net/swofty/service/generic/redis/ServiceEndpoint.java b/service.generic/src/main/java/net/swofty/service/generic/redis/ServiceEndpoint.java deleted file mode 100644 index 1588069a0..000000000 --- a/service.generic/src/main/java/net/swofty/service/generic/redis/ServiceEndpoint.java +++ /dev/null @@ -1,9 +0,0 @@ -package net.swofty.service.generic.redis; - -import net.swofty.commons.impl.ServiceProxyRequest; -import net.swofty.commons.protocol.ProtocolObject; - -public interface ServiceEndpoint { - ProtocolObject associatedProtocolObject(); - R onMessage(ServiceProxyRequest message, T messageObject); -} diff --git a/service.generic/src/main/java/net/swofty/service/generic/redis/ServiceToServerManager.java b/service.generic/src/main/java/net/swofty/service/generic/redis/ServiceToServerManager.java index d8a2f6456..5d326e6ca 100644 --- a/service.generic/src/main/java/net/swofty/service/generic/redis/ServiceToServerManager.java +++ b/service.generic/src/main/java/net/swofty/service/generic/redis/ServiceToServerManager.java @@ -1,7 +1,8 @@ package net.swofty.service.generic.redis; import net.swofty.commons.ServiceType; -import net.swofty.commons.protocol.ServicePushProtocol; +import net.swofty.commons.protocol.RedisProtocol; +import net.swofty.commons.redis.RedisChannels; import net.swofty.commons.redis.RedisEnvelope; import net.swofty.commons.protocol.objects.data.GetPlayerDataPushProtocol; import net.swofty.commons.protocol.objects.data.LockPlayerDataPushProtocol; @@ -37,7 +38,7 @@ public static void initialize(ServiceType serviceType) { currentServiceType = serviceType; // Register response handler for server responses - RedisAPI.getInstance().registerChannel("service_response", (event) -> { + RedisAPI.getInstance().registerChannel(RedisChannels.SERVICE_RESPONSE, (event) -> { String messageWithoutFilter = event.message.substring(event.message.indexOf(";") + 1); RedisEnvelope envelope = RedisEnvelope.deserialize(messageWithoutFilter); UUID requestId = UUID.fromString(envelope.id()); @@ -48,7 +49,7 @@ public static void initialize(ServiceType serviceType) { } }); - RedisAPI.getInstance().registerChannel("service_broadcast_response", (event) -> { + RedisAPI.getInstance().registerChannel(RedisChannels.SERVICE_BROADCAST_RESPONSE, (event) -> { String messageWithoutFilter = event.message.substring(event.message.indexOf(";") + 1); RedisEnvelope envelope = RedisEnvelope.deserialize(messageWithoutFilter); UUID requestId = UUID.fromString(envelope.id()); @@ -63,7 +64,7 @@ public static void initialize(ServiceType serviceType) { public static CompletableFuture sendToServer( UUID serverUUID, - ServicePushProtocol protocol, + RedisProtocol protocol, T message ) { UUID requestId = UUID.randomUUID(); @@ -91,7 +92,7 @@ public static CompletableFuture sendToServer( }); String serialized = protocol.translateToString(message); - String channelName = "service_" + protocol.channel(); + String channelName = RedisChannels.serviceRequest(protocol); RedisAPI.getInstance().publishMessage( serverUUID.toString(), @@ -103,7 +104,7 @@ public static CompletableFuture sendToServer( } public static CompletableFuture> sendToAllServers( - ServicePushProtocol protocol, + RedisProtocol protocol, T message, int timeoutMs ) { @@ -115,9 +116,9 @@ public static CompletableFuture> sendToAllServers( pendingBroadcastRequests.put(requestId, broadcastRequest); String serialized = protocol.translateToString(message); - String channelName = "service_broadcast_" + protocol.channel(); + String channelName = RedisChannels.serviceBroadcast(protocol); - RedisAPI.getInstance().publishMessage("all", + RedisAPI.getInstance().publishMessage(RedisChannels.ALL_SERVERS, ChannelRegistry.getFromName(channelName), new RedisEnvelope(requestId.toString(), currentServiceType.name(), serialized).serialize()); @@ -145,7 +146,7 @@ public static CompletableFuture> sendToAllServers( public static CompletableFuture> sendToServers( List serverUUIDs, - ServicePushProtocol protocol, + RedisProtocol protocol, T message ) { Map> futures = new ConcurrentHashMap<>(); @@ -205,4 +206,4 @@ public static CompletableFuture> return sendToServers(List.of(serverUUID), GAME_INFORMATION_PROTOCOL, new GameInformationPushProtocol.Request(playerUUID, gameId)); } -} \ No newline at end of file +} diff --git a/service.itemtracker/src/main/java/net/swofty/service/itemtracker/ItemTrackerService.java b/service.itemtracker/src/main/java/net/swofty/service/itemtracker/ItemTrackerService.java index b6cfd5a9a..33b955cf7 100644 --- a/service.itemtracker/src/main/java/net/swofty/service/itemtracker/ItemTrackerService.java +++ b/service.itemtracker/src/main/java/net/swofty/service/itemtracker/ItemTrackerService.java @@ -3,7 +3,7 @@ import net.swofty.commons.ServiceType; import net.swofty.commons.config.ConfigProvider; import net.swofty.service.generic.SkyBlockService; -import net.swofty.service.generic.redis.ServiceEndpoint; +import net.swofty.commons.redis.RedisMessageHandler; import java.util.List; @@ -20,7 +20,7 @@ public ServiceType getType() { } @Override - public List getEndpoints() { - return loopThroughPackage("net.swofty.service.itemtracker.endpoints", ServiceEndpoint.class).toList(); + public List getEndpoints() { + return loopThroughPackage("net.swofty.service.itemtracker.endpoints", RedisMessageHandler.class).toList(); } } diff --git a/service.itemtracker/src/main/java/net/swofty/service/itemtracker/endpoints/EndpointGetTrackedItem.java b/service.itemtracker/src/main/java/net/swofty/service/itemtracker/endpoints/EndpointGetTrackedItem.java index 9cc671a73..ab7aec89a 100644 --- a/service.itemtracker/src/main/java/net/swofty/service/itemtracker/endpoints/EndpointGetTrackedItem.java +++ b/service.itemtracker/src/main/java/net/swofty/service/itemtracker/endpoints/EndpointGetTrackedItem.java @@ -1,24 +1,24 @@ package net.swofty.service.itemtracker.endpoints; import net.swofty.commons.TrackedItem; -import net.swofty.commons.impl.ServiceProxyRequest; -import net.swofty.commons.protocol.objects.itemtracker.TrackedItemRetrieveProtocolObject; -import net.swofty.service.generic.redis.ServiceEndpoint; +import net.swofty.commons.protocol.objects.itemtracker.TrackedItemRetrieveProtocol; +import net.swofty.commons.redis.RedisMessageHandler; import net.swofty.service.itemtracker.TrackedItemsDatabase; import java.util.UUID; +import net.swofty.commons.redis.RedisMessageContext; -public class EndpointGetTrackedItem implements ServiceEndpoint< - TrackedItemRetrieveProtocolObject.TrackedItemRetrieveMessage, - TrackedItemRetrieveProtocolObject.TrackedItemResponse> { +public class EndpointGetTrackedItem implements RedisMessageHandler< + TrackedItemRetrieveProtocol.TrackedItemRetrieveMessage, + TrackedItemRetrieveProtocol.TrackedItemResponse> { @Override - public TrackedItemRetrieveProtocolObject associatedProtocolObject() { - return new TrackedItemRetrieveProtocolObject(); + public TrackedItemRetrieveProtocol protocol() { + return new TrackedItemRetrieveProtocol(); } @Override - public TrackedItemRetrieveProtocolObject.TrackedItemResponse onMessage(ServiceProxyRequest message, TrackedItemRetrieveProtocolObject.TrackedItemRetrieveMessage messageObject) { + public TrackedItemRetrieveProtocol.TrackedItemResponse handle(TrackedItemRetrieveProtocol.TrackedItemRetrieveMessage messageObject, RedisMessageContext context) { UUID itemUUID = messageObject.itemUUID(); if (!new TrackedItemsDatabase(itemUUID).exists()) { @@ -26,6 +26,6 @@ public TrackedItemRetrieveProtocolObject.TrackedItemResponse onMessage(ServicePr } TrackedItem item = new TrackedItemsDatabase(itemUUID).get(); - return new TrackedItemRetrieveProtocolObject.TrackedItemResponse(item, true, null); + return new TrackedItemRetrieveProtocol.TrackedItemResponse(item, true, null); } } \ No newline at end of file diff --git a/service.itemtracker/src/main/java/net/swofty/service/itemtracker/endpoints/EndpointUpdateItem.java b/service.itemtracker/src/main/java/net/swofty/service/itemtracker/endpoints/EndpointUpdateItem.java index 098f7410e..afa529fdd 100644 --- a/service.itemtracker/src/main/java/net/swofty/service/itemtracker/endpoints/EndpointUpdateItem.java +++ b/service.itemtracker/src/main/java/net/swofty/service/itemtracker/endpoints/EndpointUpdateItem.java @@ -1,24 +1,24 @@ package net.swofty.service.itemtracker.endpoints; import net.swofty.commons.TrackedItem; -import net.swofty.commons.impl.ServiceProxyRequest; -import net.swofty.commons.protocol.objects.itemtracker.TrackedItemUpdateProtocolObject; -import net.swofty.service.generic.redis.ServiceEndpoint; +import net.swofty.commons.protocol.objects.itemtracker.TrackedItemUpdateProtocol; +import net.swofty.commons.redis.RedisMessageHandler; import net.swofty.service.itemtracker.TrackedItemsDatabase; import java.util.UUID; +import net.swofty.commons.redis.RedisMessageContext; -public class EndpointUpdateItem implements ServiceEndpoint< - TrackedItemUpdateProtocolObject.TrackedItemUpdateMessage, - TrackedItemUpdateProtocolObject.TrackedItemUpdateResponse> { +public class EndpointUpdateItem implements RedisMessageHandler< + TrackedItemUpdateProtocol.TrackedItemUpdateMessage, + TrackedItemUpdateProtocol.TrackedItemUpdateResponse> { @Override - public TrackedItemUpdateProtocolObject associatedProtocolObject() { - return new TrackedItemUpdateProtocolObject(); + public TrackedItemUpdateProtocol protocol() { + return new TrackedItemUpdateProtocol(); } @Override - public TrackedItemUpdateProtocolObject.TrackedItemUpdateResponse onMessage(ServiceProxyRequest message, TrackedItemUpdateProtocolObject.TrackedItemUpdateMessage messageObject) { + public TrackedItemUpdateProtocol.TrackedItemUpdateResponse handle(TrackedItemUpdateProtocol.TrackedItemUpdateMessage messageObject, RedisMessageContext context) { UUID itemUUID = messageObject.itemUUID(); UUID attachedPlayerUUID = messageObject.attachedPlayerUUID(); UUID attachedPlayerProfile = messageObject.attachedPlayerProfile(); @@ -41,6 +41,6 @@ public TrackedItemUpdateProtocolObject.TrackedItemUpdateResponse onMessage(Servi } }); - return new TrackedItemUpdateProtocolObject.TrackedItemUpdateResponse(); + return new TrackedItemUpdateProtocol.TrackedItemUpdateResponse(); } } diff --git a/service.orchestrator/src/main/java/net/swofty/service/orchestrator/OrchestratorService.java b/service.orchestrator/src/main/java/net/swofty/service/orchestrator/OrchestratorService.java index 480e257d4..510f7f2f8 100644 --- a/service.orchestrator/src/main/java/net/swofty/service/orchestrator/OrchestratorService.java +++ b/service.orchestrator/src/main/java/net/swofty/service/orchestrator/OrchestratorService.java @@ -2,7 +2,7 @@ import net.swofty.commons.ServiceType; import net.swofty.service.generic.SkyBlockService; -import net.swofty.service.generic.redis.ServiceEndpoint; +import net.swofty.commons.redis.RedisMessageHandler; import java.util.List; import java.util.concurrent.Executors; @@ -28,7 +28,7 @@ public ServiceType getType() { } @Override - public List getEndpoints() { - return loopThroughPackage("net.swofty.service.orchestrator.endpoints", ServiceEndpoint.class).toList(); + public List getEndpoints() { + return loopThroughPackage("net.swofty.service.orchestrator.endpoints", RedisMessageHandler.class).toList(); } } \ No newline at end of file diff --git a/service.orchestrator/src/main/java/net/swofty/service/orchestrator/endpoints/GameChooseEndpoint.java b/service.orchestrator/src/main/java/net/swofty/service/orchestrator/endpoints/GameChooseEndpoint.java index b301bc696..05dd4337a 100644 --- a/service.orchestrator/src/main/java/net/swofty/service/orchestrator/endpoints/GameChooseEndpoint.java +++ b/service.orchestrator/src/main/java/net/swofty/service/orchestrator/endpoints/GameChooseEndpoint.java @@ -1,25 +1,24 @@ package net.swofty.service.orchestrator.endpoints; -import net.swofty.commons.impl.ServiceProxyRequest; -import net.swofty.commons.protocol.ProtocolObject; -import net.swofty.commons.protocol.objects.orchestrator.ChooseGameProtocolObject; -import net.swofty.service.generic.redis.ServiceEndpoint; +import net.swofty.commons.protocol.RedisProtocol; +import net.swofty.commons.protocol.objects.orchestrator.ChooseGameProtocol; +import net.swofty.commons.redis.RedisMessageHandler; import net.swofty.service.generic.redis.ServiceToServerManager; +import net.swofty.commons.redis.RedisMessageContext; -public class GameChooseEndpoint implements ServiceEndpoint - { +public class GameChooseEndpoint implements RedisMessageHandler + { @Override - public ProtocolObject associatedProtocolObject() { - return new ChooseGameProtocolObject(); + public RedisProtocol protocol() { + return new ChooseGameProtocol(); } @Override - public ChooseGameProtocolObject.ChooseGameResponse onMessage(ServiceProxyRequest message, - ChooseGameProtocolObject.ChooseGameMessage body) { + public ChooseGameProtocol.ChooseGameResponse handle(ChooseGameProtocol.ChooseGameMessage body, RedisMessageContext context) { ServiceToServerManager.gameInformation(body.server().uuid(), body.player(), body.gameId()); - return new ChooseGameProtocolObject.ChooseGameResponse(true, null); + return new ChooseGameProtocol.ChooseGameResponse(true, null); } } diff --git a/service.orchestrator/src/main/java/net/swofty/service/orchestrator/endpoints/GameHeartbeatEndpoint.java b/service.orchestrator/src/main/java/net/swofty/service/orchestrator/endpoints/GameHeartbeatEndpoint.java index 17fc357e8..2380d44b0 100644 --- a/service.orchestrator/src/main/java/net/swofty/service/orchestrator/endpoints/GameHeartbeatEndpoint.java +++ b/service.orchestrator/src/main/java/net/swofty/service/orchestrator/endpoints/GameHeartbeatEndpoint.java @@ -1,23 +1,22 @@ package net.swofty.service.orchestrator.endpoints; -import net.swofty.commons.impl.ServiceProxyRequest; -import net.swofty.commons.protocol.ProtocolObject; -import net.swofty.commons.protocol.objects.orchestrator.GameHeartbeatProtocolObject; -import net.swofty.service.generic.redis.ServiceEndpoint; +import net.swofty.commons.protocol.RedisProtocol; +import net.swofty.commons.protocol.objects.orchestrator.GameHeartbeatProtocol; +import net.swofty.commons.redis.RedisMessageHandler; import net.swofty.service.orchestrator.OrchestratorCache; +import net.swofty.commons.redis.RedisMessageContext; -public class GameHeartbeatEndpoint implements ServiceEndpoint - { +public class GameHeartbeatEndpoint implements RedisMessageHandler + { @Override - public ProtocolObject associatedProtocolObject() { - return new GameHeartbeatProtocolObject(); + public RedisProtocol protocol() { + return new GameHeartbeatProtocol(); } @Override - public GameHeartbeatProtocolObject.HeartbeatResponse onMessage(ServiceProxyRequest message, - GameHeartbeatProtocolObject.HeartbeatMessage body) { + public GameHeartbeatProtocol.HeartbeatResponse handle(GameHeartbeatProtocol.HeartbeatMessage body, RedisMessageContext context) { OrchestratorCache.handleHeartbeat( body.uuid(), body.shortName(), @@ -26,6 +25,6 @@ public GameHeartbeatProtocolObject.HeartbeatResponse onMessage(ServiceProxyReque body.onlinePlayers(), body.games() ); - return new GameHeartbeatProtocolObject.HeartbeatResponse(true, null); + return new GameHeartbeatProtocol.HeartbeatResponse(true, null); } } \ No newline at end of file diff --git a/service.orchestrator/src/main/java/net/swofty/service/orchestrator/endpoints/GetGameCountsEndpoint.java b/service.orchestrator/src/main/java/net/swofty/service/orchestrator/endpoints/GetGameCountsEndpoint.java index 41c61ae53..219fc98f3 100644 --- a/service.orchestrator/src/main/java/net/swofty/service/orchestrator/endpoints/GetGameCountsEndpoint.java +++ b/service.orchestrator/src/main/java/net/swofty/service/orchestrator/endpoints/GetGameCountsEndpoint.java @@ -1,23 +1,23 @@ package net.swofty.service.orchestrator.endpoints; -import net.swofty.commons.impl.ServiceProxyRequest; -import net.swofty.commons.protocol.ProtocolObject; -import net.swofty.commons.protocol.objects.orchestrator.GetGameCountsProtocolObject; -import net.swofty.service.generic.redis.ServiceEndpoint; +import net.swofty.commons.protocol.RedisProtocol; +import net.swofty.commons.protocol.objects.orchestrator.GetGameCountsProtocol; +import net.swofty.commons.redis.RedisMessageHandler; import net.swofty.service.orchestrator.OrchestratorCache; +import net.swofty.commons.redis.RedisMessageContext; -public class GetGameCountsEndpoint implements ServiceEndpoint - { +public class GetGameCountsEndpoint implements RedisMessageHandler + { @Override - public ProtocolObject associatedProtocolObject() { - return new GetGameCountsProtocolObject(); + public RedisProtocol protocol() { + return new GetGameCountsProtocol(); } @Override - public GetGameCountsProtocolObject.GetGameCountsResponse onMessage(ServiceProxyRequest message, GetGameCountsProtocolObject.GetGameCountsMessage body) { + public GetGameCountsProtocol.GetGameCountsResponse handle(GetGameCountsProtocol.GetGameCountsMessage body, RedisMessageContext context) { var stats = OrchestratorCache.getGameCounts(body.type(), body.gameTypeName(), body.mapName()); - return new GetGameCountsProtocolObject.GetGameCountsResponse(stats.playerCount(), stats.gameCount(), true, null); + return new GetGameCountsProtocol.GetGameCountsResponse(stats.playerCount(), stats.gameCount(), true, null); } } diff --git a/service.orchestrator/src/main/java/net/swofty/service/orchestrator/endpoints/GetMapsEndpoint.java b/service.orchestrator/src/main/java/net/swofty/service/orchestrator/endpoints/GetMapsEndpoint.java index d50d0ad01..efc96459a 100644 --- a/service.orchestrator/src/main/java/net/swofty/service/orchestrator/endpoints/GetMapsEndpoint.java +++ b/service.orchestrator/src/main/java/net/swofty/service/orchestrator/endpoints/GetMapsEndpoint.java @@ -1,23 +1,23 @@ package net.swofty.service.orchestrator.endpoints; -import net.swofty.commons.impl.ServiceProxyRequest; -import net.swofty.commons.protocol.ProtocolObject; -import net.swofty.commons.protocol.objects.orchestrator.GetMapsProtocolObject; -import net.swofty.service.generic.redis.ServiceEndpoint; +import net.swofty.commons.protocol.RedisProtocol; +import net.swofty.commons.protocol.objects.orchestrator.GetMapsProtocol; +import net.swofty.commons.redis.RedisMessageHandler; import net.swofty.service.orchestrator.OrchestratorCache; +import net.swofty.commons.redis.RedisMessageContext; -public class GetMapsEndpoint implements ServiceEndpoint - { +public class GetMapsEndpoint implements RedisMessageHandler + { @Override - public ProtocolObject associatedProtocolObject() { - return new GetMapsProtocolObject(); + public RedisProtocol protocol() { + return new GetMapsProtocol(); } @Override - public GetMapsProtocolObject.GetMapsResponse onMessage(ServiceProxyRequest message, GetMapsProtocolObject.GetMapsMessage body) { + public GetMapsProtocol.GetMapsResponse handle(GetMapsProtocol.GetMapsMessage body, RedisMessageContext context) { var maps = OrchestratorCache.getMaps(body.type(), body.mode()); - return new GetMapsProtocolObject.GetMapsResponse(maps.stream().sorted().toList(), true, null); + return new GetMapsProtocol.GetMapsResponse(maps.stream().sorted().toList(), true, null); } } \ No newline at end of file diff --git a/service.orchestrator/src/main/java/net/swofty/service/orchestrator/endpoints/GetServerForMapEndpoint.java b/service.orchestrator/src/main/java/net/swofty/service/orchestrator/endpoints/GetServerForMapEndpoint.java index 16de8f9d1..f9124cad1 100644 --- a/service.orchestrator/src/main/java/net/swofty/service/orchestrator/endpoints/GetServerForMapEndpoint.java +++ b/service.orchestrator/src/main/java/net/swofty/service/orchestrator/endpoints/GetServerForMapEndpoint.java @@ -2,47 +2,46 @@ import net.swofty.commons.ServerType; import net.swofty.commons.UnderstandableProxyServer; -import net.swofty.commons.impl.ServiceProxyRequest; -import net.swofty.commons.protocol.ProtocolObject; -import net.swofty.commons.protocol.objects.orchestrator.GetServerForMapProtocolObject; +import net.swofty.commons.protocol.RedisProtocol; +import net.swofty.commons.protocol.objects.orchestrator.GetServerForMapProtocol; import net.swofty.commons.protocol.objects.game.InstantiateGamePushProtocol; import net.swofty.commons.bedwars.BedwarsGameType; import net.swofty.commons.murdermystery.MurderMysteryGameType; import net.swofty.commons.skywars.SkywarsGameType; import net.swofty.service.generic.redis.ServiceToServerManager; -import net.swofty.service.generic.redis.ServiceEndpoint; +import net.swofty.commons.redis.RedisMessageHandler; import net.swofty.service.orchestrator.OrchestratorCache; import org.tinylog.Logger; import java.util.ArrayList; import java.util.concurrent.CompletableFuture; +import net.swofty.commons.redis.RedisMessageContext; -public class GetServerForMapEndpoint implements ServiceEndpoint - { +public class GetServerForMapEndpoint implements RedisMessageHandler + { @Override - public ProtocolObject associatedProtocolObject() { - return new GetServerForMapProtocolObject(); + public RedisProtocol protocol() { + return new GetServerForMapProtocol(); } @Override - public GetServerForMapProtocolObject.GetServerForMapResponse onMessage(ServiceProxyRequest message, - GetServerForMapProtocolObject.GetServerForMapMessage body) { + public GetServerForMapProtocol.GetServerForMapResponse handle(GetServerForMapProtocol.GetServerForMapMessage body, RedisMessageContext context) { return switch (body.type()) { case BEDWARS_GAME -> handleBedwars(body); case MURDER_MYSTERY_GAME -> handleMurderMystery(body); case SKYWARS_GAME -> handleSkywars(body); - default -> new GetServerForMapProtocolObject.GetServerForMapResponse(null, null, true, null); + default -> new GetServerForMapProtocol.GetServerForMapResponse(null, null, true, null); }; } - private GetServerForMapProtocolObject.GetServerForMapResponse handleBedwars( - GetServerForMapProtocolObject.GetServerForMapMessage body) { + private GetServerForMapProtocol.GetServerForMapResponse handleBedwars( + GetServerForMapProtocol.GetServerForMapMessage body) { try { BedwarsGameType gameType = parseBedwarsGameType(body.mode()); if (gameType == null) { - return new GetServerForMapProtocolObject.GetServerForMapResponse(null, null, true, null); + return new GetServerForMapProtocol.GetServerForMapResponse(null, null, true, null); } int neededSlots = body.neededSlots() > 0 ? body.neededSlots() : 1; @@ -61,7 +60,7 @@ private GetServerForMapProtocolObject.GetServerForMapResponse handleBedwars( hostingServer.maxPlayers(), hostingServer.shortName() ); - return new GetServerForMapProtocolObject.GetServerForMapResponse(proxy, existingGameWithServer.game().getGameId().toString(), true, null); + return new GetServerForMapProtocol.GetServerForMapResponse(proxy, existingGameWithServer.game().getGameId().toString(), true, null); } } @@ -87,25 +86,25 @@ private GetServerForMapProtocolObject.GetServerForMapResponse handleBedwars( availableServer.maxPlayers(), availableServer.shortName() ); - return new GetServerForMapProtocolObject.GetServerForMapResponse(proxy, response.gameId(), true, null); + return new GetServerForMapProtocol.GetServerForMapResponse(proxy, response.gameId(), true, null); } } catch (Exception e) { Logger.error(e, "Failed to instantiate Bedwars game"); } } - return new GetServerForMapProtocolObject.GetServerForMapResponse(null, null, true, null); + return new GetServerForMapProtocol.GetServerForMapResponse(null, null, true, null); } catch (Exception e) { - return new GetServerForMapProtocolObject.GetServerForMapResponse(null, null, true, null); + return new GetServerForMapProtocol.GetServerForMapResponse(null, null, true, null); } } - private GetServerForMapProtocolObject.GetServerForMapResponse handleMurderMystery( - GetServerForMapProtocolObject.GetServerForMapMessage body) { + private GetServerForMapProtocol.GetServerForMapResponse handleMurderMystery( + GetServerForMapProtocol.GetServerForMapMessage body) { try { MurderMysteryGameType gameType = parseMurderMysteryGameType(body.mode()); if (gameType == null) { - return new GetServerForMapProtocolObject.GetServerForMapResponse(null, null, true, null); + return new GetServerForMapProtocol.GetServerForMapResponse(null, null, true, null); } int neededSlots = body.neededSlots() > 0 ? body.neededSlots() : 1; @@ -125,7 +124,7 @@ private GetServerForMapProtocolObject.GetServerForMapResponse handleMurderMyster hostingServer.maxPlayers(), hostingServer.shortName() ); - return new GetServerForMapProtocolObject.GetServerForMapResponse(proxy, existingGameWithServer.game().getGameId().toString(), true, null); + return new GetServerForMapProtocol.GetServerForMapResponse(proxy, existingGameWithServer.game().getGameId().toString(), true, null); } } @@ -152,16 +151,16 @@ private GetServerForMapProtocolObject.GetServerForMapResponse handleMurderMyster availableServer.maxPlayers(), availableServer.shortName() ); - return new GetServerForMapProtocolObject.GetServerForMapResponse(proxy, response.gameId(), true, null); + return new GetServerForMapProtocol.GetServerForMapResponse(proxy, response.gameId(), true, null); } } catch (Exception e) { Logger.error(e, "Failed to instantiate Murder Mystery game"); } } - return new GetServerForMapProtocolObject.GetServerForMapResponse(null, null, true, null); + return new GetServerForMapProtocol.GetServerForMapResponse(null, null, true, null); } catch (Exception e) { - return new GetServerForMapProtocolObject.GetServerForMapResponse(null, null, true, null); + return new GetServerForMapProtocol.GetServerForMapResponse(null, null, true, null); } } @@ -202,12 +201,12 @@ private MurderMysteryGameType parseMurderMysteryGameType(String mode) { }; } - private GetServerForMapProtocolObject.GetServerForMapResponse handleSkywars( - GetServerForMapProtocolObject.GetServerForMapMessage body) { + private GetServerForMapProtocol.GetServerForMapResponse handleSkywars( + GetServerForMapProtocol.GetServerForMapMessage body) { try { SkywarsGameType gameType = parseSkywarsGameType(body.mode()); if (gameType == null) { - return new GetServerForMapProtocolObject.GetServerForMapResponse(null, null, true, null); + return new GetServerForMapProtocol.GetServerForMapResponse(null, null, true, null); } int neededSlots = body.neededSlots() > 0 ? body.neededSlots() : 1; @@ -227,7 +226,7 @@ private GetServerForMapProtocolObject.GetServerForMapResponse handleSkywars( hostingServer.maxPlayers(), hostingServer.shortName() ); - return new GetServerForMapProtocolObject.GetServerForMapResponse(proxy, existingGameWithServer.game().getGameId().toString(), true, null); + return new GetServerForMapProtocol.GetServerForMapResponse(proxy, existingGameWithServer.game().getGameId().toString(), true, null); } } @@ -254,16 +253,16 @@ private GetServerForMapProtocolObject.GetServerForMapResponse handleSkywars( availableServer.maxPlayers(), availableServer.shortName() ); - return new GetServerForMapProtocolObject.GetServerForMapResponse(proxy, response.gameId(), true, null); + return new GetServerForMapProtocol.GetServerForMapResponse(proxy, response.gameId(), true, null); } } catch (Exception e) { Logger.error(e, "Failed to instantiate Skywars game"); } } - return new GetServerForMapProtocolObject.GetServerForMapResponse(null, null, true, null); + return new GetServerForMapProtocol.GetServerForMapResponse(null, null, true, null); } catch (Exception e) { - return new GetServerForMapProtocolObject.GetServerForMapResponse(null, null, true, null); + return new GetServerForMapProtocol.GetServerForMapResponse(null, null, true, null); } } diff --git a/service.orchestrator/src/main/java/net/swofty/service/orchestrator/endpoints/RejoinGameEndpoint.java b/service.orchestrator/src/main/java/net/swofty/service/orchestrator/endpoints/RejoinGameEndpoint.java index b5170e0b8..9fca76c54 100644 --- a/service.orchestrator/src/main/java/net/swofty/service/orchestrator/endpoints/RejoinGameEndpoint.java +++ b/service.orchestrator/src/main/java/net/swofty/service/orchestrator/endpoints/RejoinGameEndpoint.java @@ -2,43 +2,42 @@ import net.swofty.commons.ServerType; import net.swofty.commons.UnderstandableProxyServer; -import net.swofty.commons.impl.ServiceProxyRequest; -import net.swofty.commons.protocol.ProtocolObject; -import net.swofty.commons.protocol.objects.orchestrator.RejoinGameProtocolObject; -import net.swofty.service.generic.redis.ServiceEndpoint; +import net.swofty.commons.protocol.RedisProtocol; +import net.swofty.commons.protocol.objects.orchestrator.RejoinGameProtocol; +import net.swofty.commons.redis.RedisMessageHandler; import net.swofty.service.orchestrator.OrchestratorCache; import org.tinylog.Logger; import java.util.ArrayList; +import net.swofty.commons.redis.RedisMessageContext; -public class RejoinGameEndpoint implements ServiceEndpoint< - RejoinGameProtocolObject.RejoinGameRequest, - RejoinGameProtocolObject.RejoinGameResponse> { +public class RejoinGameEndpoint implements RedisMessageHandler< + RejoinGameProtocol.RejoinGameRequest, + RejoinGameProtocol.RejoinGameResponse> { @Override - public ProtocolObject associatedProtocolObject() { - return new RejoinGameProtocolObject(); + public RedisProtocol protocol() { + return new RejoinGameProtocol(); } @Override - public RejoinGameProtocolObject.RejoinGameResponse onMessage(ServiceProxyRequest message, - RejoinGameProtocolObject.RejoinGameRequest body) { + public RejoinGameProtocol.RejoinGameResponse handle(RejoinGameProtocol.RejoinGameRequest body, RedisMessageContext context) { try { // Find the game this player is part of (active or disconnected) OrchestratorCache.GameWithServer gameWithServer = OrchestratorCache.findPlayerGame(body.playerUuid()); if (gameWithServer == null) { - return new RejoinGameProtocolObject.RejoinGameResponse(false, null, null, null, null, false, true, null); + return new RejoinGameProtocol.RejoinGameResponse(false, null, null, null, null, false, true, null); } OrchestratorCache.GameServerState hostingServer = OrchestratorCache.getServerByUuid(gameWithServer.serverUuid()); if (hostingServer == null) { - return new RejoinGameProtocolObject.RejoinGameResponse(false, null, null, null, null, false, true, null); + return new RejoinGameProtocol.RejoinGameResponse(false, null, null, null, null, false, true, null); } // Skywars does not support rejoining if (hostingServer.type() == ServerType.SKYWARS_GAME) { - return new RejoinGameProtocolObject.RejoinGameResponse(false, null, null, null, null, false, true, null); + return new RejoinGameProtocol.RejoinGameResponse(false, null, null, null, null, false, true, null); } // Check if this player is in the disconnected list (meaning they should rejoin) @@ -48,7 +47,7 @@ public RejoinGameProtocolObject.RejoinGameResponse onMessage(ServiceProxyRequest if (!isDisconnected) { // Player is already in an active game, not a rejoin scenario - return new RejoinGameProtocolObject.RejoinGameResponse(false, null, null, null, null, false, true, null); + return new RejoinGameProtocol.RejoinGameResponse(false, null, null, null, null, false, true, null); } UnderstandableProxyServer proxy = new UnderstandableProxyServer( @@ -61,7 +60,7 @@ public RejoinGameProtocolObject.RejoinGameResponse onMessage(ServiceProxyRequest hostingServer.shortName() ); - return new RejoinGameProtocolObject.RejoinGameResponse( + return new RejoinGameProtocol.RejoinGameResponse( true, proxy, gameWithServer.game().getGameId().toString(), @@ -73,7 +72,7 @@ public RejoinGameProtocolObject.RejoinGameResponse onMessage(ServiceProxyRequest ); } catch (Exception e) { Logger.error(e, "Failed to check rejoin"); - return new RejoinGameProtocolObject.RejoinGameResponse(false, null, null, null, null, false, true, null); + return new RejoinGameProtocol.RejoinGameResponse(false, null, null, null, null, false, true, null); } } } diff --git a/service.party/src/main/java/net/swofty/service/party/PartyService.java b/service.party/src/main/java/net/swofty/service/party/PartyService.java index b9d6cb6ca..c272992ad 100644 --- a/service.party/src/main/java/net/swofty/service/party/PartyService.java +++ b/service.party/src/main/java/net/swofty/service/party/PartyService.java @@ -2,7 +2,7 @@ import net.swofty.commons.ServiceType; import net.swofty.service.generic.SkyBlockService; -import net.swofty.service.generic.redis.ServiceEndpoint; +import net.swofty.commons.redis.RedisMessageHandler; import java.util.List; @@ -18,7 +18,7 @@ public ServiceType getType() { } @Override - public List getEndpoints() { - return loopThroughPackage("net.swofty.service.party.endpoints", ServiceEndpoint.class).toList(); + public List getEndpoints() { + return loopThroughPackage("net.swofty.service.party.endpoints", RedisMessageHandler.class).toList(); } } \ No newline at end of file diff --git a/service.party/src/main/java/net/swofty/service/party/endpoints/GetPartyEndpoint.java b/service.party/src/main/java/net/swofty/service/party/endpoints/GetPartyEndpoint.java index 59f588dcf..43d8535b6 100644 --- a/service.party/src/main/java/net/swofty/service/party/endpoints/GetPartyEndpoint.java +++ b/service.party/src/main/java/net/swofty/service/party/endpoints/GetPartyEndpoint.java @@ -1,27 +1,27 @@ package net.swofty.service.party.endpoints; -import net.swofty.commons.impl.ServiceProxyRequest; import net.swofty.commons.party.FullParty; -import net.swofty.commons.protocol.ProtocolObject; -import net.swofty.commons.protocol.objects.party.GetPartyProtocolObject; -import net.swofty.service.generic.redis.ServiceEndpoint; +import net.swofty.commons.protocol.RedisProtocol; +import net.swofty.commons.protocol.objects.party.GetPartyProtocol; +import net.swofty.commons.redis.RedisMessageHandler; import net.swofty.service.party.PartyCache; import java.util.UUID; +import net.swofty.commons.redis.RedisMessageContext; -public class GetPartyEndpoint implements ServiceEndpoint - { +public class GetPartyEndpoint implements RedisMessageHandler + { @Override - public ProtocolObject associatedProtocolObject() { - return new GetPartyProtocolObject(); + public RedisProtocol protocol() { + return new GetPartyProtocol(); } @Override - public GetPartyProtocolObject.GetPartyResponse onMessage(ServiceProxyRequest message, GetPartyProtocolObject.GetPartyMessage messageObject) { + public GetPartyProtocol.GetPartyResponse handle(GetPartyProtocol.GetPartyMessage messageObject, RedisMessageContext context) { UUID memberUUID = messageObject.memberUuid(); FullParty party = PartyCache.getPartyFromPlayer(memberUUID); if (party == null) throw new RuntimeException("Player is not in a party"); - return new GetPartyProtocolObject.GetPartyResponse(party, true, null); + return new GetPartyProtocol.GetPartyResponse(party, true, null); } } diff --git a/service.party/src/main/java/net/swofty/service/party/endpoints/IsPlayerInPartyEndpoint.java b/service.party/src/main/java/net/swofty/service/party/endpoints/IsPlayerInPartyEndpoint.java index 0abb8a6e2..6104036a6 100644 --- a/service.party/src/main/java/net/swofty/service/party/endpoints/IsPlayerInPartyEndpoint.java +++ b/service.party/src/main/java/net/swofty/service/party/endpoints/IsPlayerInPartyEndpoint.java @@ -1,27 +1,27 @@ package net.swofty.service.party.endpoints; -import net.swofty.commons.impl.ServiceProxyRequest; -import net.swofty.commons.protocol.objects.party.IsPlayerInPartyProtocolObject; -import net.swofty.service.generic.redis.ServiceEndpoint; +import net.swofty.commons.protocol.objects.party.IsPlayerInPartyProtocol; +import net.swofty.commons.redis.RedisMessageHandler; import net.swofty.service.party.PartyCache; import java.util.UUID; +import net.swofty.commons.redis.RedisMessageContext; -public class IsPlayerInPartyEndpoint implements ServiceEndpoint< - IsPlayerInPartyProtocolObject.IsPlayerInPartyMessage, - IsPlayerInPartyProtocolObject.IsPlayerInPartyResponse> { +public class IsPlayerInPartyEndpoint implements RedisMessageHandler< + IsPlayerInPartyProtocol.IsPlayerInPartyMessage, + IsPlayerInPartyProtocol.IsPlayerInPartyResponse> { @Override - public IsPlayerInPartyProtocolObject associatedProtocolObject() { - return new IsPlayerInPartyProtocolObject(); + public IsPlayerInPartyProtocol protocol() { + return new IsPlayerInPartyProtocol(); } @Override - public IsPlayerInPartyProtocolObject.IsPlayerInPartyResponse onMessage(ServiceProxyRequest message, IsPlayerInPartyProtocolObject.IsPlayerInPartyMessage messageObject) { + public IsPlayerInPartyProtocol.IsPlayerInPartyResponse handle(IsPlayerInPartyProtocol.IsPlayerInPartyMessage messageObject, RedisMessageContext context) { UUID playerUUID = messageObject.playerUUID(); boolean isInParty = PartyCache.isInParty(playerUUID); - return new IsPlayerInPartyProtocolObject.IsPlayerInPartyResponse(isInParty, true, null); + return new IsPlayerInPartyProtocol.IsPlayerInPartyResponse(isInParty, true, null); } } \ No newline at end of file diff --git a/service.party/src/main/java/net/swofty/service/party/endpoints/PartyActionEndpoint.java b/service.party/src/main/java/net/swofty/service/party/endpoints/PartyActionEndpoint.java index e6733773b..37adb1a43 100644 --- a/service.party/src/main/java/net/swofty/service/party/endpoints/PartyActionEndpoint.java +++ b/service.party/src/main/java/net/swofty/service/party/endpoints/PartyActionEndpoint.java @@ -1,23 +1,23 @@ package net.swofty.service.party.endpoints; -import net.swofty.commons.impl.ServiceProxyRequest; import net.swofty.commons.party.PartyAction; -import net.swofty.commons.protocol.objects.party.SendPartyActionProtocolObject; -import net.swofty.commons.protocol.objects.party.SendPartyActionProtocolObject.Request; -import net.swofty.commons.protocol.objects.party.SendPartyActionProtocolObject.Response; -import net.swofty.service.generic.redis.ServiceEndpoint; +import net.swofty.commons.protocol.objects.party.SendPartyActionProtocol; +import net.swofty.commons.protocol.objects.party.SendPartyActionProtocol.Request; +import net.swofty.commons.protocol.objects.party.SendPartyActionProtocol.Response; +import net.swofty.commons.redis.RedisMessageHandler; import net.swofty.service.party.PartyCache; import org.tinylog.Logger; +import net.swofty.commons.redis.RedisMessageContext; -public class PartyActionEndpoint implements ServiceEndpoint { +public class PartyActionEndpoint implements RedisMessageHandler { @Override - public SendPartyActionProtocolObject associatedProtocolObject() { - return new SendPartyActionProtocolObject(); + public SendPartyActionProtocol protocol() { + return new SendPartyActionProtocol(); } @Override - public Response onMessage(ServiceProxyRequest message, Request request) { + public Response handle(Request request, RedisMessageContext context) { try { PartyAction action = request.action(); switch (action) { diff --git a/service.punishment/src/main/java/net/swofty/service/punishment/ProxyRedis.java b/service.punishment/src/main/java/net/swofty/service/punishment/ProxyRedis.java index f6eb9d655..8a70e44c0 100644 --- a/service.punishment/src/main/java/net/swofty/service/punishment/ProxyRedis.java +++ b/service.punishment/src/main/java/net/swofty/service/punishment/ProxyRedis.java @@ -4,7 +4,7 @@ import redis.clients.jedis.JedisPool; import redis.clients.jedis.JedisPoolConfig; -import net.swofty.commons.protocol.ProtocolObject; +import net.swofty.commons.protocol.RedisProtocol; import net.swofty.commons.redis.RedisEnvelope; import java.net.URI; @@ -63,7 +63,7 @@ public static CompletableFuture publishMessage(String filterId, String cha }); } - public static void publishToProxy(ProtocolObject protocol, T message) { + public static void publishToProxy(RedisProtocol protocol, T message) { UUID uuid = UUID.randomUUID(); String serialized = protocol.translateToString(message); publishMessage("proxy", protocol.channel(), diff --git a/service.punishment/src/main/java/net/swofty/service/punishment/PunishmentService.java b/service.punishment/src/main/java/net/swofty/service/punishment/PunishmentService.java index 2d2fb5ddf..aa2bb6815 100644 --- a/service.punishment/src/main/java/net/swofty/service/punishment/PunishmentService.java +++ b/service.punishment/src/main/java/net/swofty/service/punishment/PunishmentService.java @@ -4,7 +4,7 @@ import net.swofty.commons.config.ConfigProvider; import net.swofty.commons.punishment.PunishmentRedis; import net.swofty.service.generic.SkyBlockService; -import net.swofty.service.generic.redis.ServiceEndpoint; +import net.swofty.commons.redis.RedisMessageHandler; import java.util.List; @@ -24,7 +24,7 @@ public ServiceType getType() { } @Override - public List getEndpoints() { - return loopThroughPackage("net.swofty.service.punishment.endpoints", ServiceEndpoint.class).toList(); + public List getEndpoints() { + return loopThroughPackage("net.swofty.service.punishment.endpoints", RedisMessageHandler.class).toList(); } } diff --git a/service.punishment/src/main/java/net/swofty/service/punishment/endpoints/GetActivePunishmentEndpoint.java b/service.punishment/src/main/java/net/swofty/service/punishment/endpoints/GetActivePunishmentEndpoint.java index 0dab4f1f9..15b0464ee 100644 --- a/service.punishment/src/main/java/net/swofty/service/punishment/endpoints/GetActivePunishmentEndpoint.java +++ b/service.punishment/src/main/java/net/swofty/service/punishment/endpoints/GetActivePunishmentEndpoint.java @@ -1,33 +1,33 @@ package net.swofty.service.punishment.endpoints; -import net.swofty.commons.impl.ServiceProxyRequest; -import net.swofty.commons.protocol.ProtocolObject; -import net.swofty.commons.protocol.objects.punishment.GetActivePunishmentProtocolObject; +import net.swofty.commons.protocol.RedisProtocol; +import net.swofty.commons.protocol.objects.punishment.GetActivePunishmentProtocol; import net.swofty.commons.punishment.ActivePunishment; import net.swofty.commons.punishment.PunishmentRedis; -import net.swofty.service.generic.redis.ServiceEndpoint; +import net.swofty.commons.redis.RedisMessageHandler; import java.util.List; import java.util.Optional; +import net.swofty.commons.redis.RedisMessageContext; -public class GetActivePunishmentEndpoint implements ServiceEndpoint - { +public class GetActivePunishmentEndpoint implements RedisMessageHandler + { @Override - public ProtocolObject associatedProtocolObject() { - return new GetActivePunishmentProtocolObject(); + public RedisProtocol protocol() { + return new GetActivePunishmentProtocol(); } @Override - public GetActivePunishmentProtocolObject.GetActivePunishmentResponse onMessage(ServiceProxyRequest message, GetActivePunishmentProtocolObject.GetActivePunishmentMessage messageObject) { + public GetActivePunishmentProtocol.GetActivePunishmentResponse handle(GetActivePunishmentProtocol.GetActivePunishmentMessage messageObject, RedisMessageContext context) { Optional existing = PunishmentRedis.getActive(messageObject.target(), messageObject.type()); if (existing.isEmpty()) { - return new GetActivePunishmentProtocolObject.GetActivePunishmentResponse(false, null, null, null, 0, List.of(), true, null); + return new GetActivePunishmentProtocol.GetActivePunishmentResponse(false, null, null, null, 0, List.of(), true, null); } ActivePunishment punishment = existing.get(); - return new GetActivePunishmentProtocolObject.GetActivePunishmentResponse( + return new GetActivePunishmentProtocol.GetActivePunishmentResponse( true, punishment.type(), punishment.banId(), diff --git a/service.punishment/src/main/java/net/swofty/service/punishment/endpoints/PunishPlayerEndpoint.java b/service.punishment/src/main/java/net/swofty/service/punishment/endpoints/PunishPlayerEndpoint.java index 970b7b0cd..5cff291fd 100644 --- a/service.punishment/src/main/java/net/swofty/service/punishment/endpoints/PunishPlayerEndpoint.java +++ b/service.punishment/src/main/java/net/swofty/service/punishment/endpoints/PunishPlayerEndpoint.java @@ -1,47 +1,46 @@ package net.swofty.service.punishment.endpoints; import com.google.gson.Gson; -import net.swofty.commons.impl.ServiceProxyRequest; -import net.swofty.commons.protocol.ProtocolObject; -import net.swofty.commons.protocol.objects.proxy.to.PunishPlayerProtocol; -import net.swofty.commons.protocol.objects.punishment.PunishPlayerProtocolObject; +import net.swofty.commons.protocol.RedisProtocol; +import net.swofty.commons.protocol.objects.punishment.PunishPlayerServiceProtocol; import net.swofty.commons.punishment.*; -import net.swofty.service.generic.redis.ServiceEndpoint; +import net.swofty.commons.redis.RedisMessageHandler; import net.swofty.service.punishment.ProxyRedis; import org.tinylog.Logger; import java.time.Instant; import java.util.Optional; +import net.swofty.commons.redis.RedisMessageContext; -public class PunishPlayerEndpoint implements ServiceEndpoint - { +public class PunishPlayerEndpoint implements RedisMessageHandler + { @Override - public ProtocolObject associatedProtocolObject() { - return new PunishPlayerProtocolObject(); + public RedisProtocol protocol() { + return new PunishPlayerServiceProtocol(); } @Override - public PunishPlayerProtocolObject.PunishPlayerResponse onMessage(ServiceProxyRequest message, PunishPlayerProtocolObject.PunishPlayerMessage messageObject) { + public PunishPlayerServiceProtocol.PunishPlayerResponse handle(PunishPlayerServiceProtocol.PunishPlayerMessage messageObject, RedisMessageContext context) { PunishmentType punishmentType; try { punishmentType = PunishmentType.valueOf(messageObject.type()); } catch (IllegalArgumentException e) { - return new PunishPlayerProtocolObject.PunishPlayerResponse(false, null, PunishPlayerProtocolObject.ErrorCode.INVALID_TYPE, "The punishment type provided is invalid."); + return new PunishPlayerServiceProtocol.PunishPlayerResponse(false, null, PunishPlayerServiceProtocol.ErrorCode.INVALID_TYPE, "The punishment type provided is invalid."); } Instant now = Instant.now(); if (messageObject.expiresAt() > 0 && Instant.ofEpochMilli(messageObject.expiresAt()).isBefore(now)) { - return new PunishPlayerProtocolObject.PunishPlayerResponse(false, null, PunishPlayerProtocolObject.ErrorCode.INVALID_EXPIRY, "The expiration time provided is invalid."); + return new PunishPlayerServiceProtocol.PunishPlayerResponse(false, null, PunishPlayerServiceProtocol.ErrorCode.INVALID_EXPIRY, "The expiration time provided is invalid."); } boolean hasOverwriteTag = messageObject.tags() != null && messageObject.tags().contains(PunishmentTag.OVERWRITE); if (!hasOverwriteTag) { Optional existing = PunishmentRedis.getActive(messageObject.target(), messageObject.type()); if (existing.isPresent()) { - return new PunishPlayerProtocolObject.PunishPlayerResponse(false, null, - PunishPlayerProtocolObject.ErrorCode.ALREADY_PUNISHED, existing.get().banId()); + return new PunishPlayerServiceProtocol.PunishPlayerResponse(false, null, + PunishPlayerServiceProtocol.ErrorCode.ALREADY_PUNISHED, existing.get().banId()); } } @@ -59,13 +58,13 @@ public PunishPlayerProtocolObject.PunishPlayerResponse onMessage(ServiceProxyReq ); } catch (Exception e) { Logger.error("Failed to save punishment to Redis", e); - return new PunishPlayerProtocolObject.PunishPlayerResponse(false, null, - PunishPlayerProtocolObject.ErrorCode.DATABASE_ERROR, "Failed to save punishment."); + return new PunishPlayerServiceProtocol.PunishPlayerResponse(false, null, + PunishPlayerServiceProtocol.ErrorCode.DATABASE_ERROR, "Failed to save punishment."); } Gson gson = new Gson(); - ProxyRedis.publishToProxy(new PunishPlayerProtocol(), - new PunishPlayerProtocol.Request( + ProxyRedis.publishToProxy(new net.swofty.commons.protocol.objects.proxy.to.PunishPlayerProtocol(), + new net.swofty.commons.protocol.objects.proxy.to.PunishPlayerProtocol.Request( messageObject.target().toString(), messageObject.type(), id.id().toString(), @@ -80,6 +79,6 @@ public PunishPlayerProtocolObject.PunishPlayerResponse onMessage(ServiceProxyReq reason.getReasonString(), messageObject.expiresAt() ); - return new PunishPlayerProtocolObject.PunishPlayerResponse(true, id.id(), null, null); + return new PunishPlayerServiceProtocol.PunishPlayerResponse(true, id.id(), null, null); } } diff --git a/service.punishment/src/main/java/net/swofty/service/punishment/endpoints/UnpunishPlayerEndpoint.java b/service.punishment/src/main/java/net/swofty/service/punishment/endpoints/UnpunishPlayerEndpoint.java index 1479c8901..faafdf13e 100644 --- a/service.punishment/src/main/java/net/swofty/service/punishment/endpoints/UnpunishPlayerEndpoint.java +++ b/service.punishment/src/main/java/net/swofty/service/punishment/endpoints/UnpunishPlayerEndpoint.java @@ -1,40 +1,40 @@ package net.swofty.service.punishment.endpoints; -import net.swofty.commons.impl.ServiceProxyRequest; -import net.swofty.commons.protocol.ProtocolObject; -import net.swofty.commons.protocol.objects.punishment.UnpunishPlayerProtocolObject; +import net.swofty.commons.protocol.RedisProtocol; +import net.swofty.commons.protocol.objects.punishment.UnpunishPlayerProtocol; import net.swofty.commons.punishment.ActivePunishment; import net.swofty.commons.punishment.PunishmentRedis; -import net.swofty.service.generic.redis.ServiceEndpoint; +import net.swofty.commons.redis.RedisMessageHandler; import org.tinylog.Logger; import java.util.Optional; +import net.swofty.commons.redis.RedisMessageContext; -public class UnpunishPlayerEndpoint implements ServiceEndpoint - { +public class UnpunishPlayerEndpoint implements RedisMessageHandler + { @Override - public ProtocolObject associatedProtocolObject() { - return new UnpunishPlayerProtocolObject(); + public RedisProtocol protocol() { + return new UnpunishPlayerProtocol(); } @Override - public UnpunishPlayerProtocolObject.UnpunishPlayerResponse onMessage(ServiceProxyRequest message, UnpunishPlayerProtocolObject.UnpunishPlayerMessage messageObject) { + public UnpunishPlayerProtocol.UnpunishPlayerResponse handle(UnpunishPlayerProtocol.UnpunishPlayerMessage messageObject, RedisMessageContext context) { Optional existing = PunishmentRedis.getActive(messageObject.target(), messageObject.type()); if (existing.isEmpty()) { - return new UnpunishPlayerProtocolObject.UnpunishPlayerResponse(false, "No active " + messageObject.type().toLowerCase() + " found for this player."); + return new UnpunishPlayerProtocol.UnpunishPlayerResponse(false, "No active " + messageObject.type().toLowerCase() + " found for this player."); } try { PunishmentRedis.revoke(messageObject.target(), messageObject.type()); } catch (Exception e) { Logger.error("Failed to revoke punishment", e); - return new UnpunishPlayerProtocolObject.UnpunishPlayerResponse(false, "Failed to revoke punishment from database."); + return new UnpunishPlayerProtocol.UnpunishPlayerResponse(false, "Failed to revoke punishment from database."); } Logger.info("Revoked {} for {} by staff {}", messageObject.type(), messageObject.target(), messageObject.staff()); - return new UnpunishPlayerProtocolObject.UnpunishPlayerResponse(true, null); + return new UnpunishPlayerProtocol.UnpunishPlayerResponse(true, null); } } diff --git a/type.backwaterbayou/src/main/java/net/swofty/type/backwaterbayou/TypeBackwaterBayouLoader.java b/type.backwaterbayou/src/main/java/net/swofty/type/backwaterbayou/TypeBackwaterBayouLoader.java index 92cf45931..08eff5dfb 100644 --- a/type.backwaterbayou/src/main/java/net/swofty/type/backwaterbayou/TypeBackwaterBayouLoader.java +++ b/type.backwaterbayou/src/main/java/net/swofty/type/backwaterbayou/TypeBackwaterBayouLoader.java @@ -5,7 +5,7 @@ import net.swofty.commons.CustomWorlds; import net.swofty.commons.ServerType; import net.swofty.commons.ServiceType; -import net.swofty.proxyapi.redis.TypedProxyHandler; +import net.swofty.commons.redis.RedisMessageHandler; import net.swofty.type.generic.tab.AreaServerModule; import net.swofty.type.generic.SkyBlockTypeLoader; import net.swofty.type.generic.entity.npc.HypixelNPC; @@ -83,7 +83,7 @@ public List getNPCs() { @Override - public List> getTypedProxyHandlers() { + public List> getProxyHandlers() { return List.of(); } diff --git a/type.bedwarsconfigurator/src/main/java/net/swofty/type/bedwarsconfigurator/TypeBedWarsConfiguratorLoader.java b/type.bedwarsconfigurator/src/main/java/net/swofty/type/bedwarsconfigurator/TypeBedWarsConfiguratorLoader.java index dbc62a348..94457fa4e 100644 --- a/type.bedwarsconfigurator/src/main/java/net/swofty/type/bedwarsconfigurator/TypeBedWarsConfiguratorLoader.java +++ b/type.bedwarsconfigurator/src/main/java/net/swofty/type/bedwarsconfigurator/TypeBedWarsConfiguratorLoader.java @@ -9,7 +9,7 @@ import net.swofty.commons.ServerType; import net.swofty.commons.ServiceType; import net.swofty.commons.bedwars.map.BedWarsMapsConfig; -import net.swofty.proxyapi.redis.TypedProxyHandler; +import net.swofty.commons.redis.RedisMessageHandler; import net.swofty.type.generic.HypixelGenericLoader; import net.swofty.type.generic.HypixelTypeLoader; import net.swofty.type.generic.command.HypixelCommand; @@ -135,7 +135,7 @@ public List getNPCs() { @Override - public List> getTypedProxyHandlers() { + public List> getProxyHandlers() { return List.of(); } diff --git a/type.bedwarsgame/src/main/java/net/swofty/type/bedwarsgame/TypeBedWarsGameLoader.java b/type.bedwarsgame/src/main/java/net/swofty/type/bedwarsgame/TypeBedWarsGameLoader.java index 683844e13..a9c83c265 100644 --- a/type.bedwarsgame/src/main/java/net/swofty/type/bedwarsgame/TypeBedWarsGameLoader.java +++ b/type.bedwarsgame/src/main/java/net/swofty/type/bedwarsgame/TypeBedWarsGameLoader.java @@ -21,10 +21,9 @@ import net.swofty.commons.CustomWorlds; import net.swofty.commons.ServerType; import net.swofty.commons.ServiceType; -import net.swofty.commons.protocol.objects.orchestrator.GameHeartbeatProtocolObject; +import net.swofty.commons.protocol.objects.orchestrator.GameHeartbeatProtocol; import net.swofty.proxyapi.ProxyService; -import net.swofty.proxyapi.redis.TypedProxyHandler; -import net.swofty.proxyapi.redis.TypedServiceHandler; +import net.swofty.commons.redis.RedisMessageHandler; import net.swofty.pvp.MinestomPvP; import net.swofty.pvp.feature.CombatFeatureSet; import net.swofty.pvp.feature.CombatFeatures; @@ -246,7 +245,7 @@ public void afterInitialize(MinecraftServer server) { commonsGames.add(commonsGame); } - var heartbeat = new GameHeartbeatProtocolObject.HeartbeatMessage( + var heartbeat = new GameHeartbeatProtocol.HeartbeatMessage( uuid, shortName, getType(), @@ -322,19 +321,19 @@ public List getNPCs() { @Override @SuppressWarnings("unchecked") - public List> getTypedServiceHandlers() { + public List> getServiceHandlers() { return (List) HypixelGenericLoader.loopThroughPackage( "net.swofty.type.bedwarsgame.redis.service", - TypedServiceHandler.class + RedisMessageHandler.class ).toList(); } @Override @SuppressWarnings("unchecked") - public List> getTypedProxyHandlers() { - return (List>) (List) HypixelGenericLoader.loopThroughPackage( + public List> getProxyHandlers() { + return (List>) (List) HypixelGenericLoader.loopThroughPackage( "net.swofty.type.bedwarsgame.redis", - TypedProxyHandler.class + RedisMessageHandler.class ).toList(); } diff --git a/type.bedwarsgame/src/main/java/net/swofty/type/bedwarsgame/events/ActionPlayerJoin.java b/type.bedwarsgame/src/main/java/net/swofty/type/bedwarsgame/events/ActionPlayerJoin.java index eacf679a5..e386341dd 100644 --- a/type.bedwarsgame/src/main/java/net/swofty/type/bedwarsgame/events/ActionPlayerJoin.java +++ b/type.bedwarsgame/src/main/java/net/swofty/type/bedwarsgame/events/ActionPlayerJoin.java @@ -12,7 +12,7 @@ import net.swofty.type.generic.event.HypixelEventClass; import net.swofty.type.generic.event.phase.EventPhase; import net.swofty.type.generic.event.phase.PhasedEvent; -import net.swofty.type.generic.redis.service.TypedGameInformationHandler; +import net.swofty.type.generic.redis.service.GameInformationHandler; import net.swofty.type.generic.utility.MathUtility; import org.tinylog.Logger; @@ -32,7 +32,7 @@ public void run(AsyncPlayerConfigurationEvent event) { private void tryJoinGame(BedWarsPlayer player, boolean isRetry) { if (!player.isOnline()) return; - String preferredGameId = TypedGameInformationHandler.game.remove(player.getUuid()); + String preferredGameId = GameInformationHandler.game.remove(player.getUuid()); if (preferredGameId == null) { if (!isRetry) { Logger.info("No game assignment found for " + player.getUsername() + ", retrying in 1 second..."); diff --git a/type.bedwarsgame/src/main/java/net/swofty/type/bedwarsgame/redis/service/TypedInstantiateGameHandler.java b/type.bedwarsgame/src/main/java/net/swofty/type/bedwarsgame/redis/service/InstantiateGameHandler.java similarity index 85% rename from type.bedwarsgame/src/main/java/net/swofty/type/bedwarsgame/redis/service/TypedInstantiateGameHandler.java rename to type.bedwarsgame/src/main/java/net/swofty/type/bedwarsgame/redis/service/InstantiateGameHandler.java index 6310515b7..b53952246 100644 --- a/type.bedwarsgame/src/main/java/net/swofty/type/bedwarsgame/redis/service/TypedInstantiateGameHandler.java +++ b/type.bedwarsgame/src/main/java/net/swofty/type/bedwarsgame/redis/service/InstantiateGameHandler.java @@ -2,25 +2,26 @@ import net.swofty.commons.bedwars.BedwarsGameType; import net.swofty.commons.bedwars.map.BedWarsMapsConfig; -import net.swofty.commons.protocol.ServicePushProtocol; +import net.swofty.commons.protocol.RedisProtocol; import net.swofty.commons.protocol.objects.game.InstantiateGamePushProtocol; import net.swofty.commons.protocol.objects.game.InstantiateGamePushProtocol.Request; import net.swofty.commons.protocol.objects.game.InstantiateGamePushProtocol.Response; -import net.swofty.proxyapi.redis.TypedServiceHandler; +import net.swofty.commons.redis.RedisMessageHandler; import net.swofty.type.bedwarsgame.TypeBedWarsGameLoader; import net.swofty.type.bedwarsgame.game.Game; +import net.swofty.commons.redis.RedisMessageContext; -public class TypedInstantiateGameHandler implements TypedServiceHandler { +public class InstantiateGameHandler implements RedisMessageHandler { private static final InstantiateGamePushProtocol PROTOCOL = new InstantiateGamePushProtocol(); @Override - public ServicePushProtocol getProtocol() { + public RedisProtocol protocol() { return PROTOCOL; } @Override - public Response onMessage(Request request) { + public Response handle(Request request, RedisMessageContext context) { try { BedwarsGameType gameType = BedwarsGameType.valueOf(request.gameType().toUpperCase()); diff --git a/type.bedwarslobby/src/main/java/net/swofty/type/bedwarslobby/TypeBedWarsLobbyLoader.java b/type.bedwarslobby/src/main/java/net/swofty/type/bedwarslobby/TypeBedWarsLobbyLoader.java index b11bef5af..83334b7f3 100644 --- a/type.bedwarslobby/src/main/java/net/swofty/type/bedwarslobby/TypeBedWarsLobbyLoader.java +++ b/type.bedwarslobby/src/main/java/net/swofty/type/bedwarslobby/TypeBedWarsLobbyLoader.java @@ -7,8 +7,7 @@ import net.swofty.commons.CustomWorlds; import net.swofty.commons.ServerType; import net.swofty.commons.ServiceType; -import net.swofty.proxyapi.redis.TypedProxyHandler; -import net.swofty.proxyapi.redis.TypedServiceHandler; +import net.swofty.commons.redis.RedisMessageHandler; import net.swofty.type.bedwarslobby.hologram.LeaderboardHologramManager; import net.swofty.type.bedwarslobby.item.impl.BedWarsMenu; import net.swofty.type.bedwarslobby.item.impl.Collectibles; @@ -190,15 +189,15 @@ public List getNPCs() { @Override @SuppressWarnings("unchecked") - public List> getTypedServiceHandlers() { + public List> getServiceHandlers() { return (List) HypixelGenericLoader.loopThroughPackage( "net.swofty.type.bedwarslobby.redis.service", - TypedServiceHandler.class + RedisMessageHandler.class ).toList(); } @Override - public List> getTypedProxyHandlers() { + public List> getProxyHandlers() { return List.of(); } diff --git a/type.bedwarslobby/src/main/java/net/swofty/type/bedwarslobby/commands/RejoinCommand.java b/type.bedwarslobby/src/main/java/net/swofty/type/bedwarslobby/commands/RejoinCommand.java index 3cf6020ad..90f4b435e 100644 --- a/type.bedwarslobby/src/main/java/net/swofty/type/bedwarslobby/commands/RejoinCommand.java +++ b/type.bedwarslobby/src/main/java/net/swofty/type/bedwarslobby/commands/RejoinCommand.java @@ -1,8 +1,8 @@ package net.swofty.type.bedwarslobby.commands; import net.swofty.commons.ServiceType; -import net.swofty.commons.protocol.objects.orchestrator.ChooseGameProtocolObject; -import net.swofty.commons.protocol.objects.orchestrator.RejoinGameProtocolObject; +import net.swofty.commons.protocol.objects.orchestrator.ChooseGameProtocol; +import net.swofty.commons.protocol.objects.orchestrator.RejoinGameProtocol; import net.swofty.proxyapi.ProxyService; import net.swofty.type.generic.command.CommandParameters; import net.swofty.type.generic.command.HypixelCommand; @@ -26,18 +26,18 @@ public void registerUsage(MinestomCommand command) { HypixelPlayer player = (HypixelPlayer) sender; // Query orchestrator for active game - RejoinGameProtocolObject.RejoinGameRequest request = - new RejoinGameProtocolObject.RejoinGameRequest(player.getUuid()); + RejoinGameProtocol.RejoinGameRequest request = + new RejoinGameProtocol.RejoinGameRequest(player.getUuid()); ORCHESTRATOR.handleRequest(request).thenAccept(response -> { - if (response instanceof RejoinGameProtocolObject.RejoinGameResponse resp) { + if (response instanceof RejoinGameProtocol.RejoinGameResponse resp) { if (resp.hasActiveGame() && resp.server() != null) { // Send the player to the game player.sendMessage("§aRejoining your game..."); // Notify the game server about this player - ChooseGameProtocolObject.ChooseGameMessage chooseMsg = - new ChooseGameProtocolObject.ChooseGameMessage( + ChooseGameProtocol.ChooseGameMessage chooseMsg = + new ChooseGameProtocol.ChooseGameMessage( player.getUuid(), resp.server(), resp.gameId() diff --git a/type.bedwarslobby/src/main/java/net/swofty/type/bedwarslobby/events/ActionRejoinCheck.java b/type.bedwarslobby/src/main/java/net/swofty/type/bedwarslobby/events/ActionRejoinCheck.java index c5c37698e..b54536780 100644 --- a/type.bedwarslobby/src/main/java/net/swofty/type/bedwarslobby/events/ActionRejoinCheck.java +++ b/type.bedwarslobby/src/main/java/net/swofty/type/bedwarslobby/events/ActionRejoinCheck.java @@ -5,7 +5,7 @@ import net.kyori.adventure.text.format.NamedTextColor; import net.minestom.server.event.player.PlayerSpawnEvent; import net.swofty.commons.ServiceType; -import net.swofty.commons.protocol.objects.orchestrator.RejoinGameProtocolObject; +import net.swofty.commons.protocol.objects.orchestrator.RejoinGameProtocol; import net.swofty.proxyapi.ProxyService; import net.swofty.type.generic.event.EventNodes; import net.swofty.type.generic.event.HypixelEventClass; @@ -24,11 +24,11 @@ public void run(PlayerSpawnEvent event) { // Delay slightly to ensure player is fully spawned MathUtility.delay(() -> { // Check if player has an active game to rejoin - RejoinGameProtocolObject.RejoinGameRequest request = - new RejoinGameProtocolObject.RejoinGameRequest(player.getUuid()); + RejoinGameProtocol.RejoinGameRequest request = + new RejoinGameProtocol.RejoinGameRequest(player.getUuid()); ORCHESTRATOR.handleRequest(request).thenAccept(response -> { - if (response instanceof RejoinGameProtocolObject.RejoinGameResponse resp + if (response instanceof RejoinGameProtocol.RejoinGameResponse resp && resp.hasActiveGame()) { // Show rejoin message Component message = Component.text("You have a game currently ongoing! ", NamedTextColor.RED) diff --git a/type.bedwarslobby/src/main/java/net/swofty/type/bedwarslobby/gui/GUIMapSelection.java b/type.bedwarslobby/src/main/java/net/swofty/type/bedwarslobby/gui/GUIMapSelection.java index 283df8b17..c2800cdbc 100644 --- a/type.bedwarslobby/src/main/java/net/swofty/type/bedwarslobby/gui/GUIMapSelection.java +++ b/type.bedwarslobby/src/main/java/net/swofty/type/bedwarslobby/gui/GUIMapSelection.java @@ -9,7 +9,7 @@ import net.swofty.commons.bedwars.BedwarsGameType; import net.swofty.commons.ServerType; import net.swofty.commons.ServiceType; -import net.swofty.commons.protocol.objects.orchestrator.GetMapsProtocolObject; +import net.swofty.commons.protocol.objects.orchestrator.GetMapsProtocol; import net.swofty.proxyapi.ProxyService; import net.swofty.type.generic.data.handlers.BedWarsDataHandler; import net.swofty.type.lobby.LobbyOrchestratorConnector; @@ -69,12 +69,12 @@ public void run(InventoryPreClickEvent e, HypixelPlayer player) { private void loadMaps(HypixelPlayer player) { ProxyService orchestratorService = new ProxyService(ServiceType.ORCHESTRATOR); - GetMapsProtocolObject.GetMapsMessage message = - new GetMapsProtocolObject.GetMapsMessage(ServerType.BEDWARS_GAME, gameType.toString()); + GetMapsProtocol.GetMapsMessage message = + new GetMapsProtocol.GetMapsMessage(ServerType.BEDWARS_GAME, gameType.toString()); orchestratorService.handleRequest(message) .thenAccept(response -> { - if (response instanceof GetMapsProtocolObject.GetMapsResponse mapsResponse) { + if (response instanceof GetMapsProtocol.GetMapsResponse mapsResponse) { maps = mapsResponse.maps(); mapsLoaded = true; diff --git a/type.crimsonisle/src/main/java/net/swofty/type/crimsonisle/TypeCrimsonIsleLoader.java b/type.crimsonisle/src/main/java/net/swofty/type/crimsonisle/TypeCrimsonIsleLoader.java index 2e0c332b5..510ae0db6 100644 --- a/type.crimsonisle/src/main/java/net/swofty/type/crimsonisle/TypeCrimsonIsleLoader.java +++ b/type.crimsonisle/src/main/java/net/swofty/type/crimsonisle/TypeCrimsonIsleLoader.java @@ -5,7 +5,7 @@ import net.swofty.commons.CustomWorlds; import net.swofty.commons.ServerType; import net.swofty.commons.ServiceType; -import net.swofty.proxyapi.redis.TypedProxyHandler; +import net.swofty.commons.redis.RedisMessageHandler; import net.swofty.type.generic.tab.AreaServerModule; import net.swofty.type.generic.SkyBlockTypeLoader; import net.swofty.type.generic.entity.npc.HypixelNPC; @@ -83,7 +83,7 @@ public List getNPCs() { @Override - public List> getTypedProxyHandlers() { + public List> getProxyHandlers() { return List.of(); } diff --git a/type.deepcaverns/src/main/java/net/swofty/type/deepcaverns/TypeDeepCavernsLoader.java b/type.deepcaverns/src/main/java/net/swofty/type/deepcaverns/TypeDeepCavernsLoader.java index 5d5625373..41b402a6a 100644 --- a/type.deepcaverns/src/main/java/net/swofty/type/deepcaverns/TypeDeepCavernsLoader.java +++ b/type.deepcaverns/src/main/java/net/swofty/type/deepcaverns/TypeDeepCavernsLoader.java @@ -5,7 +5,7 @@ import net.swofty.commons.CustomWorlds; import net.swofty.commons.ServerType; import net.swofty.commons.ServiceType; -import net.swofty.proxyapi.redis.TypedProxyHandler; +import net.swofty.commons.redis.RedisMessageHandler; import net.swofty.type.generic.tab.AreaServerModule; import net.swofty.type.generic.SkyBlockTypeLoader; @@ -87,7 +87,7 @@ public List getNPCs() { @Override - public List> getTypedProxyHandlers() { + public List> getProxyHandlers() { return List.of(); } diff --git a/type.dungeonhub/src/main/java/net/swofty/type/dungeonhub/TypeDungeonHubLoader.java b/type.dungeonhub/src/main/java/net/swofty/type/dungeonhub/TypeDungeonHubLoader.java index c0fe2bf19..72a76bf09 100644 --- a/type.dungeonhub/src/main/java/net/swofty/type/dungeonhub/TypeDungeonHubLoader.java +++ b/type.dungeonhub/src/main/java/net/swofty/type/dungeonhub/TypeDungeonHubLoader.java @@ -5,7 +5,7 @@ import net.swofty.commons.CustomWorlds; import net.swofty.commons.ServerType; import net.swofty.commons.ServiceType; -import net.swofty.proxyapi.redis.TypedProxyHandler; +import net.swofty.commons.redis.RedisMessageHandler; import net.swofty.type.generic.tab.AreaServerModule; import net.swofty.type.generic.SkyBlockTypeLoader; import net.swofty.type.generic.entity.npc.HypixelNPC; @@ -87,7 +87,7 @@ public List getNPCs() { @Override - public List> getTypedProxyHandlers() { + public List> getProxyHandlers() { return List.of(); } diff --git a/type.dwarvenmines/src/main/java/net/swofty/type/dwarvenmines/TypeDwarvenMinesLoader.java b/type.dwarvenmines/src/main/java/net/swofty/type/dwarvenmines/TypeDwarvenMinesLoader.java index 15f99ab5b..e85957a20 100644 --- a/type.dwarvenmines/src/main/java/net/swofty/type/dwarvenmines/TypeDwarvenMinesLoader.java +++ b/type.dwarvenmines/src/main/java/net/swofty/type/dwarvenmines/TypeDwarvenMinesLoader.java @@ -12,7 +12,7 @@ import net.swofty.commons.CustomWorlds; import net.swofty.commons.ServerType; import net.swofty.commons.ServiceType; -import net.swofty.proxyapi.redis.TypedProxyHandler; +import net.swofty.commons.redis.RedisMessageHandler; import net.swofty.type.dwarvenmines.gui.GUIGemstoneGrinder; import net.swofty.type.generic.tab.AreaServerModule; import net.swofty.type.generic.HypixelConst; @@ -104,7 +104,7 @@ public List getNPCs() { @Override - public List> getTypedProxyHandlers() { + public List> getProxyHandlers() { return List.of(); } diff --git a/type.galatea/src/main/java/net/swofty/type/galatea/TypeGalateaLoader.java b/type.galatea/src/main/java/net/swofty/type/galatea/TypeGalateaLoader.java index 529a2551a..9d656f852 100644 --- a/type.galatea/src/main/java/net/swofty/type/galatea/TypeGalateaLoader.java +++ b/type.galatea/src/main/java/net/swofty/type/galatea/TypeGalateaLoader.java @@ -6,7 +6,7 @@ import net.swofty.commons.ServerType; import net.swofty.commons.ServiceType; import net.swofty.commons.Songs; -import net.swofty.proxyapi.redis.TypedProxyHandler; +import net.swofty.commons.redis.RedisMessageHandler; import net.swofty.type.generic.tab.AreaServerModule; import net.swofty.type.generic.SkyBlockTypeLoader; import net.swofty.type.generic.entity.npc.HypixelNPC; @@ -91,7 +91,7 @@ public List getNPCs() { @Override - public List> getTypedProxyHandlers() { + public List> getProxyHandlers() { return List.of(); } diff --git a/type.generic/src/main/java/net/swofty/type/generic/HypixelTypeLoader.java b/type.generic/src/main/java/net/swofty/type/generic/HypixelTypeLoader.java index 4ef484fe6..9a234a8d6 100644 --- a/type.generic/src/main/java/net/swofty/type/generic/HypixelTypeLoader.java +++ b/type.generic/src/main/java/net/swofty/type/generic/HypixelTypeLoader.java @@ -7,8 +7,7 @@ import net.swofty.commons.CustomWorlds; import net.swofty.commons.ServerType; import net.swofty.commons.ServiceType; -import net.swofty.proxyapi.redis.TypedProxyHandler; -import net.swofty.proxyapi.redis.TypedServiceHandler; +import net.swofty.commons.redis.RedisMessageHandler; import net.swofty.type.generic.data.GameDataHandler; import net.swofty.type.generic.entity.npc.HypixelNPC; import net.swofty.type.generic.event.HypixelEventClass; @@ -37,7 +36,7 @@ public interface HypixelTypeLoader { List getNPCs(); - List> getTypedProxyHandlers(); + List> getProxyHandlers(); record LoaderValues(Function spawnPosition, boolean announceDeathMessages) {} @@ -48,7 +47,7 @@ record LoaderValues(Function spawnPosition, boolean announceDea * These handlers will be automatically loaded/saved on player join/quit. * @return List of GameDataHandler classes to load */ - default List> getTypedServiceHandlers() { + default List> getServiceHandlers() { return List.of(); } diff --git a/type.generic/src/main/java/net/swofty/type/generic/command/commands/BanCommand.java b/type.generic/src/main/java/net/swofty/type/generic/command/commands/BanCommand.java index 81b11f8af..2fe0dec90 100644 --- a/type.generic/src/main/java/net/swofty/type/generic/command/commands/BanCommand.java +++ b/type.generic/src/main/java/net/swofty/type/generic/command/commands/BanCommand.java @@ -8,7 +8,7 @@ import net.minestom.server.utils.mojang.MojangUtils; import net.swofty.commons.ServiceType; import net.swofty.commons.StringUtility; -import net.swofty.commons.protocol.objects.punishment.PunishPlayerProtocolObject; +import net.swofty.commons.protocol.objects.punishment.PunishPlayerServiceProtocol; import net.swofty.commons.punishment.PunishmentReason; import net.swofty.commons.punishment.PunishmentTag; import net.swofty.commons.punishment.PunishmentType; @@ -145,7 +145,7 @@ private void banPlayer(HypixelPlayer sender, UUID targetUuid, BanType type, UUID ProxyService punishmentService = new ProxyService(ServiceType.PUNISHMENT); PunishmentReason reason = new PunishmentReason(type); ArrayList tagList = (tags != null) ? new ArrayList<>(tags) : new ArrayList<>(); - PunishPlayerProtocolObject.PunishPlayerMessage message = new PunishPlayerProtocolObject.PunishPlayerMessage( + PunishPlayerServiceProtocol.PunishPlayerMessage message = new PunishPlayerServiceProtocol.PunishPlayerMessage( targetUuid, PunishmentType.BAN.name(), reason, @@ -155,14 +155,14 @@ private void banPlayer(HypixelPlayer sender, UUID targetUuid, BanType type, UUID ); punishmentService.handleRequest(message).thenAccept(result -> { - if (result instanceof PunishPlayerProtocolObject.PunishPlayerResponse( - boolean success, String punishmentId, PunishPlayerProtocolObject.ErrorCode errorCode, + if (result instanceof PunishPlayerServiceProtocol.PunishPlayerResponse( + boolean success, String punishmentId, PunishPlayerServiceProtocol.ErrorCode errorCode, String errorMessage )) { if (success) { new ProxyPlayer(targetUuid).transferToLimbo(); sender.sendTranslated("commands.ban.success", Component.text(playerName), Component.text(punishmentId)); - } else if (errorCode == PunishPlayerProtocolObject.ErrorCode.ALREADY_PUNISHED) { + } else if (errorCode == PunishPlayerServiceProtocol.ErrorCode.ALREADY_PUNISHED) { sender.sendTranslated("commands.ban.already_banned", Component.text(errorMessage)); } else { sender.sendTranslated("commands.ban.failed", Component.text(errorMessage)); diff --git a/type.generic/src/main/java/net/swofty/type/generic/command/commands/MuteCommand.java b/type.generic/src/main/java/net/swofty/type/generic/command/commands/MuteCommand.java index a88983781..31f9aedd1 100644 --- a/type.generic/src/main/java/net/swofty/type/generic/command/commands/MuteCommand.java +++ b/type.generic/src/main/java/net/swofty/type/generic/command/commands/MuteCommand.java @@ -7,7 +7,7 @@ import net.minestom.server.command.builder.suggestion.SuggestionEntry; import net.swofty.commons.ServiceType; import net.swofty.commons.StringUtility; -import net.swofty.commons.protocol.objects.punishment.PunishPlayerProtocolObject; +import net.swofty.commons.protocol.objects.punishment.PunishPlayerServiceProtocol; import net.swofty.commons.punishment.PunishmentReason; import net.swofty.commons.punishment.PunishmentType; import net.swofty.commons.punishment.template.MuteType; @@ -94,7 +94,7 @@ private void mutePlayer(HypixelPlayer sender, UUID targetUuid, MuteType type, UU long actualTime, long expiryTime, String playerName) { ProxyService punishmentService = new ProxyService(ServiceType.PUNISHMENT); PunishmentReason reason = new PunishmentReason(type); - PunishPlayerProtocolObject.PunishPlayerMessage message = new PunishPlayerProtocolObject.PunishPlayerMessage( + PunishPlayerServiceProtocol.PunishPlayerMessage message = new PunishPlayerServiceProtocol.PunishPlayerMessage( targetUuid, PunishmentType.MUTE.name(), reason, @@ -104,10 +104,10 @@ private void mutePlayer(HypixelPlayer sender, UUID targetUuid, MuteType type, UU ); punishmentService.handleRequest(message).thenAccept(result -> { - if (result instanceof PunishPlayerProtocolObject.PunishPlayerResponse response) { + if (result instanceof PunishPlayerServiceProtocol.PunishPlayerResponse response) { if (response.success()) { sender.sendTranslated("commands.mute.success", Component.text(playerName), Component.text(response.punishmentId())); - } else if (response.errorCode() == PunishPlayerProtocolObject.ErrorCode.ALREADY_PUNISHED) { + } else if (response.errorCode() == PunishPlayerServiceProtocol.ErrorCode.ALREADY_PUNISHED) { sender.sendTranslated("commands.mute.already_muted", Component.text(response.errorMessage())); } else { sender.sendTranslated("commands.mute.failed", Component.text(response.errorMessage())); diff --git a/type.generic/src/main/java/net/swofty/type/generic/command/commands/UnBanCommand.java b/type.generic/src/main/java/net/swofty/type/generic/command/commands/UnBanCommand.java index 83b63449f..50bcb104e 100644 --- a/type.generic/src/main/java/net/swofty/type/generic/command/commands/UnBanCommand.java +++ b/type.generic/src/main/java/net/swofty/type/generic/command/commands/UnBanCommand.java @@ -3,7 +3,7 @@ import net.minestom.server.command.builder.arguments.ArgumentType; import net.minestom.server.utils.mojang.MojangUtils; import net.swofty.commons.ServiceType; -import net.swofty.commons.protocol.objects.punishment.UnpunishPlayerProtocolObject; +import net.swofty.commons.protocol.objects.punishment.UnpunishPlayerProtocol; import net.swofty.commons.punishment.PunishmentType; import net.swofty.proxyapi.ProxyService; import net.swofty.type.generic.command.CommandParameters; @@ -39,12 +39,12 @@ public void registerUsage(MinestomCommand command) { try { UUID targetUuid = MojangUtils.getUUID(playerName); ProxyService punishmentService = new ProxyService(ServiceType.PUNISHMENT); - UnpunishPlayerProtocolObject.UnpunishPlayerMessage message = new UnpunishPlayerProtocolObject.UnpunishPlayerMessage( + UnpunishPlayerProtocol.UnpunishPlayerMessage message = new UnpunishPlayerProtocol.UnpunishPlayerMessage( targetUuid, player.getUuid(), PunishmentType.BAN.name() ); punishmentService.handleRequest(message).thenAccept(result -> { - if (result instanceof UnpunishPlayerProtocolObject.UnpunishPlayerResponse response) { + if (result instanceof UnpunishPlayerProtocol.UnpunishPlayerResponse response) { if (response.success()) { player.sendMessage("§aSuccessfully unbanned player: " + playerName); } else { diff --git a/type.generic/src/main/java/net/swofty/type/generic/command/commands/UnMuteCommand.java b/type.generic/src/main/java/net/swofty/type/generic/command/commands/UnMuteCommand.java index 43e3a8fa2..5af84e38b 100644 --- a/type.generic/src/main/java/net/swofty/type/generic/command/commands/UnMuteCommand.java +++ b/type.generic/src/main/java/net/swofty/type/generic/command/commands/UnMuteCommand.java @@ -3,7 +3,7 @@ import net.minestom.server.command.builder.arguments.ArgumentType; import net.minestom.server.utils.mojang.MojangUtils; import net.swofty.commons.ServiceType; -import net.swofty.commons.protocol.objects.punishment.UnpunishPlayerProtocolObject; +import net.swofty.commons.protocol.objects.punishment.UnpunishPlayerProtocol; import net.swofty.commons.punishment.PunishmentType; import net.swofty.proxyapi.ProxyService; import net.swofty.type.generic.command.CommandParameters; @@ -39,12 +39,12 @@ public void registerUsage(MinestomCommand command) { try { UUID targetUuid = MojangUtils.getUUID(playerName); ProxyService punishmentService = new ProxyService(ServiceType.PUNISHMENT); - UnpunishPlayerProtocolObject.UnpunishPlayerMessage message = new UnpunishPlayerProtocolObject.UnpunishPlayerMessage( + UnpunishPlayerProtocol.UnpunishPlayerMessage message = new UnpunishPlayerProtocol.UnpunishPlayerMessage( targetUuid, player.getUuid(), PunishmentType.MUTE.name() ); punishmentService.handleRequest(message).thenAccept(result -> { - if (result instanceof UnpunishPlayerProtocolObject.UnpunishPlayerResponse response) { + if (result instanceof UnpunishPlayerProtocol.UnpunishPlayerResponse response) { if (response.success()) { player.sendMessage("§aSuccessfully unmuted player: " + playerName); } else { diff --git a/type.generic/src/main/java/net/swofty/type/generic/event/actions/ActionPlayerMute.java b/type.generic/src/main/java/net/swofty/type/generic/event/actions/ActionPlayerMute.java index 4c48bd8fd..9f92a0488 100644 --- a/type.generic/src/main/java/net/swofty/type/generic/event/actions/ActionPlayerMute.java +++ b/type.generic/src/main/java/net/swofty/type/generic/event/actions/ActionPlayerMute.java @@ -3,7 +3,7 @@ import net.minestom.server.entity.Player; import net.minestom.server.event.player.PlayerChatEvent; import net.swofty.commons.ServiceType; -import net.swofty.commons.protocol.objects.punishment.GetActivePunishmentProtocolObject; +import net.swofty.commons.protocol.objects.punishment.GetActivePunishmentProtocol; import net.swofty.commons.punishment.ActivePunishment; import net.swofty.commons.punishment.PunishmentMessages; import net.swofty.commons.punishment.PunishmentReason; @@ -25,12 +25,12 @@ public void onPlayerChat(PlayerChatEvent event) { Player player = event.getPlayer(); try { Object response = new ProxyService(ServiceType.PUNISHMENT) - .handleRequest(new GetActivePunishmentProtocolObject.GetActivePunishmentMessage( + .handleRequest(new GetActivePunishmentProtocol.GetActivePunishmentMessage( player.getUuid(), PunishmentType.MUTE.name())) .orTimeout(2, TimeUnit.SECONDS) .join(); - if (response instanceof GetActivePunishmentProtocolObject.GetActivePunishmentResponse( + if (response instanceof GetActivePunishmentProtocol.GetActivePunishmentResponse( boolean found, String type, String banId, PunishmentReason reason, long expiresAt, List tags, boolean success, String error ) && found) { diff --git a/type.generic/src/main/java/net/swofty/type/generic/friend/FriendManager.java b/type.generic/src/main/java/net/swofty/type/generic/friend/FriendManager.java index d21585c38..e1de742dd 100644 --- a/type.generic/src/main/java/net/swofty/type/generic/friend/FriendManager.java +++ b/type.generic/src/main/java/net/swofty/type/generic/friend/FriendManager.java @@ -7,11 +7,11 @@ import net.swofty.commons.friend.PendingFriendRequest; import net.swofty.commons.friend.events.*; import net.swofty.commons.presence.PresenceInfo; -import net.swofty.commons.protocol.objects.friend.AreFriendsProtocolObject; -import net.swofty.commons.protocol.objects.friend.GetFriendDataProtocolObject; -import net.swofty.commons.protocol.objects.friend.GetPendingFriendRequestsProtocolObject; -import net.swofty.commons.protocol.objects.friend.SendFriendEventToServiceProtocolObject; -import net.swofty.commons.protocol.objects.presence.GetPresenceBulkProtocolObject; +import net.swofty.commons.protocol.objects.friend.AreFriendsProtocol; +import net.swofty.commons.protocol.objects.friend.GetFriendDataProtocol; +import net.swofty.commons.protocol.objects.friend.GetPendingFriendRequestsProtocol; +import net.swofty.commons.protocol.objects.friend.SendFriendEventToServiceProtocol; +import net.swofty.commons.protocol.objects.presence.GetPresenceBulkProtocol; import net.swofty.proxyapi.ProxyService; import net.swofty.type.generic.data.HypixelDataHandler; import net.swofty.type.generic.user.HypixelPlayer; @@ -25,40 +25,40 @@ public class FriendManager { public static boolean areFriends(HypixelPlayer player, UUID targetUuid) { if (!friendService.isOnline().join()) return false; - AreFriendsProtocolObject.AreFriendsMessage message = new AreFriendsProtocolObject.AreFriendsMessage(player.getUuid(), targetUuid); - return friendService.handleRequest(message) - .thenApply(AreFriendsProtocolObject.AreFriendsResponse::areFriends) + AreFriendsProtocol.AreFriendsMessage message = new AreFriendsProtocol.AreFriendsMessage(player.getUuid(), targetUuid); + return friendService.handleRequest(message) + .thenApply(AreFriendsProtocol.AreFriendsResponse::areFriends) .join(); } public static @Nullable FriendData getFriendData(HypixelPlayer player) { if (!friendService.isOnline().join()) return null; - GetFriendDataProtocolObject.GetFriendDataMessage message = new GetFriendDataProtocolObject.GetFriendDataMessage(player.getUuid()); - return friendService.handleRequest(message) - .thenApply(GetFriendDataProtocolObject.GetFriendDataResponse::friendData) + GetFriendDataProtocol.GetFriendDataMessage message = new GetFriendDataProtocol.GetFriendDataMessage(player.getUuid()); + return friendService.handleRequest(message) + .thenApply(GetFriendDataProtocol.GetFriendDataResponse::friendData) .join(); } public static List getPendingRequests(HypixelPlayer player) { if (!friendService.isOnline().join()) return List.of(); - GetPendingFriendRequestsProtocolObject.GetPendingRequestsMessage message = - new GetPendingFriendRequestsProtocolObject.GetPendingRequestsMessage(player.getUuid()); - return friendService.handleRequest(message) - .thenApply(GetPendingFriendRequestsProtocolObject.GetPendingRequestsResponse::requests) + GetPendingFriendRequestsProtocol.GetPendingRequestsMessage message = + new GetPendingFriendRequestsProtocol.GetPendingRequestsMessage(player.getUuid()); + return friendService.handleRequest(message) + .thenApply(GetPendingFriendRequestsProtocol.GetPendingRequestsResponse::requests) .join(); } public static List getPresenceBulk(List uuids) { if (!friendService.isOnline().join()) return List.of(); if (uuids.isEmpty()) return List.of(); - GetPresenceBulkProtocolObject.GetPresenceBulkMessage message = - new GetPresenceBulkProtocolObject.GetPresenceBulkMessage(uuids); - return friendService.handleRequest(message) - .thenApply(GetPresenceBulkProtocolObject.GetPresenceBulkResponse::presence) + GetPresenceBulkProtocol.GetPresenceBulkMessage message = + new GetPresenceBulkProtocol.GetPresenceBulkMessage(uuids); + return friendService.handleRequest(message) + .thenApply(GetPresenceBulkProtocol.GetPresenceBulkResponse::presence) .join(); } @@ -159,7 +159,7 @@ public static void listRequests(HypixelPlayer player, int page) { } private static void sendEventToService(FriendEvent event) { - var message = new SendFriendEventToServiceProtocolObject.SendFriendEventToServiceMessage(event); + var message = new SendFriendEventToServiceProtocol.SendFriendEventToServiceMessage(event); friendService.handleRequest(message); } diff --git a/type.generic/src/main/java/net/swofty/type/generic/party/PartyManager.java b/type.generic/src/main/java/net/swofty/type/generic/party/PartyManager.java index 6b4b8c566..de7dec2b7 100644 --- a/type.generic/src/main/java/net/swofty/type/generic/party/PartyManager.java +++ b/type.generic/src/main/java/net/swofty/type/generic/party/PartyManager.java @@ -4,9 +4,9 @@ import net.swofty.commons.party.FullParty; import net.swofty.commons.party.PartyAction; import net.swofty.commons.party.PendingParty; -import net.swofty.commons.protocol.objects.party.GetPartyProtocolObject; -import net.swofty.commons.protocol.objects.party.IsPlayerInPartyProtocolObject; -import net.swofty.commons.protocol.objects.party.SendPartyActionProtocolObject; +import net.swofty.commons.protocol.objects.party.GetPartyProtocol; +import net.swofty.commons.protocol.objects.party.IsPlayerInPartyProtocol; +import net.swofty.commons.protocol.objects.party.SendPartyActionProtocol; import net.swofty.proxyapi.ProxyPlayer; import net.swofty.proxyapi.ProxyService; import net.swofty.type.generic.data.HypixelDataHandler; @@ -21,19 +21,19 @@ public class PartyManager { public static boolean isInParty(HypixelPlayer player) { if (!partyService.isOnline().join()) return false; - return partyService.handleRequest( - new IsPlayerInPartyProtocolObject.IsPlayerInPartyMessage(player.getUuid())) - .thenApply(IsPlayerInPartyProtocolObject.IsPlayerInPartyResponse::isInParty) + return partyService.handleRequest( + new IsPlayerInPartyProtocol.IsPlayerInPartyMessage(player.getUuid())) + .thenApply(IsPlayerInPartyProtocol.IsPlayerInPartyResponse::isInParty) .join(); } public static @Nullable FullParty getPartyFromPlayer(HypixelPlayer player) { if (!partyService.isOnline().join()) return null; - return (FullParty) partyService.handleRequest( - new GetPartyProtocolObject.GetPartyMessage(player.getUuid())) - .thenApply(GetPartyProtocolObject.GetPartyResponse::party) + return (FullParty) partyService.handleRequest( + new GetPartyProtocol.GetPartyMessage(player.getUuid())) + .thenApply(GetPartyProtocol.GetPartyResponse::party) .join(); } @@ -155,7 +155,7 @@ public static void hijackParty(HypixelPlayer hijacker, String targetName) { } private static void send(PartyAction action) { - partyService.handleRequest(new SendPartyActionProtocolObject.Request(action)); + partyService.handleRequest(new SendPartyActionProtocol.Request(action)); } private static void sendError(HypixelPlayer player, String message) { diff --git a/type.generic/src/main/java/net/swofty/type/generic/presence/PresenceHeartbeat.java b/type.generic/src/main/java/net/swofty/type/generic/presence/PresenceHeartbeat.java index 8b200b7bf..60f0c9735 100644 --- a/type.generic/src/main/java/net/swofty/type/generic/presence/PresenceHeartbeat.java +++ b/type.generic/src/main/java/net/swofty/type/generic/presence/PresenceHeartbeat.java @@ -4,7 +4,7 @@ import net.minestom.server.timer.TaskSchedule; import net.swofty.commons.ServiceType; import net.swofty.commons.presence.PresenceInfo; -import net.swofty.commons.protocol.objects.presence.UpdatePresenceProtocolObject; +import net.swofty.commons.protocol.objects.presence.UpdatePresenceProtocol; import net.swofty.proxyapi.redis.ServerOutboundMessage; import net.swofty.type.generic.HypixelConst; import net.swofty.type.generic.HypixelGenericLoader; @@ -47,8 +47,8 @@ private static void pulse() { ServerOutboundMessage.sendMessageToService( ServiceType.FRIEND, - new UpdatePresenceProtocolObject(), - new UpdatePresenceProtocolObject.UpdatePresenceMessage(info), + new UpdatePresenceProtocol(), + new UpdatePresenceProtocol.UpdatePresenceMessage(info), (ignored) -> {} ); } diff --git a/type.generic/src/main/java/net/swofty/type/generic/redis/RedisOriginServer.java b/type.generic/src/main/java/net/swofty/type/generic/redis/RedisOriginServer.java index 621b116ab..f9c6d3ed2 100644 --- a/type.generic/src/main/java/net/swofty/type/generic/redis/RedisOriginServer.java +++ b/type.generic/src/main/java/net/swofty/type/generic/redis/RedisOriginServer.java @@ -1,24 +1,25 @@ package net.swofty.type.generic.redis; import net.swofty.commons.ServerType; -import net.swofty.commons.protocol.ProtocolObject; +import net.swofty.commons.protocol.RedisProtocol; import net.swofty.commons.protocol.objects.proxy.from.GivePlayersOriginTypeProtocol; -import net.swofty.proxyapi.redis.TypedProxyHandler; +import net.swofty.commons.redis.RedisMessageHandler; import java.util.HashMap; import java.util.Map; import java.util.UUID; +import net.swofty.commons.redis.RedisMessageContext; -public class RedisOriginServer implements TypedProxyHandler { +public class RedisOriginServer implements RedisMessageHandler { public static Map origin = new HashMap<>(); @Override - public ProtocolObject getProtocol() { + public RedisProtocol protocol() { return new GivePlayersOriginTypeProtocol(); } @Override - public GivePlayersOriginTypeProtocol.Response onMessage(GivePlayersOriginTypeProtocol.Request message) { + public GivePlayersOriginTypeProtocol.Response handle(GivePlayersOriginTypeProtocol.Request message, RedisMessageContext context) { UUID uuid = UUID.fromString(message.uuid()); ServerType originType = ServerType.valueOf(message.originType()); origin.put(uuid, originType); diff --git a/type.generic/src/main/java/net/swofty/type/generic/redis/RedisPing.java b/type.generic/src/main/java/net/swofty/type/generic/redis/RedisPing.java index 17319c1b1..e0198b192 100644 --- a/type.generic/src/main/java/net/swofty/type/generic/redis/RedisPing.java +++ b/type.generic/src/main/java/net/swofty/type/generic/redis/RedisPing.java @@ -1,17 +1,18 @@ package net.swofty.type.generic.redis; -import net.swofty.commons.protocol.ProtocolObject; +import net.swofty.commons.protocol.RedisProtocol; import net.swofty.commons.protocol.objects.proxy.from.PingServerProtocol; -import net.swofty.proxyapi.redis.TypedProxyHandler; +import net.swofty.commons.redis.RedisMessageHandler; +import net.swofty.commons.redis.RedisMessageContext; -public class RedisPing implements TypedProxyHandler { +public class RedisPing implements RedisMessageHandler { @Override - public ProtocolObject getProtocol() { + public RedisProtocol protocol() { return new PingServerProtocol(); } @Override - public PingServerProtocol.Response onMessage(PingServerProtocol.Request message) { + public PingServerProtocol.Response handle(PingServerProtocol.Request message, RedisMessageContext context) { return new PingServerProtocol.Response(); } } diff --git a/type.generic/src/main/java/net/swofty/type/generic/redis/RedisStaffChatBroadcast.java b/type.generic/src/main/java/net/swofty/type/generic/redis/RedisStaffChatBroadcast.java index ac4469fb2..55d9fdec9 100644 --- a/type.generic/src/main/java/net/swofty/type/generic/redis/RedisStaffChatBroadcast.java +++ b/type.generic/src/main/java/net/swofty/type/generic/redis/RedisStaffChatBroadcast.java @@ -1,8 +1,8 @@ package net.swofty.type.generic.redis; -import net.swofty.commons.protocol.ProtocolObject; +import net.swofty.commons.protocol.RedisProtocol; import net.swofty.commons.protocol.objects.proxy.from.BroadcastStaffChatProtocol; -import net.swofty.proxyapi.redis.TypedProxyHandler; +import net.swofty.commons.redis.RedisMessageHandler; import net.swofty.type.generic.HypixelGenericLoader; import net.swofty.type.generic.command.commands.ChatCommand; import net.swofty.type.generic.data.HypixelDataHandler; @@ -11,15 +11,16 @@ import net.swofty.type.generic.user.categories.Rank; import java.util.UUID; +import net.swofty.commons.redis.RedisMessageContext; -public class RedisStaffChatBroadcast implements TypedProxyHandler { +public class RedisStaffChatBroadcast implements RedisMessageHandler { @Override - public ProtocolObject getProtocol() { + public RedisProtocol protocol() { return new BroadcastStaffChatProtocol(); } @Override - public BroadcastStaffChatProtocol.Response onMessage(BroadcastStaffChatProtocol.Request message) { + public BroadcastStaffChatProtocol.Response handle(BroadcastStaffChatProtocol.Request message, RedisMessageContext context) { String type = message.type(); switch (type) { diff --git a/type.generic/src/main/java/net/swofty/type/generic/redis/RedisTeleport.java b/type.generic/src/main/java/net/swofty/type/generic/redis/RedisTeleport.java index 3e849a452..7be7dae43 100644 --- a/type.generic/src/main/java/net/swofty/type/generic/redis/RedisTeleport.java +++ b/type.generic/src/main/java/net/swofty/type/generic/redis/RedisTeleport.java @@ -1,22 +1,23 @@ package net.swofty.type.generic.redis; import net.minestom.server.coordinate.Pos; -import net.swofty.commons.protocol.ProtocolObject; +import net.swofty.commons.protocol.RedisProtocol; import net.swofty.commons.protocol.objects.proxy.from.TeleportProtocol; -import net.swofty.proxyapi.redis.TypedProxyHandler; +import net.swofty.commons.redis.RedisMessageHandler; import net.swofty.type.generic.HypixelGenericLoader; import net.swofty.type.generic.user.HypixelPlayer; import java.util.UUID; +import net.swofty.commons.redis.RedisMessageContext; -public class RedisTeleport implements TypedProxyHandler { +public class RedisTeleport implements RedisMessageHandler { @Override - public ProtocolObject getProtocol() { + public RedisProtocol protocol() { return new TeleportProtocol(); } @Override - public TeleportProtocol.Response onMessage(TeleportProtocol.Request message) { + public TeleportProtocol.Response handle(TeleportProtocol.Request message, RedisMessageContext context) { UUID uuid = UUID.fromString(message.uuid()); HypixelPlayer player = HypixelGenericLoader.getFromUUID(uuid); if (player == null) return new TeleportProtocol.Response(); diff --git a/type.generic/src/main/java/net/swofty/type/generic/redis/RedisTransferredFromThisServer.java b/type.generic/src/main/java/net/swofty/type/generic/redis/RedisTransferredFromThisServer.java index abb45804e..9af0a100d 100644 --- a/type.generic/src/main/java/net/swofty/type/generic/redis/RedisTransferredFromThisServer.java +++ b/type.generic/src/main/java/net/swofty/type/generic/redis/RedisTransferredFromThisServer.java @@ -1,22 +1,23 @@ package net.swofty.type.generic.redis; -import net.swofty.commons.protocol.ProtocolObject; +import net.swofty.commons.protocol.RedisProtocol; import net.swofty.commons.protocol.objects.proxy.from.PlayerSwitchedProtocol; import net.swofty.proxyapi.ProxyPlayer; -import net.swofty.proxyapi.redis.TypedProxyHandler; +import net.swofty.commons.redis.RedisMessageHandler; import java.util.UUID; import java.util.concurrent.CompletableFuture; import java.util.concurrent.TimeUnit; +import net.swofty.commons.redis.RedisMessageContext; -public class RedisTransferredFromThisServer implements TypedProxyHandler { +public class RedisTransferredFromThisServer implements RedisMessageHandler { @Override - public ProtocolObject getProtocol() { + public RedisProtocol protocol() { return new PlayerSwitchedProtocol(); } @Override - public PlayerSwitchedProtocol.Response onMessage(PlayerSwitchedProtocol.Request message) { + public PlayerSwitchedProtocol.Response handle(PlayerSwitchedProtocol.Request message, RedisMessageContext context) { UUID uuid = UUID.fromString(message.uuid()); if (!ProxyPlayer.waitingForTransferComplete.containsKey(uuid)) { return new PlayerSwitchedProtocol.Response(); diff --git a/type.generic/src/main/java/net/swofty/type/generic/redis/service/TypedFriendEventHandler.java b/type.generic/src/main/java/net/swofty/type/generic/redis/service/FriendEventHandler.java similarity index 97% rename from type.generic/src/main/java/net/swofty/type/generic/redis/service/TypedFriendEventHandler.java rename to type.generic/src/main/java/net/swofty/type/generic/redis/service/FriendEventHandler.java index 749cfc514..930060cdb 100644 --- a/type.generic/src/main/java/net/swofty/type/generic/redis/service/TypedFriendEventHandler.java +++ b/type.generic/src/main/java/net/swofty/type/generic/redis/service/FriendEventHandler.java @@ -8,11 +8,11 @@ import net.swofty.commons.friend.FriendEvent; import net.swofty.commons.friend.FriendSettingType; import net.swofty.commons.friend.events.response.*; -import net.swofty.commons.protocol.ServicePushProtocol; +import net.swofty.commons.protocol.RedisProtocol; import net.swofty.commons.protocol.objects.friend.FriendEventPushProtocol; import net.swofty.commons.protocol.objects.friend.FriendEventPushProtocol.Request; import net.swofty.commons.protocol.objects.friend.FriendEventPushProtocol.Response; -import net.swofty.proxyapi.redis.TypedServiceHandler; +import net.swofty.commons.redis.RedisMessageHandler; import net.swofty.type.generic.HypixelGenericLoader; import net.swofty.type.generic.user.HypixelPlayer; import org.tinylog.Logger; @@ -20,18 +20,19 @@ import java.util.ArrayList; import java.util.List; import java.util.UUID; +import net.swofty.commons.redis.RedisMessageContext; -public class TypedFriendEventHandler implements TypedServiceHandler { +public class FriendEventHandler implements RedisMessageHandler { private static final FriendEventPushProtocol PROTOCOL = new FriendEventPushProtocol(); @Override - public ServicePushProtocol getProtocol() { + public RedisProtocol protocol() { return PROTOCOL; } @Override - public Response onMessage(Request message) { + public Response handle(Request message, RedisMessageContext context) { try { FriendEvent event = parseEvent(message.eventType(), message.eventData()); if (event == null) { diff --git a/type.generic/src/main/java/net/swofty/type/generic/redis/service/TypedGameInformationHandler.java b/type.generic/src/main/java/net/swofty/type/generic/redis/service/GameInformationHandler.java similarity index 64% rename from type.generic/src/main/java/net/swofty/type/generic/redis/service/TypedGameInformationHandler.java rename to type.generic/src/main/java/net/swofty/type/generic/redis/service/GameInformationHandler.java index 4892f8d9f..e0804e323 100644 --- a/type.generic/src/main/java/net/swofty/type/generic/redis/service/TypedGameInformationHandler.java +++ b/type.generic/src/main/java/net/swofty/type/generic/redis/service/GameInformationHandler.java @@ -1,28 +1,29 @@ package net.swofty.type.generic.redis.service; -import net.swofty.commons.protocol.ServicePushProtocol; +import net.swofty.commons.protocol.RedisProtocol; import net.swofty.commons.protocol.objects.game.GameInformationPushProtocol; import net.swofty.commons.protocol.objects.game.GameInformationPushProtocol.Request; import net.swofty.commons.protocol.objects.game.GameInformationPushProtocol.Response; -import net.swofty.proxyapi.redis.TypedServiceHandler; +import net.swofty.commons.redis.RedisMessageHandler; import java.util.HashMap; import java.util.Map; import java.util.UUID; +import net.swofty.commons.redis.RedisMessageContext; -public class TypedGameInformationHandler implements TypedServiceHandler { +public class GameInformationHandler implements RedisMessageHandler { public static Map game = new HashMap<>(); private static final GameInformationPushProtocol PROTOCOL = new GameInformationPushProtocol(); @Override - public ServicePushProtocol getProtocol() { + public RedisProtocol protocol() { return PROTOCOL; } @Override - public Response onMessage(Request message) { + public Response handle(Request message, RedisMessageContext context) { game.put(message.uuid(), message.gameId()); return new Response(); } diff --git a/type.generic/src/main/java/net/swofty/type/generic/redis/service/TypedKickFromGUIHandler.java b/type.generic/src/main/java/net/swofty/type/generic/redis/service/KickFromGUIHandler.java similarity index 80% rename from type.generic/src/main/java/net/swofty/type/generic/redis/service/TypedKickFromGUIHandler.java rename to type.generic/src/main/java/net/swofty/type/generic/redis/service/KickFromGUIHandler.java index f8c316e20..9121b39b2 100644 --- a/type.generic/src/main/java/net/swofty/type/generic/redis/service/TypedKickFromGUIHandler.java +++ b/type.generic/src/main/java/net/swofty/type/generic/redis/service/KickFromGUIHandler.java @@ -1,10 +1,10 @@ package net.swofty.type.generic.redis.service; -import net.swofty.commons.protocol.ServicePushProtocol; +import net.swofty.commons.protocol.RedisProtocol; import net.swofty.commons.protocol.objects.gui.KickFromGUIPushProtocol; import net.swofty.commons.protocol.objects.gui.KickFromGUIPushProtocol.Request; import net.swofty.commons.protocol.objects.gui.KickFromGUIPushProtocol.Response; -import net.swofty.proxyapi.redis.TypedServiceHandler; +import net.swofty.commons.redis.RedisMessageHandler; import net.swofty.type.generic.HypixelGenericLoader; import net.swofty.type.generic.gui.inventory.HypixelInventoryGUI; import net.swofty.type.generic.user.HypixelPlayer; @@ -12,18 +12,19 @@ import java.util.ArrayList; import java.util.List; import java.util.UUID; +import net.swofty.commons.redis.RedisMessageContext; -public class TypedKickFromGUIHandler implements TypedServiceHandler { +public class KickFromGUIHandler implements RedisMessageHandler { private static final KickFromGUIPushProtocol PROTOCOL = new KickFromGUIPushProtocol(); @Override - public ServicePushProtocol getProtocol() { + public RedisProtocol protocol() { return PROTOCOL; } @Override - public Response onMessage(Request message) { + public Response handle(Request message, RedisMessageContext context) { List kickedPlayers = new ArrayList<>(); for (UUID playerUUID : message.playerUUIDs()) { diff --git a/type.generic/src/main/java/net/swofty/type/generic/redis/service/PartyBroadcastHandler.java b/type.generic/src/main/java/net/swofty/type/generic/redis/service/PartyBroadcastHandler.java index 4779a8c51..1515b2149 100644 --- a/type.generic/src/main/java/net/swofty/type/generic/redis/service/PartyBroadcastHandler.java +++ b/type.generic/src/main/java/net/swofty/type/generic/redis/service/PartyBroadcastHandler.java @@ -8,12 +8,12 @@ import net.swofty.commons.UnderstandableProxyServer; import net.swofty.commons.party.FullParty; import net.swofty.commons.party.PartyBroadcast; -import net.swofty.commons.protocol.ServicePushProtocol; +import net.swofty.commons.protocol.RedisProtocol; import net.swofty.commons.protocol.objects.party.PartyBroadcastPushProtocol; import net.swofty.commons.protocol.objects.party.PartyBroadcastPushProtocol.Request; import net.swofty.commons.protocol.objects.party.PartyBroadcastPushProtocol.Response; import net.swofty.proxyapi.ProxyPlayer; -import net.swofty.proxyapi.redis.TypedServiceHandler; +import net.swofty.commons.redis.RedisMessageHandler; import net.swofty.type.generic.HypixelConst; import net.swofty.type.generic.HypixelGenericLoader; import net.swofty.type.generic.user.HypixelPlayer; @@ -25,19 +25,20 @@ import java.util.Map; import java.util.UUID; import java.util.concurrent.TimeUnit; +import net.swofty.commons.redis.RedisMessageContext; -public class PartyBroadcastHandler implements TypedServiceHandler { +public class PartyBroadcastHandler implements RedisMessageHandler { private static final String SEPARATOR = "§9§m-----------------------------------------------------"; private static final PartyBroadcastPushProtocol PROTOCOL = new PartyBroadcastPushProtocol(); @Override - public ServicePushProtocol getProtocol() { + public RedisProtocol protocol() { return PROTOCOL; } @Override - public Response onMessage(Request message) { + public Response handle(Request message, RedisMessageContext context) { try { PartyBroadcast broadcast = message.broadcast(); List handled = new ArrayList<>(); diff --git a/type.generic/src/main/java/net/swofty/type/generic/redis/service/TypedSendMessageHandler.java b/type.generic/src/main/java/net/swofty/type/generic/redis/service/SendMessageHandler.java similarity index 75% rename from type.generic/src/main/java/net/swofty/type/generic/redis/service/TypedSendMessageHandler.java rename to type.generic/src/main/java/net/swofty/type/generic/redis/service/SendMessageHandler.java index 6ca48f328..3628d3990 100644 --- a/type.generic/src/main/java/net/swofty/type/generic/redis/service/TypedSendMessageHandler.java +++ b/type.generic/src/main/java/net/swofty/type/generic/redis/service/SendMessageHandler.java @@ -1,24 +1,25 @@ package net.swofty.type.generic.redis.service; -import net.swofty.commons.protocol.ServicePushProtocol; +import net.swofty.commons.protocol.RedisProtocol; import net.swofty.commons.protocol.objects.messaging.SendMessagePushProtocol; import net.swofty.commons.protocol.objects.messaging.SendMessagePushProtocol.Request; import net.swofty.commons.protocol.objects.messaging.SendMessagePushProtocol.Response; -import net.swofty.proxyapi.redis.TypedServiceHandler; +import net.swofty.commons.redis.RedisMessageHandler; import net.swofty.type.generic.HypixelGenericLoader; import net.swofty.type.generic.user.HypixelPlayer; +import net.swofty.commons.redis.RedisMessageContext; -public class TypedSendMessageHandler implements TypedServiceHandler { +public class SendMessageHandler implements RedisMessageHandler { private static final SendMessagePushProtocol PROTOCOL = new SendMessagePushProtocol(); @Override - public ServicePushProtocol getProtocol() { + public RedisProtocol protocol() { return PROTOCOL; } @Override - public Response onMessage(Request message) { + public Response handle(Request message, RedisMessageContext context) { try { HypixelPlayer player = HypixelGenericLoader.getLoadedPlayers().stream() .filter(p -> p.getUuid().equals(message.playerUUID())) diff --git a/type.generic/src/main/java/net/swofty/type/generic/utility/GameCountCache.java b/type.generic/src/main/java/net/swofty/type/generic/utility/GameCountCache.java index db57377e6..2bc4c6c12 100644 --- a/type.generic/src/main/java/net/swofty/type/generic/utility/GameCountCache.java +++ b/type.generic/src/main/java/net/swofty/type/generic/utility/GameCountCache.java @@ -2,7 +2,7 @@ import net.swofty.commons.ServerType; import net.swofty.commons.ServiceType; -import net.swofty.commons.protocol.objects.orchestrator.GetGameCountsProtocolObject; +import net.swofty.commons.protocol.objects.orchestrator.GetGameCountsProtocol; import net.swofty.proxyapi.ProxyService; import java.util.Map; @@ -97,10 +97,10 @@ private static String buildCacheKey(ServerType type, String gameTypeName, String } private static void refreshAsync(ServerType type, String gameTypeName, String mapName, String cacheKey) { - var message = new GetGameCountsProtocolObject.GetGameCountsMessage(type, gameTypeName, mapName); + var message = new GetGameCountsProtocol.GetGameCountsMessage(type, gameTypeName, mapName); new ProxyService(ServiceType.ORCHESTRATOR) - .handleRequest(message) + .handleRequest(message) .thenAccept(response -> { if (response != null) { cache.put(cacheKey, new CachedCount( diff --git a/type.goldmine/src/main/java/net/swofty/type/goldmine/TypeGoldMineLoader.java b/type.goldmine/src/main/java/net/swofty/type/goldmine/TypeGoldMineLoader.java index 79b333ae7..1ebbc09dd 100644 --- a/type.goldmine/src/main/java/net/swofty/type/goldmine/TypeGoldMineLoader.java +++ b/type.goldmine/src/main/java/net/swofty/type/goldmine/TypeGoldMineLoader.java @@ -8,7 +8,7 @@ import net.swofty.commons.CustomWorlds; import net.swofty.commons.ServerType; import net.swofty.commons.ServiceType; -import net.swofty.proxyapi.redis.TypedProxyHandler; +import net.swofty.commons.redis.RedisMessageHandler; import net.swofty.type.generic.HypixelConst; import net.swofty.type.generic.SkyBlockTypeLoader; @@ -106,7 +106,7 @@ public List getNPCs() { @Override - public List> getTypedProxyHandlers() { + public List> getProxyHandlers() { return List.of(); } diff --git a/type.hub/src/main/java/net/swofty/type/hub/TypeHubLoader.java b/type.hub/src/main/java/net/swofty/type/hub/TypeHubLoader.java index 4a61fc9c0..0466668e4 100644 --- a/type.hub/src/main/java/net/swofty/type/hub/TypeHubLoader.java +++ b/type.hub/src/main/java/net/swofty/type/hub/TypeHubLoader.java @@ -20,7 +20,7 @@ import net.swofty.commons.StringUtility; import net.swofty.commons.skyblock.item.ItemType; import net.swofty.proxyapi.ProxyService; -import net.swofty.proxyapi.redis.TypedProxyHandler; +import net.swofty.commons.redis.RedisMessageHandler; import net.swofty.type.generic.HypixelConst; import net.swofty.type.generic.SkyBlockTypeLoader; import net.swofty.type.generic.entity.InteractionEntity; @@ -254,7 +254,7 @@ public List getNPCs() { @Override - public List> getTypedProxyHandlers() { + public List> getProxyHandlers() { return List.of(); } diff --git a/type.island/src/main/java/net/swofty/type/island/TypeIslandLoader.java b/type.island/src/main/java/net/swofty/type/island/TypeIslandLoader.java index 9bfcf8190..735d8f216 100644 --- a/type.island/src/main/java/net/swofty/type/island/TypeIslandLoader.java +++ b/type.island/src/main/java/net/swofty/type/island/TypeIslandLoader.java @@ -5,7 +5,7 @@ import net.swofty.commons.CustomWorlds; import net.swofty.commons.ServerType; import net.swofty.commons.ServiceType; -import net.swofty.proxyapi.redis.TypedProxyHandler; +import net.swofty.commons.redis.RedisMessageHandler; import net.swofty.type.generic.HypixelTypeLoader; import net.swofty.type.generic.SkyBlockTypeLoader; @@ -92,7 +92,7 @@ public List getNPCs() { @Override - public List> getTypedProxyHandlers() { + public List> getProxyHandlers() { return List.of(); } diff --git a/type.jerrysworkshop/src/main/java/net/swofty/type/jerrysworkshop/TypeJerrysWorkshopLoader.java b/type.jerrysworkshop/src/main/java/net/swofty/type/jerrysworkshop/TypeJerrysWorkshopLoader.java index 46e3bda21..297670611 100644 --- a/type.jerrysworkshop/src/main/java/net/swofty/type/jerrysworkshop/TypeJerrysWorkshopLoader.java +++ b/type.jerrysworkshop/src/main/java/net/swofty/type/jerrysworkshop/TypeJerrysWorkshopLoader.java @@ -8,7 +8,7 @@ import net.swofty.commons.ServerType; import net.swofty.commons.ServiceType; import net.swofty.commons.skyblock.item.ItemType; -import net.swofty.proxyapi.redis.TypedProxyHandler; +import net.swofty.commons.redis.RedisMessageHandler; import net.swofty.type.generic.HypixelConst; import net.swofty.type.generic.SkyBlockTypeLoader; import net.swofty.type.generic.entity.npc.HypixelNPC; @@ -96,7 +96,7 @@ public List getNPCs() { @Override - public List> getTypedProxyHandlers() { + public List> getProxyHandlers() { return List.of(); } diff --git a/type.lobby/src/main/java/net/swofty/type/lobby/LobbyOrchestratorConnector.java b/type.lobby/src/main/java/net/swofty/type/lobby/LobbyOrchestratorConnector.java index 9c8ea85ee..34c8d6e87 100644 --- a/type.lobby/src/main/java/net/swofty/type/lobby/LobbyOrchestratorConnector.java +++ b/type.lobby/src/main/java/net/swofty/type/lobby/LobbyOrchestratorConnector.java @@ -4,8 +4,8 @@ import net.swofty.commons.ServiceType; import net.swofty.commons.UnderstandableProxyServer; import net.swofty.commons.party.FullParty; -import net.swofty.commons.protocol.objects.orchestrator.ChooseGameProtocolObject; -import net.swofty.commons.protocol.objects.orchestrator.GetServerForMapProtocolObject; +import net.swofty.commons.protocol.objects.orchestrator.ChooseGameProtocol; +import net.swofty.commons.protocol.objects.orchestrator.GetServerForMapProtocol; import net.swofty.proxyapi.ProxyPlayer; import net.swofty.proxyapi.ProxyService; import net.swofty.type.generic.party.PartyManager; @@ -36,8 +36,8 @@ public CompletableFuture> findGameServer PLAYERS_SEARCHING.add(player.getUuid()); - GetServerForMapProtocolObject.GetServerForMapMessage message = - new GetServerForMapProtocolObject.GetServerForMapMessage( + GetServerForMapProtocol.GetServerForMapMessage message = + new GetServerForMapProtocol.GetServerForMapMessage( targetServerType, map, gameType, @@ -48,7 +48,7 @@ public CompletableFuture> findGameServer .thenApply(response -> { PLAYERS_SEARCHING.remove(player.getUuid()); - if (response instanceof GetServerForMapProtocolObject.GetServerForMapResponse( + if (response instanceof GetServerForMapProtocol.GetServerForMapResponse( UnderstandableProxyServer server, String gameId, boolean success, String error )) { return new Pair<>(server, gameId); @@ -80,8 +80,8 @@ public void sendToGame(ServerType targetServerType, String gameType, @Nullable S // Solo queue findGameServer(targetServerType, gameType, map, 1).thenAccept(pair -> { if (pair != null && pair.first() != null) { - ChooseGameProtocolObject.ChooseGameMessage message = - new ChooseGameProtocolObject.ChooseGameMessage(player.getUuid(), pair.first(), pair.second()); + ChooseGameProtocol.ChooseGameMessage message = + new ChooseGameProtocol.ChooseGameMessage(player.getUuid(), pair.first(), pair.second()); PROXY_SERVICE.handleRequest(message) .exceptionally(throwable -> { @@ -113,8 +113,8 @@ public void sendPartyToGame(ServerType targetServerType, String gameType, @Nulla List> registrationFutures = new ArrayList<>(); for (UUID memberUuid : partyMemberUuids) { - ChooseGameProtocolObject.ChooseGameMessage message = - new ChooseGameProtocolObject.ChooseGameMessage(memberUuid, server, gameId); + ChooseGameProtocol.ChooseGameMessage message = + new ChooseGameProtocol.ChooseGameMessage(memberUuid, server, gameId); registrationFutures.add( PROXY_SERVICE.handleRequest(message) diff --git a/type.murdermysteryconfigurator/src/main/java/net/swofty/type/murdermysteryconfigurator/TypeMurderMysteryConfiguratorLoader.java b/type.murdermysteryconfigurator/src/main/java/net/swofty/type/murdermysteryconfigurator/TypeMurderMysteryConfiguratorLoader.java index e480e755a..af940301a 100644 --- a/type.murdermysteryconfigurator/src/main/java/net/swofty/type/murdermysteryconfigurator/TypeMurderMysteryConfiguratorLoader.java +++ b/type.murdermysteryconfigurator/src/main/java/net/swofty/type/murdermysteryconfigurator/TypeMurderMysteryConfiguratorLoader.java @@ -9,7 +9,7 @@ import net.swofty.commons.ServerType; import net.swofty.commons.ServiceType; import net.swofty.commons.murdermystery.map.MurderMysteryMapsConfig; -import net.swofty.proxyapi.redis.TypedProxyHandler; +import net.swofty.commons.redis.RedisMessageHandler; import net.swofty.type.generic.HypixelGenericLoader; import net.swofty.type.generic.HypixelTypeLoader; import net.swofty.type.generic.command.HypixelCommand; @@ -147,7 +147,7 @@ public List getNPCs() { @Override - public List> getTypedProxyHandlers() { + public List> getProxyHandlers() { return List.of(); } diff --git a/type.murdermysterygame/src/main/java/net/swofty/type/murdermysterygame/TypeMurderMysteryGameLoader.java b/type.murdermysterygame/src/main/java/net/swofty/type/murdermysterygame/TypeMurderMysteryGameLoader.java index f97c2bd84..705fc14b8 100644 --- a/type.murdermysterygame/src/main/java/net/swofty/type/murdermysterygame/TypeMurderMysteryGameLoader.java +++ b/type.murdermysterygame/src/main/java/net/swofty/type/murdermysterygame/TypeMurderMysteryGameLoader.java @@ -22,10 +22,9 @@ import net.swofty.commons.ServiceType; import net.swofty.commons.murdermystery.MurderMysteryGameType; import net.swofty.commons.murdermystery.map.MurderMysteryMapsConfig; -import net.swofty.commons.protocol.objects.orchestrator.GameHeartbeatProtocolObject; +import net.swofty.commons.protocol.objects.orchestrator.GameHeartbeatProtocol; import net.swofty.proxyapi.ProxyService; -import net.swofty.proxyapi.redis.TypedProxyHandler; -import net.swofty.proxyapi.redis.TypedServiceHandler; +import net.swofty.commons.redis.RedisMessageHandler; import net.swofty.pvp.MinestomPvP; import net.swofty.type.generic.HypixelConst; import net.swofty.type.generic.HypixelGenericLoader; @@ -205,7 +204,7 @@ public void afterInitialize(MinecraftServer server) { commonsGames.add(commonsGame); } - var heartbeat = new GameHeartbeatProtocolObject.HeartbeatMessage( + var heartbeat = new GameHeartbeatProtocol.HeartbeatMessage( uuid, shortName, getType(), @@ -281,19 +280,19 @@ public List getNPCs() { @Override @SuppressWarnings("unchecked") - public List> getTypedServiceHandlers() { + public List> getServiceHandlers() { return (List) HypixelGenericLoader.loopThroughPackage( "net.swofty.type.murdermysterygame.redis.service", - TypedServiceHandler.class + RedisMessageHandler.class ).toList(); } @Override @SuppressWarnings("unchecked") - public List> getTypedProxyHandlers() { - return (List>) (List) HypixelGenericLoader.loopThroughPackage( + public List> getProxyHandlers() { + return (List>) (List) HypixelGenericLoader.loopThroughPackage( "net.swofty.type.murdermysterygame.redis", - TypedProxyHandler.class + RedisMessageHandler.class ).toList(); } diff --git a/type.murdermysterygame/src/main/java/net/swofty/type/murdermysterygame/events/ActionPlayerJoin.java b/type.murdermysterygame/src/main/java/net/swofty/type/murdermysterygame/events/ActionPlayerJoin.java index d645b8654..b19c1ef0f 100644 --- a/type.murdermysterygame/src/main/java/net/swofty/type/murdermysterygame/events/ActionPlayerJoin.java +++ b/type.murdermysterygame/src/main/java/net/swofty/type/murdermysterygame/events/ActionPlayerJoin.java @@ -12,7 +12,7 @@ import net.swofty.type.generic.event.HypixelEventClass; import net.swofty.type.generic.event.phase.EventPhase; import net.swofty.type.generic.event.phase.PhasedEvent; -import net.swofty.type.generic.redis.service.TypedGameInformationHandler; +import net.swofty.type.generic.redis.service.GameInformationHandler; import net.swofty.type.generic.utility.MathUtility; import org.tinylog.Logger; @@ -32,7 +32,7 @@ public void run(AsyncPlayerConfigurationEvent event) { private void tryJoinGame(MurderMysteryPlayer player, boolean isRetry) { if (!player.isOnline()) return; - String preferredGameId = TypedGameInformationHandler.game.remove(player.getUuid()); + String preferredGameId = GameInformationHandler.game.remove(player.getUuid()); if (preferredGameId == null) { if (!isRetry) { Logger.info("No game assignment found for " + player.getUsername() + ", retrying in 1 second..."); diff --git a/type.murdermysterygame/src/main/java/net/swofty/type/murdermysterygame/item/impl/PlayAgainItem.java b/type.murdermysterygame/src/main/java/net/swofty/type/murdermysterygame/item/impl/PlayAgainItem.java index f9d4c92a8..ca08ae3b7 100644 --- a/type.murdermysterygame/src/main/java/net/swofty/type/murdermysterygame/item/impl/PlayAgainItem.java +++ b/type.murdermysterygame/src/main/java/net/swofty/type/murdermysterygame/item/impl/PlayAgainItem.java @@ -5,8 +5,8 @@ import net.minestom.server.item.Material; import net.swofty.commons.ServerType; import net.swofty.commons.ServiceType; -import net.swofty.commons.protocol.objects.orchestrator.ChooseGameProtocolObject; -import net.swofty.commons.protocol.objects.orchestrator.GetServerForMapProtocolObject; +import net.swofty.commons.protocol.objects.orchestrator.ChooseGameProtocol; +import net.swofty.commons.protocol.objects.orchestrator.GetServerForMapProtocol; import net.swofty.proxyapi.ProxyService; import net.swofty.type.murdermysterygame.TypeMurderMysteryGameLoader; import net.swofty.type.murdermysterygame.game.Game; @@ -36,8 +36,8 @@ public void onItemUse(PlayerUseItemEvent event) { game.leave(player); // Queue for new game using ProxyService directly - GetServerForMapProtocolObject.GetServerForMapMessage message = - new GetServerForMapProtocolObject.GetServerForMapMessage( + GetServerForMapProtocol.GetServerForMapMessage message = + new GetServerForMapProtocol.GetServerForMapMessage( ServerType.MURDER_MYSTERY_GAME, null, gameType, @@ -45,10 +45,10 @@ public void onItemUse(PlayerUseItemEvent event) { ); PROXY_SERVICE.handleRequest(message).thenAccept(response -> { - if (response instanceof GetServerForMapProtocolObject.GetServerForMapResponse resp) { + if (response instanceof GetServerForMapProtocol.GetServerForMapResponse resp) { if (resp.server() != null) { - ChooseGameProtocolObject.ChooseGameMessage chooseMessage = - new ChooseGameProtocolObject.ChooseGameMessage( + ChooseGameProtocol.ChooseGameMessage chooseMessage = + new ChooseGameProtocol.ChooseGameMessage( player.getUuid(), resp.server(), resp.gameId() diff --git a/type.murdermysterygame/src/main/java/net/swofty/type/murdermysterygame/redis/service/TypedInstantiateGameHandler.java b/type.murdermysterygame/src/main/java/net/swofty/type/murdermysterygame/redis/service/InstantiateGameHandler.java similarity index 85% rename from type.murdermysterygame/src/main/java/net/swofty/type/murdermysterygame/redis/service/TypedInstantiateGameHandler.java rename to type.murdermysterygame/src/main/java/net/swofty/type/murdermysterygame/redis/service/InstantiateGameHandler.java index dbe7ceac4..98dc3c8ef 100644 --- a/type.murdermysterygame/src/main/java/net/swofty/type/murdermysterygame/redis/service/TypedInstantiateGameHandler.java +++ b/type.murdermysterygame/src/main/java/net/swofty/type/murdermysterygame/redis/service/InstantiateGameHandler.java @@ -2,25 +2,26 @@ import net.swofty.commons.murdermystery.MurderMysteryGameType; import net.swofty.commons.murdermystery.map.MurderMysteryMapsConfig; -import net.swofty.commons.protocol.ServicePushProtocol; +import net.swofty.commons.protocol.RedisProtocol; import net.swofty.commons.protocol.objects.game.InstantiateGamePushProtocol; import net.swofty.commons.protocol.objects.game.InstantiateGamePushProtocol.Request; import net.swofty.commons.protocol.objects.game.InstantiateGamePushProtocol.Response; -import net.swofty.proxyapi.redis.TypedServiceHandler; +import net.swofty.commons.redis.RedisMessageHandler; import net.swofty.type.murdermysterygame.TypeMurderMysteryGameLoader; import net.swofty.type.murdermysterygame.game.Game; +import net.swofty.commons.redis.RedisMessageContext; -public class TypedInstantiateGameHandler implements TypedServiceHandler { +public class InstantiateGameHandler implements RedisMessageHandler { private static final InstantiateGamePushProtocol PROTOCOL = new InstantiateGamePushProtocol(); @Override - public ServicePushProtocol getProtocol() { + public RedisProtocol protocol() { return PROTOCOL; } @Override - public Response onMessage(Request request) { + public Response handle(Request request, RedisMessageContext context) { try { MurderMysteryGameType gameType = MurderMysteryGameType.valueOf(request.gameType().toUpperCase()); diff --git a/type.murdermysterylobby/src/main/java/net/swofty/type/murdermysterylobby/TypeMurderMysteryLobbyLoader.java b/type.murdermysterylobby/src/main/java/net/swofty/type/murdermysterylobby/TypeMurderMysteryLobbyLoader.java index c30928981..46a40acc0 100644 --- a/type.murdermysterylobby/src/main/java/net/swofty/type/murdermysterylobby/TypeMurderMysteryLobbyLoader.java +++ b/type.murdermysterylobby/src/main/java/net/swofty/type/murdermysterylobby/TypeMurderMysteryLobbyLoader.java @@ -7,8 +7,7 @@ import net.swofty.commons.CustomWorlds; import net.swofty.commons.ServerType; import net.swofty.commons.ServiceType; -import net.swofty.proxyapi.redis.TypedProxyHandler; -import net.swofty.proxyapi.redis.TypedServiceHandler; +import net.swofty.commons.redis.RedisMessageHandler; import net.swofty.type.generic.HypixelConst; import net.swofty.type.generic.HypixelGenericLoader; import net.swofty.type.generic.command.HypixelCommand; @@ -173,15 +172,15 @@ public List getNPCs() { @Override @SuppressWarnings("unchecked") - public List> getTypedServiceHandlers() { + public List> getServiceHandlers() { return (List) HypixelGenericLoader.loopThroughPackage( "net.swofty.type.murdermysterylobby.redis.service", - TypedServiceHandler.class + RedisMessageHandler.class ).toList(); } @Override - public List> getTypedProxyHandlers() { + public List> getProxyHandlers() { return List.of(); } diff --git a/type.murdermysterylobby/src/main/java/net/swofty/type/murdermysterylobby/gui/GUIMapSelection.java b/type.murdermysterylobby/src/main/java/net/swofty/type/murdermysterylobby/gui/GUIMapSelection.java index 50139f052..2375f2434 100644 --- a/type.murdermysterylobby/src/main/java/net/swofty/type/murdermysterylobby/gui/GUIMapSelection.java +++ b/type.murdermysterylobby/src/main/java/net/swofty/type/murdermysterylobby/gui/GUIMapSelection.java @@ -7,7 +7,7 @@ import net.swofty.commons.murdermystery.MurderMysteryGameType; import net.swofty.commons.ServerType; import net.swofty.commons.ServiceType; -import net.swofty.commons.protocol.objects.orchestrator.GetMapsProtocolObject; +import net.swofty.commons.protocol.objects.orchestrator.GetMapsProtocol; import net.swofty.proxyapi.ProxyService; import net.swofty.type.lobby.LobbyOrchestratorConnector; import net.swofty.type.generic.gui.inventory.HypixelInventoryGUI; @@ -64,12 +64,12 @@ public void run(InventoryPreClickEvent e, HypixelPlayer player) { private void loadMaps(HypixelPlayer player) { ProxyService orchestratorService = new ProxyService(ServiceType.ORCHESTRATOR); - GetMapsProtocolObject.GetMapsMessage message = - new GetMapsProtocolObject.GetMapsMessage(ServerType.MURDER_MYSTERY_GAME, gameType.toString()); + GetMapsProtocol.GetMapsMessage message = + new GetMapsProtocol.GetMapsMessage(ServerType.MURDER_MYSTERY_GAME, gameType.toString()); orchestratorService.handleRequest(message) .thenAccept(response -> { - if (response instanceof GetMapsProtocolObject.GetMapsResponse mapsResponse) { + if (response instanceof GetMapsProtocol.GetMapsResponse mapsResponse) { maps = mapsResponse.maps(); mapsLoaded = true; diff --git a/type.prototypelobby/src/main/java/net/swofty/type/prototypelobby/TypePrototypeLobbyLoader.java b/type.prototypelobby/src/main/java/net/swofty/type/prototypelobby/TypePrototypeLobbyLoader.java index 056cd6285..0a136858c 100644 --- a/type.prototypelobby/src/main/java/net/swofty/type/prototypelobby/TypePrototypeLobbyLoader.java +++ b/type.prototypelobby/src/main/java/net/swofty/type/prototypelobby/TypePrototypeLobbyLoader.java @@ -5,8 +5,7 @@ import net.swofty.commons.CustomWorlds; import net.swofty.commons.ServerType; import net.swofty.commons.ServiceType; -import net.swofty.proxyapi.redis.TypedProxyHandler; -import net.swofty.proxyapi.redis.TypedServiceHandler; +import net.swofty.commons.redis.RedisMessageHandler; import net.swofty.type.generic.HypixelConst; import net.swofty.type.generic.HypixelGenericLoader; import net.swofty.type.generic.data.GameDataHandler; @@ -160,15 +159,15 @@ public List getNPCs() { @Override @SuppressWarnings("unchecked") - public List> getTypedServiceHandlers() { + public List> getServiceHandlers() { return (List) HypixelGenericLoader.loopThroughPackage( "net.swofty.type.prototypelobby.redis.service", - TypedServiceHandler.class + RedisMessageHandler.class ).toList(); } @Override - public List> getTypedProxyHandlers() { + public List> getProxyHandlers() { return List.of(); } diff --git a/type.ravengardlobby/src/main/java/net/swofty/type/ravengardlobby/TypeRavengardLobbyLoader.java b/type.ravengardlobby/src/main/java/net/swofty/type/ravengardlobby/TypeRavengardLobbyLoader.java index a17d2c5de..a878abaf5 100644 --- a/type.ravengardlobby/src/main/java/net/swofty/type/ravengardlobby/TypeRavengardLobbyLoader.java +++ b/type.ravengardlobby/src/main/java/net/swofty/type/ravengardlobby/TypeRavengardLobbyLoader.java @@ -10,7 +10,7 @@ import net.swofty.commons.CustomWorlds; import net.swofty.commons.ServerType; import net.swofty.commons.ServiceType; -import net.swofty.proxyapi.redis.TypedProxyHandler; +import net.swofty.commons.redis.RedisMessageHandler; import net.swofty.type.generic.HypixelConst; import net.swofty.type.generic.RavengardTypeLoader; import net.swofty.type.generic.entity.npc.HypixelNPC; @@ -114,7 +114,7 @@ public List getNPCs() { @Override - public List> getTypedProxyHandlers() { + public List> getProxyHandlers() { return List.of(); } diff --git a/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/bazaar/BazaarConnector.java b/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/bazaar/BazaarConnector.java index 0af787a8f..d5b654954 100644 --- a/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/bazaar/BazaarConnector.java +++ b/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/bazaar/BazaarConnector.java @@ -28,13 +28,13 @@ private UUID getPlayerProfileUUID() { } public CompletableFuture> getPendingOrders() { - var message = new BazaarGetPendingOrdersProtocolObject.BazaarGetPendingOrdersMessage( + var message = new BazaarGetPendingOrdersProtocol.BazaarGetPendingOrdersMessage( player.getUuid(), getPlayerProfileUUID() ); - return bazaarService.handleRequest(message) + return bazaarService.handleRequest(message) .thenApply(response -> response.orders().stream() .map(order -> new BazaarOrder( order.orderId(), @@ -48,22 +48,22 @@ public CompletableFuture> getPendingOrders() { } public CompletableFuture cancelOrder(UUID orderId) { - var message = new BazaarCancelProtocolObject.CancelMessage( + var message = new BazaarCancelProtocol.CancelMessage( orderId, player.getUuid(), getPlayerProfileUUID() ); - return bazaarService.handleRequest(message) + return bazaarService.handleRequest(message) .thenApply(response -> response.success()); } public CompletableFuture getItemData(ItemType itemType) { - var message = new BazaarGetItemProtocolObject.BazaarGetItemMessage(itemType.name()); + var message = new BazaarGetItemProtocol.BazaarGetItemMessage(itemType.name()); - return bazaarService.handleRequest(message) + return bazaarService.handleRequest(message) .thenApply(response -> { var buyOrders = response.buyOrders().stream() .map(order -> new MarketOrder( @@ -104,7 +104,7 @@ public CompletableFuture getItemStatistics(ItemType itemType) } public CompletableFuture createBuyOrder(ItemType itemType, double pricePerUnit, int quantity) { - var message = new BazaarBuyProtocolObject.BazaarBuyMessage( + var message = new BazaarBuyProtocol.BazaarBuyMessage( itemType.name(), quantity, pricePerUnit, @@ -112,8 +112,8 @@ public CompletableFuture createBuyOrder(ItemType itemType, double getPlayerProfileUUID() ); - return bazaarService.handleRequest(message) + return bazaarService.handleRequest(message) .thenApply(response -> new BazaarResult( response.success(), response.success() ? "Buy order created!" : "Failed to create buy order" @@ -121,7 +121,7 @@ public CompletableFuture createBuyOrder(ItemType itemType, double } public CompletableFuture createSellOrder(ItemType itemType, double pricePerUnit, int quantity) { - var message = new BazaarSellProtocolObject.BazaarSellMessage( + var message = new BazaarSellProtocol.BazaarSellMessage( itemType.name(), player.getUuid(), getPlayerProfileUUID(), @@ -129,8 +129,8 @@ public CompletableFuture createSellOrder(ItemType itemType, double quantity ); - return bazaarService.handleRequest(message) + return bazaarService.handleRequest(message) .thenApply(response -> new BazaarResult( response.success(), response.success() ? "Sell order created!" : "Failed to create sell order" @@ -206,13 +206,13 @@ public CompletableFuture isOnline() { } public CompletableFuture> getPendingTransactions() { - var message = new BazaarGetPendingTransactionsProtocolObject.BazaarGetPendingTransactionsMessage( + var message = new BazaarGetPendingTransactionsProtocol.BazaarGetPendingTransactionsMessage( player.getUuid(), getPlayerProfileUUID() ); - return bazaarService.handleRequest(message) + return bazaarService.handleRequest(message) .thenApply(response -> response.transactions().stream() .map(txInfo -> new PendingTransaction( txInfo.id(), @@ -224,14 +224,14 @@ public CompletableFuture> getPendingTransactions() { } public CompletableFuture processPendingTransactions(List transactionIds) { - var message = new BazaarProcessPendingTransactionsProtocolObject.BazaarProcessPendingTransactionsMessage( + var message = new BazaarProcessPendingTransactionsProtocol.BazaarProcessPendingTransactionsMessage( player.getUuid(), getPlayerProfileUUID(), transactionIds ); - return bazaarService.handleRequest(message) + return bazaarService.handleRequest(message) .thenApply(response -> new TransactionProcessResult( response.processedCount(), response.failedCount(), diff --git a/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/commands/GetTrackedItemInformationCommand.java b/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/commands/GetTrackedItemInformationCommand.java index 8eadcc4f8..e9e694900 100644 --- a/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/commands/GetTrackedItemInformationCommand.java +++ b/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/commands/GetTrackedItemInformationCommand.java @@ -3,7 +3,7 @@ import net.swofty.commons.ServiceType; import net.swofty.commons.StringUtility; import net.swofty.commons.TrackedItem; -import net.swofty.commons.protocol.objects.itemtracker.TrackedItemRetrieveProtocolObject; +import net.swofty.commons.protocol.objects.itemtracker.TrackedItemRetrieveProtocol; import net.swofty.proxyapi.ProxyService; import net.swofty.type.generic.command.CommandParameters; import net.swofty.type.generic.command.HypixelCommand; @@ -38,8 +38,8 @@ public void registerUsage(MinestomCommand command) { } long start = System.currentTimeMillis(); - CompletableFuture trackedItemFuture = service.handleRequest( - new TrackedItemRetrieveProtocolObject.TrackedItemRetrieveMessage( + CompletableFuture trackedItemFuture = service.handleRequest( + new TrackedItemRetrieveProtocol.TrackedItemRetrieveMessage( UUID.fromString(item.getAttributeHandler().getUniqueTrackedID()) )); diff --git a/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/commands/VerifyApiCommand.java b/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/commands/VerifyApiCommand.java index 0e0d99175..3d68d71e6 100644 --- a/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/commands/VerifyApiCommand.java +++ b/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/commands/VerifyApiCommand.java @@ -2,7 +2,7 @@ import net.minestom.server.command.builder.arguments.ArgumentString; import net.swofty.commons.ServiceType; -import net.swofty.commons.protocol.objects.api.APIAuthenticateCodeProtocolObject; +import net.swofty.commons.protocol.objects.api.APIAuthenticateCodeProtocol; import net.swofty.proxyapi.ProxyService; import net.swofty.type.generic.command.CommandParameters; import net.swofty.type.generic.command.HypixelCommand; @@ -35,12 +35,12 @@ public void registerUsage(MinestomCommand command) { SkyBlockPlayer player = (SkyBlockPlayer) sender; ProxyService apiService = new ProxyService(ServiceType.API); - apiService.handleRequest(new APIAuthenticateCodeProtocolObject.AuthenticateCodeMessage( + apiService.handleRequest(new APIAuthenticateCodeProtocol.AuthenticateCodeMessage( codeString, player.getUsername(), player.getUuid() )).thenAccept(nonCastedResponse -> { - APIAuthenticateCodeProtocolObject.AuthenticateCodeResponse response = (APIAuthenticateCodeProtocolObject.AuthenticateCodeResponse) nonCastedResponse; + APIAuthenticateCodeProtocol.AuthenticateCodeResponse response = (APIAuthenticateCodeProtocol.AuthenticateCodeResponse) nonCastedResponse; if (response.success()) { sender.sendMessage("§aCode '" + codeString + "' has successfully been verified! Check your web browser."); } else { diff --git a/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/data/DataMutexService.java b/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/data/DataMutexService.java index eb309067b..bd8b17454 100644 --- a/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/data/DataMutexService.java +++ b/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/data/DataMutexService.java @@ -3,9 +3,9 @@ import net.swofty.commons.ServiceType; import net.swofty.commons.UnderstandableProxyServer; import net.swofty.commons.protocol.Serializer; -import net.swofty.commons.protocol.objects.datamutex.SynchronizeDataProtocolObject; -import net.swofty.commons.protocol.objects.datamutex.UnlockDataProtocolObject; -import net.swofty.commons.protocol.objects.datamutex.UpdateSynchronizedDataProtocolObject; +import net.swofty.commons.protocol.objects.datamutex.SynchronizeDataProtocol; +import net.swofty.commons.protocol.objects.datamutex.UnlockDataProtocol; +import net.swofty.commons.protocol.objects.datamutex.UpdateSynchronizedDataProtocol; import net.swofty.proxyapi.ProxyInformation; import net.swofty.proxyapi.ProxyPlayer; import net.swofty.proxyapi.ProxyService; @@ -63,12 +63,12 @@ public void withSynchronizedData(String lockKey, List coopMembers, UUID playerUUID = coopMembers.getFirst(); Logger.info("Using playerUUID: " + playerUUID + " for synchronization"); - SynchronizeDataProtocolObject.SynchronizeDataRequest request = - new SynchronizeDataProtocolObject.SynchronizeDataRequest(onlineServers, playerUUID, dataType.getKey()); + SynchronizeDataProtocol.SynchronizeDataRequest request = + new SynchronizeDataProtocol.SynchronizeDataRequest(onlineServers, playerUUID, dataType.getKey()); Logger.info("Sending synchronization request to service..."); - CompletableFuture syncFuture = + CompletableFuture syncFuture = service.handleRequest(request); syncFuture.thenAccept(response -> { @@ -88,11 +88,11 @@ public void withSynchronizedData(String lockKey, List coopMembers, // Serialize as T String serializedData = ser.serialize(modifiedData); - UpdateSynchronizedDataProtocolObject.UpdateDataRequest updateRequest = - new UpdateSynchronizedDataProtocolObject.UpdateDataRequest( + UpdateSynchronizedDataProtocol.UpdateDataRequest updateRequest = + new UpdateSynchronizedDataProtocol.UpdateDataRequest( onlineServers, playerUUID, dataType.getKey(), serializedData); - CompletableFuture updateFuture = + CompletableFuture updateFuture = service.handleRequest(updateRequest); updateFuture.thenAccept(updateResponse -> { @@ -176,10 +176,10 @@ private void unlockData(List serverUUIDs, UUID playerUUID, String dataKey) Logger.info("Unlocking data for player " + playerUUID + " on servers: " + serverUUIDs); // Send unlock request to the mutex service, which will then unlock on all servers - service.handleRequest(new UnlockDataProtocolObject.UnlockDataRequest( + service.handleRequest(new UnlockDataProtocol.UnlockDataRequest( serverUUIDs, playerUUID, dataKey )).thenAccept(response -> { - UnlockDataProtocolObject.UnlockDataResponse responseObject = (UnlockDataProtocolObject.UnlockDataResponse) response; + UnlockDataProtocol.UnlockDataResponse responseObject = (UnlockDataProtocol.UnlockDataResponse) response; Logger.info("Unlock response: success=" + responseObject.success() + ", error=" + responseObject.error()); if (!responseObject.success()) { diff --git a/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/elections/ElectionCandidate.java b/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/elections/ElectionCandidate.java index 84f3f5e4e..31b537884 100644 --- a/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/elections/ElectionCandidate.java +++ b/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/elections/ElectionCandidate.java @@ -1,6 +1,6 @@ package net.swofty.type.skyblockgeneric.elections; -import net.swofty.commons.protocol.objects.election.GetCandidatesProtocolObject; +import net.swofty.commons.protocol.objects.election.GetCandidatesProtocol; import java.util.List; @@ -11,7 +11,7 @@ public record ElectionCandidate( double votePercentage ) { - public static ElectionCandidate fromProtocol(GetCandidatesProtocolObject.CandidateInfo info) { + public static ElectionCandidate fromProtocol(GetCandidatesProtocol.CandidateInfo info) { SkyBlockMayor mayor; try { mayor = SkyBlockMayor.valueOf(info.mayorName()); @@ -33,7 +33,7 @@ public static ElectionCandidate fromProtocol(GetCandidatesProtocolObject.Candida return new ElectionCandidate(mayor, perks, info.votes(), info.votePercentage()); } - public static List fromProtocolList(List infos) { + public static List fromProtocolList(List infos) { return infos.stream() .map(ElectionCandidate::fromProtocol) .filter(c -> c != null) diff --git a/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/elections/ElectionManager.java b/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/elections/ElectionManager.java index b8f988daf..be96fc3d1 100644 --- a/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/elections/ElectionManager.java +++ b/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/elections/ElectionManager.java @@ -5,12 +5,12 @@ import net.minestom.server.MinecraftServer; import net.minestom.server.timer.TaskSchedule; import net.swofty.commons.ServiceType; -import net.swofty.commons.protocol.objects.election.CastVoteProtocolObject; -import net.swofty.commons.protocol.objects.election.GetCandidatesProtocolObject; -import net.swofty.commons.protocol.objects.election.GetElectionDataProtocolObject; -import net.swofty.commons.protocol.objects.election.GetPlayerVoteProtocolObject; -import net.swofty.commons.protocol.objects.election.ResolveElectionProtocolObject; -import net.swofty.commons.protocol.objects.election.StartElectionProtocolObject; +import net.swofty.commons.protocol.objects.election.CastVoteProtocol; +import net.swofty.commons.protocol.objects.election.GetCandidatesProtocol; +import net.swofty.commons.protocol.objects.election.GetElectionDataProtocol; +import net.swofty.commons.protocol.objects.election.GetPlayerVoteProtocol; +import net.swofty.commons.protocol.objects.election.ResolveElectionProtocol; +import net.swofty.commons.protocol.objects.election.StartElectionProtocol; import net.swofty.proxyapi.ProxyService; import net.swofty.type.skyblockgeneric.calendar.SkyBlockCalendar; import org.tinylog.Logger; @@ -35,10 +35,10 @@ public class ElectionManager { public static void loadFromService() { SERVICE = new ProxyService(ServiceType.ELECTION); try { - GetElectionDataProtocolObject.GetElectionDataResponse response = - SERVICE.handleRequest( - new GetElectionDataProtocolObject.GetElectionDataMessage() + GetElectionDataProtocol.GetElectionDataResponse response = + SERVICE.handleRequest( + new GetElectionDataProtocol.GetElectionDataMessage() ).join(); if (response.found() && response.serializedData() != null) { @@ -81,10 +81,10 @@ public static void onElectionStart() { String serialized = GSON.toJson(electionData); try { - StartElectionProtocolObject.StartElectionResponse response = - SERVICE.handleRequest( - new StartElectionProtocolObject.StartElectionMessage(currentYear, serialized) + StartElectionProtocol.StartElectionResponse response = + SERVICE.handleRequest( + new StartElectionProtocol.StartElectionMessage(currentYear, serialized) ).join(); if (response.serializedData() != null) { @@ -107,10 +107,10 @@ public static void onElectionEnd() { int currentYear = SkyBlockCalendar.getYear(); try { - ResolveElectionProtocolObject.ResolveElectionResponse response = - SERVICE.handleRequest( - new ResolveElectionProtocolObject.ResolveElectionMessage(currentYear) + ResolveElectionProtocol.ResolveElectionResponse response = + SERVICE.handleRequest( + new ResolveElectionProtocol.ResolveElectionMessage(currentYear) ).join(); if (response.serializedData() != null) { @@ -136,9 +136,9 @@ public static CompletableFuture castVote(UUID accountId, String candidateN .anyMatch(c -> c.getMayorName().equals(candidateName)); if (!validCandidate) return CompletableFuture.completedFuture(null); - return SERVICE.handleRequest( - new CastVoteProtocolObject.CastVoteMessage(accountId, candidateName) + return SERVICE.handleRequest( + new CastVoteProtocol.CastVoteMessage(accountId, candidateName) ).thenAccept(response -> { if (response.success()) { playerVoteCache.put(accountId, candidateName); @@ -160,9 +160,9 @@ public static CompletableFuture fetchPlayerVote(UUID accountId) { String cached = playerVoteCache.get(accountId); if (cached != null) return CompletableFuture.completedFuture(cached); - return SERVICE.handleRequest( - new GetPlayerVoteProtocolObject.GetPlayerVoteMessage(accountId) + return SERVICE.handleRequest( + new GetPlayerVoteProtocol.GetPlayerVoteMessage(accountId) ).thenApply(response -> { if (response.candidateName() != null) { playerVoteCache.put(accountId, response.candidateName()); @@ -196,11 +196,11 @@ public static boolean isPerkActive(SkyBlockMayor.Perk perk) { return isMayorPerkActive(perk) || isMinisterPerkActive(perk); } - public static CompletableFuture> fetchCandidates() { - return SERVICE.handleRequest( - new GetCandidatesProtocolObject.GetCandidatesMessage() - ).thenApply(GetCandidatesProtocolObject.GetCandidatesResponse::candidates); + public static CompletableFuture> fetchCandidates() { + return SERVICE.handleRequest( + new GetCandidatesProtocol.GetCandidatesMessage() + ).thenApply(GetCandidatesProtocol.GetCandidatesResponse::candidates); } public static void checkElectionCycle() { @@ -228,13 +228,13 @@ private static void startTallyRefreshTask() { } private static void refreshTalliesAsync() { - SERVICE.handleRequest( - new GetCandidatesProtocolObject.GetCandidatesMessage() + SERVICE.handleRequest( + new GetCandidatesProtocol.GetCandidatesMessage() ).thenAccept(response -> { if (response.electionOpen()) { Map tallies = new HashMap<>(); - for (GetCandidatesProtocolObject.CandidateInfo info : response.candidates()) { + for (GetCandidatesProtocol.CandidateInfo info : response.candidates()) { tallies.put(info.mayorName(), info.votes()); } electionData.updateTallies(tallies); diff --git a/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/gui/inventories/auction/GUIAuctionBrowser.java b/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/gui/inventories/auction/GUIAuctionBrowser.java index 789545486..c05580870 100644 --- a/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/gui/inventories/auction/GUIAuctionBrowser.java +++ b/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/gui/inventories/auction/GUIAuctionBrowser.java @@ -14,7 +14,7 @@ import net.minestom.server.item.Material; import net.swofty.commons.ServiceType; import net.swofty.commons.StringUtility; -import net.swofty.commons.protocol.objects.auctions.AuctionFetchItemsProtocolObject; +import net.swofty.commons.protocol.objects.auctions.AuctionFetchItemsProtocol; import net.swofty.commons.skyblock.auctions.AuctionCategories; import net.swofty.commons.skyblock.auctions.AuctionItem; import net.swofty.commons.skyblock.auctions.AuctionsFilter; @@ -63,8 +63,8 @@ public GUIAuctionBrowser() { } private void updateItemsCache() { - AuctionFetchItemsProtocolObject.AuctionFetchItemsMessage message = - new AuctionFetchItemsProtocolObject.AuctionFetchItemsMessage( + AuctionFetchItemsProtocol.AuctionFetchItemsMessage message = + new AuctionFetchItemsProtocol.AuctionFetchItemsMessage( sorting, filter, category @@ -72,7 +72,7 @@ private void updateItemsCache() { new ProxyService(ServiceType.AUCTION_HOUSE).handleRequest(message) .thenAccept(responseRaw -> { - AuctionFetchItemsProtocolObject.AuctionFetchItemsResponse response = (AuctionFetchItemsProtocolObject.AuctionFetchItemsResponse) responseRaw; + AuctionFetchItemsProtocol.AuctionFetchItemsResponse response = (AuctionFetchItemsProtocol.AuctionFetchItemsResponse) responseRaw; List auctionItems = response.items(); // Items are already sorted, so just paginate them diff --git a/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/gui/inventories/auction/GUIAuctionCreateItem.java b/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/gui/inventories/auction/GUIAuctionCreateItem.java index f4bf753f9..383d3d9db 100644 --- a/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/gui/inventories/auction/GUIAuctionCreateItem.java +++ b/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/gui/inventories/auction/GUIAuctionCreateItem.java @@ -10,7 +10,7 @@ import net.minestom.server.item.Material; import net.swofty.commons.ServiceType; import net.swofty.commons.StringUtility; -import net.swofty.commons.protocol.objects.auctions.AuctionAddItemProtocolObject; +import net.swofty.commons.protocol.objects.auctions.AuctionAddItemProtocol; import net.swofty.commons.skyblock.auctions.AuctionCategories; import net.swofty.commons.skyblock.auctions.AuctionItem; import net.swofty.proxyapi.ProxyService; @@ -167,9 +167,9 @@ public void run(InventoryPreClickEvent e, HypixelPlayer p) { player.sendMessage(I18n.t("gui_auction.create.setup_message")); - AuctionAddItemProtocolObject.AuctionAddItemMessage message = - new AuctionAddItemProtocolObject.AuctionAddItemMessage(item, category); - CompletableFuture future = + AuctionAddItemProtocol.AuctionAddItemMessage message = + new AuctionAddItemProtocol.AuctionAddItemMessage(item, category); + CompletableFuture future = auctionService.handleRequest(message); UUID auctionUUID = future.join().uuid(); diff --git a/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/gui/inventories/auction/GUIAuctionViewItem.java b/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/gui/inventories/auction/GUIAuctionViewItem.java index 186ba4496..3b2865826 100644 --- a/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/gui/inventories/auction/GUIAuctionViewItem.java +++ b/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/gui/inventories/auction/GUIAuctionViewItem.java @@ -7,7 +7,7 @@ import net.minestom.server.item.ItemStack; import net.minestom.server.item.Material; import net.swofty.commons.ServiceType; -import net.swofty.commons.protocol.objects.auctions.AuctionFetchItemProtocolObject; +import net.swofty.commons.protocol.objects.auctions.AuctionFetchItemProtocol; import net.swofty.commons.skyblock.auctions.AuctionItem; import net.swofty.proxyapi.ProxyService; import net.swofty.type.generic.gui.inventory.HypixelInventoryGUI; @@ -50,9 +50,9 @@ public void onOpen(InventoryGUIOpenEvent e) { } public void updateItems() { - AuctionFetchItemProtocolObject.AuctionFetchItemMessage message = - new AuctionFetchItemProtocolObject.AuctionFetchItemMessage(auctionID); - CompletableFuture future = + AuctionFetchItemProtocol.AuctionFetchItemMessage message = + new AuctionFetchItemProtocol.AuctionFetchItemMessage(auctionID); + CompletableFuture future = new ProxyService(ServiceType.AUCTION_HOUSE).handleRequest(message); AuctionItem item = future.join().item(); diff --git a/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/gui/inventories/auction/GUIManageAuctions.java b/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/gui/inventories/auction/GUIManageAuctions.java index ab2fb1ca7..1ff586d33 100644 --- a/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/gui/inventories/auction/GUIManageAuctions.java +++ b/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/gui/inventories/auction/GUIManageAuctions.java @@ -9,7 +9,7 @@ import net.minestom.server.item.Material; import net.swofty.commons.ServiceType; import net.swofty.commons.StringUtility; -import net.swofty.commons.protocol.objects.auctions.AuctionFetchItemProtocolObject; +import net.swofty.commons.protocol.objects.auctions.AuctionFetchItemProtocol; import net.swofty.commons.skyblock.auctions.AuctionItem; import net.swofty.proxyapi.ProxyService; import net.swofty.type.generic.gui.inventory.HypixelInventoryGUI; @@ -61,13 +61,13 @@ public void onOpen(InventoryGUIOpenEvent e) { public void setItems() { List auctions = ((SkyBlockPlayer) getPlayer()).getSkyblockDataHandler().get(net.swofty.type.skyblockgeneric.data.SkyBlockDataHandler.Data.AUCTION_ACTIVE_OWNED, DatapointUUIDList.class).getValue(); - List> futures = new ArrayList<>(auctions.size()); + List> futures = new ArrayList<>(auctions.size()); PaginationList auctionItems = new PaginationList<>(7); auctions.forEach(uuid -> { - AuctionFetchItemProtocolObject.AuctionFetchItemMessage message = - new AuctionFetchItemProtocolObject.AuctionFetchItemMessage(uuid); - CompletableFuture future = + AuctionFetchItemProtocol.AuctionFetchItemMessage message = + new AuctionFetchItemProtocol.AuctionFetchItemMessage(uuid); + CompletableFuture future = new ProxyService(ServiceType.AUCTION_HOUSE).handleRequest(message); future.thenAccept(response -> { diff --git a/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/gui/inventories/auction/GUIViewBids.java b/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/gui/inventories/auction/GUIViewBids.java index 12af4dd70..641260b3a 100644 --- a/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/gui/inventories/auction/GUIViewBids.java +++ b/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/gui/inventories/auction/GUIViewBids.java @@ -9,7 +9,7 @@ import net.minestom.server.item.Material; import net.swofty.commons.ServiceType; import net.swofty.commons.StringUtility; -import net.swofty.commons.protocol.objects.auctions.AuctionFetchItemProtocolObject; +import net.swofty.commons.protocol.objects.auctions.AuctionFetchItemProtocol; import net.swofty.commons.skyblock.auctions.AuctionItem; import net.swofty.proxyapi.ProxyService; import net.swofty.type.generic.gui.inventory.HypixelInventoryGUI; @@ -46,13 +46,13 @@ public void onOpen(InventoryGUIOpenEvent e) { public void setItems() { List auctions = ((SkyBlockPlayer) getPlayer()).getSkyblockDataHandler().get(net.swofty.type.skyblockgeneric.data.SkyBlockDataHandler.Data.AUCTION_ACTIVE_BIDS, DatapointUUIDList.class).getValue(); - List> futures = new ArrayList<>(auctions.size()); + List> futures = new ArrayList<>(auctions.size()); PaginationList auctionItems = new PaginationList<>(7); auctions.forEach(uuid -> { - AuctionFetchItemProtocolObject.AuctionFetchItemMessage message = - new AuctionFetchItemProtocolObject.AuctionFetchItemMessage(uuid); - CompletableFuture future = + AuctionFetchItemProtocol.AuctionFetchItemMessage message = + new AuctionFetchItemProtocol.AuctionFetchItemMessage(uuid); + CompletableFuture future = new ProxyService(ServiceType.AUCTION_HOUSE).handleRequest(message); future.thenAccept(response -> { diff --git a/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/gui/inventories/auction/view/AuctionViewThirdBin.java b/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/gui/inventories/auction/view/AuctionViewThirdBin.java index 72c1c491a..00df3929e 100644 --- a/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/gui/inventories/auction/view/AuctionViewThirdBin.java +++ b/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/gui/inventories/auction/view/AuctionViewThirdBin.java @@ -7,8 +7,8 @@ import net.minestom.server.item.ItemStack; import net.minestom.server.item.Material; import net.swofty.commons.ServiceType; -import net.swofty.commons.protocol.objects.auctions.AuctionAddItemProtocolObject; -import net.swofty.commons.protocol.objects.auctions.AuctionFetchItemProtocolObject; +import net.swofty.commons.protocol.objects.auctions.AuctionAddItemProtocol; +import net.swofty.commons.protocol.objects.auctions.AuctionFetchItemProtocol; import net.swofty.commons.skyblock.auctions.AuctionCategories; import net.swofty.commons.skyblock.auctions.AuctionItem; import net.swofty.proxyapi.ProxyPlayer; @@ -107,8 +107,8 @@ public void run(InventoryPreClickEvent e, HypixelPlayer p) { player.sendMessage(I18n.t("gui_auction.view_third_bin.processing")); - CompletableFuture future = new ProxyService(ServiceType.AUCTION_HOUSE).handleRequest( - new AuctionFetchItemProtocolObject.AuctionFetchItemMessage(item.getUuid()) + CompletableFuture future = new ProxyService(ServiceType.AUCTION_HOUSE).handleRequest( + new AuctionFetchItemProtocol.AuctionFetchItemMessage(item.getUuid()) ); AuctionItem item = future.join().item(); @@ -139,8 +139,8 @@ public void run(InventoryPreClickEvent e, HypixelPlayer p) { }}); item.setEndTime(System.currentTimeMillis()); - AuctionAddItemProtocolObject.AuctionAddItemMessage message = - new AuctionAddItemProtocolObject.AuctionAddItemMessage( + AuctionAddItemProtocol.AuctionAddItemMessage message = + new AuctionAddItemProtocol.AuctionAddItemMessage( item, AuctionCategories.TOOLS); new ProxyService(ServiceType.AUCTION_HOUSE).handleRequest(message).join(); diff --git a/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/gui/inventories/auction/view/AuctionViewThirdNormal.java b/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/gui/inventories/auction/view/AuctionViewThirdNormal.java index 029ea2af7..0e6d086f8 100644 --- a/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/gui/inventories/auction/view/AuctionViewThirdNormal.java +++ b/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/gui/inventories/auction/view/AuctionViewThirdNormal.java @@ -8,8 +8,8 @@ import net.minestom.server.item.Material; import net.swofty.commons.ServiceType; import net.swofty.commons.StringUtility; -import net.swofty.commons.protocol.objects.auctions.AuctionAddItemProtocolObject; -import net.swofty.commons.protocol.objects.auctions.AuctionFetchItemProtocolObject; +import net.swofty.commons.protocol.objects.auctions.AuctionAddItemProtocol; +import net.swofty.commons.protocol.objects.auctions.AuctionFetchItemProtocol; import net.swofty.commons.skyblock.auctions.AuctionCategories; import net.swofty.commons.skyblock.auctions.AuctionItem; import net.swofty.proxyapi.ProxyPlayer; @@ -232,8 +232,8 @@ public void run(InventoryPreClickEvent e, HypixelPlayer p) { player.sendMessage(I18n.t("gui_auction.view_third_normal.processing_bid")); Thread.startVirtualThread(() -> { - AuctionFetchItemProtocolObject.AuctionFetchItemResponse itemResponse = (AuctionFetchItemProtocolObject.AuctionFetchItemResponse) new ProxyService(ServiceType.AUCTION_HOUSE).handleRequest( - new AuctionFetchItemProtocolObject.AuctionFetchItemMessage(item.getUuid()) + AuctionFetchItemProtocol.AuctionFetchItemResponse itemResponse = (AuctionFetchItemProtocol.AuctionFetchItemResponse) new ProxyService(ServiceType.AUCTION_HOUSE).handleRequest( + new AuctionFetchItemProtocol.AuctionFetchItemMessage(item.getUuid()) ).join(); AuctionItem item = itemResponse.item(); @@ -258,8 +258,8 @@ public void run(InventoryPreClickEvent e, HypixelPlayer p) { }}); item.setEndTime(item.getEndTime() + 120000); - AuctionAddItemProtocolObject.AuctionAddItemMessage message = - new AuctionAddItemProtocolObject.AuctionAddItemMessage( + AuctionAddItemProtocol.AuctionAddItemMessage message = + new AuctionAddItemProtocol.AuctionAddItemMessage( item, category); new ProxyService(ServiceType.AUCTION_HOUSE).handleRequest(message).join(); diff --git a/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/gui/inventories/museum/GUIMuseumArmorCategory.java b/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/gui/inventories/museum/GUIMuseumArmorCategory.java index fbe6c127e..f924fd05d 100644 --- a/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/gui/inventories/museum/GUIMuseumArmorCategory.java +++ b/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/gui/inventories/museum/GUIMuseumArmorCategory.java @@ -11,7 +11,7 @@ import net.swofty.commons.ServiceType; import net.swofty.commons.StringUtility; import net.swofty.commons.TrackedItem; -import net.swofty.commons.protocol.objects.itemtracker.TrackedItemRetrieveProtocolObject; +import net.swofty.commons.protocol.objects.itemtracker.TrackedItemRetrieveProtocol; import net.swofty.commons.skyblock.item.ItemType; import net.swofty.proxyapi.ProxyService; import net.swofty.type.generic.gui.inventory.HypixelPaginatedGUI; @@ -206,11 +206,11 @@ public void performSearch(HypixelPlayer player, String query, int page, int maxP continue; if (armorSets.contains(ArmorSetRegistry.getArmorSet(item.getAttributeHandler().getPotentialType()))) { - TrackedItemRetrieveProtocolObject.TrackedItemRetrieveMessage message = new TrackedItemRetrieveProtocolObject.TrackedItemRetrieveMessage( + TrackedItemRetrieveProtocol.TrackedItemRetrieveMessage message = new TrackedItemRetrieveProtocol.TrackedItemRetrieveMessage( UUID.fromString(item.getAttributeHandler().getUniqueTrackedID()) ); ProxyService proxyService = new ProxyService(ServiceType.ITEM_TRACKER); - TrackedItemRetrieveProtocolObject.TrackedItemResponse trackedItemResponse = (TrackedItemRetrieveProtocolObject.TrackedItemResponse) proxyService.handleRequest(message).join(); + TrackedItemRetrieveProtocol.TrackedItemResponse trackedItemResponse = (TrackedItemRetrieveProtocol.TrackedItemResponse) proxyService.handleRequest(message).join(); TrackedItem trackedItem = trackedItemResponse.trackedItem(); ItemStack.Builder toReturn = item.getItemStackBuilder(); @@ -295,13 +295,13 @@ public ItemStack.Builder getItem(HypixelPlayer p) { UUID leggingsUUID = UUID.fromString(leggings.getAttributeHandler().getUniqueTrackedID()); UUID bootsUUID = UUID.fromString(boots.getAttributeHandler().getUniqueTrackedID()); - TrackedItemRetrieveProtocolObject.TrackedItemResponse helmetResponse = (TrackedItemRetrieveProtocolObject.TrackedItemResponse) itemTracker.handleRequest(new TrackedItemRetrieveProtocolObject.TrackedItemRetrieveMessage(helmetUUID)).join(); + TrackedItemRetrieveProtocol.TrackedItemResponse helmetResponse = (TrackedItemRetrieveProtocol.TrackedItemResponse) itemTracker.handleRequest(new TrackedItemRetrieveProtocol.TrackedItemRetrieveMessage(helmetUUID)).join(); TrackedItem trackedHelmet = helmetResponse.trackedItem(); - TrackedItemRetrieveProtocolObject.TrackedItemResponse chestplateResponse = (TrackedItemRetrieveProtocolObject.TrackedItemResponse) itemTracker.handleRequest(new TrackedItemRetrieveProtocolObject.TrackedItemRetrieveMessage(chestplateUUID)).join(); + TrackedItemRetrieveProtocol.TrackedItemResponse chestplateResponse = (TrackedItemRetrieveProtocol.TrackedItemResponse) itemTracker.handleRequest(new TrackedItemRetrieveProtocol.TrackedItemRetrieveMessage(chestplateUUID)).join(); TrackedItem trackedChestplate = chestplateResponse.trackedItem(); - TrackedItemRetrieveProtocolObject.TrackedItemResponse leggingsResponse = (TrackedItemRetrieveProtocolObject.TrackedItemResponse) itemTracker.handleRequest(new TrackedItemRetrieveProtocolObject.TrackedItemRetrieveMessage(leggingsUUID)).join(); + TrackedItemRetrieveProtocol.TrackedItemResponse leggingsResponse = (TrackedItemRetrieveProtocol.TrackedItemResponse) itemTracker.handleRequest(new TrackedItemRetrieveProtocol.TrackedItemRetrieveMessage(leggingsUUID)).join(); TrackedItem trackedLeggings = leggingsResponse.trackedItem(); - TrackedItemRetrieveProtocolObject.TrackedItemResponse bootsResponse = (TrackedItemRetrieveProtocolObject.TrackedItemResponse) itemTracker.handleRequest(new TrackedItemRetrieveProtocolObject.TrackedItemRetrieveMessage(bootsUUID)).join(); + TrackedItemRetrieveProtocol.TrackedItemResponse bootsResponse = (TrackedItemRetrieveProtocol.TrackedItemResponse) itemTracker.handleRequest(new TrackedItemRetrieveProtocol.TrackedItemRetrieveMessage(bootsUUID)).join(); TrackedItem trackedBoots = bootsResponse.trackedItem(); int helmetValue = new ItemPriceCalculator(helmet).calculateCleanPrice().intValue(); diff --git a/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/gui/inventories/museum/GUIMuseumCategory.java b/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/gui/inventories/museum/GUIMuseumCategory.java index 7818835dc..3867728c5 100644 --- a/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/gui/inventories/museum/GUIMuseumCategory.java +++ b/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/gui/inventories/museum/GUIMuseumCategory.java @@ -11,7 +11,7 @@ import net.swofty.commons.ServiceType; import net.swofty.commons.StringUtility; import net.swofty.commons.TrackedItem; -import net.swofty.commons.protocol.objects.itemtracker.TrackedItemRetrieveProtocolObject; +import net.swofty.commons.protocol.objects.itemtracker.TrackedItemRetrieveProtocol; import net.swofty.commons.skyblock.item.ItemType; import net.swofty.proxyapi.ProxyService; import net.swofty.type.generic.gui.inventory.HypixelPaginatedGUI; @@ -135,10 +135,10 @@ public void performSearch(HypixelPlayer p, String query, int page, int maxPage) } if (category.contains(item.getAttributeHandler().getPotentialType())) { - TrackedItemRetrieveProtocolObject.TrackedItemRetrieveMessage message = new TrackedItemRetrieveProtocolObject.TrackedItemRetrieveMessage( + TrackedItemRetrieveProtocol.TrackedItemRetrieveMessage message = new TrackedItemRetrieveProtocol.TrackedItemRetrieveMessage( UUID.fromString(item.getAttributeHandler().getUniqueTrackedID()) ); - TrackedItem trackedItem = ((TrackedItemRetrieveProtocolObject.TrackedItemResponse) new ProxyService(ServiceType.ITEM_TRACKER).handleRequest(message).join()).trackedItem(); + TrackedItem trackedItem = ((TrackedItemRetrieveProtocol.TrackedItemResponse) new ProxyService(ServiceType.ITEM_TRACKER).handleRequest(message).join()).trackedItem(); ItemStack.Builder toReturn = item.getItemStackBuilder(); List lore = new ArrayList<>(item.getLore(player)); @@ -201,8 +201,8 @@ public ItemStack.Builder getItem(HypixelPlayer p) { } UUID trackedItemUUID = UUID.fromString(skyBlockItem.getAttributeHandler().getUniqueTrackedID()); - TrackedItemRetrieveProtocolObject.TrackedItemRetrieveMessage message = new TrackedItemRetrieveProtocolObject.TrackedItemRetrieveMessage(trackedItemUUID); - TrackedItem trackedItem = ((TrackedItemRetrieveProtocolObject.TrackedItemResponse) new ProxyService(ServiceType.ITEM_TRACKER) + TrackedItemRetrieveProtocol.TrackedItemRetrieveMessage message = new TrackedItemRetrieveProtocol.TrackedItemRetrieveMessage(trackedItemUUID); + TrackedItem trackedItem = ((TrackedItemRetrieveProtocol.TrackedItemResponse) new ProxyService(ServiceType.ITEM_TRACKER) .handleRequest(message).join()).trackedItem(); Locale l = player.getLocale(); diff --git a/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/gui/inventories/museum/GUIMuseumEmptyDisplay.java b/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/gui/inventories/museum/GUIMuseumEmptyDisplay.java index b81dab567..e0d4e8ffb 100644 --- a/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/gui/inventories/museum/GUIMuseumEmptyDisplay.java +++ b/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/gui/inventories/museum/GUIMuseumEmptyDisplay.java @@ -8,7 +8,7 @@ import net.swofty.commons.ServiceType; import net.swofty.commons.StringUtility; import net.swofty.commons.TrackedItem; -import net.swofty.commons.protocol.objects.itemtracker.TrackedItemRetrieveProtocolObject; +import net.swofty.commons.protocol.objects.itemtracker.TrackedItemRetrieveProtocol; import net.swofty.proxyapi.ProxyService; import net.swofty.type.generic.gui.inventory.HypixelPaginatedGUI; import net.swofty.type.generic.gui.inventory.ItemStackCreator; @@ -171,11 +171,11 @@ public ItemStack.Builder getItem(HypixelPlayer p) { } private GUIClickableItem createIndividualItemDisplay(SkyBlockItem item, int slot, SkyBlockPlayer player) { - TrackedItemRetrieveProtocolObject.TrackedItemRetrieveMessage message = new TrackedItemRetrieveProtocolObject.TrackedItemRetrieveMessage( + TrackedItemRetrieveProtocol.TrackedItemRetrieveMessage message = new TrackedItemRetrieveProtocol.TrackedItemRetrieveMessage( UUID.fromString(item.getAttributeHandler().getUniqueTrackedID()) ); ProxyService proxyService = new ProxyService(ServiceType.ITEM_TRACKER); - TrackedItemRetrieveProtocolObject.TrackedItemResponse trackedItemResponse = (TrackedItemRetrieveProtocolObject.TrackedItemResponse) proxyService.handleRequest(message).join(); + TrackedItemRetrieveProtocol.TrackedItemResponse trackedItemResponse = (TrackedItemRetrieveProtocol.TrackedItemResponse) proxyService.handleRequest(message).join(); TrackedItem trackedItem = trackedItemResponse.trackedItem(); return new GUIClickableItem(slot) { diff --git a/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/gui/inventories/museum/GUIMuseumNonEmptyDisplay.java b/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/gui/inventories/museum/GUIMuseumNonEmptyDisplay.java index d9975b496..6b8f5c94c 100644 --- a/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/gui/inventories/museum/GUIMuseumNonEmptyDisplay.java +++ b/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/gui/inventories/museum/GUIMuseumNonEmptyDisplay.java @@ -9,7 +9,7 @@ import net.swofty.commons.ServiceType; import net.swofty.commons.StringUtility; import net.swofty.commons.TrackedItem; -import net.swofty.commons.protocol.objects.itemtracker.TrackedItemRetrieveProtocolObject; +import net.swofty.commons.protocol.objects.itemtracker.TrackedItemRetrieveProtocol; import net.swofty.proxyapi.ProxyService; import net.swofty.type.generic.gui.inventory.HypixelInventoryGUI; import net.swofty.type.generic.gui.inventory.ItemStackCreator; @@ -135,13 +135,13 @@ private ItemStack.Builder createItemDisplay(SkyBlockItem item, SkyBlockPlayer pl // Get tracked item info TrackedItem trackedItem = null; try { - TrackedItemRetrieveProtocolObject.TrackedItemRetrieveMessage message = - new TrackedItemRetrieveProtocolObject.TrackedItemRetrieveMessage( + TrackedItemRetrieveProtocol.TrackedItemRetrieveMessage message = + new TrackedItemRetrieveProtocol.TrackedItemRetrieveMessage( UUID.fromString(item.getAttributeHandler().getUniqueTrackedID()) ); ProxyService proxyService = new ProxyService(ServiceType.ITEM_TRACKER); - TrackedItemRetrieveProtocolObject.TrackedItemResponse response = - (TrackedItemRetrieveProtocolObject.TrackedItemResponse) proxyService.handleRequest(message).join(); + TrackedItemRetrieveProtocol.TrackedItemResponse response = + (TrackedItemRetrieveProtocol.TrackedItemResponse) proxyService.handleRequest(message).join(); trackedItem = response.trackedItem(); } catch (Exception e) { Logger.error(e, "Error displaying museum items"); diff --git a/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/item/ItemAttributeHandler.java b/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/item/ItemAttributeHandler.java index ab2cc5494..bf565dea8 100644 --- a/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/item/ItemAttributeHandler.java +++ b/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/item/ItemAttributeHandler.java @@ -2,7 +2,7 @@ import net.minestom.server.color.Color; import net.swofty.commons.ServiceType; -import net.swofty.commons.protocol.objects.itemtracker.TrackedItemUpdateProtocolObject; +import net.swofty.commons.protocol.objects.itemtracker.TrackedItemUpdateProtocol; import net.swofty.commons.skyblock.item.ItemType; import net.swofty.commons.skyblock.item.Rarity; import net.swofty.commons.skyblock.item.attribute.attributes.*; @@ -243,15 +243,15 @@ public void setUniqueTrackedID(String uniqueTrackedID, SkyBlockPlayer player) { ProxyService itemTracker = new ProxyService(ServiceType.ITEM_TRACKER); if (!itemTracker.isOnline().join()) return; - TrackedItemUpdateProtocolObject.TrackedItemUpdateMessage message = - new TrackedItemUpdateProtocolObject.TrackedItemUpdateMessage( + TrackedItemUpdateProtocol.TrackedItemUpdateMessage message = + new TrackedItemUpdateProtocol.TrackedItemUpdateMessage( UUID.fromString(uniqueTrackedID), player.getUuid(), player.getProfiles().getCurrentlySelected(), item.getAttributeHandler().getTypeAsString() ); - CompletableFuture future + CompletableFuture future = itemTracker.handleRequest(message); }); } diff --git a/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/redis/RedisHasIslandLoaded.java b/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/redis/RedisHasIslandLoaded.java index 0623ddb63..0515d6c30 100644 --- a/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/redis/RedisHasIslandLoaded.java +++ b/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/redis/RedisHasIslandLoaded.java @@ -1,20 +1,21 @@ package net.swofty.type.skyblockgeneric.redis; -import net.swofty.commons.protocol.ProtocolObject; +import net.swofty.commons.protocol.RedisProtocol; import net.swofty.commons.protocol.objects.proxy.from.DoesServerHaveIslandProtocol; -import net.swofty.proxyapi.redis.TypedProxyHandler; +import net.swofty.commons.redis.RedisMessageHandler; import net.swofty.type.skyblockgeneric.user.island.SkyBlockIsland; import java.util.UUID; +import net.swofty.commons.redis.RedisMessageContext; -public class RedisHasIslandLoaded implements TypedProxyHandler { +public class RedisHasIslandLoaded implements RedisMessageHandler { @Override - public ProtocolObject getProtocol() { + public RedisProtocol protocol() { return new DoesServerHaveIslandProtocol(); } @Override - public DoesServerHaveIslandProtocol.Response onMessage(DoesServerHaveIslandProtocol.Request message) { + public DoesServerHaveIslandProtocol.Response handle(DoesServerHaveIslandProtocol.Request message, RedisMessageContext context) { UUID islandUUID = UUID.fromString(message.islandUuid()); return new DoesServerHaveIslandProtocol.Response(SkyBlockIsland.hasIsland(islandUUID), true, null); } diff --git a/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/redis/RedisRefreshCoopData.java b/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/redis/RedisRefreshCoopData.java index 98787f01f..10a3f8bcb 100644 --- a/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/redis/RedisRefreshCoopData.java +++ b/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/redis/RedisRefreshCoopData.java @@ -1,8 +1,8 @@ package net.swofty.type.skyblockgeneric.redis; -import net.swofty.commons.protocol.ProtocolObject; +import net.swofty.commons.protocol.RedisProtocol; import net.swofty.commons.protocol.objects.proxy.from.RefreshCoopDataProtocol; -import net.swofty.proxyapi.redis.TypedProxyHandler; +import net.swofty.commons.redis.RedisMessageHandler; import net.swofty.type.skyblockgeneric.SkyBlockGenericLoader; import net.swofty.type.generic.data.mongodb.ProfilesDatabase; import net.swofty.type.skyblockgeneric.data.SkyBlockDataHandler; @@ -11,15 +11,16 @@ import org.bson.Document; import java.util.UUID; +import net.swofty.commons.redis.RedisMessageContext; -public class RedisRefreshCoopData implements TypedProxyHandler { +public class RedisRefreshCoopData implements RedisMessageHandler { @Override - public ProtocolObject getProtocol() { + public RedisProtocol protocol() { return new RefreshCoopDataProtocol(); } @Override - public RefreshCoopDataProtocol.Response onMessage(RefreshCoopDataProtocol.Request message) { + public RefreshCoopDataProtocol.Response handle(RefreshCoopDataProtocol.Request message, RedisMessageContext context) { UUID uuid = UUID.fromString(message.uuid()); String datapoint = message.datapoint(); diff --git a/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/redis/RedisRunEvent.java b/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/redis/RedisRunEvent.java index d00fe36fb..bac32fba4 100644 --- a/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/redis/RedisRunEvent.java +++ b/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/redis/RedisRunEvent.java @@ -1,9 +1,9 @@ package net.swofty.type.skyblockgeneric.redis; import net.minestom.server.event.Event; -import net.swofty.commons.protocol.ProtocolObject; +import net.swofty.commons.protocol.RedisProtocol; import net.swofty.commons.protocol.objects.proxy.from.RunEventProtocol; -import net.swofty.proxyapi.redis.TypedProxyHandler; +import net.swofty.commons.redis.RedisMessageHandler; import net.swofty.type.skyblockgeneric.SkyBlockGenericLoader; import net.swofty.type.generic.event.HypixelEventHandler; import net.swofty.type.skyblockgeneric.user.SkyBlockPlayer; @@ -11,15 +11,16 @@ import java.lang.reflect.InvocationTargetException; import java.util.UUID; +import net.swofty.commons.redis.RedisMessageContext; -public class RedisRunEvent implements TypedProxyHandler { +public class RedisRunEvent implements RedisMessageHandler { @Override - public ProtocolObject getProtocol() { + public RedisProtocol protocol() { return new RunEventProtocol(); } @Override - public RunEventProtocol.Response onMessage(RunEventProtocol.Request message) { + public RunEventProtocol.Response handle(RunEventProtocol.Request message, RedisMessageContext context) { UUID uuid = UUID.fromString(message.uuid()); String eventClassName = message.event(); String eventArgs = message.data(); diff --git a/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/redis/service/TypedBazaarTransactionHandler.java b/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/redis/service/BazaarTransactionHandler.java similarity index 93% rename from type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/redis/service/TypedBazaarTransactionHandler.java rename to type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/redis/service/BazaarTransactionHandler.java index 75d9a35d2..c6cd36ec8 100644 --- a/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/redis/service/TypedBazaarTransactionHandler.java +++ b/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/redis/service/BazaarTransactionHandler.java @@ -1,13 +1,13 @@ package net.swofty.type.skyblockgeneric.redis.service; -import net.swofty.commons.protocol.ServicePushProtocol; +import net.swofty.commons.protocol.RedisProtocol; import net.swofty.commons.protocol.objects.bazaar.BazaarTransactionPushProtocol; import net.swofty.commons.protocol.objects.bazaar.BazaarTransactionPushProtocol.Request; import net.swofty.commons.protocol.objects.bazaar.BazaarTransactionPushProtocol.Response; import net.swofty.commons.skyblock.bazaar.BazaarTransaction; import net.swofty.commons.skyblock.bazaar.OrderExpiredBazaarTransaction; import net.swofty.commons.skyblock.bazaar.SuccessfulBazaarTransaction; -import net.swofty.proxyapi.redis.TypedServiceHandler; +import net.swofty.commons.redis.RedisMessageHandler; import net.swofty.type.skyblockgeneric.SkyBlockGenericLoader; import net.swofty.type.skyblockgeneric.bazaar.BazaarAwarder; import net.swofty.type.skyblockgeneric.user.SkyBlockPlayer; @@ -15,18 +15,19 @@ import org.tinylog.Logger; import java.util.UUID; +import net.swofty.commons.redis.RedisMessageContext; -public class TypedBazaarTransactionHandler implements TypedServiceHandler { +public class BazaarTransactionHandler implements RedisMessageHandler { private static final BazaarTransactionPushProtocol PROTOCOL = new BazaarTransactionPushProtocol(); @Override - public ServicePushProtocol getProtocol() { + public RedisProtocol protocol() { return PROTOCOL; } @Override - public Response onMessage(Request message) { + public Response handle(Request message, RedisMessageContext context) { try { String transactionType = message.transactionType(); JSONObject data = new JSONObject(message.transactionJson()); diff --git a/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/redis/service/TypedDarkAuctionEventHandler.java b/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/redis/service/DarkAuctionEventHandler.java similarity index 89% rename from type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/redis/service/TypedDarkAuctionEventHandler.java rename to type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/redis/service/DarkAuctionEventHandler.java index 649745efb..62fd15b38 100644 --- a/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/redis/service/TypedDarkAuctionEventHandler.java +++ b/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/redis/service/DarkAuctionEventHandler.java @@ -1,29 +1,30 @@ package net.swofty.type.skyblockgeneric.redis.service; import net.swofty.commons.ServerType; -import net.swofty.commons.protocol.ServicePushProtocol; +import net.swofty.commons.protocol.RedisProtocol; import net.swofty.commons.protocol.objects.darkauction.DarkAuctionEventPushProtocol; import net.swofty.commons.protocol.objects.darkauction.DarkAuctionEventPushProtocol.Request; import net.swofty.commons.protocol.objects.darkauction.DarkAuctionEventPushProtocol.Response; import net.swofty.commons.protocol.objects.darkauction.DarkAuctionEventProtocol; -import net.swofty.proxyapi.redis.TypedServiceHandler; +import net.swofty.commons.redis.RedisMessageHandler; import net.swofty.type.generic.HypixelConst; import net.swofty.type.skyblockgeneric.darkauction.DarkAuctionHandler; import org.json.JSONArray; import org.json.JSONObject; import org.tinylog.Logger; +import net.swofty.commons.redis.RedisMessageContext; -public class TypedDarkAuctionEventHandler implements TypedServiceHandler { +public class DarkAuctionEventHandler implements RedisMessageHandler { private static final DarkAuctionEventPushProtocol PROTOCOL = new DarkAuctionEventPushProtocol(); @Override - public ServicePushProtocol getProtocol() { + public RedisProtocol protocol() { return PROTOCOL; } @Override - public Response onMessage(Request request) { + public Response handle(Request request, RedisMessageContext context) { if (HypixelConst.getTypeLoader().getType() != ServerType.SKYBLOCK_HUB) { return null; } diff --git a/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/redis/service/TypedGetPlayerDataHandler.java b/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/redis/service/GetPlayerDataHandler.java similarity index 80% rename from type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/redis/service/TypedGetPlayerDataHandler.java rename to type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/redis/service/GetPlayerDataHandler.java index bf28c31af..890a74874 100644 --- a/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/redis/service/TypedGetPlayerDataHandler.java +++ b/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/redis/service/GetPlayerDataHandler.java @@ -1,26 +1,27 @@ package net.swofty.type.skyblockgeneric.redis.service; -import net.swofty.commons.protocol.ServicePushProtocol; +import net.swofty.commons.protocol.RedisProtocol; import net.swofty.commons.protocol.objects.data.GetPlayerDataPushProtocol; import net.swofty.commons.protocol.objects.data.GetPlayerDataPushProtocol.Request; import net.swofty.commons.protocol.objects.data.GetPlayerDataPushProtocol.Response; -import net.swofty.proxyapi.redis.TypedServiceHandler; +import net.swofty.commons.redis.RedisMessageHandler; import net.swofty.type.skyblockgeneric.SkyBlockGenericLoader; import net.swofty.type.skyblockgeneric.data.SkyBlockDataHandler; import net.swofty.type.skyblockgeneric.data.SkyBlockDatapoint; import net.swofty.type.skyblockgeneric.user.SkyBlockPlayer; +import net.swofty.commons.redis.RedisMessageContext; -public class TypedGetPlayerDataHandler implements TypedServiceHandler { +public class GetPlayerDataHandler implements RedisMessageHandler { private static final GetPlayerDataPushProtocol PROTOCOL = new GetPlayerDataPushProtocol(); @Override - public ServicePushProtocol getProtocol() { + public RedisProtocol protocol() { return PROTOCOL; } @Override - public Response onMessage(Request message) { + public Response handle(Request message, RedisMessageContext context) { SkyBlockPlayer player = SkyBlockGenericLoader.getFromUUID(message.playerUUID()); if (player == null) { return Response.failure("Player not found on this server"); diff --git a/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/redis/service/TypedLockPlayerDataHandler.java b/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/redis/service/LockPlayerDataHandler.java similarity index 75% rename from type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/redis/service/TypedLockPlayerDataHandler.java rename to type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/redis/service/LockPlayerDataHandler.java index 50b266928..5f23265ba 100644 --- a/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/redis/service/TypedLockPlayerDataHandler.java +++ b/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/redis/service/LockPlayerDataHandler.java @@ -1,25 +1,26 @@ package net.swofty.type.skyblockgeneric.redis.service; -import net.swofty.commons.protocol.ServicePushProtocol; +import net.swofty.commons.protocol.RedisProtocol; import net.swofty.commons.protocol.objects.data.LockPlayerDataPushProtocol; import net.swofty.commons.protocol.objects.data.LockPlayerDataPushProtocol.Request; import net.swofty.commons.protocol.objects.data.LockPlayerDataPushProtocol.Response; -import net.swofty.proxyapi.redis.TypedServiceHandler; +import net.swofty.commons.redis.RedisMessageHandler; import net.swofty.type.skyblockgeneric.SkyBlockGenericLoader; import net.swofty.type.skyblockgeneric.redis.service.manager.ServerLockManager; import net.swofty.type.skyblockgeneric.user.SkyBlockPlayer; +import net.swofty.commons.redis.RedisMessageContext; -public class TypedLockPlayerDataHandler implements TypedServiceHandler { +public class LockPlayerDataHandler implements RedisMessageHandler { private static final LockPlayerDataPushProtocol PROTOCOL = new LockPlayerDataPushProtocol(); @Override - public ServicePushProtocol getProtocol() { + public RedisProtocol protocol() { return PROTOCOL; } @Override - public Response onMessage(Request message) { + public Response handle(Request message, RedisMessageContext context) { SkyBlockPlayer player = SkyBlockGenericLoader.getFromUUID(message.playerUUID()); if (player == null) { return Response.failure("Player not found on this server"); diff --git a/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/redis/service/TypedUnlockPlayerDataHandler.java b/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/redis/service/UnlockPlayerDataHandler.java similarity index 66% rename from type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/redis/service/TypedUnlockPlayerDataHandler.java rename to type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/redis/service/UnlockPlayerDataHandler.java index b60fc632c..2cbdaa3d4 100644 --- a/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/redis/service/TypedUnlockPlayerDataHandler.java +++ b/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/redis/service/UnlockPlayerDataHandler.java @@ -1,23 +1,24 @@ package net.swofty.type.skyblockgeneric.redis.service; -import net.swofty.commons.protocol.ServicePushProtocol; +import net.swofty.commons.protocol.RedisProtocol; import net.swofty.commons.protocol.objects.data.UnlockPlayerDataPushProtocol; import net.swofty.commons.protocol.objects.data.UnlockPlayerDataPushProtocol.Request; import net.swofty.commons.protocol.objects.data.UnlockPlayerDataPushProtocol.Response; -import net.swofty.proxyapi.redis.TypedServiceHandler; +import net.swofty.commons.redis.RedisMessageHandler; import net.swofty.type.skyblockgeneric.redis.service.manager.ServerLockManager; +import net.swofty.commons.redis.RedisMessageContext; -public class TypedUnlockPlayerDataHandler implements TypedServiceHandler { +public class UnlockPlayerDataHandler implements RedisMessageHandler { private static final UnlockPlayerDataPushProtocol PROTOCOL = new UnlockPlayerDataPushProtocol(); @Override - public ServicePushProtocol getProtocol() { + public RedisProtocol protocol() { return PROTOCOL; } @Override - public Response onMessage(Request message) { + public Response handle(Request message, RedisMessageContext context) { String lockKey = message.playerUUID() + ":" + message.dataKey(); ServerLockManager.releaseLock(lockKey); return Response.success(System.currentTimeMillis()); diff --git a/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/redis/service/TypedUpdatePlayerDataHandler.java b/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/redis/service/UpdatePlayerDataHandler.java similarity index 82% rename from type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/redis/service/TypedUpdatePlayerDataHandler.java rename to type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/redis/service/UpdatePlayerDataHandler.java index f9da00e09..1bdbcd852 100644 --- a/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/redis/service/TypedUpdatePlayerDataHandler.java +++ b/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/redis/service/UpdatePlayerDataHandler.java @@ -1,26 +1,27 @@ package net.swofty.type.skyblockgeneric.redis.service; -import net.swofty.commons.protocol.ServicePushProtocol; +import net.swofty.commons.protocol.RedisProtocol; import net.swofty.commons.protocol.objects.data.UpdatePlayerDataPushProtocol; import net.swofty.commons.protocol.objects.data.UpdatePlayerDataPushProtocol.Request; import net.swofty.commons.protocol.objects.data.UpdatePlayerDataPushProtocol.Response; -import net.swofty.proxyapi.redis.TypedServiceHandler; +import net.swofty.commons.redis.RedisMessageHandler; import net.swofty.type.generic.data.Datapoint; import net.swofty.type.generic.data.HypixelDataHandler; import net.swofty.type.skyblockgeneric.SkyBlockGenericLoader; import net.swofty.type.skyblockgeneric.user.SkyBlockPlayer; +import net.swofty.commons.redis.RedisMessageContext; -public class TypedUpdatePlayerDataHandler implements TypedServiceHandler { +public class UpdatePlayerDataHandler implements RedisMessageHandler { private static final UpdatePlayerDataPushProtocol PROTOCOL = new UpdatePlayerDataPushProtocol(); @Override - public ServicePushProtocol getProtocol() { + public RedisProtocol protocol() { return PROTOCOL; } @Override - public Response onMessage(Request message) { + public Response handle(Request message, RedisMessageContext context) { SkyBlockPlayer player = SkyBlockGenericLoader.getFromUUID(message.playerUUID()); if (player == null) { return Response.failure("Player not found on this server"); diff --git a/type.skywarsconfigurator/src/main/java/net/swofty/type/skywarsconfigurator/TypeSkyWarsConfiguratorLoader.java b/type.skywarsconfigurator/src/main/java/net/swofty/type/skywarsconfigurator/TypeSkyWarsConfiguratorLoader.java index eecd23562..fe9018e8d 100644 --- a/type.skywarsconfigurator/src/main/java/net/swofty/type/skywarsconfigurator/TypeSkyWarsConfiguratorLoader.java +++ b/type.skywarsconfigurator/src/main/java/net/swofty/type/skywarsconfigurator/TypeSkyWarsConfiguratorLoader.java @@ -10,7 +10,7 @@ import net.swofty.commons.CustomWorlds; import net.swofty.commons.ServerType; import net.swofty.commons.ServiceType; -import net.swofty.proxyapi.redis.TypedProxyHandler; +import net.swofty.commons.redis.RedisMessageHandler; import net.swofty.type.generic.HypixelGenericLoader; import net.swofty.type.generic.HypixelTypeLoader; import net.swofty.type.generic.command.HypixelCommand; @@ -116,7 +116,7 @@ public List getNPCs() { @Override - public List> getTypedProxyHandlers() { + public List> getProxyHandlers() { return List.of(); } diff --git a/type.skywarsgame/src/main/java/net/swofty/type/skywarsgame/TypeSkywarsGameLoader.java b/type.skywarsgame/src/main/java/net/swofty/type/skywarsgame/TypeSkywarsGameLoader.java index 43d3a6950..ccc0cb7ec 100644 --- a/type.skywarsgame/src/main/java/net/swofty/type/skywarsgame/TypeSkywarsGameLoader.java +++ b/type.skywarsgame/src/main/java/net/swofty/type/skywarsgame/TypeSkywarsGameLoader.java @@ -20,12 +20,11 @@ import net.swofty.commons.CustomWorlds; import net.swofty.commons.ServerType; import net.swofty.commons.ServiceType; -import net.swofty.commons.protocol.objects.orchestrator.GameHeartbeatProtocolObject; +import net.swofty.commons.protocol.objects.orchestrator.GameHeartbeatProtocol; import net.swofty.commons.skywars.SkywarsGameType; import net.swofty.commons.skywars.map.SkywarsMapsConfig; import net.swofty.proxyapi.ProxyService; -import net.swofty.proxyapi.redis.TypedProxyHandler; -import net.swofty.proxyapi.redis.TypedServiceHandler; +import net.swofty.commons.redis.RedisMessageHandler; import net.swofty.pvp.MinestomPvP; import net.swofty.type.generic.HypixelConst; import net.swofty.type.generic.HypixelGenericLoader; @@ -222,7 +221,7 @@ public void afterInitialize(MinecraftServer server) { commonsGames.add(commonsGame); } - var heartbeat = new GameHeartbeatProtocolObject.HeartbeatMessage( + var heartbeat = new GameHeartbeatProtocol.HeartbeatMessage( uuid, shortName, getType(), @@ -294,15 +293,15 @@ public List getNPCs() { @Override @SuppressWarnings("unchecked") - public List> getTypedServiceHandlers() { + public List> getServiceHandlers() { return (List) HypixelGenericLoader.loopThroughPackage( "net.swofty.type.skywarsgame.redis.service", - TypedServiceHandler.class + RedisMessageHandler.class ).toList(); } @Override - public List> getTypedProxyHandlers() { + public List> getProxyHandlers() { return List.of(); } diff --git a/type.skywarsgame/src/main/java/net/swofty/type/skywarsgame/events/ActionPlayerJoin.java b/type.skywarsgame/src/main/java/net/swofty/type/skywarsgame/events/ActionPlayerJoin.java index 505a0c134..00010ea34 100644 --- a/type.skywarsgame/src/main/java/net/swofty/type/skywarsgame/events/ActionPlayerJoin.java +++ b/type.skywarsgame/src/main/java/net/swofty/type/skywarsgame/events/ActionPlayerJoin.java @@ -8,7 +8,7 @@ import net.swofty.type.generic.event.HypixelEventClass; import net.swofty.type.generic.event.phase.EventPhase; import net.swofty.type.generic.event.phase.PhasedEvent; -import net.swofty.type.generic.redis.service.TypedGameInformationHandler; +import net.swofty.type.generic.redis.service.GameInformationHandler; import net.swofty.type.generic.utility.MathUtility; import net.swofty.type.skywarsgame.TypeSkywarsGameLoader; import net.swofty.type.skywarsgame.game.SkywarsGame; @@ -31,7 +31,7 @@ public void onJoin(AsyncPlayerConfigurationEvent event) { private void tryJoinGame(SkywarsPlayer player, boolean isRetry) { if (!player.isOnline()) return; - String assignedGameId = TypedGameInformationHandler.game.remove(player.getUuid()); + String assignedGameId = GameInformationHandler.game.remove(player.getUuid()); if (assignedGameId == null) { if (!isRetry) { Logger.info("No game assignment found for " + player.getUsername() + ", retrying in 1 second..."); diff --git a/type.skywarsgame/src/main/java/net/swofty/type/skywarsgame/item/impl/PlayAgainItem.java b/type.skywarsgame/src/main/java/net/swofty/type/skywarsgame/item/impl/PlayAgainItem.java index f30012396..cc80c4ce9 100644 --- a/type.skywarsgame/src/main/java/net/swofty/type/skywarsgame/item/impl/PlayAgainItem.java +++ b/type.skywarsgame/src/main/java/net/swofty/type/skywarsgame/item/impl/PlayAgainItem.java @@ -5,8 +5,8 @@ import net.minestom.server.item.Material; import net.swofty.commons.ServerType; import net.swofty.commons.ServiceType; -import net.swofty.commons.protocol.objects.orchestrator.ChooseGameProtocolObject; -import net.swofty.commons.protocol.objects.orchestrator.GetServerForMapProtocolObject; +import net.swofty.commons.protocol.objects.orchestrator.ChooseGameProtocol; +import net.swofty.commons.protocol.objects.orchestrator.GetServerForMapProtocol; import net.swofty.proxyapi.ProxyService; import net.swofty.type.skywarsgame.TypeSkywarsGameLoader; import net.swofty.type.skywarsgame.game.SkywarsGame; @@ -35,8 +35,8 @@ public void onItemUse(PlayerUseItemEvent event) { String gameType = game.getGameType().name(); game.leave(player); - GetServerForMapProtocolObject.GetServerForMapMessage message = - new GetServerForMapProtocolObject.GetServerForMapMessage( + GetServerForMapProtocol.GetServerForMapMessage message = + new GetServerForMapProtocol.GetServerForMapMessage( ServerType.SKYWARS_GAME, null, gameType, @@ -44,10 +44,10 @@ public void onItemUse(PlayerUseItemEvent event) { ); PROXY_SERVICE.handleRequest(message).thenAccept(response -> { - if (response instanceof GetServerForMapProtocolObject.GetServerForMapResponse resp) { + if (response instanceof GetServerForMapProtocol.GetServerForMapResponse resp) { if (resp.server() != null) { - ChooseGameProtocolObject.ChooseGameMessage chooseMessage = - new ChooseGameProtocolObject.ChooseGameMessage( + ChooseGameProtocol.ChooseGameMessage chooseMessage = + new ChooseGameProtocol.ChooseGameMessage( player.getUuid(), resp.server(), resp.gameId() diff --git a/type.skywarsgame/src/main/java/net/swofty/type/skywarsgame/redis/service/TypedInstantiateGameHandler.java b/type.skywarsgame/src/main/java/net/swofty/type/skywarsgame/redis/service/InstantiateGameHandler.java similarity index 88% rename from type.skywarsgame/src/main/java/net/swofty/type/skywarsgame/redis/service/TypedInstantiateGameHandler.java rename to type.skywarsgame/src/main/java/net/swofty/type/skywarsgame/redis/service/InstantiateGameHandler.java index 159c7d4a7..88a1ef8c5 100644 --- a/type.skywarsgame/src/main/java/net/swofty/type/skywarsgame/redis/service/TypedInstantiateGameHandler.java +++ b/type.skywarsgame/src/main/java/net/swofty/type/skywarsgame/redis/service/InstantiateGameHandler.java @@ -1,29 +1,30 @@ package net.swofty.type.skywarsgame.redis.service; -import net.swofty.commons.protocol.ServicePushProtocol; +import net.swofty.commons.protocol.RedisProtocol; import net.swofty.commons.protocol.objects.game.InstantiateGamePushProtocol; import net.swofty.commons.protocol.objects.game.InstantiateGamePushProtocol.Request; import net.swofty.commons.protocol.objects.game.InstantiateGamePushProtocol.Response; import net.swofty.commons.skywars.SkywarsGameType; import net.swofty.commons.skywars.map.SkywarsMapsConfig; -import net.swofty.proxyapi.redis.TypedServiceHandler; +import net.swofty.commons.redis.RedisMessageHandler; import net.swofty.type.skywarsgame.TypeSkywarsGameLoader; import net.swofty.type.skywarsgame.game.SkywarsGame; import java.util.List; import java.util.concurrent.ThreadLocalRandom; +import net.swofty.commons.redis.RedisMessageContext; -public class TypedInstantiateGameHandler implements TypedServiceHandler { +public class InstantiateGameHandler implements RedisMessageHandler { private static final InstantiateGamePushProtocol PROTOCOL = new InstantiateGamePushProtocol(); @Override - public ServicePushProtocol getProtocol() { + public RedisProtocol protocol() { return PROTOCOL; } @Override - public Response onMessage(Request request) { + public Response handle(Request request, RedisMessageContext context) { try { SkywarsGameType gameType = SkywarsGameType.from(request.gameType().toUpperCase()); if (gameType == null) { diff --git a/type.skywarslobby/src/main/java/net/swofty/type/skywarslobby/TypeSkyWarsLobbyLoader.java b/type.skywarslobby/src/main/java/net/swofty/type/skywarslobby/TypeSkyWarsLobbyLoader.java index 24141d03f..0a457f3ca 100644 --- a/type.skywarslobby/src/main/java/net/swofty/type/skywarslobby/TypeSkyWarsLobbyLoader.java +++ b/type.skywarslobby/src/main/java/net/swofty/type/skywarslobby/TypeSkyWarsLobbyLoader.java @@ -7,8 +7,7 @@ import net.swofty.commons.CustomWorlds; import net.swofty.commons.ServerType; import net.swofty.commons.ServiceType; -import net.swofty.proxyapi.redis.TypedProxyHandler; -import net.swofty.proxyapi.redis.TypedServiceHandler; +import net.swofty.commons.redis.RedisMessageHandler; import net.swofty.type.generic.HypixelConst; import net.swofty.type.generic.HypixelGenericLoader; import net.swofty.type.generic.command.HypixelCommand; @@ -199,15 +198,15 @@ public List getNPCs() { @Override @SuppressWarnings("unchecked") - public List> getTypedServiceHandlers() { + public List> getServiceHandlers() { return (List) HypixelGenericLoader.loopThroughPackage( "net.swofty.type.skywarslobby.redis.service", - TypedServiceHandler.class + RedisMessageHandler.class ).toList(); } @Override - public List> getTypedProxyHandlers() { + public List> getProxyHandlers() { return List.of(); } diff --git a/type.skywarslobby/src/main/java/net/swofty/type/skywarslobby/gui/GUIMapSelectionSkywars.java b/type.skywarslobby/src/main/java/net/swofty/type/skywarslobby/gui/GUIMapSelectionSkywars.java index 61a019e08..2af8bd477 100644 --- a/type.skywarslobby/src/main/java/net/swofty/type/skywarslobby/gui/GUIMapSelectionSkywars.java +++ b/type.skywarslobby/src/main/java/net/swofty/type/skywarslobby/gui/GUIMapSelectionSkywars.java @@ -6,7 +6,7 @@ import net.minestom.server.item.Material; import net.swofty.commons.ServerType; import net.swofty.commons.ServiceType; -import net.swofty.commons.protocol.objects.orchestrator.GetMapsProtocolObject; +import net.swofty.commons.protocol.objects.orchestrator.GetMapsProtocol; import net.swofty.commons.skywars.SkywarsGameType; import net.swofty.proxyapi.ProxyService; import net.swofty.type.generic.gui.inventory.HypixelInventoryGUI; @@ -61,12 +61,12 @@ public void run(InventoryPreClickEvent e, HypixelPlayer player) { private void loadMaps(HypixelPlayer player) { ProxyService orchestratorService = new ProxyService(ServiceType.ORCHESTRATOR); - GetMapsProtocolObject.GetMapsMessage message = - new GetMapsProtocolObject.GetMapsMessage(ServerType.SKYWARS_GAME, gameType.name()); + GetMapsProtocol.GetMapsMessage message = + new GetMapsProtocol.GetMapsMessage(ServerType.SKYWARS_GAME, gameType.name()); orchestratorService.handleRequest(message) .thenAccept(response -> { - if (response instanceof GetMapsProtocolObject.GetMapsResponse mapsResponse) { + if (response instanceof GetMapsProtocol.GetMapsResponse mapsResponse) { maps = mapsResponse.maps(); mapsLoaded = true; populateMaps(player); diff --git a/type.spidersden/src/main/java/net/swofty/type/spidersden/TypeSpidersDenLoader.java b/type.spidersden/src/main/java/net/swofty/type/spidersden/TypeSpidersDenLoader.java index de5042327..13a4e8c5d 100644 --- a/type.spidersden/src/main/java/net/swofty/type/spidersden/TypeSpidersDenLoader.java +++ b/type.spidersden/src/main/java/net/swofty/type/spidersden/TypeSpidersDenLoader.java @@ -5,7 +5,7 @@ import net.swofty.commons.CustomWorlds; import net.swofty.commons.ServerType; import net.swofty.commons.ServiceType; -import net.swofty.proxyapi.redis.TypedProxyHandler; +import net.swofty.commons.redis.RedisMessageHandler; import net.swofty.type.generic.SkyBlockTypeLoader; import net.swofty.type.generic.entity.npc.HypixelNPC; import net.swofty.type.generic.event.HypixelEventClass; @@ -87,7 +87,7 @@ public List getNPCs() { @Override - public List> getTypedProxyHandlers() { + public List> getProxyHandlers() { return List.of(); } diff --git a/type.theend/src/main/java/net/swofty/type/theend/TypeTheEndLoader.java b/type.theend/src/main/java/net/swofty/type/theend/TypeTheEndLoader.java index 99448ca3f..353a48845 100644 --- a/type.theend/src/main/java/net/swofty/type/theend/TypeTheEndLoader.java +++ b/type.theend/src/main/java/net/swofty/type/theend/TypeTheEndLoader.java @@ -8,7 +8,7 @@ import net.swofty.commons.CustomWorlds; import net.swofty.commons.ServerType; import net.swofty.commons.ServiceType; -import net.swofty.proxyapi.redis.TypedProxyHandler; +import net.swofty.commons.redis.RedisMessageHandler; import net.swofty.type.generic.SkyBlockTypeLoader; import net.swofty.type.generic.entity.npc.HypixelNPC; import net.swofty.type.generic.event.HypixelEventClass; @@ -98,7 +98,7 @@ public List getNPCs() { @Override - public List> getTypedProxyHandlers() { + public List> getProxyHandlers() { return List.of(); } diff --git a/type.thefarmingislands/src/main/java/net/swofty/type/thefarmingislands/TypeTheFarmingIslandsLoader.java b/type.thefarmingislands/src/main/java/net/swofty/type/thefarmingislands/TypeTheFarmingIslandsLoader.java index 9bb241c6d..ab782deba 100644 --- a/type.thefarmingislands/src/main/java/net/swofty/type/thefarmingislands/TypeTheFarmingIslandsLoader.java +++ b/type.thefarmingislands/src/main/java/net/swofty/type/thefarmingislands/TypeTheFarmingIslandsLoader.java @@ -5,7 +5,7 @@ import net.swofty.commons.CustomWorlds; import net.swofty.commons.ServerType; import net.swofty.commons.ServiceType; -import net.swofty.proxyapi.redis.TypedProxyHandler; +import net.swofty.commons.redis.RedisMessageHandler; import net.swofty.type.generic.SkyBlockTypeLoader; import net.swofty.type.generic.entity.npc.HypixelNPC; @@ -87,7 +87,7 @@ public List getNPCs() { @Override - public List> getTypedProxyHandlers() { + public List> getProxyHandlers() { return List.of(); } diff --git a/type.thepark/src/main/java/net/swofty/type/thepark/TypeTheParkLoader.java b/type.thepark/src/main/java/net/swofty/type/thepark/TypeTheParkLoader.java index 9c93591b6..afc21d45b 100644 --- a/type.thepark/src/main/java/net/swofty/type/thepark/TypeTheParkLoader.java +++ b/type.thepark/src/main/java/net/swofty/type/thepark/TypeTheParkLoader.java @@ -16,7 +16,7 @@ import net.swofty.commons.CustomWorlds; import net.swofty.commons.ServerType; import net.swofty.commons.ServiceType; -import net.swofty.proxyapi.redis.TypedProxyHandler; +import net.swofty.commons.redis.RedisMessageHandler; import net.swofty.type.generic.HypixelConst; import net.swofty.type.generic.SkyBlockTypeLoader; import net.swofty.type.generic.entity.BlockDisplayEntity; @@ -273,7 +273,7 @@ public List getNPCs() { @Override - public List> getTypedProxyHandlers() { + public List> getProxyHandlers() { return List.of(); } diff --git a/velocity.extension/src/main/java/net/swofty/velocity/SkyBlockVelocity.java b/velocity.extension/src/main/java/net/swofty/velocity/SkyBlockVelocity.java index 71db2586e..fdb20cabe 100644 --- a/velocity.extension/src/main/java/net/swofty/velocity/SkyBlockVelocity.java +++ b/velocity.extension/src/main/java/net/swofty/velocity/SkyBlockVelocity.java @@ -39,9 +39,9 @@ import net.swofty.commons.ServiceType; import net.swofty.commons.config.ConfigProvider; import net.swofty.commons.config.Settings; -import net.swofty.commons.protocol.ProtocolObject; +import net.swofty.commons.protocol.RedisProtocol; import net.swofty.commons.protocol.objects.proxy.from.*; -import net.swofty.commons.protocol.objects.punishment.GetActivePunishmentProtocolObject; +import net.swofty.commons.protocol.objects.punishment.GetActivePunishmentProtocol; import net.swofty.commons.punishment.ActivePunishment; import net.swofty.commons.punishment.PunishmentMessages; import net.swofty.commons.punishment.PunishmentReason; @@ -233,17 +233,17 @@ public void onProxyInitialization(ProxyInitializeEvent event) { listener.onMessage(event2.channel, event2.message); }); }); - ProtocolObject[] fromProxyProtocols = { + RedisProtocol[] fromProxyProtocols = { new TeleportProtocol(), new PlayerSwitchedProtocol(), new DoesServerHaveIslandProtocol(), new RefreshCoopDataProtocol(), new RunEventProtocol(), new PingServerProtocol(), new GivePlayersOriginTypeProtocol(), new BroadcastStaffChatProtocol() }; - for (ProtocolObject protocol : fromProxyProtocols) { + for (RedisProtocol protocol : fromProxyProtocols) { RedisMessage.registerProxyToServer(protocol); } - loopThroughPackage("net.swofty.commons.protocol.objects", ProtocolObject.class) - .forEach(ServerOutboundMessage::registerFromProtocolObject); + loopThroughPackage("net.swofty.commons.protocol.objects", RedisProtocol.class) + .forEach(ServerOutboundMessage::registerResponseProtocol); RedisAPI.getInstance().startListeners(); // Setup GameManager @@ -255,14 +255,14 @@ private boolean checkPunished(Player player) { ProxyService service = new ProxyService(ServiceType.PUNISHMENT); CompletableFuture banFuture = service.handleRequest( - new GetActivePunishmentProtocolObject.GetActivePunishmentMessage(player.getUniqueId(), PunishmentType.BAN.name())); + new GetActivePunishmentProtocol.GetActivePunishmentMessage(player.getUniqueId(), PunishmentType.BAN.name())); CompletableFuture muteFuture = service.handleRequest( - new GetActivePunishmentProtocolObject.GetActivePunishmentMessage(player.getUniqueId(), PunishmentType.MUTE.name())); + new GetActivePunishmentProtocol.GetActivePunishmentMessage(player.getUniqueId(), PunishmentType.MUTE.name())); CompletableFuture.allOf(banFuture, muteFuture).orTimeout(3, TimeUnit.SECONDS).join(); Object banResult = banFuture.join(); - if (banResult instanceof GetActivePunishmentProtocolObject.GetActivePunishmentResponse( + if (banResult instanceof GetActivePunishmentProtocol.GetActivePunishmentResponse( boolean found1, String type1, String id, PunishmentReason reason1, long at, List tags1, boolean success1, String error1 ) && found1) { @@ -273,7 +273,7 @@ private boolean checkPunished(Player player) { } Object muteResult = muteFuture.join(); - if (muteResult instanceof GetActivePunishmentProtocolObject.GetActivePunishmentResponse( + if (muteResult instanceof GetActivePunishmentProtocol.GetActivePunishmentResponse( boolean found, String type, String banId, PunishmentReason reason, long expiresAt, List tags, boolean success, String error ) && found) { diff --git a/velocity.extension/src/main/java/net/swofty/velocity/presence/PresencePublisher.java b/velocity.extension/src/main/java/net/swofty/velocity/presence/PresencePublisher.java index 6d8a8c9a3..a7a1a9691 100644 --- a/velocity.extension/src/main/java/net/swofty/velocity/presence/PresencePublisher.java +++ b/velocity.extension/src/main/java/net/swofty/velocity/presence/PresencePublisher.java @@ -3,7 +3,7 @@ import com.velocitypowered.api.proxy.Player; import com.velocitypowered.api.proxy.server.RegisteredServer; import net.swofty.commons.presence.PresenceInfo; -import net.swofty.commons.protocol.objects.presence.UpdatePresenceProtocolObject; +import net.swofty.commons.protocol.objects.presence.UpdatePresenceProtocol; import net.swofty.proxyapi.redis.ServerOutboundMessage; import java.util.UUID; @@ -22,8 +22,8 @@ public static void publish(Player player, boolean online, String serverType, UUI ); ServerOutboundMessage.sendMessageToAllServicesFireAndForget( - new UpdatePresenceProtocolObject(), - new UpdatePresenceProtocolObject.UpdatePresenceMessage(info) + new UpdatePresenceProtocol(), + new UpdatePresenceProtocol.UpdatePresenceMessage(info) ); } diff --git a/velocity.extension/src/main/java/net/swofty/velocity/redis/RedisListener.java b/velocity.extension/src/main/java/net/swofty/velocity/redis/RedisListener.java index 8eb50828e..998a32545 100644 --- a/velocity.extension/src/main/java/net/swofty/velocity/redis/RedisListener.java +++ b/velocity.extension/src/main/java/net/swofty/velocity/redis/RedisListener.java @@ -1,6 +1,7 @@ package net.swofty.velocity.redis; -import net.swofty.commons.protocol.ProtocolObject; +import net.swofty.commons.protocol.RedisProtocol; +import net.swofty.commons.redis.RedisChannels; import net.swofty.commons.redis.RedisEnvelope; import net.swofty.redisapi.api.ChannelRegistry; import net.swofty.redisapi.api.RedisAPI; @@ -9,17 +10,17 @@ import java.util.UUID; public abstract class RedisListener { - private final ProtocolObject protocol; + private final RedisProtocol protocol; public RedisListener() { - this.protocol = getProtocol(); + this.protocol = protocol(); } - public abstract ProtocolObject getProtocol(); + public abstract RedisProtocol protocol(); public abstract R receivedMessage(T message, UUID serverUUID); public String getChannelName() { - return protocol.channel(); + return RedisChannels.protocol(protocol); } public void onMessage(String channel, String message) { diff --git a/velocity.extension/src/main/java/net/swofty/velocity/redis/RedisMessage.java b/velocity.extension/src/main/java/net/swofty/velocity/redis/RedisMessage.java index b2e28910a..25449487a 100644 --- a/velocity.extension/src/main/java/net/swofty/velocity/redis/RedisMessage.java +++ b/velocity.extension/src/main/java/net/swofty/velocity/redis/RedisMessage.java @@ -1,6 +1,7 @@ package net.swofty.velocity.redis; -import net.swofty.commons.protocol.ProtocolObject; +import net.swofty.commons.protocol.RedisProtocol; +import net.swofty.commons.redis.RedisChannels; import net.swofty.commons.redis.RedisEnvelope; import net.swofty.redisapi.api.ChannelRegistry; import net.swofty.redisapi.api.RedisAPI; @@ -15,7 +16,7 @@ public class RedisMessage { private static final Map> callbacks = new HashMap<>(); public static CompletableFuture sendMessageToServer(UUID server, - ProtocolObject protocol, + RedisProtocol protocol, T message) { UUID requestID = UUID.randomUUID(); CompletableFuture rawFuture = new CompletableFuture<>(); @@ -25,14 +26,14 @@ public static CompletableFuture sendMessageToServer(UUID server, String serialized = protocol.translateToString(message); RedisAPI.getInstance().publishMessage( server.toString(), - ChannelRegistry.getFromName(protocol.channel()), + ChannelRegistry.getFromName(RedisChannels.protocol(protocol)), new RedisEnvelope(requestID.toString(), "proxy", serialized).serialize()); return rawFuture.thenApply(protocol::translateReturnFromString); } - public static void registerProxyToServer(ProtocolObject protocol) { - RedisAPI.getInstance().registerChannel(protocol.channel(), (event) -> { + public static void registerProxyToServer(RedisProtocol protocol) { + RedisAPI.getInstance().registerChannel(RedisChannels.protocol(protocol), (event) -> { String messageWithoutFilter = event.message.substring(event.message.indexOf(";") + 1); RedisEnvelope envelope = RedisEnvelope.deserialize(messageWithoutFilter); UUID request = UUID.fromString(envelope.id()); diff --git a/velocity.extension/src/main/java/net/swofty/velocity/redis/listeners/ListenerPlayerCount.java b/velocity.extension/src/main/java/net/swofty/velocity/redis/listeners/ListenerPlayerCount.java index 71dcdc996..0f167729f 100644 --- a/velocity.extension/src/main/java/net/swofty/velocity/redis/listeners/ListenerPlayerCount.java +++ b/velocity.extension/src/main/java/net/swofty/velocity/redis/listeners/ListenerPlayerCount.java @@ -1,7 +1,7 @@ package net.swofty.velocity.redis.listeners; import net.swofty.commons.ServerType; -import net.swofty.commons.protocol.ProtocolObject; +import net.swofty.commons.protocol.RedisProtocol; import net.swofty.commons.protocol.objects.proxy.to.PlayerCountProtocol; import net.swofty.velocity.gamemanager.GameManager; import net.swofty.velocity.redis.ChannelListener; @@ -16,7 +16,7 @@ public class ListenerPlayerCount extends RedisListener< PlayerCountProtocol.Response> { @Override - public ProtocolObject getProtocol() { + public RedisProtocol protocol() { return new PlayerCountProtocol(); } diff --git a/velocity.extension/src/main/java/net/swofty/velocity/redis/listeners/ListenerPlayerHandler.java b/velocity.extension/src/main/java/net/swofty/velocity/redis/listeners/ListenerPlayerHandler.java index 4d9c5fcaf..34a7c75fa 100644 --- a/velocity.extension/src/main/java/net/swofty/velocity/redis/listeners/ListenerPlayerHandler.java +++ b/velocity.extension/src/main/java/net/swofty/velocity/redis/listeners/ListenerPlayerHandler.java @@ -7,7 +7,7 @@ import net.swofty.commons.ServerType; import net.swofty.commons.StringUtility; import net.swofty.commons.UnderstandableProxyServer; -import net.swofty.commons.protocol.ProtocolObject; +import net.swofty.commons.protocol.RedisProtocol; import net.swofty.commons.protocol.objects.proxy.from.GivePlayersOriginTypeProtocol; import net.swofty.commons.protocol.objects.proxy.from.RefreshCoopDataProtocol; import net.swofty.commons.protocol.objects.proxy.from.RunEventProtocol; @@ -33,7 +33,7 @@ public class ListenerPlayerHandler extends RedisListener< private static final PlayerHandlerProtocol.Response EMPTY = new PlayerHandlerProtocol.Response(Map.of(), true, null); @Override - public ProtocolObject getProtocol() { + public RedisProtocol protocol() { return new PlayerHandlerProtocol(); } diff --git a/velocity.extension/src/main/java/net/swofty/velocity/redis/listeners/ListenerPlayerPunished.java b/velocity.extension/src/main/java/net/swofty/velocity/redis/listeners/ListenerPlayerPunished.java index 7a6dad533..a0be9d865 100644 --- a/velocity.extension/src/main/java/net/swofty/velocity/redis/listeners/ListenerPlayerPunished.java +++ b/velocity.extension/src/main/java/net/swofty/velocity/redis/listeners/ListenerPlayerPunished.java @@ -3,7 +3,7 @@ import com.google.gson.Gson; import io.sentry.Sentry; import net.kyori.adventure.text.Component; -import net.swofty.commons.protocol.ProtocolObject; +import net.swofty.commons.protocol.RedisProtocol; import net.swofty.commons.protocol.objects.proxy.to.PunishPlayerProtocol; import net.swofty.commons.punishment.PunishmentReason; import net.swofty.commons.punishment.PunishmentTag; @@ -26,7 +26,7 @@ public class ListenerPlayerPunished extends RedisListener< PunishPlayerProtocol.Response> { @Override - public ProtocolObject getProtocol() { + public RedisProtocol protocol() { return new PunishPlayerProtocol(); } diff --git a/velocity.extension/src/main/java/net/swofty/velocity/redis/listeners/ListenerProxyOnline.java b/velocity.extension/src/main/java/net/swofty/velocity/redis/listeners/ListenerProxyOnline.java index 319f20892..80916ccaa 100644 --- a/velocity.extension/src/main/java/net/swofty/velocity/redis/listeners/ListenerProxyOnline.java +++ b/velocity.extension/src/main/java/net/swofty/velocity/redis/listeners/ListenerProxyOnline.java @@ -1,6 +1,6 @@ package net.swofty.velocity.redis.listeners; -import net.swofty.commons.protocol.ProtocolObject; +import net.swofty.commons.protocol.RedisProtocol; import net.swofty.commons.protocol.objects.proxy.to.ProxyIsOnlineProtocol; import net.swofty.velocity.gamemanager.GameManager; import net.swofty.velocity.redis.ChannelListener; @@ -14,7 +14,7 @@ public class ListenerProxyOnline extends RedisListener< ProxyIsOnlineProtocol.Response> { @Override - public ProtocolObject getProtocol() { + public RedisProtocol protocol() { return new ProxyIsOnlineProtocol(); } diff --git a/velocity.extension/src/main/java/net/swofty/velocity/redis/listeners/ListenerRegisterTestFlow.java b/velocity.extension/src/main/java/net/swofty/velocity/redis/listeners/ListenerRegisterTestFlow.java index e14e5f244..bcd98c208 100644 --- a/velocity.extension/src/main/java/net/swofty/velocity/redis/listeners/ListenerRegisterTestFlow.java +++ b/velocity.extension/src/main/java/net/swofty/velocity/redis/listeners/ListenerRegisterTestFlow.java @@ -1,6 +1,6 @@ package net.swofty.velocity.redis.listeners; -import net.swofty.commons.protocol.ProtocolObject; +import net.swofty.commons.protocol.RedisProtocol; import net.swofty.commons.protocol.objects.proxy.to.RegisterTestFlowProtocol; import net.swofty.velocity.redis.ChannelListener; import net.swofty.velocity.redis.RedisListener; @@ -19,7 +19,7 @@ public class ListenerRegisterTestFlow extends RedisListener< RegisterTestFlowProtocol.Response> { @Override - public ProtocolObject getProtocol() { + public RedisProtocol protocol() { return new RegisterTestFlowProtocol(); } diff --git a/velocity.extension/src/main/java/net/swofty/velocity/redis/listeners/ListenerServerFinishedWithPlayer.java b/velocity.extension/src/main/java/net/swofty/velocity/redis/listeners/ListenerServerFinishedWithPlayer.java index fbd03e942..156d4fef9 100644 --- a/velocity.extension/src/main/java/net/swofty/velocity/redis/listeners/ListenerServerFinishedWithPlayer.java +++ b/velocity.extension/src/main/java/net/swofty/velocity/redis/listeners/ListenerServerFinishedWithPlayer.java @@ -1,7 +1,7 @@ package net.swofty.velocity.redis.listeners; import com.velocitypowered.api.proxy.Player; -import net.swofty.commons.protocol.ProtocolObject; +import net.swofty.commons.protocol.RedisProtocol; import net.swofty.commons.protocol.objects.proxy.to.FinishedWithPlayerProtocol; import net.swofty.velocity.SkyBlockVelocity; import net.swofty.velocity.gamemanager.TransferHandler; @@ -17,7 +17,7 @@ public class ListenerServerFinishedWithPlayer extends RedisListener< FinishedWithPlayerProtocol.Response> { @Override - public ProtocolObject getProtocol() { + public RedisProtocol protocol() { return new FinishedWithPlayerProtocol(); } diff --git a/velocity.extension/src/main/java/net/swofty/velocity/redis/listeners/ListenerServerInitialized.java b/velocity.extension/src/main/java/net/swofty/velocity/redis/listeners/ListenerServerInitialized.java index 12950bce2..d40de4dc7 100644 --- a/velocity.extension/src/main/java/net/swofty/velocity/redis/listeners/ListenerServerInitialized.java +++ b/velocity.extension/src/main/java/net/swofty/velocity/redis/listeners/ListenerServerInitialized.java @@ -2,7 +2,7 @@ import net.swofty.commons.ServerType; import net.swofty.commons.config.ConfigProvider; -import net.swofty.commons.protocol.ProtocolObject; +import net.swofty.commons.protocol.RedisProtocol; import net.swofty.commons.protocol.objects.proxy.to.RegisterServerProtocol; import net.swofty.velocity.gamemanager.GameManager; import net.swofty.velocity.redis.ChannelListener; @@ -16,7 +16,7 @@ public class ListenerServerInitialized extends RedisListener< RegisterServerProtocol.Response> { @Override - public ProtocolObject getProtocol() { + public RedisProtocol protocol() { return new RegisterServerProtocol(); } diff --git a/velocity.extension/src/main/java/net/swofty/velocity/redis/listeners/ListenerServerName.java b/velocity.extension/src/main/java/net/swofty/velocity/redis/listeners/ListenerServerName.java index 1a9afbdbf..378bf726a 100644 --- a/velocity.extension/src/main/java/net/swofty/velocity/redis/listeners/ListenerServerName.java +++ b/velocity.extension/src/main/java/net/swofty/velocity/redis/listeners/ListenerServerName.java @@ -1,6 +1,6 @@ package net.swofty.velocity.redis.listeners; -import net.swofty.commons.protocol.ProtocolObject; +import net.swofty.commons.protocol.RedisProtocol; import net.swofty.commons.protocol.objects.proxy.to.RequestServerNameProtocol; import net.swofty.velocity.gamemanager.GameManager; import net.swofty.velocity.redis.ChannelListener; @@ -14,7 +14,7 @@ public class ListenerServerName extends RedisListener< RequestServerNameProtocol.Response> { @Override - public ProtocolObject getProtocol() { + public RedisProtocol protocol() { return new RequestServerNameProtocol(); } diff --git a/velocity.extension/src/main/java/net/swofty/velocity/redis/listeners/ListenerServersInformation.java b/velocity.extension/src/main/java/net/swofty/velocity/redis/listeners/ListenerServersInformation.java index ffd3323bb..23625a665 100644 --- a/velocity.extension/src/main/java/net/swofty/velocity/redis/listeners/ListenerServersInformation.java +++ b/velocity.extension/src/main/java/net/swofty/velocity/redis/listeners/ListenerServersInformation.java @@ -3,7 +3,7 @@ import com.velocitypowered.api.proxy.Player; import net.swofty.commons.ServerType; import net.swofty.commons.UnderstandableProxyServer; -import net.swofty.commons.protocol.ProtocolObject; +import net.swofty.commons.protocol.RedisProtocol; import net.swofty.commons.protocol.objects.proxy.to.RequestServersProtocol; import net.swofty.velocity.SkyBlockVelocity; import net.swofty.velocity.gamemanager.GameManager; @@ -19,7 +19,7 @@ public class ListenerServersInformation extends RedisListener< RequestServersProtocol.Response> { @Override - public ProtocolObject getProtocol() { + public RedisProtocol protocol() { return new RequestServersProtocol(); } diff --git a/velocity.extension/src/main/java/net/swofty/velocity/redis/listeners/ListenerStaffChat.java b/velocity.extension/src/main/java/net/swofty/velocity/redis/listeners/ListenerStaffChat.java index 4f66465e5..30063d4b3 100644 --- a/velocity.extension/src/main/java/net/swofty/velocity/redis/listeners/ListenerStaffChat.java +++ b/velocity.extension/src/main/java/net/swofty/velocity/redis/listeners/ListenerStaffChat.java @@ -1,6 +1,6 @@ package net.swofty.velocity.redis.listeners; -import net.swofty.commons.protocol.ProtocolObject; +import net.swofty.commons.protocol.RedisProtocol; import net.swofty.commons.protocol.objects.proxy.from.BroadcastStaffChatProtocol; import net.swofty.commons.protocol.objects.proxy.to.StaffChatProtocol; import net.swofty.velocity.gamemanager.GameManager; @@ -16,7 +16,7 @@ public class ListenerStaffChat extends RedisListener< StaffChatProtocol.Response> { @Override - public ProtocolObject getProtocol() { + public RedisProtocol protocol() { return new StaffChatProtocol(); } diff --git a/velocity.extension/src/main/java/net/swofty/velocity/redis/listeners/ListenerTestFlowServerReady.java b/velocity.extension/src/main/java/net/swofty/velocity/redis/listeners/ListenerTestFlowServerReady.java index 8f6f86ab8..57f5130ed 100644 --- a/velocity.extension/src/main/java/net/swofty/velocity/redis/listeners/ListenerTestFlowServerReady.java +++ b/velocity.extension/src/main/java/net/swofty/velocity/redis/listeners/ListenerTestFlowServerReady.java @@ -1,7 +1,7 @@ package net.swofty.velocity.redis.listeners; import net.swofty.commons.ServerType; -import net.swofty.commons.protocol.ProtocolObject; +import net.swofty.commons.protocol.RedisProtocol; import net.swofty.commons.protocol.objects.proxy.to.TestFlowServerReadyProtocol; import net.swofty.velocity.redis.ChannelListener; import net.swofty.velocity.redis.RedisListener; @@ -16,7 +16,7 @@ public class ListenerTestFlowServerReady extends RedisListener< TestFlowServerReadyProtocol.Response> { @Override - public ProtocolObject getProtocol() { + public RedisProtocol protocol() { return new TestFlowServerReadyProtocol(); } From 7123fdfffa46d06b0af46537dda387c13d63cb1b Mon Sep 17 00:00:00 2001 From: "Jacob Nardella (Swofty)" Date: Fri, 15 May 2026 11:40:59 +1000 Subject: [PATCH 103/113] chore(redis): remove protocol test --- .../commons/protocol/RedisProtocolTest.java | 44 ------------------- 1 file changed, 44 deletions(-) delete mode 100644 commons/src/test/java/net/swofty/commons/protocol/RedisProtocolTest.java diff --git a/commons/src/test/java/net/swofty/commons/protocol/RedisProtocolTest.java b/commons/src/test/java/net/swofty/commons/protocol/RedisProtocolTest.java deleted file mode 100644 index 42a908815..000000000 --- a/commons/src/test/java/net/swofty/commons/protocol/RedisProtocolTest.java +++ /dev/null @@ -1,44 +0,0 @@ -package net.swofty.commons.protocol; - -import org.junit.jupiter.api.Test; -import java.util.UUID; -import static org.junit.jupiter.api.Assertions.*; - -class RedisProtocolTest { - - public record TestPushRequest(UUID playerId, String item, int amount) {} - public record TestPushResponse(boolean handled) {} - - static class TestPush extends RedisProtocol { - public TestPush() { - super(TestPushRequest.class, TestPushResponse.class); - } - } - - @Test - void channelNameDerivedFromClassName() { - var protocol = new TestPush(); - assertEquals("TestPush", protocol.channel()); - } - - @Test - void serializesRequestRoundTrip() { - var protocol = new TestPush(); - UUID id = UUID.randomUUID(); - var original = new TestPushRequest(id, "diamond", 5); - String json = protocol.translateToString(original); - TestPushRequest result = protocol.translateFromString(json); - assertEquals(id, result.playerId()); - assertEquals("diamond", result.item()); - assertEquals(5, result.amount()); - } - - @Test - void serializesResponseRoundTrip() { - var protocol = new TestPush(); - var original = new TestPushResponse(true); - String json = protocol.translateReturnToString(original); - TestPushResponse result = protocol.translateReturnFromString(json); - assertTrue(result.handled()); - } -} From 3b84ea2d1dedb10fc0c644019a6e17ccc248734b Mon Sep 17 00:00:00 2001 From: "Jacob Nardella (Swofty)" Date: Fri, 15 May 2026 11:45:25 +1000 Subject: [PATCH 104/113] refactor(proxy): use shared redis message handlers --- .../net/swofty/velocity/SkyBlockVelocity.java | 14 ++--- .../velocity/redis/ChannelListener.java | 8 --- .../velocity/redis/RedisHandlerRegistry.java | 51 +++++++++++++++++++ .../swofty/velocity/redis/RedisListener.java | 51 ------------------- .../redis/listeners/ListenerPlayerCount.java | 9 ++-- .../listeners/ListenerPlayerHandler.java | 9 ++-- .../listeners/ListenerPlayerPunished.java | 9 ++-- .../redis/listeners/ListenerProxyOnline.java | 11 ++-- .../listeners/ListenerRegisterTestFlow.java | 13 +++-- .../ListenerServerFinishedWithPlayer.java | 9 ++-- .../listeners/ListenerServerInitialized.java | 11 ++-- .../redis/listeners/ListenerServerName.java | 11 ++-- .../listeners/ListenerServersInformation.java | 11 ++-- .../redis/listeners/ListenerStaffChat.java | 9 ++-- .../ListenerTestFlowServerReady.java | 15 +++--- 15 files changed, 108 insertions(+), 133 deletions(-) delete mode 100644 velocity.extension/src/main/java/net/swofty/velocity/redis/ChannelListener.java create mode 100644 velocity.extension/src/main/java/net/swofty/velocity/redis/RedisHandlerRegistry.java delete mode 100644 velocity.extension/src/main/java/net/swofty/velocity/redis/RedisListener.java diff --git a/velocity.extension/src/main/java/net/swofty/velocity/SkyBlockVelocity.java b/velocity.extension/src/main/java/net/swofty/velocity/SkyBlockVelocity.java index fdb20cabe..8fec5db02 100644 --- a/velocity.extension/src/main/java/net/swofty/velocity/SkyBlockVelocity.java +++ b/velocity.extension/src/main/java/net/swofty/velocity/SkyBlockVelocity.java @@ -42,6 +42,7 @@ import net.swofty.commons.protocol.RedisProtocol; import net.swofty.commons.protocol.objects.proxy.from.*; import net.swofty.commons.protocol.objects.punishment.GetActivePunishmentProtocol; +import net.swofty.commons.redis.RedisMessageHandler; import net.swofty.commons.punishment.ActivePunishment; import net.swofty.commons.punishment.PunishmentMessages; import net.swofty.commons.punishment.PunishmentReason; @@ -66,8 +67,7 @@ import net.swofty.velocity.gamemanager.TransferHandler; import net.swofty.velocity.packet.PlayerChannelHandler; import net.swofty.velocity.presence.PresencePublisher; -import net.swofty.velocity.redis.ChannelListener; -import net.swofty.velocity.redis.RedisListener; +import net.swofty.velocity.redis.RedisHandlerRegistry; import net.swofty.velocity.redis.RedisMessage; import net.swofty.velocity.redis.listeners.ListenerStaffChat; import net.swofty.velocity.testflow.TestFlowManager; @@ -225,14 +225,8 @@ public void onProxyInitialization(ProxyInitializeEvent event) { // Setup Redis RedisAPI.generateInstance(ConfigProvider.settings().getRedisUri()); RedisAPI.getInstance().setFilterId("proxy"); - loopThroughPackage("net.swofty.velocity.redis.listeners", RedisListener.class) - .forEach(listener -> { - RedisAPI.getInstance().registerChannel( - listener.getChannelName(), - (event2) -> { - listener.onMessage(event2.channel, event2.message); - }); - }); + loopThroughPackage("net.swofty.velocity.redis.listeners", RedisMessageHandler.class) + .forEach(RedisHandlerRegistry::register); RedisProtocol[] fromProxyProtocols = { new TeleportProtocol(), new PlayerSwitchedProtocol(), new DoesServerHaveIslandProtocol(), new RefreshCoopDataProtocol(), diff --git a/velocity.extension/src/main/java/net/swofty/velocity/redis/ChannelListener.java b/velocity.extension/src/main/java/net/swofty/velocity/redis/ChannelListener.java deleted file mode 100644 index c58fa472d..000000000 --- a/velocity.extension/src/main/java/net/swofty/velocity/redis/ChannelListener.java +++ /dev/null @@ -1,8 +0,0 @@ -package net.swofty.velocity.redis; - -import java.lang.annotation.Retention; -import java.lang.annotation.RetentionPolicy; - -@Retention(RetentionPolicy.RUNTIME) -public @interface ChannelListener { -} diff --git a/velocity.extension/src/main/java/net/swofty/velocity/redis/RedisHandlerRegistry.java b/velocity.extension/src/main/java/net/swofty/velocity/redis/RedisHandlerRegistry.java new file mode 100644 index 000000000..bd25a0e87 --- /dev/null +++ b/velocity.extension/src/main/java/net/swofty/velocity/redis/RedisHandlerRegistry.java @@ -0,0 +1,51 @@ +package net.swofty.velocity.redis; + +import net.swofty.commons.protocol.RedisProtocol; +import net.swofty.commons.redis.RedisChannels; +import net.swofty.commons.redis.RedisEndpoint; +import net.swofty.commons.redis.RedisEnvelope; +import net.swofty.commons.redis.RedisMessageContext; +import net.swofty.commons.redis.RedisMessageHandler; +import net.swofty.redisapi.api.ChannelRegistry; +import net.swofty.redisapi.api.RedisAPI; +import org.tinylog.Logger; + +import java.util.UUID; + +public final class RedisHandlerRegistry { + private RedisHandlerRegistry() { + } + + public static void register(RedisMessageHandler handler) { + RedisProtocol protocol = handler.protocol(); + + RedisAPI.getInstance().registerChannel(RedisChannels.protocol(protocol), event -> { + String messageWithoutFilter = event.message.substring(event.message.indexOf(";") + 1); + RedisEnvelope envelope = RedisEnvelope.deserialize(messageWithoutFilter); + RedisMessageContext context = RedisMessageContext.proxyToServer( + UUID.fromString(envelope.id()), + envelope.from(), + RedisEndpoint.proxy().id(), + protocol.channel() + ); + + T message = protocol.translateFromString(envelope.payload()); + + Thread.startVirtualThread(() -> { + R response; + try { + response = handler.handle(message, context); + } catch (Exception e) { + Logger.error(e, "Error on channel {} with message {}", event.channel, envelope.payload()); + return; + } + + String serializedResponse = protocol.translateReturnToString(response); + RedisAPI.getInstance().publishMessage( + envelope.from(), + ChannelRegistry.getFromName(event.channel), + new RedisEnvelope(envelope.id(), RedisEndpoint.proxy().id(), serializedResponse).serialize()); + }); + }); + } +} diff --git a/velocity.extension/src/main/java/net/swofty/velocity/redis/RedisListener.java b/velocity.extension/src/main/java/net/swofty/velocity/redis/RedisListener.java deleted file mode 100644 index 998a32545..000000000 --- a/velocity.extension/src/main/java/net/swofty/velocity/redis/RedisListener.java +++ /dev/null @@ -1,51 +0,0 @@ -package net.swofty.velocity.redis; - -import net.swofty.commons.protocol.RedisProtocol; -import net.swofty.commons.redis.RedisChannels; -import net.swofty.commons.redis.RedisEnvelope; -import net.swofty.redisapi.api.ChannelRegistry; -import net.swofty.redisapi.api.RedisAPI; -import org.tinylog.Logger; - -import java.util.UUID; - -public abstract class RedisListener { - private final RedisProtocol protocol; - - public RedisListener() { - this.protocol = protocol(); - } - - public abstract RedisProtocol protocol(); - public abstract R receivedMessage(T message, UUID serverUUID); - - public String getChannelName() { - return RedisChannels.protocol(protocol); - } - - public void onMessage(String channel, String message) { - String messageWithoutFilter = message.substring(message.indexOf(";") + 1); - RedisEnvelope envelope = RedisEnvelope.deserialize(messageWithoutFilter); - UUID uuid = UUID.fromString(envelope.id()); - UUID filterID = UUID.fromString(envelope.from()); - - T typedMessage = protocol.translateFromString(envelope.payload()); - - Thread.startVirtualThread(() -> { - R response; - try { - response = receivedMessage(typedMessage, filterID); - } catch (Exception e) { - Logger.error(e, "Error on channel {} with message {}", channel, envelope.payload()); - return; - } - - String serializedResponse = protocol.translateReturnToString(response); - - RedisAPI.getInstance().publishMessage( - filterID.toString(), - ChannelRegistry.getFromName(channel), - new RedisEnvelope(envelope.id(), "proxy", serializedResponse).serialize()); - }); - } -} diff --git a/velocity.extension/src/main/java/net/swofty/velocity/redis/listeners/ListenerPlayerCount.java b/velocity.extension/src/main/java/net/swofty/velocity/redis/listeners/ListenerPlayerCount.java index 0f167729f..a27bab6ab 100644 --- a/velocity.extension/src/main/java/net/swofty/velocity/redis/listeners/ListenerPlayerCount.java +++ b/velocity.extension/src/main/java/net/swofty/velocity/redis/listeners/ListenerPlayerCount.java @@ -4,14 +4,13 @@ import net.swofty.commons.protocol.RedisProtocol; import net.swofty.commons.protocol.objects.proxy.to.PlayerCountProtocol; import net.swofty.velocity.gamemanager.GameManager; -import net.swofty.velocity.redis.ChannelListener; -import net.swofty.velocity.redis.RedisListener; +import net.swofty.commons.redis.RedisMessageContext; +import net.swofty.commons.redis.RedisMessageHandler; import java.util.List; import java.util.UUID; -@ChannelListener -public class ListenerPlayerCount extends RedisListener< +public class ListenerPlayerCount implements RedisMessageHandler< PlayerCountProtocol.Request, PlayerCountProtocol.Response> { @@ -21,7 +20,7 @@ public RedisProtocol } @Override - public PlayerCountProtocol.Response receivedMessage(PlayerCountProtocol.Request message, UUID serverUUID) { + public PlayerCountProtocol.Response handle(PlayerCountProtocol.Request message, RedisMessageContext context) { switch (message.lookupType()) { case ALL -> { int count = GameManager.getServers().values().stream() diff --git a/velocity.extension/src/main/java/net/swofty/velocity/redis/listeners/ListenerPlayerHandler.java b/velocity.extension/src/main/java/net/swofty/velocity/redis/listeners/ListenerPlayerHandler.java index 34a7c75fa..4473791a8 100644 --- a/velocity.extension/src/main/java/net/swofty/velocity/redis/listeners/ListenerPlayerHandler.java +++ b/velocity.extension/src/main/java/net/swofty/velocity/redis/listeners/ListenerPlayerHandler.java @@ -17,16 +17,15 @@ import net.swofty.velocity.gamemanager.GameManager; import net.swofty.velocity.gamemanager.TransferHandler; import net.swofty.velocity.presence.PresencePublisher; -import net.swofty.velocity.redis.ChannelListener; -import net.swofty.velocity.redis.RedisListener; +import net.swofty.commons.redis.RedisMessageContext; +import net.swofty.commons.redis.RedisMessageHandler; import net.swofty.velocity.redis.RedisMessage; import java.util.Map; import java.util.Optional; import java.util.UUID; -@ChannelListener -public class ListenerPlayerHandler extends RedisListener< +public class ListenerPlayerHandler implements RedisMessageHandler< PlayerHandlerProtocol.Request, PlayerHandlerProtocol.Response> { @@ -38,7 +37,7 @@ public RedisProtocol data = message.data() != null ? message.data() : Map.of(); diff --git a/velocity.extension/src/main/java/net/swofty/velocity/redis/listeners/ListenerPlayerPunished.java b/velocity.extension/src/main/java/net/swofty/velocity/redis/listeners/ListenerPlayerPunished.java index a0be9d865..1049648ee 100644 --- a/velocity.extension/src/main/java/net/swofty/velocity/redis/listeners/ListenerPlayerPunished.java +++ b/velocity.extension/src/main/java/net/swofty/velocity/redis/listeners/ListenerPlayerPunished.java @@ -13,15 +13,14 @@ import net.swofty.commons.punishment.template.BanType; import net.swofty.commons.punishment.template.MuteType; import net.swofty.velocity.SkyBlockVelocity; -import net.swofty.velocity.redis.ChannelListener; -import net.swofty.velocity.redis.RedisListener; +import net.swofty.commons.redis.RedisMessageContext; +import net.swofty.commons.redis.RedisMessageHandler; import org.tinylog.Logger; import java.util.List; import java.util.UUID; -@ChannelListener -public class ListenerPlayerPunished extends RedisListener< +public class ListenerPlayerPunished implements RedisMessageHandler< PunishPlayerProtocol.Request, PunishPlayerProtocol.Response> { @@ -31,7 +30,7 @@ public RedisProtocol { @@ -19,8 +18,8 @@ public RedisProtocol { @@ -24,7 +23,7 @@ public RedisProtocol { @@ -22,7 +21,7 @@ public RedisProtocol potentialPlayer = SkyBlockVelocity.getServer().getPlayer(playerUUID); diff --git a/velocity.extension/src/main/java/net/swofty/velocity/redis/listeners/ListenerServerInitialized.java b/velocity.extension/src/main/java/net/swofty/velocity/redis/listeners/ListenerServerInitialized.java index d40de4dc7..e4c94c06c 100644 --- a/velocity.extension/src/main/java/net/swofty/velocity/redis/listeners/ListenerServerInitialized.java +++ b/velocity.extension/src/main/java/net/swofty/velocity/redis/listeners/ListenerServerInitialized.java @@ -5,13 +5,12 @@ import net.swofty.commons.protocol.RedisProtocol; import net.swofty.commons.protocol.objects.proxy.to.RegisterServerProtocol; import net.swofty.velocity.gamemanager.GameManager; -import net.swofty.velocity.redis.ChannelListener; -import net.swofty.velocity.redis.RedisListener; +import net.swofty.commons.redis.RedisMessageContext; +import net.swofty.commons.redis.RedisMessageHandler; import java.util.UUID; -@ChannelListener -public class ListenerServerInitialized extends RedisListener< +public class ListenerServerInitialized implements RedisMessageHandler< RegisterServerProtocol.Request, RegisterServerProtocol.Response> { @@ -21,7 +20,7 @@ public RedisProtocol { @@ -19,8 +18,8 @@ public RedisProtocol { @@ -24,9 +23,9 @@ public RedisProtocol { diff --git a/velocity.extension/src/main/java/net/swofty/velocity/redis/listeners/ListenerStaffChat.java b/velocity.extension/src/main/java/net/swofty/velocity/redis/listeners/ListenerStaffChat.java index 30063d4b3..f8dd93bbe 100644 --- a/velocity.extension/src/main/java/net/swofty/velocity/redis/listeners/ListenerStaffChat.java +++ b/velocity.extension/src/main/java/net/swofty/velocity/redis/listeners/ListenerStaffChat.java @@ -4,14 +4,13 @@ import net.swofty.commons.protocol.objects.proxy.from.BroadcastStaffChatProtocol; import net.swofty.commons.protocol.objects.proxy.to.StaffChatProtocol; import net.swofty.velocity.gamemanager.GameManager; -import net.swofty.velocity.redis.ChannelListener; -import net.swofty.velocity.redis.RedisListener; +import net.swofty.commons.redis.RedisMessageContext; +import net.swofty.commons.redis.RedisMessageHandler; import net.swofty.velocity.redis.RedisMessage; import java.util.UUID; -@ChannelListener -public class ListenerStaffChat extends RedisListener< +public class ListenerStaffChat implements RedisMessageHandler< StaffChatProtocol.Request, StaffChatProtocol.Response> { @@ -21,7 +20,7 @@ public RedisProtocol prot } @Override - public StaffChatProtocol.Response receivedMessage(StaffChatProtocol.Request message, UUID serverUUID) { + public StaffChatProtocol.Response handle(StaffChatProtocol.Request message, RedisMessageContext context) { broadcastToAllServers(new BroadcastStaffChatProtocol.Request( message.type(), message.formattedMessage(), message.uuid())); return new StaffChatProtocol.Response(); diff --git a/velocity.extension/src/main/java/net/swofty/velocity/redis/listeners/ListenerTestFlowServerReady.java b/velocity.extension/src/main/java/net/swofty/velocity/redis/listeners/ListenerTestFlowServerReady.java index 57f5130ed..e9cf5abef 100644 --- a/velocity.extension/src/main/java/net/swofty/velocity/redis/listeners/ListenerTestFlowServerReady.java +++ b/velocity.extension/src/main/java/net/swofty/velocity/redis/listeners/ListenerTestFlowServerReady.java @@ -3,15 +3,14 @@ import net.swofty.commons.ServerType; import net.swofty.commons.protocol.RedisProtocol; import net.swofty.commons.protocol.objects.proxy.to.TestFlowServerReadyProtocol; -import net.swofty.velocity.redis.ChannelListener; -import net.swofty.velocity.redis.RedisListener; +import net.swofty.commons.redis.RedisMessageContext; +import net.swofty.commons.redis.RedisMessageHandler; import net.swofty.velocity.testflow.TestFlowManager; import org.tinylog.Logger; import java.util.UUID; -@ChannelListener -public class ListenerTestFlowServerReady extends RedisListener< +public class ListenerTestFlowServerReady implements RedisMessageHandler< TestFlowServerReadyProtocol.Request, TestFlowServerReadyProtocol.Response> { @@ -21,21 +20,21 @@ public RedisProtocol Date: Fri, 15 May 2026 11:51:49 +1000 Subject: [PATCH 105/113] refactor(redis): centralize message bus plumbing --- commons/build.gradle.kts | 1 + .../commons/punishment/PunishmentRedis.java | 21 +- .../commons/redis/RedisConnectionPool.java | 36 +++ .../swofty/commons/redis/RedisMessageBus.java | 213 ++++++++++++++++++ .../commons/redis/RedisMessageContext.java | 7 + .../java/net/swofty/proxyapi/ProxyAPI.java | 109 ++++----- .../proxyapi/redis/ServerOutboundMessage.java | 98 +++----- .../service/generic/ServiceInitializer.java | 39 ++-- .../generic/redis/BroadcastRequest.java | 30 --- .../generic/redis/ServiceToServerManager.java | 128 ++--------- .../swofty/service/punishment/ProxyRedis.java | 76 ------- .../service/punishment/PunishmentService.java | 3 +- .../endpoints/PunishPlayerEndpoint.java | 15 +- .../leaderboard/LeaderboardService.java | 22 +- .../velocity/redis/RedisHandlerRegistry.java | 46 ++-- .../swofty/velocity/redis/RedisMessage.java | 43 +--- 16 files changed, 405 insertions(+), 482 deletions(-) create mode 100644 commons/src/main/java/net/swofty/commons/redis/RedisConnectionPool.java create mode 100644 commons/src/main/java/net/swofty/commons/redis/RedisMessageBus.java delete mode 100644 service.generic/src/main/java/net/swofty/service/generic/redis/BroadcastRequest.java delete mode 100644 service.punishment/src/main/java/net/swofty/service/punishment/ProxyRedis.java diff --git a/commons/build.gradle.kts b/commons/build.gradle.kts index 828815d35..5dc94206e 100644 --- a/commons/build.gradle.kts +++ b/commons/build.gradle.kts @@ -28,6 +28,7 @@ dependencies { // Must match AtlasRedisAPI's Jedis version to avoid conflicts implementation(libs.jedis) + implementation(libs.atlas.redis) implementation(libs.configlib.yaml) diff --git a/commons/src/main/java/net/swofty/commons/punishment/PunishmentRedis.java b/commons/src/main/java/net/swofty/commons/punishment/PunishmentRedis.java index c1d1e8faf..d4e5f8746 100644 --- a/commons/src/main/java/net/swofty/commons/punishment/PunishmentRedis.java +++ b/commons/src/main/java/net/swofty/commons/punishment/PunishmentRedis.java @@ -1,13 +1,11 @@ package net.swofty.commons.punishment; import com.google.gson.Gson; +import net.swofty.commons.redis.RedisConnectionPool; import org.tinylog.Logger; import redis.clients.jedis.Jedis; import redis.clients.jedis.JedisPool; -import redis.clients.jedis.JedisPoolConfig; -import java.net.URI; -import java.time.Duration; import java.util.ArrayList; import java.util.HashMap; import java.util.List; @@ -31,22 +29,7 @@ private static synchronized void connectSync(String redisUri) { connecting = true; try { - JedisPoolConfig poolConfig = new JedisPoolConfig(); - poolConfig.setMaxTotal(20); - poolConfig.setMaxIdle(5); - poolConfig.setMinIdle(1); - poolConfig.setMaxWait(Duration.ofSeconds(2)); - poolConfig.setTestOnBorrow(true); - poolConfig.setTestWhileIdle(true); - poolConfig.setBlockWhenExhausted(false); - - URI uri = URI.create(redisUri); - jedisPool = new JedisPool(poolConfig, uri); - - try (Jedis jedis = jedisPool.getResource()) { - jedis.ping(); - } - + jedisPool = RedisConnectionPool.connect(redisUri, RedisConnectionPool.Settings.standard()); initialized = true; Logger.info("PunishmentService: connected to Redis"); } catch (Exception e) { diff --git a/commons/src/main/java/net/swofty/commons/redis/RedisConnectionPool.java b/commons/src/main/java/net/swofty/commons/redis/RedisConnectionPool.java new file mode 100644 index 000000000..553c89b64 --- /dev/null +++ b/commons/src/main/java/net/swofty/commons/redis/RedisConnectionPool.java @@ -0,0 +1,36 @@ +package net.swofty.commons.redis; + +import redis.clients.jedis.Jedis; +import redis.clients.jedis.JedisPool; +import redis.clients.jedis.JedisPoolConfig; + +import java.net.URI; +import java.time.Duration; + +public final class RedisConnectionPool { + private RedisConnectionPool() { + } + + public static JedisPool connect(String redisUri, Settings settings) { + JedisPoolConfig poolConfig = new JedisPoolConfig(); + poolConfig.setMaxTotal(settings.maxTotal()); + poolConfig.setMaxIdle(settings.maxIdle()); + poolConfig.setMinIdle(settings.minIdle()); + poolConfig.setMaxWait(settings.maxWait()); + poolConfig.setTestOnBorrow(true); + poolConfig.setTestWhileIdle(true); + poolConfig.setBlockWhenExhausted(false); + + JedisPool pool = new JedisPool(poolConfig, URI.create(redisUri)); + try (Jedis jedis = pool.getResource()) { + jedis.ping(); + } + return pool; + } + + public record Settings(int maxTotal, int maxIdle, int minIdle, Duration maxWait) { + public static Settings standard() { + return new Settings(20, 5, 1, Duration.ofSeconds(2)); + } + } +} diff --git a/commons/src/main/java/net/swofty/commons/redis/RedisMessageBus.java b/commons/src/main/java/net/swofty/commons/redis/RedisMessageBus.java new file mode 100644 index 000000000..eeb9a8cbd --- /dev/null +++ b/commons/src/main/java/net/swofty/commons/redis/RedisMessageBus.java @@ -0,0 +1,213 @@ +package net.swofty.commons.redis; + +import net.swofty.commons.protocol.RedisProtocol; +import net.swofty.redisapi.api.ChannelRegistry; +import net.swofty.redisapi.api.RedisAPI; +import org.tinylog.Logger; + +import java.util.List; +import java.util.Map; +import java.util.UUID; +import java.util.concurrent.CompletableFuture; +import java.util.concurrent.ConcurrentHashMap; +import java.util.concurrent.CopyOnWriteArrayList; +import java.util.concurrent.Executors; +import java.util.concurrent.ScheduledExecutorService; +import java.util.concurrent.TimeUnit; +import java.util.function.Function; + +public final class RedisMessageBus { + private static final Map>> handlers = new ConcurrentHashMap<>(); + private static final Map> pendingResponses = new ConcurrentHashMap<>(); + private static final Map pendingBroadcasts = new ConcurrentHashMap<>(); + private static final Map registeredChannels = new ConcurrentHashMap<>(); + private static final ScheduledExecutorService scheduler = Executors.newSingleThreadScheduledExecutor(r -> { + Thread thread = new Thread(r, "redis-message-bus-timeouts"); + thread.setDaemon(true); + return thread; + }); + + private RedisMessageBus() { + } + + public static void registerHandler(RedisEndpoint localEndpoint, + String channel, + RedisMessageHandler handler, + ContextFactory contextFactory, + Function responseTarget, + Function responseChannel) { + handlers.computeIfAbsent(channel, ignored -> new CopyOnWriteArrayList<>()) + .add(new RegisteredHandler<>(localEndpoint, handler, contextFactory, responseTarget, responseChannel)); + ensureChannelRegistered(channel); + } + + public static void registerResponseChannel(String channel) { + ensureChannelRegistered(channel); + } + + public static CompletableFuture request(RedisEndpoint origin, + String target, + String requestChannel, + String responseChannel, + RedisProtocol protocol, + T message) { + return requestRaw(origin, target, requestChannel, responseChannel, protocol, message) + .thenApply(protocol::translateReturnFromString); + } + + public static CompletableFuture requestRaw(RedisEndpoint origin, + String target, + String requestChannel, + String responseChannel, + RedisProtocol protocol, + Object message) { + UUID requestId = UUID.randomUUID(); + CompletableFuture future = new CompletableFuture<>(); + + ensureChannelRegistered(responseChannel); + pendingResponses.put(requestId, future); + future.orTimeout(10, TimeUnit.SECONDS) + .whenComplete((ignored, throwable) -> pendingResponses.remove(requestId)); + + publishRaw(requestId, origin, target, requestChannel, protocol.translateToString(message)); + return future; + } + + public static void publish(RedisEndpoint origin, + String target, + String channel, + RedisProtocol protocol, + Object message) { + publishRaw(UUID.randomUUID(), origin, target, channel, protocol.translateToString(message)); + } + + public static CompletableFuture> requestBroadcast(RedisEndpoint origin, + String target, + String requestChannel, + String responseChannel, + RedisProtocol protocol, + T message, + int timeoutMs) { + UUID requestId = UUID.randomUUID(); + BroadcastCollector collector = new BroadcastCollector(); + pendingBroadcasts.put(requestId, collector); + ensureChannelRegistered(responseChannel); + + publishRaw(requestId, origin, target, requestChannel, protocol.translateToString(message)); + + scheduler.schedule(() -> { + BroadcastCollector removed = pendingBroadcasts.remove(requestId); + if (removed != null) { + removed.complete(); + } + }, timeoutMs, TimeUnit.MILLISECONDS); + + return collector.future().thenApply(rawResponses -> { + Map typedResponses = new ConcurrentHashMap<>(); + rawResponses.forEach((uuid, payload) -> { + try { + typedResponses.put(uuid, protocol.translateReturnFromString(payload)); + } catch (Exception exception) { + Logger.error(exception, "Failed to deserialize Redis broadcast response from {}", uuid); + } + }); + return typedResponses; + }); + } + + public static void publishRaw(UUID requestId, + RedisEndpoint origin, + String target, + String channel, + String payload) { + RedisAPI.getInstance().publishMessage( + target, + ChannelRegistry.getFromName(channel), + new RedisEnvelope(requestId.toString(), origin.id(), payload).serialize() + ); + } + + private static void ensureChannelRegistered(String channel) { + if (registeredChannels.putIfAbsent(channel, true) != null) return; + + RedisAPI.getInstance().registerChannel(channel, event -> { + RedisEnvelope envelope = unwrap(event.message); + UUID requestId = UUID.fromString(envelope.id()); + + CompletableFuture pendingResponse = pendingResponses.remove(requestId); + if (pendingResponse != null) { + pendingResponse.complete(envelope.payload()); + return; + } + + BroadcastCollector collector = pendingBroadcasts.get(requestId); + if (collector != null) { + collector.add(UUID.fromString(envelope.from()), envelope.payload()); + return; + } + + List> channelHandlers = handlers.get(event.channel); + if (channelHandlers == null) return; + + channelHandlers.forEach(handler -> Thread.startVirtualThread(() -> handler.handle(envelope, event.channel))); + }); + } + + private static RedisEnvelope unwrap(String message) { + int split = message.indexOf(";"); + return RedisEnvelope.deserialize(split == -1 ? message : message.substring(split + 1)); + } + + @FunctionalInterface + public interface ContextFactory { + RedisMessageContext create(RedisEnvelope envelope, String channel); + } + + private record RegisteredHandler( + RedisEndpoint localEndpoint, + RedisMessageHandler handler, + ContextFactory contextFactory, + Function responseTarget, + Function responseChannel + ) { + private void handle(RedisEnvelope envelope, String channel) { + RedisProtocol protocol = handler.protocol(); + + try { + T message = protocol.translateFromString(envelope.payload()); + RedisMessageContext context = contextFactory.create(envelope, channel); + R response = handler.handle(message, context); + if (response == null) return; + + publishRaw( + UUID.fromString(envelope.id()), + localEndpoint, + responseTarget.apply(envelope), + responseChannel.apply(envelope), + protocol.translateReturnToString(response) + ); + } catch (Exception exception) { + Logger.error(exception, "Failed to handle Redis message on channel {}", channel); + } + } + } + + private static final class BroadcastCollector { + private final CompletableFuture> future = new CompletableFuture<>(); + private final Map responses = new ConcurrentHashMap<>(); + + private void add(UUID endpoint, String payload) { + if (!future.isDone()) { + responses.put(endpoint, payload); + } + } + + private void complete() { + future.complete(Map.copyOf(responses)); + } + + private CompletableFuture> future() { + return future; + } + } +} diff --git a/commons/src/main/java/net/swofty/commons/redis/RedisMessageContext.java b/commons/src/main/java/net/swofty/commons/redis/RedisMessageContext.java index 603c7579e..031e09be1 100644 --- a/commons/src/main/java/net/swofty/commons/redis/RedisMessageContext.java +++ b/commons/src/main/java/net/swofty/commons/redis/RedisMessageContext.java @@ -9,6 +9,13 @@ public record RedisMessageContext( String channel, boolean broadcast ) { + public static RedisMessageContext between(UUID requestId, + RedisEndpoint origin, + RedisEndpoint destination, + String channel) { + return new RedisMessageContext(requestId, origin, destination, channel, false); + } + public static RedisMessageContext proxyToServer(UUID requestId, String proxyId, String serverId, String channel) { return new RedisMessageContext( requestId, diff --git a/proxy.api/src/main/java/net/swofty/proxyapi/ProxyAPI.java b/proxy.api/src/main/java/net/swofty/proxyapi/ProxyAPI.java index 1920f6c74..79e0aeb07 100644 --- a/proxy.api/src/main/java/net/swofty/proxyapi/ProxyAPI.java +++ b/proxy.api/src/main/java/net/swofty/proxyapi/ProxyAPI.java @@ -2,10 +2,10 @@ import net.swofty.commons.protocol.RedisProtocol; import net.swofty.commons.redis.RedisChannels; -import net.swofty.commons.redis.RedisEnvelope; +import net.swofty.commons.redis.RedisEndpoint; +import net.swofty.commons.redis.RedisMessageBus; import net.swofty.commons.redis.RedisMessageContext; import net.swofty.commons.redis.RedisMessageHandler; -import net.swofty.redisapi.api.ChannelRegistry; import net.swofty.redisapi.api.RedisAPI; import java.util.UUID; @@ -23,84 +23,51 @@ public ProxyAPI(String URI, UUID serverUUID) { public void registerProxyHandler(RedisMessageHandler handler) { RedisProtocol protocol = handler.protocol(); - RedisAPI.getInstance().registerChannel(RedisChannels.protocol(protocol), (event) -> { - String messageWithoutFilter = event.message.substring(event.message.indexOf(";") + 1); - RedisEnvelope envelope = RedisEnvelope.deserialize(messageWithoutFilter); - String rawMessage = envelope.payload(); - - T typedMessage = protocol.translateFromString(rawMessage); - RedisMessageContext context = RedisMessageContext.proxyToServer( - UUID.fromString(envelope.id()), - envelope.from(), - serverUUID.toString(), - protocol.channel() - ); - R response = handler.handle(typedMessage, context); - - String serializedResponse = protocol.translateReturnToString(response); - - RedisAPI.getInstance().publishMessage( - RedisChannels.PROXY_RESPONSE, - ChannelRegistry.getFromName(RedisChannels.protocol(protocol)), - new RedisEnvelope(envelope.id(), serverUUID.toString(), serializedResponse).serialize()); - }); + RedisMessageBus.registerHandler( + RedisEndpoint.server(serverUUID), + RedisChannels.protocol(protocol), + handler, + (envelope, channel) -> RedisMessageContext.between( + UUID.fromString(envelope.id()), + RedisEndpoint.proxy(), + RedisEndpoint.server(serverUUID), + protocol.channel() + ), + envelope -> RedisChannels.PROXY_RESPONSE, + envelope -> RedisChannels.protocol(protocol) + ); } public void registerServiceHandler(RedisMessageHandler handler) { RedisProtocol protocol = handler.protocol(); - String channelName = RedisChannels.serviceRequest(protocol); - - RedisAPI.getInstance().registerChannel(channelName, (event) -> { - String messageWithoutFilter = event.message.substring(event.message.indexOf(";") + 1); - RedisEnvelope envelope = RedisEnvelope.deserialize(messageWithoutFilter); - String serviceId = envelope.from(); - String rawMessage = envelope.payload(); - Thread.startVirtualThread(() -> { - T typedMessage = protocol.translateFromString(rawMessage); - RedisMessageContext context = RedisMessageContext.serviceToServer( + RedisMessageBus.registerHandler( + RedisEndpoint.server(serverUUID), + RedisChannels.serviceRequest(protocol), + handler, + (envelope, channel) -> RedisMessageContext.between( UUID.fromString(envelope.id()), - serviceId, - serverUUID.toString(), + RedisEndpoint.service(envelope.from()), + RedisEndpoint.server(serverUUID), protocol.channel() - ); - R response = handler.handle(typedMessage, context); - - String serializedResponse = protocol.translateReturnToString(response); - - RedisAPI.getInstance().publishMessage( - serviceId, - ChannelRegistry.getFromName(RedisChannels.SERVICE_RESPONSE), - new RedisEnvelope(envelope.id(), serverUUID.toString(), serializedResponse).serialize()); - }); - }); - - RedisAPI.getInstance().registerChannel(RedisChannels.serviceBroadcast(protocol), (event) -> { - String messageWithoutFilter = event.message.substring(event.message.indexOf(";") + 1); - RedisEnvelope envelope = RedisEnvelope.deserialize(messageWithoutFilter); - String serviceId = envelope.from(); - String rawMessage = envelope.payload(); - - Thread.startVirtualThread(() -> { - T typedMessage = protocol.translateFromString(rawMessage); - RedisMessageContext context = RedisMessageContext.serviceToServer( + ), + envelope -> envelope.from(), + envelope -> RedisChannels.SERVICE_RESPONSE + ); + + RedisMessageBus.registerHandler( + RedisEndpoint.server(serverUUID), + RedisChannels.serviceBroadcast(protocol), + handler, + (envelope, channel) -> RedisMessageContext.between( UUID.fromString(envelope.id()), - serviceId, - serverUUID.toString(), + RedisEndpoint.service(envelope.from()), + RedisEndpoint.server(serverUUID), protocol.channel() - ).asBroadcast(); - R response = handler.handle(typedMessage, context); - - if (response == null) return; - - String serializedResponse = protocol.translateReturnToString(response); - - RedisAPI.getInstance().publishMessage( - serviceId, - ChannelRegistry.getFromName(RedisChannels.SERVICE_BROADCAST_RESPONSE), - new RedisEnvelope(envelope.id(), serverUUID.toString(), serializedResponse).serialize()); - }); - }); + ).asBroadcast(), + envelope -> envelope.from(), + envelope -> RedisChannels.SERVICE_BROADCAST_RESPONSE + ); } public void start() { diff --git a/proxy.api/src/main/java/net/swofty/proxyapi/redis/ServerOutboundMessage.java b/proxy.api/src/main/java/net/swofty/proxyapi/redis/ServerOutboundMessage.java index 05b847ecf..3a099f44f 100644 --- a/proxy.api/src/main/java/net/swofty/proxyapi/redis/ServerOutboundMessage.java +++ b/proxy.api/src/main/java/net/swofty/proxyapi/redis/ServerOutboundMessage.java @@ -3,8 +3,8 @@ import net.swofty.commons.ServiceType; import net.swofty.commons.protocol.RedisProtocol; import net.swofty.commons.redis.RedisChannels; -import net.swofty.commons.redis.RedisEnvelope; -import net.swofty.redisapi.api.ChannelRegistry; +import net.swofty.commons.redis.RedisEndpoint; +import net.swofty.commons.redis.RedisMessageBus; import net.swofty.redisapi.api.RedisAPI; import org.tinylog.Logger; @@ -12,93 +12,59 @@ import java.lang.reflect.Type; import java.util.HashMap; import java.util.Map; -import java.util.UUID; import java.util.function.Consumer; public class ServerOutboundMessage { - private static final Map> redisMessageListeners = new HashMap<>(); public static final Map protocols = new HashMap<>(); public static void sendToProxy(RedisProtocol protocol, T request, Consumer response) { - UUID uuid = UUID.randomUUID(); - UUID filterID = UUID.fromString(RedisAPI.getInstance().getFilterId()); - - Consumer consumer = (s) -> { - R typed = protocol.translateReturnFromString(s); - response.accept(typed); - }; - redisMessageListeners.put(uuid, consumer); - - String serialized = protocol.translateToString(request); - RedisAPI.getInstance().publishMessage(RedisChannels.PROXY_RESPONSE, - ChannelRegistry.getFromName(RedisChannels.protocol(protocol)), - new RedisEnvelope(uuid.toString(), filterID.toString(), serialized).serialize()); + RedisMessageBus.request( + localEndpoint(), + RedisChannels.PROXY_RESPONSE, + RedisChannels.protocol(protocol), + RedisChannels.protocol(protocol), + protocol, + request + ).thenAccept(response); } public static void registerToProxyProtocol(RedisProtocol protocol) { - RedisAPI.getInstance().registerChannel(RedisChannels.protocol(protocol), (event) -> { - String messageWithoutFilter = event.message.substring(event.message.indexOf(";") + 1); - - RedisEnvelope envelope = RedisEnvelope.deserialize(messageWithoutFilter); - UUID uuid = UUID.fromString(envelope.id()); - - redisMessageListeners.get(uuid).accept(envelope.payload()); - redisMessageListeners.remove(uuid); - }); + RedisMessageBus.registerResponseChannel(RedisChannels.protocol(protocol)); } public static void registerResponseProtocol(RedisProtocol protocol) { String requestTypeName = getRequestTypeName(protocol); protocols.put(requestTypeName, protocol); - RedisAPI.getInstance().registerChannel(RedisChannels.protocol(protocol), (event) -> { - String messageWithoutFilter = event.message.substring(event.message.indexOf(";") + 1); - - RedisEnvelope envelope = RedisEnvelope.deserialize(messageWithoutFilter); - UUID uuid = UUID.fromString(envelope.id()); - String message = envelope.payload(); - - try { - redisMessageListeners.get(uuid).accept(message); - redisMessageListeners.remove(uuid); - } catch (Exception e) { - Logger.error("Failed to handle message from " + uuid + ": " + e.getMessage()); - } - }); + RedisMessageBus.registerResponseChannel(RedisChannels.protocol(protocol)); } public static void sendMessageToService(ServiceType service, RedisProtocol specification, Object rawMessage, Consumer response) { - UUID requestId = UUID.randomUUID(); - String callbackId = RedisAPI.getInstance().getFilterId(); - if (callbackId == null) return; - - redisMessageListeners.put(requestId, response); - - String message = specification.translateToString(rawMessage); - - RedisAPI.getInstance().publishMessage(service.name(), - ChannelRegistry.getFromName(specification.channel()), - new RedisEnvelope(requestId.toString(), callbackId, message).serialize()); + RedisMessageBus.requestRaw( + localEndpoint(), + service.name(), + specification.channel(), + specification.channel(), + specification, + rawMessage + ).thenAccept(response).exceptionally(throwable -> { + Logger.error(throwable, "Failed to receive response from service {}", service.name()); + return null; + }); } public static void sendMessageToServiceFireAndForget(ServiceType service, RedisProtocol specification, Object rawMessage) { - UUID requestId = UUID.randomUUID(); - String callback = null; - try { - callback = RedisAPI.getInstance().getFilterId(); - } catch (Exception ignored) { - } - - String message = specification.translateToString(rawMessage); - RedisAPI.getInstance().publishMessage( + RedisMessageBus.publish( + localEndpoint(), service.name(), - ChannelRegistry.getFromName(specification.channel()), - new RedisEnvelope(requestId.toString(), callback != null ? callback : "proxy", message).serialize() + specification.channel(), + specification, + rawMessage ); } @@ -127,4 +93,12 @@ private static String getRequestTypeName(RedisProtocol protocolObject) { throw new IllegalArgumentException("Could not determine the type T for the given RedisProtocol"); } + + private static RedisEndpoint localEndpoint() { + String filterId = RedisAPI.getInstance().getFilterId(); + if (RedisEndpoint.proxy().id().equals(filterId)) { + return RedisEndpoint.proxy(); + } + return RedisEndpoint.server(filterId); + } } diff --git a/service.generic/src/main/java/net/swofty/service/generic/ServiceInitializer.java b/service.generic/src/main/java/net/swofty/service/generic/ServiceInitializer.java index 6677af125..d8992a57a 100644 --- a/service.generic/src/main/java/net/swofty/service/generic/ServiceInitializer.java +++ b/service.generic/src/main/java/net/swofty/service/generic/ServiceInitializer.java @@ -4,11 +4,11 @@ import net.swofty.commons.config.ConfigProvider; import net.swofty.commons.protocol.RedisProtocol; import net.swofty.commons.redis.RedisChannels; -import net.swofty.commons.redis.RedisEnvelope; +import net.swofty.commons.redis.RedisEndpoint; +import net.swofty.commons.redis.RedisMessageBus; import net.swofty.commons.redis.RedisMessageContext; import net.swofty.commons.redis.RedisMessageHandler; import net.swofty.commons.skyblock.item.attribute.ItemAttribute; -import net.swofty.redisapi.api.ChannelRegistry; import net.swofty.redisapi.api.RedisAPI; import net.swofty.service.generic.redis.PingEndpoint; import net.swofty.service.generic.redis.ServiceRedisManager; @@ -28,11 +28,7 @@ public void init() { Logger.info("Initializing service {}...", service.getType().name()); ItemAttribute.registerItemAttributes(); - /** - * Register Redis - */ ServiceRedisManager.connect(ConfigProvider.settings().getRedisUri(), service.getType()); - // Initialize service-to-server communication ServiceToServerManager.initialize(service.getType()); List endpoints = new ArrayList<>(service.getEndpoints()); @@ -42,28 +38,19 @@ public void init() { RedisProtocol protocolObject = endpoint.protocol(); Logger.debug("Registering channel {}", protocolObject.channel()); - RedisAPI.getInstance().registerChannel(RedisChannels.protocol(protocolObject), message -> { - // Everything after the first semicolon is the actual message - String realMessage = message.message.substring(message.message.indexOf(";") + 1); - RedisEnvelope envelope = RedisEnvelope.deserialize(realMessage); - - Object messageData = protocolObject.translateFromString(envelope.payload()); - - Thread.startVirtualThread(() -> { - RedisMessageContext context = RedisMessageContext.serverToService( + RedisMessageBus.registerHandler( + RedisEndpoint.service(service.getType()), + RedisChannels.protocol(protocolObject), + endpoint, + (envelope, channel) -> RedisMessageContext.between( UUID.fromString(envelope.id()), - envelope.from(), - service.getType().name(), + RedisEndpoint.server(envelope.from()), + RedisEndpoint.service(service.getType()), protocolObject.channel() - ); - Object rawResponse = endpoint.handle(messageData, context); - String response = protocolObject.translateReturnToString(rawResponse); - - RedisAPI.getInstance().publishMessage(envelope.from(), - ChannelRegistry.getFromName(protocolObject.channel()), - new RedisEnvelope(envelope.id(), service.getType().name(), response).serialize()).join(); - }); - }); + ), + envelope -> envelope.from(), + envelope -> RedisChannels.protocol(protocolObject) + ); }); RedisAPI.getInstance().startListeners(); diff --git a/service.generic/src/main/java/net/swofty/service/generic/redis/BroadcastRequest.java b/service.generic/src/main/java/net/swofty/service/generic/redis/BroadcastRequest.java deleted file mode 100644 index cc687fdee..000000000 --- a/service.generic/src/main/java/net/swofty/service/generic/redis/BroadcastRequest.java +++ /dev/null @@ -1,30 +0,0 @@ -package net.swofty.service.generic.redis; - -import lombok.Getter; -import org.json.JSONObject; - -import java.util.Map; -import java.util.UUID; -import java.util.concurrent.CompletableFuture; -import java.util.concurrent.ConcurrentHashMap; - -public class BroadcastRequest { - @Getter - private final CompletableFuture> future; - private final Map responses; - - public BroadcastRequest(CompletableFuture> future) { - this.future = future; - this.responses = new ConcurrentHashMap<>(); - } - - public synchronized void addResponse(UUID serverUUID, JSONObject response) { - if (!future.isDone()) { - responses.put(serverUUID, response); - } - } - - public Map getResponses() { - return new ConcurrentHashMap<>(responses); - } -} \ No newline at end of file diff --git a/service.generic/src/main/java/net/swofty/service/generic/redis/ServiceToServerManager.java b/service.generic/src/main/java/net/swofty/service/generic/redis/ServiceToServerManager.java index 5d326e6ca..35eed1f97 100644 --- a/service.generic/src/main/java/net/swofty/service/generic/redis/ServiceToServerManager.java +++ b/service.generic/src/main/java/net/swofty/service/generic/redis/ServiceToServerManager.java @@ -3,63 +3,28 @@ import net.swofty.commons.ServiceType; import net.swofty.commons.protocol.RedisProtocol; import net.swofty.commons.redis.RedisChannels; -import net.swofty.commons.redis.RedisEnvelope; +import net.swofty.commons.redis.RedisEndpoint; +import net.swofty.commons.redis.RedisMessageBus; import net.swofty.commons.protocol.objects.data.GetPlayerDataPushProtocol; import net.swofty.commons.protocol.objects.data.LockPlayerDataPushProtocol; import net.swofty.commons.protocol.objects.data.UnlockPlayerDataPushProtocol; import net.swofty.commons.protocol.objects.data.UpdatePlayerDataPushProtocol; import net.swofty.commons.protocol.objects.game.GameInformationPushProtocol; import net.swofty.commons.protocol.objects.gui.KickFromGUIPushProtocol; -import net.swofty.redisapi.api.ChannelRegistry; -import net.swofty.redisapi.api.RedisAPI; -import org.json.JSONObject; -import org.tinylog.Logger; import java.util.List; import java.util.Map; import java.util.UUID; -import java.util.concurrent.*; -import java.util.concurrent.TimeoutException; +import java.util.concurrent.CompletableFuture; +import java.util.concurrent.ConcurrentHashMap; public class ServiceToServerManager { - private static final Map> pendingRequests = new ConcurrentHashMap<>(); - // Keep track of in-flight broadcasts - private static final Map pendingBroadcastRequests = new ConcurrentHashMap<>(); - // Single threaded scheduler to fire timeouts - private static final ScheduledExecutorService scheduler = - Executors.newSingleThreadScheduledExecutor(r -> { - Thread t = new Thread(r, "broadcast-timeouter"); - t.setDaemon(true); - return t; - }); private static ServiceType currentServiceType; public static void initialize(ServiceType serviceType) { currentServiceType = serviceType; - - // Register response handler for server responses - RedisAPI.getInstance().registerChannel(RedisChannels.SERVICE_RESPONSE, (event) -> { - String messageWithoutFilter = event.message.substring(event.message.indexOf(";") + 1); - RedisEnvelope envelope = RedisEnvelope.deserialize(messageWithoutFilter); - UUID requestId = UUID.fromString(envelope.id()); - - CompletableFuture future = pendingRequests.remove(requestId); - if (future != null) { - future.complete(new JSONObject(envelope.payload())); - } - }); - - RedisAPI.getInstance().registerChannel(RedisChannels.SERVICE_BROADCAST_RESPONSE, (event) -> { - String messageWithoutFilter = event.message.substring(event.message.indexOf(";") + 1); - RedisEnvelope envelope = RedisEnvelope.deserialize(messageWithoutFilter); - UUID requestId = UUID.fromString(envelope.id()); - UUID serverUUID = UUID.fromString(envelope.from()); - - BroadcastRequest broadcastRequest = pendingBroadcastRequests.get(requestId); - if (broadcastRequest != null) { - broadcastRequest.addResponse(serverUUID, new JSONObject(envelope.payload())); - } - }); + RedisMessageBus.registerResponseChannel(RedisChannels.SERVICE_RESPONSE); + RedisMessageBus.registerResponseChannel(RedisChannels.SERVICE_BROADCAST_RESPONSE); } public static CompletableFuture sendToServer( @@ -67,40 +32,14 @@ public static CompletableFuture sendToServer( RedisProtocol protocol, T message ) { - UUID requestId = UUID.randomUUID(); - CompletableFuture future = new CompletableFuture<>(); - CompletableFuture rawFuture = new CompletableFuture<>(); - - pendingRequests.put(requestId, rawFuture); - - rawFuture.orTimeout(10, TimeUnit.SECONDS).exceptionally(throwable -> { - pendingRequests.remove(requestId); - return null; - }); - - rawFuture.thenAccept(json -> { - if (json == null) { - future.completeExceptionally(new TimeoutException("Service push timed out")); - return; - } - try { - R response = protocol.translateReturnFromString(json.toString()); - future.complete(response); - } catch (Exception e) { - future.completeExceptionally(e); - } - }); - - String serialized = protocol.translateToString(message); - String channelName = RedisChannels.serviceRequest(protocol); - - RedisAPI.getInstance().publishMessage( + return RedisMessageBus.request( + RedisEndpoint.service(currentServiceType), serverUUID.toString(), - ChannelRegistry.getFromName(channelName), - new RedisEnvelope(requestId.toString(), currentServiceType.name(), serialized).serialize() + RedisChannels.serviceRequest(protocol), + RedisChannels.SERVICE_RESPONSE, + protocol, + message ); - - return future; } public static CompletableFuture> sendToAllServers( @@ -108,40 +47,15 @@ public static CompletableFuture> sendToAllServers( T message, int timeoutMs ) { - UUID requestId = UUID.randomUUID(); - CompletableFuture> rawFuture = new CompletableFuture<>(); - CompletableFuture> typedFuture = new CompletableFuture<>(); - - BroadcastRequest broadcastRequest = new BroadcastRequest(rawFuture); - pendingBroadcastRequests.put(requestId, broadcastRequest); - - String serialized = protocol.translateToString(message); - String channelName = RedisChannels.serviceBroadcast(protocol); - - RedisAPI.getInstance().publishMessage(RedisChannels.ALL_SERVERS, - ChannelRegistry.getFromName(channelName), - new RedisEnvelope(requestId.toString(), currentServiceType.name(), serialized).serialize()); - - scheduler.schedule(() -> { - BroadcastRequest req = pendingBroadcastRequests.remove(requestId); - if (req != null) { - req.getFuture().complete(req.getResponses()); - } - }, timeoutMs, TimeUnit.MILLISECONDS); - - rawFuture.thenAccept(rawMap -> { - Map typedMap = new ConcurrentHashMap<>(); - rawMap.forEach((uuid, json) -> { - try { - typedMap.put(uuid, protocol.translateReturnFromString(json.toString())); - } catch (Exception e) { - Logger.error(e, "Failed to deserialize push response from {}", uuid); - } - }); - typedFuture.complete(typedMap); - }); - - return typedFuture; + return RedisMessageBus.requestBroadcast( + RedisEndpoint.service(currentServiceType), + RedisChannels.ALL_SERVERS, + RedisChannels.serviceBroadcast(protocol), + RedisChannels.SERVICE_BROADCAST_RESPONSE, + protocol, + message, + timeoutMs + ); } public static CompletableFuture> sendToServers( diff --git a/service.punishment/src/main/java/net/swofty/service/punishment/ProxyRedis.java b/service.punishment/src/main/java/net/swofty/service/punishment/ProxyRedis.java deleted file mode 100644 index 8a70e44c0..000000000 --- a/service.punishment/src/main/java/net/swofty/service/punishment/ProxyRedis.java +++ /dev/null @@ -1,76 +0,0 @@ -package net.swofty.service.punishment; -import org.tinylog.Logger; -import redis.clients.jedis.Jedis; -import redis.clients.jedis.JedisPool; -import redis.clients.jedis.JedisPoolConfig; - -import net.swofty.commons.protocol.RedisProtocol; -import net.swofty.commons.redis.RedisEnvelope; - -import java.net.URI; -import java.time.Duration; -import java.util.UUID; -import java.util.concurrent.CompletableFuture; - -public class ProxyRedis { - private static JedisPool jedisPool; - private static volatile boolean initialized = false; - private static volatile boolean connecting = false; - - public static void connect(String redisUri) { - Thread.startVirtualThread(() -> connectSync(redisUri)); - } - - private static synchronized void connectSync(String redisUri) { - if (initialized || connecting) return; - connecting = true; - - try { - JedisPoolConfig poolConfig = new JedisPoolConfig(); - poolConfig.setMaxTotal(5); - poolConfig.setMaxIdle(1); - poolConfig.setMinIdle(1); - poolConfig.setMaxWait(Duration.ofSeconds(2)); - poolConfig.setTestOnBorrow(true); - poolConfig.setTestWhileIdle(true); - poolConfig.setBlockWhenExhausted(false); - - URI uri = URI.create(redisUri); - jedisPool = new JedisPool(poolConfig, uri); - - try (Jedis jedis = jedisPool.getResource()) { - jedis.ping(); - } - - initialized = true; - Logger.info("ProxyRedis: connected to Redis"); - } catch (Exception e) { - Logger.error("ProxyRedis: Redis not available player ban enforcement unavailable"); - initialized = false; - jedisPool = null; - } finally { - connecting = false; - } - } - - public static CompletableFuture publishMessage(String filterId, String channel, String message) { - return CompletableFuture.runAsync(() -> { - try (Jedis jedis = jedisPool.getResource()) { - jedis.publish(channel, filterId + ";" + message); - } catch (Exception ex) { - throw new RuntimeException("Failed to publish message to Redis", ex); - } - }); - } - - public static void publishToProxy(RedisProtocol protocol, T message) { - UUID uuid = UUID.randomUUID(); - String serialized = protocol.translateToString(message); - publishMessage("proxy", protocol.channel(), - new RedisEnvelope(uuid.toString(), uuid.toString(), serialized).serialize()); - } - - public static boolean isInitialized() { - return initialized && jedisPool != null && !jedisPool.isClosed(); - } -} diff --git a/service.punishment/src/main/java/net/swofty/service/punishment/PunishmentService.java b/service.punishment/src/main/java/net/swofty/service/punishment/PunishmentService.java index aa2bb6815..1cb8fdc50 100644 --- a/service.punishment/src/main/java/net/swofty/service/punishment/PunishmentService.java +++ b/service.punishment/src/main/java/net/swofty/service/punishment/PunishmentService.java @@ -13,9 +13,8 @@ public class PunishmentService implements SkyBlockService { static void main(String[] args) { String mongoUri = ConfigProvider.settings().getMongodb(); new PunishmentDatabase(null).connect(mongoUri); - SkyBlockService.init(new PunishmentService()); PunishmentRedis.connect(ConfigProvider.settings().getRedisUri()); - ProxyRedis.connect(ConfigProvider.settings().getRedisUri()); + SkyBlockService.init(new PunishmentService()); } @Override diff --git a/service.punishment/src/main/java/net/swofty/service/punishment/endpoints/PunishPlayerEndpoint.java b/service.punishment/src/main/java/net/swofty/service/punishment/endpoints/PunishPlayerEndpoint.java index 5cff291fd..a47c11d3c 100644 --- a/service.punishment/src/main/java/net/swofty/service/punishment/endpoints/PunishPlayerEndpoint.java +++ b/service.punishment/src/main/java/net/swofty/service/punishment/endpoints/PunishPlayerEndpoint.java @@ -3,9 +3,11 @@ import com.google.gson.Gson; import net.swofty.commons.protocol.RedisProtocol; import net.swofty.commons.protocol.objects.punishment.PunishPlayerServiceProtocol; +import net.swofty.commons.protocol.objects.proxy.to.PunishPlayerProtocol; import net.swofty.commons.punishment.*; +import net.swofty.commons.redis.RedisEndpoint; +import net.swofty.commons.redis.RedisMessageBus; import net.swofty.commons.redis.RedisMessageHandler; -import net.swofty.service.punishment.ProxyRedis; import org.tinylog.Logger; import java.time.Instant; @@ -63,8 +65,12 @@ public PunishPlayerServiceProtocol.PunishPlayerResponse handle(PunishPlayerServi } Gson gson = new Gson(); - ProxyRedis.publishToProxy(new net.swofty.commons.protocol.objects.proxy.to.PunishPlayerProtocol(), - new net.swofty.commons.protocol.objects.proxy.to.PunishPlayerProtocol.Request( + RedisMessageBus.publish( + RedisEndpoint.service(context.destination().id()), + RedisEndpoint.proxy().id(), + new PunishPlayerProtocol().channel(), + new PunishPlayerProtocol(), + new PunishPlayerProtocol.Request( messageObject.target().toString(), messageObject.type(), id.id().toString(), @@ -72,7 +78,8 @@ public PunishPlayerServiceProtocol.PunishPlayerResponse handle(PunishPlayerServi reason.getBanType() != null ? reason.getBanType().name() : null, reason.getMuteType() != null ? reason.getMuteType().name() : null, messageObject.tags() != null ? gson.toJson(messageObject.tags()) : null - )); + ) + ); Logger.info("Issued {} punishment to {} for reason '{}' (expires at: {})", messageObject.type(), messageObject.target(), diff --git a/type.generic/src/main/java/net/swofty/type/generic/leaderboard/LeaderboardService.java b/type.generic/src/main/java/net/swofty/type/generic/leaderboard/LeaderboardService.java index 4ca436d2d..31afc144c 100644 --- a/type.generic/src/main/java/net/swofty/type/generic/leaderboard/LeaderboardService.java +++ b/type.generic/src/main/java/net/swofty/type/generic/leaderboard/LeaderboardService.java @@ -1,13 +1,11 @@ package net.swofty.type.generic.leaderboard; +import net.swofty.commons.redis.RedisConnectionPool; import org.tinylog.Logger; import redis.clients.jedis.Jedis; import redis.clients.jedis.JedisPool; -import redis.clients.jedis.JedisPoolConfig; import redis.clients.jedis.resps.Tuple; -import java.net.URI; -import java.time.Duration; import java.util.ArrayList; import java.util.List; import java.util.UUID; @@ -31,23 +29,7 @@ private static synchronized void connectSync(String redisUri) { connecting = true; try { - JedisPoolConfig poolConfig = new JedisPoolConfig(); - poolConfig.setMaxTotal(20); - poolConfig.setMaxIdle(5); - poolConfig.setMinIdle(1); - poolConfig.setMaxWait(Duration.ofSeconds(2)); - poolConfig.setTestOnBorrow(true); - poolConfig.setTestWhileIdle(true); - poolConfig.setBlockWhenExhausted(false); - - URI uri = URI.create(redisUri); - jedisPool = new JedisPool(poolConfig, uri); - - // Test connection - try (Jedis jedis = jedisPool.getResource()) { - jedis.ping(); - } - + jedisPool = RedisConnectionPool.connect(redisUri, RedisConnectionPool.Settings.standard()); initialized = true; Logger.info("LeaderboardService connected to Redis"); } catch (Exception e) { diff --git a/velocity.extension/src/main/java/net/swofty/velocity/redis/RedisHandlerRegistry.java b/velocity.extension/src/main/java/net/swofty/velocity/redis/RedisHandlerRegistry.java index bd25a0e87..049fd185e 100644 --- a/velocity.extension/src/main/java/net/swofty/velocity/redis/RedisHandlerRegistry.java +++ b/velocity.extension/src/main/java/net/swofty/velocity/redis/RedisHandlerRegistry.java @@ -3,12 +3,9 @@ import net.swofty.commons.protocol.RedisProtocol; import net.swofty.commons.redis.RedisChannels; import net.swofty.commons.redis.RedisEndpoint; -import net.swofty.commons.redis.RedisEnvelope; +import net.swofty.commons.redis.RedisMessageBus; import net.swofty.commons.redis.RedisMessageContext; import net.swofty.commons.redis.RedisMessageHandler; -import net.swofty.redisapi.api.ChannelRegistry; -import net.swofty.redisapi.api.RedisAPI; -import org.tinylog.Logger; import java.util.UUID; @@ -19,33 +16,18 @@ private RedisHandlerRegistry() { public static void register(RedisMessageHandler handler) { RedisProtocol protocol = handler.protocol(); - RedisAPI.getInstance().registerChannel(RedisChannels.protocol(protocol), event -> { - String messageWithoutFilter = event.message.substring(event.message.indexOf(";") + 1); - RedisEnvelope envelope = RedisEnvelope.deserialize(messageWithoutFilter); - RedisMessageContext context = RedisMessageContext.proxyToServer( - UUID.fromString(envelope.id()), - envelope.from(), - RedisEndpoint.proxy().id(), - protocol.channel() - ); - - T message = protocol.translateFromString(envelope.payload()); - - Thread.startVirtualThread(() -> { - R response; - try { - response = handler.handle(message, context); - } catch (Exception e) { - Logger.error(e, "Error on channel {} with message {}", event.channel, envelope.payload()); - return; - } - - String serializedResponse = protocol.translateReturnToString(response); - RedisAPI.getInstance().publishMessage( - envelope.from(), - ChannelRegistry.getFromName(event.channel), - new RedisEnvelope(envelope.id(), RedisEndpoint.proxy().id(), serializedResponse).serialize()); - }); - }); + RedisMessageBus.registerHandler( + RedisEndpoint.proxy(), + RedisChannels.protocol(protocol), + handler, + (envelope, channel) -> RedisMessageContext.between( + UUID.fromString(envelope.id()), + RedisEndpoint.server(envelope.from()), + RedisEndpoint.proxy(), + protocol.channel() + ), + envelope -> envelope.from(), + envelope -> RedisChannels.protocol(protocol) + ); } } diff --git a/velocity.extension/src/main/java/net/swofty/velocity/redis/RedisMessage.java b/velocity.extension/src/main/java/net/swofty/velocity/redis/RedisMessage.java index 25449487a..da74ccd49 100644 --- a/velocity.extension/src/main/java/net/swofty/velocity/redis/RedisMessage.java +++ b/velocity.extension/src/main/java/net/swofty/velocity/redis/RedisMessage.java @@ -2,50 +2,27 @@ import net.swofty.commons.protocol.RedisProtocol; import net.swofty.commons.redis.RedisChannels; -import net.swofty.commons.redis.RedisEnvelope; -import net.swofty.redisapi.api.ChannelRegistry; -import net.swofty.redisapi.api.RedisAPI; -import org.tinylog.Logger; +import net.swofty.commons.redis.RedisEndpoint; +import net.swofty.commons.redis.RedisMessageBus; -import java.util.HashMap; -import java.util.Map; import java.util.UUID; import java.util.concurrent.CompletableFuture; public class RedisMessage { - private static final Map> callbacks = new HashMap<>(); - public static CompletableFuture sendMessageToServer(UUID server, RedisProtocol protocol, T message) { - UUID requestID = UUID.randomUUID(); - CompletableFuture rawFuture = new CompletableFuture<>(); - - callbacks.put(requestID, rawFuture); - - String serialized = protocol.translateToString(message); - RedisAPI.getInstance().publishMessage( + return RedisMessageBus.request( + RedisEndpoint.proxy(), server.toString(), - ChannelRegistry.getFromName(RedisChannels.protocol(protocol)), - new RedisEnvelope(requestID.toString(), "proxy", serialized).serialize()); - - return rawFuture.thenApply(protocol::translateReturnFromString); + RedisChannels.protocol(protocol), + RedisChannels.protocol(protocol), + protocol, + message + ); } public static void registerProxyToServer(RedisProtocol protocol) { - RedisAPI.getInstance().registerChannel(RedisChannels.protocol(protocol), (event) -> { - String messageWithoutFilter = event.message.substring(event.message.indexOf(";") + 1); - RedisEnvelope envelope = RedisEnvelope.deserialize(messageWithoutFilter); - UUID request = UUID.fromString(envelope.id()); - String rawMessage = envelope.payload(); - - try { - callbacks.get(request).complete(rawMessage); - callbacks.remove(request); - } catch (Exception e) { - Logger.error(e, "RedisMessage error processing channel={} message={}", - event.channel, event.message); - } - }); + RedisMessageBus.registerResponseChannel(RedisChannels.protocol(protocol)); } } From f3f0d21c692162753ac7520e3e4549f61b2ef5cb Mon Sep 17 00:00:00 2001 From: "Jacob Nardella (Swofty)" Date: Fri, 15 May 2026 12:43:07 +1000 Subject: [PATCH 106/113] refactor(redis): replace runtime adapters with shared client --- .../net/swofty/commons/redis/RedisClient.java | 177 ++++++++++++++++++ .../main/java/net/swofty/loader/Hypixel.java | 34 ++-- .../java/net/swofty/proxyapi/ProxyAPI.java | 2 + .../net/swofty/proxyapi/ProxyInformation.java | 26 +-- .../java/net/swofty/proxyapi/ProxyPlayer.java | 60 +++--- .../net/swofty/proxyapi/ProxyService.java | 38 +--- .../proxyapi/redis/ServerOutboundMessage.java | 104 ---------- .../service/bazaar/BazaarPropagator.java | 4 +- .../darkauction/DarkAuctionScheduler.java | 4 +- .../endpoints/SynchronizeDataEndpoint.java | 20 +- .../endpoints/UnlockDataEndpoint.java | 8 +- .../UpdateSynchronizedDataEndpoint.java | 9 +- .../swofty/service/friend/FriendCache.java | 6 +- .../service/generic/ServiceInitializer.java | 5 +- .../generic/redis/ServiceRedisManager.java | 3 + .../generic/redis/ServiceToServerManager.java | 123 ------------ .../endpoints/GameChooseEndpoint.java | 6 +- .../endpoints/GetServerForMapEndpoint.java | 8 +- .../net/swofty/service/party/PartyCache.java | 8 +- .../swofty/type/generic/chat/StaffChat.java | 6 +- .../generic/presence/PresenceHeartbeat.java | 8 +- .../user/flow/GenericPlayerDataFlow.java | 6 +- .../net/swofty/velocity/SkyBlockVelocity.java | 9 +- .../velocity/gamemanager/GameManager.java | 4 +- .../velocity/gamemanager/TransferHandler.java | 12 +- .../gamemanager/impl/IslandCheck.java | 4 +- .../velocity/presence/PresencePublisher.java | 5 +- .../swofty/velocity/redis/RedisMessage.java | 28 --- .../listeners/ListenerPlayerHandler.java | 8 +- .../redis/listeners/ListenerStaffChat.java | 4 +- 30 files changed, 317 insertions(+), 422 deletions(-) create mode 100644 commons/src/main/java/net/swofty/commons/redis/RedisClient.java delete mode 100644 proxy.api/src/main/java/net/swofty/proxyapi/redis/ServerOutboundMessage.java delete mode 100644 service.generic/src/main/java/net/swofty/service/generic/redis/ServiceToServerManager.java delete mode 100644 velocity.extension/src/main/java/net/swofty/velocity/redis/RedisMessage.java diff --git a/commons/src/main/java/net/swofty/commons/redis/RedisClient.java b/commons/src/main/java/net/swofty/commons/redis/RedisClient.java new file mode 100644 index 000000000..e00573d19 --- /dev/null +++ b/commons/src/main/java/net/swofty/commons/redis/RedisClient.java @@ -0,0 +1,177 @@ +package net.swofty.commons.redis; + +import net.swofty.commons.ServiceType; +import net.swofty.commons.protocol.RedisProtocol; +import net.swofty.commons.protocol.objects.PingProtocol; + +import java.lang.reflect.ParameterizedType; +import java.lang.reflect.Type; +import java.util.Map; +import java.util.UUID; +import java.util.concurrent.CompletableFuture; +import java.util.concurrent.ConcurrentHashMap; +import java.util.concurrent.TimeUnit; +import java.util.concurrent.atomic.AtomicBoolean; + +public final class RedisClient { + private static final Map> protocolsByRequest = new ConcurrentHashMap<>(); + private static volatile RedisEndpoint localEndpoint; + + private RedisClient() { + } + + public static void identify(RedisEndpoint endpoint) { + localEndpoint = endpoint; + } + + public static RedisEndpoint localEndpoint() { + if (localEndpoint == null) { + throw new IllegalStateException("RedisClient local endpoint has not been identified"); + } + return localEndpoint; + } + + public static void registerResponseProtocol(RedisProtocol protocol) { + protocolsByRequest.put(requestTypeName(protocol), protocol); + RedisMessageBus.registerResponseChannel(RedisChannels.protocol(protocol)); + } + + public static void registerResponseChannel(String channel) { + RedisMessageBus.registerResponseChannel(channel); + } + + public static void registerResponseProtocols(Iterable> protocols) { + protocols.forEach(RedisClient::registerResponseProtocol); + } + + public static CompletableFuture requestProxy(RedisProtocol protocol, T message) { + return request(RedisEndpoint.proxy().id(), RedisChannels.protocol(protocol), RedisChannels.protocol(protocol), protocol, message); + } + + public static CompletableFuture requestServer(UUID server, RedisProtocol protocol, T message) { + return request(server.toString(), RedisChannels.protocol(protocol), RedisChannels.protocol(protocol), protocol, message); + } + + public static CompletableFuture requestService(ServiceType service, RedisProtocol protocol, T message) { + return request(service.name(), RedisChannels.protocol(protocol), RedisChannels.protocol(protocol), protocol, message); + } + + public static CompletableFuture requestService(ServiceType service, T message) { + RedisProtocol protocol = protocolFor(message); + return requestService(service, protocol, message); + } + + public static CompletableFuture requestServiceFromServer(ServiceType service, RedisProtocol protocol, T message) { + return requestService(service, protocol, message); + } + + public static void publishService(ServiceType service, RedisProtocol protocol, T message) { + RedisMessageBus.publish(localEndpoint(), service.name(), RedisChannels.protocol(protocol), protocol, message); + } + + public static void publishAllServices(RedisProtocol protocol, T message) { + for (ServiceType serviceType : ServiceType.values()) { + publishService(serviceType, protocol, message); + } + } + + public static CompletableFuture requestServerFromService(UUID server, + RedisProtocol protocol, + T message) { + return RedisMessageBus.request( + localEndpoint(), + server.toString(), + RedisChannels.serviceRequest(protocol), + RedisChannels.SERVICE_RESPONSE, + protocol, + message + ); + } + + public static CompletableFuture> requestAllServersFromService(RedisProtocol protocol, + T message, + int timeoutMs) { + return RedisMessageBus.requestBroadcast( + localEndpoint(), + RedisChannels.ALL_SERVERS, + RedisChannels.serviceBroadcast(protocol), + RedisChannels.SERVICE_BROADCAST_RESPONSE, + protocol, + message, + timeoutMs + ); + } + + public static CompletableFuture> requestServersFromService(Iterable servers, + RedisProtocol protocol, + T message) { + Map> futures = new ConcurrentHashMap<>(); + for (UUID server : servers) { + futures.put(server, requestServerFromService(server, protocol, message)); + } + + return CompletableFuture.allOf(futures.values().toArray(new CompletableFuture[0])) + .thenApply(ignored -> { + Map responses = new ConcurrentHashMap<>(); + futures.forEach((server, future) -> { + try { + responses.put(server, future.get()); + } catch (Exception ignoredException) { + } + }); + return responses; + }); + } + + public static CompletableFuture isServiceOnline(ServiceType service) { + CompletableFuture future = new CompletableFuture<>(); + AtomicBoolean responded = new AtomicBoolean(false); + + requestService(service, new PingProtocol(), new PingProtocol.EmptyMessage()).thenAccept(response -> { + responded.set(true); + future.complete(true); + }); + + CompletableFuture.delayedExecutor(150, TimeUnit.MILLISECONDS).execute(() -> { + if (!responded.get()) { + future.complete(false); + } + }); + + return future; + } + + @SuppressWarnings("unchecked") + public static RedisProtocol protocolFor(T request) { + RedisProtocol protocol = protocolsByRequest.get(request.getClass().getSimpleName()); + if (protocol == null) { + throw new IllegalArgumentException("No Redis protocol registered for " + request.getClass().getSimpleName()); + } + return (RedisProtocol) protocol; + } + + private static CompletableFuture request(String target, + String requestChannel, + String responseChannel, + RedisProtocol protocol, + T message) { + return RedisMessageBus.request(localEndpoint(), target, requestChannel, responseChannel, protocol, message); + } + + private static String requestTypeName(RedisProtocol protocol) { + Type genericSuperclass = protocol.getClass().getGenericSuperclass(); + + if (genericSuperclass instanceof ParameterizedType paramType) { + Type[] typeArguments = paramType.getActualTypeArguments(); + if (typeArguments.length > 0) { + Type firstTypeArg = typeArguments[0]; + if (firstTypeArg instanceof Class) { + return ((Class) firstTypeArg).getSimpleName(); + } + return firstTypeArg.getTypeName(); + } + } + + throw new IllegalArgumentException("Could not determine request type for " + protocol.getClass().getName()); + } +} diff --git a/loader/src/main/java/net/swofty/loader/Hypixel.java b/loader/src/main/java/net/swofty/loader/Hypixel.java index 13e84accb..32b57db7a 100644 --- a/loader/src/main/java/net/swofty/loader/Hypixel.java +++ b/loader/src/main/java/net/swofty/loader/Hypixel.java @@ -22,9 +22,9 @@ import net.swofty.commons.config.ConfigProvider; import net.swofty.commons.protocol.RedisProtocol; import net.swofty.commons.protocol.objects.proxy.to.*; +import net.swofty.commons.redis.RedisClient; import net.swofty.proxyapi.ProxyAPI; import net.swofty.proxyapi.ProxyService; -import net.swofty.proxyapi.redis.ServerOutboundMessage; import net.swofty.commons.redis.RedisMessageHandler; import net.swofty.spark.Spark; import net.swofty.type.generic.HypixelConst; @@ -178,13 +178,13 @@ static void main(String[] args) { new PunishPlayerProtocol() }; for (RedisProtocol protocol : toProxyProtocols) { - ServerOutboundMessage.registerToProxyProtocol(protocol); + RedisClient.registerResponseProtocol(protocol); } List protocols = SkyBlockGenericLoader.loopThroughPackage( "net.swofty.commons.protocol.objects", RedisProtocol.class) .filter(obj -> !obj.getClass().getPackageName().startsWith("net.swofty.commons.protocol.objects.proxy")) .toList(); - protocols.forEach(ServerOutboundMessage::registerResponseProtocol); + protocols.forEach(RedisClient::registerResponseProtocol); proxyAPI.start(); // Start spark if enabled @@ -226,9 +226,9 @@ static void main(String[] args) { HypixelConst.setMaxPlayers(maxPlayers); HypixelConst.setServerUUID(serverUUID); - ServerOutboundMessage.sendToProxy(new RequestServerNameProtocol(), - new RequestServerNameProtocol.Request(), - (response) -> { + RedisClient.requestProxy(new RequestServerNameProtocol(), + new RequestServerNameProtocol.Request()) + .thenAccept(response -> { if (isTestFlow) { String serverNameRaw = response.shortenedServerName().substring(1); String serverName = "isolated" + serverNameRaw; @@ -276,14 +276,14 @@ public void onFlag(UUID uuid, FlagType flagType) { System.exit(0); }); - ServerOutboundMessage.sendToProxy(new RegisterServerProtocol(), + RedisClient.requestProxy(new RegisterServerProtocol(), new RegisterServerProtocol.Request( serverType.name(), maxPlayers, InetAddress.getLocalHost().getHostName(), null, isTestFlow ? true : null, isTestFlow ? testFlowName : null, isTestFlow ? testFlowIndex : null, - isTestFlow ? testFlowTotal : null), - (response) -> startServer.complete(response.port())); + isTestFlow ? testFlowTotal : null)) + .thenAccept(response -> startServer.complete(response.port())); } private static void handleTestFlowRegistration(String testFlowName, String handler, String players, @@ -310,9 +310,9 @@ private static void handleTestFlowRegistration(String testFlowName, String handl configList.add(Map.of("type", type, "count", count)); } - ServerOutboundMessage.sendToProxy(new RegisterTestFlowProtocol(), - new RegisterTestFlowProtocol.Request(testFlowName, handler, playerList, configList), - (response) -> { + RedisClient.requestProxy(new RegisterTestFlowProtocol(), + new RegisterTestFlowProtocol.Request(testFlowName, handler, playerList, configList)) + .thenAccept(response -> { Logger.info("Test flow registered successfully with proxy"); notifyTestFlowServerReady(testFlowName, serverType, index); }); @@ -323,9 +323,9 @@ private static void handleTestFlowRegistration(String testFlowName, String handl } private static void notifyTestFlowServerReady(String testFlowName, ServerType serverType, String index) { - ServerOutboundMessage.sendToProxy(new TestFlowServerReadyProtocol(), - new TestFlowServerReadyProtocol.Request(testFlowName, serverType.name(), Integer.parseInt(index)), - (response) -> { + RedisClient.requestProxy(new TestFlowServerReadyProtocol(), + new TestFlowServerReadyProtocol.Request(testFlowName, serverType.name(), Integer.parseInt(index))) + .thenAccept(response -> { Logger.info("Notified proxy that " + serverType.name() + " server " + index + " is ready for test flow: " + testFlowName); }); } @@ -345,8 +345,8 @@ private static void checkProxyConnected(Scheduler scheduler) { AtomicBoolean responded = new AtomicBoolean(false); try { - ServerOutboundMessage.sendToProxy(new ProxyIsOnlineProtocol(), - new ProxyIsOnlineProtocol.Request(), (response) -> { + RedisClient.requestProxy(new ProxyIsOnlineProtocol(), + new ProxyIsOnlineProtocol.Request()).thenAccept(response -> { if (response.online()) { responded.set(true); } diff --git a/proxy.api/src/main/java/net/swofty/proxyapi/ProxyAPI.java b/proxy.api/src/main/java/net/swofty/proxyapi/ProxyAPI.java index 79e0aeb07..916a97539 100644 --- a/proxy.api/src/main/java/net/swofty/proxyapi/ProxyAPI.java +++ b/proxy.api/src/main/java/net/swofty/proxyapi/ProxyAPI.java @@ -2,6 +2,7 @@ import net.swofty.commons.protocol.RedisProtocol; import net.swofty.commons.redis.RedisChannels; +import net.swofty.commons.redis.RedisClient; import net.swofty.commons.redis.RedisEndpoint; import net.swofty.commons.redis.RedisMessageBus; import net.swofty.commons.redis.RedisMessageContext; @@ -18,6 +19,7 @@ public ProxyAPI(String URI, UUID serverUUID) { RedisAPI.generateInstance(URI); RedisAPI.getInstance().setFilterId(serverUUID.toString()); + RedisClient.identify(RedisEndpoint.server(serverUUID)); } public void registerProxyHandler(RedisMessageHandler handler) { diff --git a/proxy.api/src/main/java/net/swofty/proxyapi/ProxyInformation.java b/proxy.api/src/main/java/net/swofty/proxyapi/ProxyInformation.java index 6d50a5196..6e99682d9 100644 --- a/proxy.api/src/main/java/net/swofty/proxyapi/ProxyInformation.java +++ b/proxy.api/src/main/java/net/swofty/proxyapi/ProxyInformation.java @@ -3,7 +3,7 @@ import net.swofty.commons.ServerType; import net.swofty.commons.UnderstandableProxyServer; import net.swofty.commons.protocol.objects.proxy.to.RequestServersProtocol; -import net.swofty.proxyapi.redis.ServerOutboundMessage; +import net.swofty.commons.redis.RedisClient; import org.json.JSONObject; import java.util.List; @@ -15,33 +15,33 @@ public class ProxyInformation { public CompletableFuture getServerInformation(UUID uuid) { CompletableFuture future = new CompletableFuture<>(); - ServerOutboundMessage.sendToProxy(PROTOCOL, - new RequestServersProtocol.Request("UUID", null, uuid.toString()), - response -> future.complete(UnderstandableProxyServer.fromJSON(new JSONObject(response.serversList())).getFirst())); + RedisClient.requestProxy(PROTOCOL, + new RequestServersProtocol.Request("UUID", null, uuid.toString())) + .thenAccept(response -> future.complete(UnderstandableProxyServer.fromJSON(new JSONObject(response.serversList())).getFirst())); return future; } public CompletableFuture> getServerInformation(ServerType type) { CompletableFuture> future = new CompletableFuture<>(); - ServerOutboundMessage.sendToProxy(PROTOCOL, - new RequestServersProtocol.Request("TYPE", type.name(), null), - response -> future.complete(UnderstandableProxyServer.fromJSON(new JSONObject(response.serversList())))); + RedisClient.requestProxy(PROTOCOL, + new RequestServersProtocol.Request("TYPE", type.name(), null)) + .thenAccept(response -> future.complete(UnderstandableProxyServer.fromJSON(new JSONObject(response.serversList())))); return future; } public CompletableFuture> getAllServersInformation() { CompletableFuture> future = new CompletableFuture<>(); - ServerOutboundMessage.sendToProxy(PROTOCOL, - new RequestServersProtocol.Request("ALL", null, null), - response -> future.complete(UnderstandableProxyServer.fromJSON(new JSONObject(response.serversList())))); + RedisClient.requestProxy(PROTOCOL, + new RequestServersProtocol.Request("ALL", null, null)) + .thenAccept(response -> future.complete(UnderstandableProxyServer.fromJSON(new JSONObject(response.serversList())))); return future; } public CompletableFuture getServerInformation(ProxyPlayer player) { CompletableFuture future = new CompletableFuture<>(); - ServerOutboundMessage.sendToProxy(PROTOCOL, - new RequestServersProtocol.Request("PLAYER_UUID", null, player.getUuid().toString()), - response -> future.complete(UnderstandableProxyServer.fromJSON(new JSONObject(response.serversList())).getFirst())); + RedisClient.requestProxy(PROTOCOL, + new RequestServersProtocol.Request("PLAYER_UUID", null, player.getUuid().toString())) + .thenAccept(response -> future.complete(UnderstandableProxyServer.fromJSON(new JSONObject(response.serversList())).getFirst())); return future; } } diff --git a/proxy.api/src/main/java/net/swofty/proxyapi/ProxyPlayer.java b/proxy.api/src/main/java/net/swofty/proxyapi/ProxyPlayer.java index ad03ebe62..30425cee3 100644 --- a/proxy.api/src/main/java/net/swofty/proxyapi/ProxyPlayer.java +++ b/proxy.api/src/main/java/net/swofty/proxyapi/ProxyPlayer.java @@ -8,8 +8,8 @@ import net.swofty.commons.ServerType; import net.swofty.commons.UnderstandableProxyServer; import net.swofty.commons.protocol.objects.proxy.to.PlayerHandlerProtocol; +import net.swofty.commons.redis.RedisClient; import net.swofty.proxyapi.impl.ProxyUnderstandableEvent; -import net.swofty.proxyapi.redis.ServerOutboundMessage; import org.json.JSONObject; import java.util.Map; @@ -33,10 +33,9 @@ public ProxyPlayer(UUID uuid) { } public void sendMessage(Component message) { - ServerOutboundMessage.sendToProxy(PLAYER_HANDLER, + RedisClient.requestProxy(PLAYER_HANDLER, new PlayerHandlerProtocol.Request(uuid.toString(), PlayerHandlerProtocol.Action.MESSAGE, - Map.of("message", JSONComponentSerializer.json().serialize(message))), - response -> {}); + Map.of("message", JSONComponentSerializer.json().serialize(message)))); } public void sendMessage(String message) { @@ -44,18 +43,17 @@ public void sendMessage(String message) { } public void teleport(Pos pos) { - ServerOutboundMessage.sendToProxy(PLAYER_HANDLER, + RedisClient.requestProxy(PLAYER_HANDLER, new PlayerHandlerProtocol.Request(uuid.toString(), PlayerHandlerProtocol.Action.TELEPORT, Map.of("x", pos.x(), "y", pos.y(), "z", pos.z(), - "yaw", pos.yaw(), "pitch", pos.pitch())), - response -> {}); + "yaw", pos.yaw(), "pitch", pos.pitch()))); } public CompletableFuture getServer() { CompletableFuture future = new CompletableFuture<>(); - ServerOutboundMessage.sendToProxy(PLAYER_HANDLER, - new PlayerHandlerProtocol.Request(uuid.toString(), PlayerHandlerProtocol.Action.GET_SERVER, Map.of()), - response -> { + RedisClient.requestProxy(PLAYER_HANDLER, + new PlayerHandlerProtocol.Request(uuid.toString(), PlayerHandlerProtocol.Action.GET_SERVER, Map.of())) + .thenAccept(response -> { @SuppressWarnings("unchecked") Map serverMap = (Map) response.data().get("server"); if (serverMap != null) { @@ -69,9 +67,9 @@ public CompletableFuture getServer() { public CompletableFuture isOnline() { CompletableFuture future = new CompletableFuture<>(); - ServerOutboundMessage.sendToProxy(PLAYER_HANDLER, - new PlayerHandlerProtocol.Request(uuid.toString(), PlayerHandlerProtocol.Action.IS_ONLINE, Map.of()), - response -> { + RedisClient.requestProxy(PLAYER_HANDLER, + new PlayerHandlerProtocol.Request(uuid.toString(), PlayerHandlerProtocol.Action.IS_ONLINE, Map.of())) + .thenAccept(response -> { Object isOnline = response.data().get("isOnline"); future.complete(Boolean.TRUE.equals(isOnline)); }); @@ -79,51 +77,46 @@ public CompletableFuture isOnline() { } public void runEvent(ProxyUnderstandableEvent event) { - ServerOutboundMessage.sendToProxy(PLAYER_HANDLER, + RedisClient.requestProxy(PLAYER_HANDLER, new PlayerHandlerProtocol.Request(uuid.toString(), PlayerHandlerProtocol.Action.EVENT, Map.of("event", event.getClass().getName(), - "data", event.asProxyUnderstandable())), - response -> {}); + "data", event.asProxyUnderstandable()))); } public CompletableFuture transferToWithIndication(UUID serverToTransferTo) { CompletableFuture future = new CompletableFuture<>(); - ServerOutboundMessage.sendToProxy(PLAYER_HANDLER, + RedisClient.requestProxy(PLAYER_HANDLER, new PlayerHandlerProtocol.Request(uuid.toString(), PlayerHandlerProtocol.Action.TRANSFER_WITH_UUID, - Map.of("server_uuid", serverToTransferTo.toString())), - response -> {}); + Map.of("server_uuid", serverToTransferTo.toString()))); waitingForTransferComplete.put(uuid, future); return future; } public void transferTo(ServerType serverType) { - ServerOutboundMessage.sendToProxy(PLAYER_HANDLER, + RedisClient.requestProxy(PLAYER_HANDLER, new PlayerHandlerProtocol.Request(uuid.toString(), PlayerHandlerProtocol.Action.TRANSFER, - Map.of("type", serverType.toString())), - response -> {}); + Map.of("type", serverType.toString()))); } public void transferToLimbo() { - ServerOutboundMessage.sendToProxy(PLAYER_HANDLER, - new PlayerHandlerProtocol.Request(uuid.toString(), PlayerHandlerProtocol.Action.LIMBO, Map.of()), - response -> {}); + RedisClient.requestProxy(PLAYER_HANDLER, + new PlayerHandlerProtocol.Request(uuid.toString(), PlayerHandlerProtocol.Action.LIMBO, Map.of())); } public CompletableFuture transferToWithIndication(ServerType serverType) { CompletableFuture future = new CompletableFuture<>(); - ServerOutboundMessage.sendToProxy(PLAYER_HANDLER, + RedisClient.requestProxy(PLAYER_HANDLER, new PlayerHandlerProtocol.Request(uuid.toString(), PlayerHandlerProtocol.Action.TRANSFER, - Map.of("type", serverType.toString())), - response -> {}); + Map.of("type", serverType.toString()))); waitingForTransferComplete.put(uuid, future); return future; } public CompletableFuture getBankHash() { CompletableFuture future = new CompletableFuture<>(); - ServerOutboundMessage.sendToProxy(PLAYER_HANDLER, - new PlayerHandlerProtocol.Request(uuid.toString(), PlayerHandlerProtocol.Action.BANK_HASH, Map.of()), - response -> { + RedisClient.requestProxy(PLAYER_HANDLER, + new PlayerHandlerProtocol.Request(uuid.toString(), PlayerHandlerProtocol.Action.BANK_HASH, Map.of())) + .thenAccept(response -> { Object bankHash = response.data().get("bankHash"); future.complete(UUID.fromString((String) bankHash)); }); @@ -131,9 +124,8 @@ public CompletableFuture getBankHash() { } public void refreshCoopData(String datapoint) { - ServerOutboundMessage.sendToProxy(PLAYER_HANDLER, + RedisClient.requestProxy(PLAYER_HANDLER, new PlayerHandlerProtocol.Request(uuid.toString(), PlayerHandlerProtocol.Action.REFRESH_COOP_DATA, - Map.of("datapoint", datapoint)), - response -> {}); + Map.of("datapoint", datapoint))); } } diff --git a/proxy.api/src/main/java/net/swofty/proxyapi/ProxyService.java b/proxy.api/src/main/java/net/swofty/proxyapi/ProxyService.java index d4fa0047a..222d53c12 100644 --- a/proxy.api/src/main/java/net/swofty/proxyapi/ProxyService.java +++ b/proxy.api/src/main/java/net/swofty/proxyapi/ProxyService.java @@ -1,48 +1,16 @@ package net.swofty.proxyapi; import net.swofty.commons.ServiceType; -import net.swofty.commons.protocol.RedisProtocol; -import net.swofty.commons.protocol.objects.PingProtocol; -import net.swofty.proxyapi.redis.ServerOutboundMessage; +import net.swofty.commons.redis.RedisClient; import java.util.concurrent.CompletableFuture; -import java.util.concurrent.TimeUnit; -import java.util.concurrent.atomic.AtomicBoolean; public record ProxyService(ServiceType type) { public CompletableFuture isOnline() { - CompletableFuture future = new CompletableFuture<>(); - AtomicBoolean hasReceivedResponse = new AtomicBoolean(false); - - ServerOutboundMessage.sendMessageToService(type, new PingProtocol(), - new PingProtocol.EmptyMessage(), (s) -> { - future.complete(true); - hasReceivedResponse.set(true); - }); - - CompletableFuture.delayedExecutor(150, TimeUnit.MILLISECONDS) - .execute(() -> { - if (!hasReceivedResponse.get()) { - future.complete(false); - } - }); - - return future; + return RedisClient.isServiceOnline(type); } public CompletableFuture handleRequest(T request) { - RedisProtocol protocol = ServerOutboundMessage.protocols.get(request.getClass().getSimpleName()); - - CompletableFuture future = new CompletableFuture<>(); - Thread.startVirtualThread(() -> - ServerOutboundMessage.sendMessageToService( - type, - protocol, - request, - (s) -> Thread.startVirtualThread( - () -> future.complete(protocol.translateReturnFromString(s)) - ) - )); - return future; + return RedisClient.requestService(type, request); } } diff --git a/proxy.api/src/main/java/net/swofty/proxyapi/redis/ServerOutboundMessage.java b/proxy.api/src/main/java/net/swofty/proxyapi/redis/ServerOutboundMessage.java deleted file mode 100644 index 3a099f44f..000000000 --- a/proxy.api/src/main/java/net/swofty/proxyapi/redis/ServerOutboundMessage.java +++ /dev/null @@ -1,104 +0,0 @@ -package net.swofty.proxyapi.redis; - -import net.swofty.commons.ServiceType; -import net.swofty.commons.protocol.RedisProtocol; -import net.swofty.commons.redis.RedisChannels; -import net.swofty.commons.redis.RedisEndpoint; -import net.swofty.commons.redis.RedisMessageBus; -import net.swofty.redisapi.api.RedisAPI; -import org.tinylog.Logger; - -import java.lang.reflect.ParameterizedType; -import java.lang.reflect.Type; -import java.util.HashMap; -import java.util.Map; -import java.util.function.Consumer; - -public class ServerOutboundMessage { - public static final Map protocols = new HashMap<>(); - - public static void sendToProxy(RedisProtocol protocol, T request, Consumer response) { - RedisMessageBus.request( - localEndpoint(), - RedisChannels.PROXY_RESPONSE, - RedisChannels.protocol(protocol), - RedisChannels.protocol(protocol), - protocol, - request - ).thenAccept(response); - } - - public static void registerToProxyProtocol(RedisProtocol protocol) { - RedisMessageBus.registerResponseChannel(RedisChannels.protocol(protocol)); - } - - public static void registerResponseProtocol(RedisProtocol protocol) { - String requestTypeName = getRequestTypeName(protocol); - protocols.put(requestTypeName, protocol); - - RedisMessageBus.registerResponseChannel(RedisChannels.protocol(protocol)); - } - - public static void sendMessageToService(ServiceType service, - RedisProtocol specification, - Object rawMessage, - Consumer response) { - RedisMessageBus.requestRaw( - localEndpoint(), - service.name(), - specification.channel(), - specification.channel(), - specification, - rawMessage - ).thenAccept(response).exceptionally(throwable -> { - Logger.error(throwable, "Failed to receive response from service {}", service.name()); - return null; - }); - } - - public static void sendMessageToServiceFireAndForget(ServiceType service, - RedisProtocol specification, - Object rawMessage) { - RedisMessageBus.publish( - localEndpoint(), - service.name(), - specification.channel(), - specification, - rawMessage - ); - } - - public static void sendMessageToAllServicesFireAndForget(RedisProtocol specification, - Object rawMessage) { - for (ServiceType serviceType : ServiceType.values()) { - sendMessageToServiceFireAndForget(serviceType, specification, rawMessage); - } - } - - private static String getRequestTypeName(RedisProtocol protocolObject) { - Class clazz = protocolObject.getClass(); - Type genericSuperclass = clazz.getGenericSuperclass(); - - if (genericSuperclass instanceof ParameterizedType paramType) { - Type[] typeArguments = paramType.getActualTypeArguments(); - if (typeArguments.length > 0) { - Type firstTypeArg = typeArguments[0]; - if (firstTypeArg instanceof Class) { - return ((Class) firstTypeArg).getSimpleName(); - } else { - return firstTypeArg.getTypeName(); - } - } - } - - throw new IllegalArgumentException("Could not determine the type T for the given RedisProtocol"); - } - - private static RedisEndpoint localEndpoint() { - String filterId = RedisAPI.getInstance().getFilterId(); - if (RedisEndpoint.proxy().id().equals(filterId)) { - return RedisEndpoint.proxy(); - } - return RedisEndpoint.server(filterId); - } -} diff --git a/service.bazaar/src/main/java/net/swofty/service/bazaar/BazaarPropagator.java b/service.bazaar/src/main/java/net/swofty/service/bazaar/BazaarPropagator.java index b5e3dc20c..75fbc3367 100644 --- a/service.bazaar/src/main/java/net/swofty/service/bazaar/BazaarPropagator.java +++ b/service.bazaar/src/main/java/net/swofty/service/bazaar/BazaarPropagator.java @@ -5,7 +5,7 @@ import net.swofty.commons.skyblock.bazaar.BazaarTransaction; import net.swofty.commons.skyblock.bazaar.SuccessfulBazaarTransaction; import net.swofty.commons.skyblock.bazaar.OrderExpiredBazaarTransaction; -import net.swofty.service.generic.redis.ServiceToServerManager; +import net.swofty.commons.redis.RedisClient; import org.tinylog.Logger; import java.util.Map; @@ -23,7 +23,7 @@ public void propagate(BazaarTransaction tx) { tx.toJSON().toString() ); - ServiceToServerManager.sendToAllServers(PROTOCOL, request, 5000) + RedisClient.requestAllServersFromService(PROTOCOL, request, 5000) .thenAccept(responses -> handleServerResponses(tx, responses)) .exceptionally(throwable -> { Logger.error(throwable, "Failed to get responses from servers for transaction"); diff --git a/service.darkauction/src/main/java/net/swofty/service/darkauction/DarkAuctionScheduler.java b/service.darkauction/src/main/java/net/swofty/service/darkauction/DarkAuctionScheduler.java index d824be5c4..43e0f320e 100644 --- a/service.darkauction/src/main/java/net/swofty/service/darkauction/DarkAuctionScheduler.java +++ b/service.darkauction/src/main/java/net/swofty/service/darkauction/DarkAuctionScheduler.java @@ -3,7 +3,7 @@ import net.swofty.commons.skyblock.auctions.DarkAuctionPhase; import net.swofty.commons.protocol.objects.darkauction.DarkAuctionEventProtocol; import net.swofty.commons.protocol.objects.darkauction.DarkAuctionEventPushProtocol; -import net.swofty.service.generic.redis.ServiceToServerManager; +import net.swofty.commons.redis.RedisClient; import org.tinylog.Logger; import java.util.ArrayList; @@ -177,7 +177,7 @@ private static void broadcastEvent(DarkAuctionEventProtocol.EventType type, Dark Logger.debug("Broadcasting {} event for auction {}", type, auction.getAuctionId()); - ServiceToServerManager.sendToAllServers( + RedisClient.requestAllServersFromService( new DarkAuctionEventPushProtocol(), request, 5000 diff --git a/service.datamutex/src/main/java/net/swofty/service/datamutex/endpoints/SynchronizeDataEndpoint.java b/service.datamutex/src/main/java/net/swofty/service/datamutex/endpoints/SynchronizeDataEndpoint.java index ce91b2f03..2662b3357 100644 --- a/service.datamutex/src/main/java/net/swofty/service/datamutex/endpoints/SynchronizeDataEndpoint.java +++ b/service.datamutex/src/main/java/net/swofty/service/datamutex/endpoints/SynchronizeDataEndpoint.java @@ -4,10 +4,11 @@ import net.swofty.commons.protocol.objects.data.GetPlayerDataPushProtocol; import net.swofty.commons.protocol.objects.data.LockPlayerDataPushProtocol; +import net.swofty.commons.protocol.objects.data.UnlockPlayerDataPushProtocol; import net.swofty.commons.protocol.objects.datamutex.SynchronizeDataProtocol; import net.swofty.service.datamutex.DataLockManager; import net.swofty.commons.redis.RedisMessageHandler; -import net.swofty.service.generic.redis.ServiceToServerManager; +import net.swofty.commons.redis.RedisClient; import java.util.HashMap; import java.util.List; @@ -44,8 +45,9 @@ public SynchronizeDataProtocol.SynchronizeDataResponse handle(SynchronizeDataPro false, null, "Data is currently locked by another operation"); } - Map lockResults = ServiceToServerManager - .lockPlayerData(serverUUIDs, playerUUID, dataKey) + Map lockResults = RedisClient + .requestServersFromService(serverUUIDs, new LockPlayerDataPushProtocol(), + new LockPlayerDataPushProtocol.Request(playerUUID, dataKey)) .get(); boolean allLocked = lockResults.values().stream() @@ -55,7 +57,8 @@ public SynchronizeDataProtocol.SynchronizeDataResponse handle(SynchronizeDataPro Logger.debug("sync: failed to lock all servers (results={}), rolling back", lockResults); DataLockManager.releaseLock(lockKey, requesterId); - ServiceToServerManager.unlockPlayerData(serverUUIDs, playerUUID, dataKey); + RedisClient.requestServersFromService(serverUUIDs, new UnlockPlayerDataPushProtocol(), + new UnlockPlayerDataPushProtocol.Request(playerUUID, dataKey)); return new SynchronizeDataProtocol.SynchronizeDataResponse( false, null, "Failed to acquire locks on all servers"); } @@ -63,7 +66,8 @@ public SynchronizeDataProtocol.SynchronizeDataResponse handle(SynchronizeDataPro Map> dataFutures = new HashMap<>(); for (UUID serverUUID : serverUUIDs) { dataFutures.put(serverUUID, - ServiceToServerManager.getPlayerData(serverUUID, playerUUID, dataKey)); + RedisClient.requestServerFromService(serverUUID, new GetPlayerDataPushProtocol(), + new GetPlayerDataPushProtocol.Request(playerUUID, dataKey))); } Map allData = new HashMap<>(); @@ -83,7 +87,8 @@ public SynchronizeDataProtocol.SynchronizeDataResponse handle(SynchronizeDataPro if (latestData == null) { Logger.debug("sync: no valid data among {} responses, rolling back", allData.size()); DataLockManager.releaseLock(lockKey, requesterId); - ServiceToServerManager.unlockPlayerData(serverUUIDs, playerUUID, dataKey); + RedisClient.requestServersFromService(serverUUIDs, new UnlockPlayerDataPushProtocol(), + new UnlockPlayerDataPushProtocol.Request(playerUUID, dataKey)); return new SynchronizeDataProtocol.SynchronizeDataResponse( false, null, "No valid data found on any server"); } @@ -95,7 +100,8 @@ public SynchronizeDataProtocol.SynchronizeDataResponse handle(SynchronizeDataPro } catch (Exception e) { Logger.error(e, "Error occurred in data mutex endpoint (lockKey={})", lockKey); DataLockManager.releaseLock(lockKey, requesterId); - ServiceToServerManager.unlockPlayerData(serverUUIDs, playerUUID, dataKey); + RedisClient.requestServersFromService(serverUUIDs, new UnlockPlayerDataPushProtocol(), + new UnlockPlayerDataPushProtocol.Request(playerUUID, dataKey)); return new SynchronizeDataProtocol.SynchronizeDataResponse( false, null, "Error during synchronization: " + e.getMessage()); } diff --git a/service.datamutex/src/main/java/net/swofty/service/datamutex/endpoints/UnlockDataEndpoint.java b/service.datamutex/src/main/java/net/swofty/service/datamutex/endpoints/UnlockDataEndpoint.java index 21c855ef9..4c6b667cc 100644 --- a/service.datamutex/src/main/java/net/swofty/service/datamutex/endpoints/UnlockDataEndpoint.java +++ b/service.datamutex/src/main/java/net/swofty/service/datamutex/endpoints/UnlockDataEndpoint.java @@ -1,9 +1,10 @@ package net.swofty.service.datamutex.endpoints; +import net.swofty.commons.protocol.objects.data.UnlockPlayerDataPushProtocol; import net.swofty.commons.protocol.objects.datamutex.UnlockDataProtocol; import net.swofty.service.datamutex.DataLockManager; import net.swofty.commons.redis.RedisMessageHandler; -import net.swofty.service.generic.redis.ServiceToServerManager; +import net.swofty.commons.redis.RedisClient; import org.tinylog.Logger; import java.util.List; @@ -33,7 +34,8 @@ public UnlockDataProtocol.UnlockDataResponse handle(UnlockDataProtocol.UnlockDat // Release service-level lock DataLockManager.releaseLock(lockKey, requesterId); - ServiceToServerManager.unlockPlayerData(serverUUIDs, playerUUID, dataKey) + RedisClient.requestServersFromService(serverUUIDs, new UnlockPlayerDataPushProtocol(), + new UnlockPlayerDataPushProtocol.Request(playerUUID, dataKey)) .thenAccept(results -> results.forEach((serverUUID, response) -> { if (!response.success()) { Logger.warn("Failed to unlock data on server {} for player {}, dataKey: {}", @@ -53,4 +55,4 @@ public UnlockDataProtocol.UnlockDataResponse handle(UnlockDataProtocol.UnlockDat false, "Error during unlock: " + e.getMessage()); } } -} \ No newline at end of file +} diff --git a/service.datamutex/src/main/java/net/swofty/service/datamutex/endpoints/UpdateSynchronizedDataEndpoint.java b/service.datamutex/src/main/java/net/swofty/service/datamutex/endpoints/UpdateSynchronizedDataEndpoint.java index 5263521e1..b2563b3f8 100644 --- a/service.datamutex/src/main/java/net/swofty/service/datamutex/endpoints/UpdateSynchronizedDataEndpoint.java +++ b/service.datamutex/src/main/java/net/swofty/service/datamutex/endpoints/UpdateSynchronizedDataEndpoint.java @@ -3,10 +3,11 @@ import org.tinylog.Logger; import net.swofty.commons.protocol.objects.data.UpdatePlayerDataPushProtocol; +import net.swofty.commons.protocol.objects.data.UnlockPlayerDataPushProtocol; import net.swofty.commons.protocol.objects.datamutex.UpdateSynchronizedDataProtocol; import net.swofty.service.datamutex.DataLockManager; import net.swofty.commons.redis.RedisMessageHandler; -import net.swofty.service.generic.redis.ServiceToServerManager; +import net.swofty.commons.redis.RedisClient; import java.util.HashMap; import java.util.List; @@ -49,7 +50,8 @@ public UpdateSynchronizedDataProtocol.UpdateDataResponse handle(UpdateSynchroniz Map> updateFutures = new HashMap<>(); for (UUID serverUUID : serverUUIDs) { updateFutures.put(serverUUID, - ServiceToServerManager.updatePlayerData(serverUUID, playerUUID, dataKey, newData)); + RedisClient.requestServerFromService(serverUUID, new UpdatePlayerDataPushProtocol(), + new UpdatePlayerDataPushProtocol.Request(playerUUID, dataKey, newData))); } Map updateResults = new HashMap<>(); @@ -74,7 +76,8 @@ public UpdateSynchronizedDataProtocol.UpdateDataResponse handle(UpdateSynchroniz false, "Error during data update: " + e.getMessage()); } finally { DataLockManager.releaseLock(lockKey, requesterId); - ServiceToServerManager.unlockPlayerData(serverUUIDs, playerUUID, dataKey); + RedisClient.requestServersFromService(serverUUIDs, new UnlockPlayerDataPushProtocol(), + new UnlockPlayerDataPushProtocol.Request(playerUUID, dataKey)); } } } diff --git a/service.friend/src/main/java/net/swofty/service/friend/FriendCache.java b/service.friend/src/main/java/net/swofty/service/friend/FriendCache.java index 5cd5ee6a8..e49031d10 100644 --- a/service.friend/src/main/java/net/swofty/service/friend/FriendCache.java +++ b/service.friend/src/main/java/net/swofty/service/friend/FriendCache.java @@ -7,7 +7,7 @@ import net.swofty.commons.friend.events.response.*; import net.swofty.commons.protocol.objects.friend.FriendEventPushProtocol; import net.swofty.commons.protocol.objects.messaging.SendMessagePushProtocol; -import net.swofty.service.generic.redis.ServiceToServerManager; +import net.swofty.commons.redis.RedisClient; import org.bson.Document; import org.tinylog.Logger; @@ -496,7 +496,7 @@ private static void persistFriendData(UUID playerUuid) { } private static void sendEvent(FriendEvent event) { - ServiceToServerManager.sendToAllServers( + RedisClient.requestAllServersFromService( new FriendEventPushProtocol(), new FriendEventPushProtocol.Request( event.getClass().getSimpleName(), @@ -512,7 +512,7 @@ private static void sendErrorToPlayer(UUID playerUUID, String message) { } private static void sendMessageToPlayer(UUID playerUUID, String message) { - ServiceToServerManager.sendToAllServers( + RedisClient.requestAllServersFromService( new SendMessagePushProtocol(), new SendMessagePushProtocol.Request(playerUUID, message), 300 diff --git a/service.generic/src/main/java/net/swofty/service/generic/ServiceInitializer.java b/service.generic/src/main/java/net/swofty/service/generic/ServiceInitializer.java index d8992a57a..5e769729c 100644 --- a/service.generic/src/main/java/net/swofty/service/generic/ServiceInitializer.java +++ b/service.generic/src/main/java/net/swofty/service/generic/ServiceInitializer.java @@ -4,6 +4,7 @@ import net.swofty.commons.config.ConfigProvider; import net.swofty.commons.protocol.RedisProtocol; import net.swofty.commons.redis.RedisChannels; +import net.swofty.commons.redis.RedisClient; import net.swofty.commons.redis.RedisEndpoint; import net.swofty.commons.redis.RedisMessageBus; import net.swofty.commons.redis.RedisMessageContext; @@ -12,7 +13,6 @@ import net.swofty.redisapi.api.RedisAPI; import net.swofty.service.generic.redis.PingEndpoint; import net.swofty.service.generic.redis.ServiceRedisManager; -import net.swofty.service.generic.redis.ServiceToServerManager; import org.tinylog.Logger; import java.util.ArrayList; @@ -29,7 +29,8 @@ public void init() { ItemAttribute.registerItemAttributes(); ServiceRedisManager.connect(ConfigProvider.settings().getRedisUri(), service.getType()); - ServiceToServerManager.initialize(service.getType()); + RedisClient.registerResponseChannel(RedisChannels.SERVICE_RESPONSE); + RedisClient.registerResponseChannel(RedisChannels.SERVICE_BROADCAST_RESPONSE); List endpoints = new ArrayList<>(service.getEndpoints()); endpoints.add(new PingEndpoint()); diff --git a/service.generic/src/main/java/net/swofty/service/generic/redis/ServiceRedisManager.java b/service.generic/src/main/java/net/swofty/service/generic/redis/ServiceRedisManager.java index 5e4723c38..1ae13157d 100644 --- a/service.generic/src/main/java/net/swofty/service/generic/redis/ServiceRedisManager.java +++ b/service.generic/src/main/java/net/swofty/service/generic/redis/ServiceRedisManager.java @@ -1,11 +1,14 @@ package net.swofty.service.generic.redis; import net.swofty.commons.ServiceType; +import net.swofty.commons.redis.RedisClient; +import net.swofty.commons.redis.RedisEndpoint; import net.swofty.redisapi.api.RedisAPI; public class ServiceRedisManager { public static void connect(String URI, ServiceType type) { RedisAPI.generateInstance(URI); RedisAPI.getInstance().setFilterId(type.name()); + RedisClient.identify(RedisEndpoint.service(type)); } } diff --git a/service.generic/src/main/java/net/swofty/service/generic/redis/ServiceToServerManager.java b/service.generic/src/main/java/net/swofty/service/generic/redis/ServiceToServerManager.java deleted file mode 100644 index 35eed1f97..000000000 --- a/service.generic/src/main/java/net/swofty/service/generic/redis/ServiceToServerManager.java +++ /dev/null @@ -1,123 +0,0 @@ -package net.swofty.service.generic.redis; - -import net.swofty.commons.ServiceType; -import net.swofty.commons.protocol.RedisProtocol; -import net.swofty.commons.redis.RedisChannels; -import net.swofty.commons.redis.RedisEndpoint; -import net.swofty.commons.redis.RedisMessageBus; -import net.swofty.commons.protocol.objects.data.GetPlayerDataPushProtocol; -import net.swofty.commons.protocol.objects.data.LockPlayerDataPushProtocol; -import net.swofty.commons.protocol.objects.data.UnlockPlayerDataPushProtocol; -import net.swofty.commons.protocol.objects.data.UpdatePlayerDataPushProtocol; -import net.swofty.commons.protocol.objects.game.GameInformationPushProtocol; -import net.swofty.commons.protocol.objects.gui.KickFromGUIPushProtocol; - -import java.util.List; -import java.util.Map; -import java.util.UUID; -import java.util.concurrent.CompletableFuture; -import java.util.concurrent.ConcurrentHashMap; - -public class ServiceToServerManager { - private static ServiceType currentServiceType; - - public static void initialize(ServiceType serviceType) { - currentServiceType = serviceType; - RedisMessageBus.registerResponseChannel(RedisChannels.SERVICE_RESPONSE); - RedisMessageBus.registerResponseChannel(RedisChannels.SERVICE_BROADCAST_RESPONSE); - } - - public static CompletableFuture sendToServer( - UUID serverUUID, - RedisProtocol protocol, - T message - ) { - return RedisMessageBus.request( - RedisEndpoint.service(currentServiceType), - serverUUID.toString(), - RedisChannels.serviceRequest(protocol), - RedisChannels.SERVICE_RESPONSE, - protocol, - message - ); - } - - public static CompletableFuture> sendToAllServers( - RedisProtocol protocol, - T message, - int timeoutMs - ) { - return RedisMessageBus.requestBroadcast( - RedisEndpoint.service(currentServiceType), - RedisChannels.ALL_SERVERS, - RedisChannels.serviceBroadcast(protocol), - RedisChannels.SERVICE_BROADCAST_RESPONSE, - protocol, - message, - timeoutMs - ); - } - - public static CompletableFuture> sendToServers( - List serverUUIDs, - RedisProtocol protocol, - T message - ) { - Map> futures = new ConcurrentHashMap<>(); - - for (UUID serverUUID : serverUUIDs) { - futures.put(serverUUID, sendToServer(serverUUID, protocol, message)); - } - - return CompletableFuture.allOf(futures.values().toArray(new CompletableFuture[0])) - .thenApply(v -> { - Map results = new ConcurrentHashMap<>(); - futures.forEach((uuid, future) -> { - try { - results.put(uuid, future.get()); - } catch (Exception e) { - // skip failed entries - } - }); - return results; - }); - } - - private static final GetPlayerDataPushProtocol GET_PLAYER_DATA_PROTOCOL = new GetPlayerDataPushProtocol(); - private static final UpdatePlayerDataPushProtocol UPDATE_PLAYER_DATA_PROTOCOL = new UpdatePlayerDataPushProtocol(); - private static final LockPlayerDataPushProtocol LOCK_PLAYER_DATA_PROTOCOL = new LockPlayerDataPushProtocol(); - private static final UnlockPlayerDataPushProtocol UNLOCK_PLAYER_DATA_PROTOCOL = new UnlockPlayerDataPushProtocol(); - - public static CompletableFuture getPlayerData(UUID serverUUID, UUID playerUUID, String dataKey) { - return sendToServer(serverUUID, GET_PLAYER_DATA_PROTOCOL, - new GetPlayerDataPushProtocol.Request(playerUUID, dataKey)); - } - - public static CompletableFuture updatePlayerData(UUID serverUUID, UUID playerUUID, String dataKey, String newData) { - return sendToServer(serverUUID, UPDATE_PLAYER_DATA_PROTOCOL, - new UpdatePlayerDataPushProtocol.Request(playerUUID, dataKey, newData)); - } - - public static CompletableFuture> lockPlayerData(List serverUUIDs, UUID playerUUID, String dataKey) { - return sendToServers(serverUUIDs, LOCK_PLAYER_DATA_PROTOCOL, - new LockPlayerDataPushProtocol.Request(playerUUID, dataKey)); - } - - public static CompletableFuture> unlockPlayerData(List serverUUIDs, UUID playerUUID, String dataKey) { - return sendToServers(serverUUIDs, UNLOCK_PLAYER_DATA_PROTOCOL, - new UnlockPlayerDataPushProtocol.Request(playerUUID, dataKey)); - } - - private static final KickFromGUIPushProtocol KICK_FROM_GUI_PROTOCOL = new KickFromGUIPushProtocol(); - private static final GameInformationPushProtocol GAME_INFORMATION_PROTOCOL = new GameInformationPushProtocol(); - - public static CompletableFuture> kickFromGUI(List serverUUIDs, List playerUUIDs, String guiType) { - return sendToServers(serverUUIDs, KICK_FROM_GUI_PROTOCOL, - new KickFromGUIPushProtocol.Request(playerUUIDs, guiType)); - } - - public static CompletableFuture> gameInformation(UUID serverUUID, UUID playerUUID, String gameId) { - return sendToServers(List.of(serverUUID), GAME_INFORMATION_PROTOCOL, - new GameInformationPushProtocol.Request(playerUUID, gameId)); - } -} diff --git a/service.orchestrator/src/main/java/net/swofty/service/orchestrator/endpoints/GameChooseEndpoint.java b/service.orchestrator/src/main/java/net/swofty/service/orchestrator/endpoints/GameChooseEndpoint.java index 05dd4337a..30783d14e 100644 --- a/service.orchestrator/src/main/java/net/swofty/service/orchestrator/endpoints/GameChooseEndpoint.java +++ b/service.orchestrator/src/main/java/net/swofty/service/orchestrator/endpoints/GameChooseEndpoint.java @@ -1,9 +1,10 @@ package net.swofty.service.orchestrator.endpoints; import net.swofty.commons.protocol.RedisProtocol; +import net.swofty.commons.protocol.objects.game.GameInformationPushProtocol; import net.swofty.commons.protocol.objects.orchestrator.ChooseGameProtocol; import net.swofty.commons.redis.RedisMessageHandler; -import net.swofty.service.generic.redis.ServiceToServerManager; +import net.swofty.commons.redis.RedisClient; import net.swofty.commons.redis.RedisMessageContext; public class GameChooseEndpoint implements RedisMessageHandler @@ -17,7 +18,8 @@ public RedisProtocol responseFuture = ServiceToServerManager.sendToServer( + CompletableFuture responseFuture = RedisClient.requestServerFromService( availableServer.uuid(), new InstantiateGamePushProtocol(), new InstantiateGamePushProtocol.Request(gameType.toString(), body.map()) @@ -133,7 +133,7 @@ private GetServerForMapProtocol.GetServerForMapResponse handleMurderMystery( ServerType.MURDER_MYSTERY_GAME, gameType.getMaxPlayers()); if (availableServer != null) { try { - CompletableFuture responseFuture = ServiceToServerManager.sendToServer( + CompletableFuture responseFuture = RedisClient.requestServerFromService( availableServer.uuid(), new InstantiateGamePushProtocol(), new InstantiateGamePushProtocol.Request(gameType.name(), body.map()) @@ -235,7 +235,7 @@ private GetServerForMapProtocol.GetServerForMapResponse handleSkywars( ServerType.SKYWARS_GAME, gameType.getMaxPlayers()); if (availableServer != null) { try { - CompletableFuture responseFuture = ServiceToServerManager.sendToServer( + CompletableFuture responseFuture = RedisClient.requestServerFromService( availableServer.uuid(), new InstantiateGamePushProtocol(), new InstantiateGamePushProtocol.Request(gameType.name(), body.map()) diff --git a/service.party/src/main/java/net/swofty/service/party/PartyCache.java b/service.party/src/main/java/net/swofty/service/party/PartyCache.java index eb03948ca..87e81f9f5 100644 --- a/service.party/src/main/java/net/swofty/service/party/PartyCache.java +++ b/service.party/src/main/java/net/swofty/service/party/PartyCache.java @@ -6,7 +6,7 @@ import net.swofty.commons.party.PendingParty; import net.swofty.commons.protocol.objects.messaging.SendMessagePushProtocol; import net.swofty.commons.protocol.objects.party.PartyBroadcastPushProtocol; -import net.swofty.service.generic.redis.ServiceToServerManager; +import net.swofty.commons.redis.RedisClient; import java.util.ArrayList; import java.util.HashMap; @@ -276,7 +276,7 @@ public static void handleWarp(PartyAction.Warp action) { .filter(uuid -> !uuid.equals(warperUUID)) .toList(); - Map responses = ServiceToServerManager.sendToAllServers( + Map responses = RedisClient.requestAllServersFromService( new PartyBroadcastPushProtocol(), new PartyBroadcastPushProtocol.Request(new PartyBroadcast.Warp(party, warperUUID)), WARP_BROADCAST_TIMEOUT_MS).join(); @@ -368,7 +368,7 @@ private static void cancelDisconnectTimer(UUID playerUUID) { } private static void broadcast(PartyBroadcast broadcast) { - ServiceToServerManager.sendToAllServers( + RedisClient.requestAllServersFromService( new PartyBroadcastPushProtocol(), new PartyBroadcastPushProtocol.Request(broadcast), BROADCAST_TIMEOUT_MS); @@ -376,7 +376,7 @@ private static void broadcast(PartyBroadcast broadcast) { private static void sendErrorToPlayer(UUID playerUUID, String message) { String separator = "§9§m-----------------------------------------------------"; - ServiceToServerManager.sendToAllServers( + RedisClient.requestAllServersFromService( new SendMessagePushProtocol(), new SendMessagePushProtocol.Request(playerUUID, separator + "\n" + message + "\n" + separator), BROADCAST_TIMEOUT_MS); diff --git a/type.generic/src/main/java/net/swofty/type/generic/chat/StaffChat.java b/type.generic/src/main/java/net/swofty/type/generic/chat/StaffChat.java index da9f39fea..6d8bd2850 100644 --- a/type.generic/src/main/java/net/swofty/type/generic/chat/StaffChat.java +++ b/type.generic/src/main/java/net/swofty/type/generic/chat/StaffChat.java @@ -1,7 +1,7 @@ package net.swofty.type.generic.chat; import net.swofty.commons.protocol.objects.proxy.to.StaffChatProtocol; -import net.swofty.proxyapi.redis.ServerOutboundMessage; +import net.swofty.commons.redis.RedisClient; import net.swofty.type.generic.user.HypixelPlayer; public final class StaffChat { @@ -20,8 +20,6 @@ public static void sendNotification(String message) { } private static void broadcastViaProxy(String formattedMessage) { - ServerOutboundMessage.sendToProxy(PROTOCOL, - new StaffChatProtocol.Request("message", formattedMessage, null), - response -> {}); + RedisClient.requestProxy(PROTOCOL, new StaffChatProtocol.Request("message", formattedMessage, null)); } } diff --git a/type.generic/src/main/java/net/swofty/type/generic/presence/PresenceHeartbeat.java b/type.generic/src/main/java/net/swofty/type/generic/presence/PresenceHeartbeat.java index 60f0c9735..4a0c72be5 100644 --- a/type.generic/src/main/java/net/swofty/type/generic/presence/PresenceHeartbeat.java +++ b/type.generic/src/main/java/net/swofty/type/generic/presence/PresenceHeartbeat.java @@ -5,7 +5,7 @@ import net.swofty.commons.ServiceType; import net.swofty.commons.presence.PresenceInfo; import net.swofty.commons.protocol.objects.presence.UpdatePresenceProtocol; -import net.swofty.proxyapi.redis.ServerOutboundMessage; +import net.swofty.commons.redis.RedisClient; import net.swofty.type.generic.HypixelConst; import net.swofty.type.generic.HypixelGenericLoader; import net.swofty.type.generic.user.HypixelPlayer; @@ -45,13 +45,11 @@ private static void pulse() { System.currentTimeMillis() ); - ServerOutboundMessage.sendMessageToService( + RedisClient.publishService( ServiceType.FRIEND, new UpdatePresenceProtocol(), - new UpdatePresenceProtocol.UpdatePresenceMessage(info), - (ignored) -> {} + new UpdatePresenceProtocol.UpdatePresenceMessage(info) ); } } } - diff --git a/type.generic/src/main/java/net/swofty/type/generic/user/flow/GenericPlayerDataFlow.java b/type.generic/src/main/java/net/swofty/type/generic/user/flow/GenericPlayerDataFlow.java index 24a740b32..46e08510f 100644 --- a/type.generic/src/main/java/net/swofty/type/generic/user/flow/GenericPlayerDataFlow.java +++ b/type.generic/src/main/java/net/swofty/type/generic/user/flow/GenericPlayerDataFlow.java @@ -1,7 +1,7 @@ package net.swofty.type.generic.user.flow; import net.swofty.commons.protocol.objects.proxy.to.FinishedWithPlayerProtocol; -import net.swofty.proxyapi.redis.ServerOutboundMessage; +import net.swofty.commons.redis.RedisClient; import net.swofty.type.generic.HypixelConst; import net.swofty.type.generic.data.DataHandler; import net.swofty.type.generic.data.Datapoint; @@ -109,9 +109,7 @@ public static void save(HypixelPlayer player) { gameHandler.removeFromCache(uuid); } - ServerOutboundMessage.sendToProxy(new FinishedWithPlayerProtocol(), - new FinishedWithPlayerProtocol.Request(uuid.toString()), - response -> {}); + RedisClient.requestProxy(new FinishedWithPlayerProtocol(), new FinishedWithPlayerProtocol.Request(uuid.toString())); MathUtility.delay(() -> HypixelConst.getTypeLoader().getTablistManager().deleteTablistEntries(player), 5); } diff --git a/velocity.extension/src/main/java/net/swofty/velocity/SkyBlockVelocity.java b/velocity.extension/src/main/java/net/swofty/velocity/SkyBlockVelocity.java index 8fec5db02..0e7b6dd30 100644 --- a/velocity.extension/src/main/java/net/swofty/velocity/SkyBlockVelocity.java +++ b/velocity.extension/src/main/java/net/swofty/velocity/SkyBlockVelocity.java @@ -42,6 +42,8 @@ import net.swofty.commons.protocol.RedisProtocol; import net.swofty.commons.protocol.objects.proxy.from.*; import net.swofty.commons.protocol.objects.punishment.GetActivePunishmentProtocol; +import net.swofty.commons.redis.RedisClient; +import net.swofty.commons.redis.RedisEndpoint; import net.swofty.commons.redis.RedisMessageHandler; import net.swofty.commons.punishment.ActivePunishment; import net.swofty.commons.punishment.PunishmentMessages; @@ -49,7 +51,6 @@ import net.swofty.commons.punishment.PunishmentTag; import net.swofty.commons.punishment.PunishmentType; import net.swofty.proxyapi.ProxyService; -import net.swofty.proxyapi.redis.ServerOutboundMessage; import net.swofty.redisapi.api.RedisAPI; import net.swofty.velocity.command.LimboCommand; import net.swofty.velocity.command.LobbyCommand; @@ -68,7 +69,6 @@ import net.swofty.velocity.packet.PlayerChannelHandler; import net.swofty.velocity.presence.PresencePublisher; import net.swofty.velocity.redis.RedisHandlerRegistry; -import net.swofty.velocity.redis.RedisMessage; import net.swofty.velocity.redis.listeners.ListenerStaffChat; import net.swofty.velocity.testflow.TestFlowManager; import net.swofty.velocity.viaversion.injector.SkyBlockViaInjector; @@ -225,6 +225,7 @@ public void onProxyInitialization(ProxyInitializeEvent event) { // Setup Redis RedisAPI.generateInstance(ConfigProvider.settings().getRedisUri()); RedisAPI.getInstance().setFilterId("proxy"); + RedisClient.identify(RedisEndpoint.proxy()); loopThroughPackage("net.swofty.velocity.redis.listeners", RedisMessageHandler.class) .forEach(RedisHandlerRegistry::register); RedisProtocol[] fromProxyProtocols = { @@ -234,10 +235,10 @@ public void onProxyInitialization(ProxyInitializeEvent event) { new GivePlayersOriginTypeProtocol(), new BroadcastStaffChatProtocol() }; for (RedisProtocol protocol : fromProxyProtocols) { - RedisMessage.registerProxyToServer(protocol); + RedisClient.registerResponseProtocol(protocol); } loopThroughPackage("net.swofty.commons.protocol.objects", RedisProtocol.class) - .forEach(ServerOutboundMessage::registerResponseProtocol); + .forEach(RedisClient::registerResponseProtocol); RedisAPI.getInstance().startListeners(); // Setup GameManager diff --git a/velocity.extension/src/main/java/net/swofty/velocity/gamemanager/GameManager.java b/velocity.extension/src/main/java/net/swofty/velocity/gamemanager/GameManager.java index 5a9cbfbd0..4e96bd4cb 100644 --- a/velocity.extension/src/main/java/net/swofty/velocity/gamemanager/GameManager.java +++ b/velocity.extension/src/main/java/net/swofty/velocity/gamemanager/GameManager.java @@ -8,7 +8,7 @@ import net.swofty.commons.config.ConfigProvider; import net.swofty.commons.protocol.objects.proxy.from.PingServerProtocol; import net.swofty.velocity.SkyBlockVelocity; -import net.swofty.velocity.redis.RedisMessage; +import net.swofty.commons.redis.RedisClient; import net.swofty.velocity.testflow.TestFlowManager; import org.jetbrains.annotations.Nullable; @@ -104,7 +104,7 @@ public static void loopServers(ProxyServer server) { AtomicBoolean pingSuccess = new AtomicBoolean(false); long startTime = System.currentTimeMillis(); - RedisMessage.sendMessageToServer(registeredServer.internalID(), + RedisClient.requestServer(registeredServer.internalID(), new PingServerProtocol(), new PingServerProtocol.Request() ).thenRun(() -> { pingSuccess.set(true); diff --git a/velocity.extension/src/main/java/net/swofty/velocity/gamemanager/TransferHandler.java b/velocity.extension/src/main/java/net/swofty/velocity/gamemanager/TransferHandler.java index 8592726a7..cd2947dda 100644 --- a/velocity.extension/src/main/java/net/swofty/velocity/gamemanager/TransferHandler.java +++ b/velocity.extension/src/main/java/net/swofty/velocity/gamemanager/TransferHandler.java @@ -7,7 +7,7 @@ import net.swofty.commons.protocol.objects.proxy.from.GivePlayersOriginTypeProtocol; import net.swofty.commons.protocol.objects.proxy.from.PlayerSwitchedProtocol; import net.swofty.velocity.SkyBlockVelocity; -import net.swofty.velocity.redis.RedisMessage; +import net.swofty.commons.redis.RedisClient; import java.util.Map; import java.util.Set; @@ -66,7 +66,7 @@ public void previousServerIsFinished(RegisteredServer manualPick) { UUID serverUUID = UUID.fromString(manualPick.getServerInfo().getName()); UUID originServerUUID = UUID.fromString(originServer.getServerInfo().getName()); - RedisMessage.sendMessageToServer(serverUUID, + RedisClient.requestServer(serverUUID, new GivePlayersOriginTypeProtocol(), new GivePlayersOriginTypeProtocol.Request( player.getUniqueId().toString(), originServerType.name())); @@ -78,7 +78,7 @@ public void previousServerIsFinished(RegisteredServer manualPick) { player.sendMessage(Component.text("§7Sending to server " + manualPickAsGame.displayName() + "...")); player.createConnectionRequest(manualPick).connectWithIndication(); - RedisMessage.sendMessageToServer(originServerUUID, + RedisClient.requestServer(originServerUUID, new PlayerSwitchedProtocol(), new PlayerSwitchedProtocol.Request(player.getUniqueId().toString())); }).start(); @@ -112,7 +112,7 @@ public void previousServerIsFinished() { UUID sendingToServerUUID = server.internalID(); ServerType originServerType = GameManager.getTypeFromRegisteredServer(originServer); - RedisMessage.sendMessageToServer(sendingToServerUUID, + RedisClient.requestServer(sendingToServerUUID, new GivePlayersOriginTypeProtocol(), new GivePlayersOriginTypeProtocol.Request( player.getUniqueId().toString(), originServerType.name())); @@ -123,7 +123,7 @@ public void previousServerIsFinished() { player.sendMessage(Component.text("§7Sending to server " + server.displayName() + "...")); player.createConnectionRequest(server.registeredServer()).connectWithIndication(); - RedisMessage.sendMessageToServer(originServerUUID, + RedisClient.requestServer(originServerUUID, new PlayerSwitchedProtocol(), new PlayerSwitchedProtocol.Request(player.getUniqueId().toString())); }).start(); @@ -166,7 +166,7 @@ public CompletableFuture transferTo(RegisteredServer toTransferTo) { UUID serverUUID = UUID.fromString(toTransferTo.getServerInfo().getName()); if (originServer != null && originServerType != null) { - RedisMessage.sendMessageToServer(serverUUID, + RedisClient.requestServer(serverUUID, new GivePlayersOriginTypeProtocol(), new GivePlayersOriginTypeProtocol.Request( player.getUniqueId().toString(), originServerType.name())); diff --git a/velocity.extension/src/main/java/net/swofty/velocity/gamemanager/impl/IslandCheck.java b/velocity.extension/src/main/java/net/swofty/velocity/gamemanager/impl/IslandCheck.java index cd6960154..82a5b0bd1 100644 --- a/velocity.extension/src/main/java/net/swofty/velocity/gamemanager/impl/IslandCheck.java +++ b/velocity.extension/src/main/java/net/swofty/velocity/gamemanager/impl/IslandCheck.java @@ -7,7 +7,7 @@ import net.swofty.velocity.data.UserDatabase; import net.swofty.velocity.gamemanager.BalanceConfiguration; import net.swofty.velocity.gamemanager.GameManager; -import net.swofty.velocity.redis.RedisMessage; +import net.swofty.commons.redis.RedisClient; import org.bson.Document; import org.jetbrains.annotations.NotNull; @@ -49,7 +49,7 @@ private static AtomicReference getGameServerAtomicRefere ArrayList gameServers = entry.getValue(); gameServers.forEach(gameServer -> { - DoesServerHaveIslandProtocol.Response response = RedisMessage.sendMessageToServer( + DoesServerHaveIslandProtocol.Response response = RedisClient.requestServer( gameServer.internalID(), new DoesServerHaveIslandProtocol(), new DoesServerHaveIslandProtocol.Request(islandUUID.toString())).join(); diff --git a/velocity.extension/src/main/java/net/swofty/velocity/presence/PresencePublisher.java b/velocity.extension/src/main/java/net/swofty/velocity/presence/PresencePublisher.java index a7a1a9691..79027305f 100644 --- a/velocity.extension/src/main/java/net/swofty/velocity/presence/PresencePublisher.java +++ b/velocity.extension/src/main/java/net/swofty/velocity/presence/PresencePublisher.java @@ -4,7 +4,7 @@ import com.velocitypowered.api.proxy.server.RegisteredServer; import net.swofty.commons.presence.PresenceInfo; import net.swofty.commons.protocol.objects.presence.UpdatePresenceProtocol; -import net.swofty.proxyapi.redis.ServerOutboundMessage; +import net.swofty.commons.redis.RedisClient; import java.util.UUID; @@ -21,7 +21,7 @@ public static void publish(Player player, boolean online, String serverType, UUI System.currentTimeMillis() ); - ServerOutboundMessage.sendMessageToAllServicesFireAndForget( + RedisClient.publishAllServices( new UpdatePresenceProtocol(), new UpdatePresenceProtocol.UpdatePresenceMessage(info) ); @@ -38,4 +38,3 @@ public static void publish(Player player, boolean online, RegisteredServer serve publish(player, online, serverType, serverId); } } - diff --git a/velocity.extension/src/main/java/net/swofty/velocity/redis/RedisMessage.java b/velocity.extension/src/main/java/net/swofty/velocity/redis/RedisMessage.java deleted file mode 100644 index da74ccd49..000000000 --- a/velocity.extension/src/main/java/net/swofty/velocity/redis/RedisMessage.java +++ /dev/null @@ -1,28 +0,0 @@ -package net.swofty.velocity.redis; - -import net.swofty.commons.protocol.RedisProtocol; -import net.swofty.commons.redis.RedisChannels; -import net.swofty.commons.redis.RedisEndpoint; -import net.swofty.commons.redis.RedisMessageBus; - -import java.util.UUID; -import java.util.concurrent.CompletableFuture; - -public class RedisMessage { - public static CompletableFuture sendMessageToServer(UUID server, - RedisProtocol protocol, - T message) { - return RedisMessageBus.request( - RedisEndpoint.proxy(), - server.toString(), - RedisChannels.protocol(protocol), - RedisChannels.protocol(protocol), - protocol, - message - ); - } - - public static void registerProxyToServer(RedisProtocol protocol) { - RedisMessageBus.registerResponseChannel(RedisChannels.protocol(protocol)); - } -} diff --git a/velocity.extension/src/main/java/net/swofty/velocity/redis/listeners/ListenerPlayerHandler.java b/velocity.extension/src/main/java/net/swofty/velocity/redis/listeners/ListenerPlayerHandler.java index 4473791a8..4098e209c 100644 --- a/velocity.extension/src/main/java/net/swofty/velocity/redis/listeners/ListenerPlayerHandler.java +++ b/velocity.extension/src/main/java/net/swofty/velocity/redis/listeners/ListenerPlayerHandler.java @@ -19,7 +19,7 @@ import net.swofty.velocity.presence.PresencePublisher; import net.swofty.commons.redis.RedisMessageContext; import net.swofty.commons.redis.RedisMessageHandler; -import net.swofty.velocity.redis.RedisMessage; +import net.swofty.commons.redis.RedisClient; import java.util.Map; import java.util.Optional; @@ -125,7 +125,7 @@ public PlayerHandlerProtocol.Response handle(PlayerHandlerProtocol.Request messa Number z = (Number) data.get("z"); Number yaw = (Number) data.get("yaw"); Number pitch = (Number) data.get("pitch"); - RedisMessage.sendMessageToServer(server, + RedisClient.requestServer(server, new TeleportProtocol(), new TeleportProtocol.Request(uuid.toString(), x.doubleValue(), y.doubleValue(), z.doubleValue(), @@ -136,7 +136,7 @@ public PlayerHandlerProtocol.Response handle(PlayerHandlerProtocol.Request messa return EMPTY; } UUID server = UUID.fromString(potentialServer.get().getServer().getServerInfo().getName()); - RedisMessage.sendMessageToServer(server, + RedisClient.requestServer(server, new RunEventProtocol(), new RunEventProtocol.Request(uuid.toString(), (String) data.get("event"), @@ -147,7 +147,7 @@ public PlayerHandlerProtocol.Response handle(PlayerHandlerProtocol.Request messa return EMPTY; } UUID server = UUID.fromString(potentialServer.get().getServer().getServerInfo().getName()); - RedisMessage.sendMessageToServer(server, + RedisClient.requestServer(server, new RefreshCoopDataProtocol(), new RefreshCoopDataProtocol.Request(uuid.toString(), (String) data.get("datapoint"))).join(); diff --git a/velocity.extension/src/main/java/net/swofty/velocity/redis/listeners/ListenerStaffChat.java b/velocity.extension/src/main/java/net/swofty/velocity/redis/listeners/ListenerStaffChat.java index f8dd93bbe..27c6ef8ec 100644 --- a/velocity.extension/src/main/java/net/swofty/velocity/redis/listeners/ListenerStaffChat.java +++ b/velocity.extension/src/main/java/net/swofty/velocity/redis/listeners/ListenerStaffChat.java @@ -6,7 +6,7 @@ import net.swofty.velocity.gamemanager.GameManager; import net.swofty.commons.redis.RedisMessageContext; import net.swofty.commons.redis.RedisMessageHandler; -import net.swofty.velocity.redis.RedisMessage; +import net.swofty.commons.redis.RedisClient; import java.util.UUID; @@ -29,7 +29,7 @@ public StaffChatProtocol.Response handle(StaffChatProtocol.Request message, Redi public static void broadcastToAllServers(BroadcastStaffChatProtocol.Request message) { GameManager.getServers().forEach((serverType, serverList) -> { serverList.forEach(gameServer -> { - RedisMessage.sendMessageToServer( + RedisClient.requestServer( gameServer.internalID(), new BroadcastStaffChatProtocol(), message From 36383eb7622bbe531488b6b4a0a113dca7e81868 Mon Sep 17 00:00:00 2001 From: "Jacob Nardella (Swofty)" Date: Fri, 15 May 2026 13:35:50 +1000 Subject: [PATCH 107/113] feat(fishing): add full trophy fish roster --- .../commons/skyblock/item/ItemType.java | 144 +++++++++++ .../skyblock/fishing/trophy_fish.yml | 182 +++++++++++++- .../skyblock/items/fishing/trophy_fish.yml | 223 ++++++++++++++++++ .../fishing/FishingContext.java | 2 + .../fishing/FishingService.java | 1 + .../fishing/catches/CatchPayload.java | 8 + .../fishing/registry/FishingRegistry.java | 1 + .../registry/TrophyFishDefinition.java | 1 + .../fishing/resolver/FishingLootResolver.java | 88 +++++-- 9 files changed, 617 insertions(+), 33 deletions(-) create mode 100644 configuration/skyblock/items/fishing/trophy_fish.yml diff --git a/commons/src/generated/java/net/swofty/commons/skyblock/item/ItemType.java b/commons/src/generated/java/net/swofty/commons/skyblock/item/ItemType.java index 0021effb6..ccfbbf17e 100644 --- a/commons/src/generated/java/net/swofty/commons/skyblock/item/ItemType.java +++ b/commons/src/generated/java/net/swofty/commons/skyblock/item/ItemType.java @@ -406,14 +406,50 @@ public enum ItemType { BROKEN_RADAR(Material.PLAYER_HEAD, Rarity.UNCOMMON), + BRONZE_BLOBFISH(Material.PLAYER_HEAD, Rarity.COMMON), + BRONZE_BOWL(Material.PLAYER_HEAD, Rarity.UNCOMMON), + BRONZE_FLYFISH(Material.PLAYER_HEAD, Rarity.COMMON), + + BRONZE_GOLDEN_FISH(Material.PLAYER_HEAD, Rarity.COMMON), + + BRONZE_GUSHER(Material.PLAYER_HEAD, Rarity.COMMON), + + BRONZE_KARATE_FISH(Material.PLAYER_HEAD, Rarity.COMMON), + + BRONZE_LAVAHORSE(Material.PLAYER_HEAD, Rarity.COMMON), + + BRONZE_MANA_RAY(Material.PLAYER_HEAD, Rarity.COMMON), + + BRONZE_MOLDFIN(Material.PLAYER_HEAD, Rarity.COMMON), + + BRONZE_OBFUSCATED_1(Material.PLAYER_HEAD, Rarity.COMMON), + + BRONZE_OBFUSCATED_2(Material.PLAYER_HEAD, Rarity.COMMON), + + BRONZE_OBFUSCATED_3(Material.PLAYER_HEAD, Rarity.COMMON), + BRONZE_SHIP_ENGINE(Material.PLAYER_HEAD, Rarity.RARE), BRONZE_SHIP_HELM(Material.PLAYER_HEAD, Rarity.RARE), BRONZE_SHIP_HULL(Material.PLAYER_HEAD, Rarity.RARE), + BRONZE_SKELETON_FISH(Material.PLAYER_HEAD, Rarity.COMMON), + + BRONZE_SLUGFISH(Material.PLAYER_HEAD, Rarity.COMMON), + + BRONZE_SOUL_FISH(Material.PLAYER_HEAD, Rarity.COMMON), + + BRONZE_STEAMING_HOT_FLOUNDER(Material.PLAYER_HEAD, Rarity.COMMON), + + BRONZE_SULPHUR_SKITTER(Material.PLAYER_HEAD, Rarity.COMMON), + + BRONZE_VANILLE(Material.PLAYER_HEAD, Rarity.COMMON), + + BRONZE_VOLCANIC_STONEFISH(Material.PLAYER_HEAD, Rarity.COMMON), + BROWN_BANNER(Material.BROWN_BANNER, Rarity.COMMON), BROWN_BED(Material.BROWN_BED, Rarity.COMMON), @@ -900,32 +936,68 @@ public enum ItemType { DIAMOND_AXE(Material.DIAMOND_AXE, Rarity.COMMON), + DIAMOND_BLOBFISH(Material.PLAYER_HEAD, Rarity.COMMON), + DIAMOND_BLOCK(Material.DIAMOND_BLOCK, Rarity.COMMON), DIAMOND_BOOTS(Material.DIAMOND_BOOTS, Rarity.COMMON), DIAMOND_CHESTPLATE(Material.DIAMOND_CHESTPLATE, Rarity.COMMON), + DIAMOND_FLYFISH(Material.PLAYER_HEAD, Rarity.COMMON), + + DIAMOND_GOLDEN_FISH(Material.PLAYER_HEAD, Rarity.COMMON), + + DIAMOND_GUSHER(Material.PLAYER_HEAD, Rarity.COMMON), + DIAMOND_HELMET(Material.DIAMOND_HELMET, Rarity.COMMON), DIAMOND_HOE(Material.DIAMOND_HOE, Rarity.COMMON), + DIAMOND_KARATE_FISH(Material.PLAYER_HEAD, Rarity.COMMON), + + DIAMOND_LAVAHORSE(Material.PLAYER_HEAD, Rarity.COMMON), + DIAMOND_LEGGINGS(Material.DIAMOND_LEGGINGS, Rarity.COMMON), DIAMOND_MAGMAFISH(Material.PLAYER_HEAD, Rarity.COMMON), + DIAMOND_MANA_RAY(Material.PLAYER_HEAD, Rarity.COMMON), + DIAMOND_MINION(Material.PLAYER_HEAD, Rarity.COMMON), + DIAMOND_MOLDFIN(Material.PLAYER_HEAD, Rarity.COMMON), + + DIAMOND_OBFUSCATED_1(Material.PLAYER_HEAD, Rarity.COMMON), + + DIAMOND_OBFUSCATED_2(Material.PLAYER_HEAD, Rarity.COMMON), + + DIAMOND_OBFUSCATED_3(Material.PLAYER_HEAD, Rarity.COMMON), + DIAMOND_ORE(Material.DIAMOND_ORE, Rarity.COMMON), DIAMOND_PICKAXE(Material.DIAMOND_PICKAXE, Rarity.COMMON), DIAMOND_SHOVEL(Material.DIAMOND_SHOVEL, Rarity.COMMON), + DIAMOND_SKELETON_FISH(Material.PLAYER_HEAD, Rarity.COMMON), + + DIAMOND_SLUGFISH(Material.PLAYER_HEAD, Rarity.COMMON), + + DIAMOND_SOUL_FISH(Material.PLAYER_HEAD, Rarity.COMMON), + DIAMOND_SPREADING(Material.DIAMOND, Rarity.COMMON), + DIAMOND_STEAMING_HOT_FLOUNDER(Material.PLAYER_HEAD, Rarity.COMMON), + + DIAMOND_SULPHUR_SKITTER(Material.PLAYER_HEAD, Rarity.COMMON), + DIAMOND_SWORD(Material.DIAMOND_SWORD, Rarity.COMMON), + DIAMOND_VANILLE(Material.PLAYER_HEAD, Rarity.COMMON), + + DIAMOND_VOLCANIC_STONEFISH(Material.PLAYER_HEAD, Rarity.COMMON), + DIGESTED_MOSQUITO(Material.ROTTEN_FLESH, Rarity.LEGENDARY), DIORITE(Material.DIORITE, Rarity.COMMON), @@ -1580,20 +1652,56 @@ public enum ItemType { GOLDEN_TOOTH(Material.GOLD_NUGGET, Rarity.RARE), + GOLD_BLOBFISH(Material.PLAYER_HEAD, Rarity.COMMON), + GOLD_BLOCK(Material.GOLD_BLOCK, Rarity.COMMON), + GOLD_FLYFISH(Material.PLAYER_HEAD, Rarity.COMMON), + GOLD_GIFT_TALISMAN(Material.PLAYER_HEAD, Rarity.LEGENDARY), + GOLD_GOLDEN_FISH(Material.PLAYER_HEAD, Rarity.COMMON), + + GOLD_GUSHER(Material.PLAYER_HEAD, Rarity.COMMON), + GOLD_INGOT(Material.GOLD_INGOT, Rarity.COMMON), + GOLD_KARATE_FISH(Material.PLAYER_HEAD, Rarity.COMMON), + + GOLD_LAVAHORSE(Material.PLAYER_HEAD, Rarity.COMMON), + GOLD_MAGMAFISH(Material.PLAYER_HEAD, Rarity.COMMON), + GOLD_MANA_RAY(Material.PLAYER_HEAD, Rarity.COMMON), + GOLD_MINION(Material.PLAYER_HEAD, Rarity.COMMON), + GOLD_MOLDFIN(Material.PLAYER_HEAD, Rarity.COMMON), + GOLD_NUGGET(Material.GOLD_NUGGET, Rarity.COMMON), + GOLD_OBFUSCATED_1(Material.PLAYER_HEAD, Rarity.COMMON), + + GOLD_OBFUSCATED_2(Material.PLAYER_HEAD, Rarity.COMMON), + + GOLD_OBFUSCATED_3(Material.PLAYER_HEAD, Rarity.COMMON), + GOLD_ORE(Material.GOLD_ORE, Rarity.COMMON), + GOLD_SKELETON_FISH(Material.PLAYER_HEAD, Rarity.COMMON), + + GOLD_SLUGFISH(Material.PLAYER_HEAD, Rarity.COMMON), + + GOLD_SOUL_FISH(Material.PLAYER_HEAD, Rarity.COMMON), + + GOLD_STEAMING_HOT_FLOUNDER(Material.PLAYER_HEAD, Rarity.COMMON), + + GOLD_SULPHUR_SKITTER(Material.PLAYER_HEAD, Rarity.COMMON), + + GOLD_VANILLE(Material.PLAYER_HEAD, Rarity.COMMON), + + GOLD_VOLCANIC_STONEFISH(Material.PLAYER_HEAD, Rarity.COMMON), + GRANITE(Material.GRANITE, Rarity.COMMON), GRANITE_SLAB(Material.GRANITE_SLAB, Rarity.COMMON), @@ -2982,10 +3090,46 @@ public enum ItemType { SHREDDED_LINE(Material.PLAYER_HEAD, Rarity.RARE), + SILVER_BLOBFISH(Material.PLAYER_HEAD, Rarity.COMMON), + SILVER_FANG(Material.IRON_SWORD, Rarity.UNCOMMON), + SILVER_FLYFISH(Material.PLAYER_HEAD, Rarity.COMMON), + + SILVER_GOLDEN_FISH(Material.PLAYER_HEAD, Rarity.COMMON), + + SILVER_GUSHER(Material.PLAYER_HEAD, Rarity.COMMON), + + SILVER_KARATE_FISH(Material.PLAYER_HEAD, Rarity.COMMON), + + SILVER_LAVAHORSE(Material.PLAYER_HEAD, Rarity.COMMON), + SILVER_MAGMAFISH(Material.PLAYER_HEAD, Rarity.COMMON), + SILVER_MANA_RAY(Material.PLAYER_HEAD, Rarity.COMMON), + + SILVER_MOLDFIN(Material.PLAYER_HEAD, Rarity.COMMON), + + SILVER_OBFUSCATED_1(Material.PLAYER_HEAD, Rarity.COMMON), + + SILVER_OBFUSCATED_2(Material.PLAYER_HEAD, Rarity.COMMON), + + SILVER_OBFUSCATED_3(Material.PLAYER_HEAD, Rarity.COMMON), + + SILVER_SKELETON_FISH(Material.PLAYER_HEAD, Rarity.COMMON), + + SILVER_SLUGFISH(Material.PLAYER_HEAD, Rarity.COMMON), + + SILVER_SOUL_FISH(Material.PLAYER_HEAD, Rarity.COMMON), + + SILVER_STEAMING_HOT_FLOUNDER(Material.PLAYER_HEAD, Rarity.COMMON), + + SILVER_SULPHUR_SKITTER(Material.PLAYER_HEAD, Rarity.COMMON), + + SILVER_VANILLE(Material.PLAYER_HEAD, Rarity.COMMON), + + SILVER_VOLCANIC_STONEFISH(Material.PLAYER_HEAD, Rarity.COMMON), + SINFUL_DICE(Material.PLAYER_HEAD, Rarity.EPIC), SINSEEKER_SCYTHE(Material.GOLDEN_HOE, Rarity.EPIC), diff --git a/configuration/skyblock/fishing/trophy_fish.yml b/configuration/skyblock/fishing/trophy_fish.yml index 229f74b3d..221ff93b0 100644 --- a/configuration/skyblock/fishing/trophy_fish.yml +++ b/configuration/skyblock/fishing/trophy_fish.yml @@ -1,13 +1,171 @@ trophyFish: - - id: MAGMAFISH - displayName: Magmafish - catchChance: 18 - regions: [ ] - requiredFishingLevel: 0 - minimumCastTimeMs: 0 - requiresStarterRodWithoutEnchantments: false - specialGoldenFish: false - bronzeItemId: MAGMAFISH - silverItemId: SILVER_MAGMAFISH - goldItemId: GOLD_MAGMAFISH - diamondItemId: DIAMOND_MAGMAFISH + - id: SULPHUR_SKITTER + displayName: Sulphur Skitter + catchChance: 30 + regions: [BLAZING_VOLCANO] + requiredFishingLevel: 0 + bronzeItemId: BRONZE_SULPHUR_SKITTER + silverItemId: SILVER_SULPHUR_SKITTER + goldItemId: GOLD_SULPHUR_SKITTER + diamondItemId: DIAMOND_SULPHUR_SKITTER + - id: BLOBFISH + displayName: Blobfish + catchChance: 25 + regions: [ ] + requiredFishingLevel: 0 + bronzeItemId: BRONZE_BLOBFISH + silverItemId: SILVER_BLOBFISH + goldItemId: GOLD_BLOBFISH + diamondItemId: DIAMOND_BLOBFISH + - id: OBFUSCATED_1 + displayName: Obfuscated 1 + catchChance: 25 + regions: [ ] + requiredFishingLevel: 0 + requiredBaitId: CORRUPTED_BAIT + bronzeItemId: BRONZE_OBFUSCATED_1 + silverItemId: SILVER_OBFUSCATED_1 + goldItemId: GOLD_OBFUSCATED_1 + diamondItemId: DIAMOND_OBFUSCATED_1 + - id: STEAMING_HOT_FLOUNDER + displayName: Steaming-Hot Flounder + catchChance: 20 + regions: [BLAZING_VOLCANO] + requiredFishingLevel: 0 + bronzeItemId: BRONZE_STEAMING_HOT_FLOUNDER + silverItemId: SILVER_STEAMING_HOT_FLOUNDER + goldItemId: GOLD_STEAMING_HOT_FLOUNDER + diamondItemId: DIAMOND_STEAMING_HOT_FLOUNDER + - id: GUSHER + displayName: Gusher + catchChance: 20 + regions: [BLAZING_VOLCANO] + requiredFishingLevel: 0 + bronzeItemId: BRONZE_GUSHER + silverItemId: SILVER_GUSHER + goldItemId: GOLD_GUSHER + diamondItemId: DIAMOND_GUSHER + - id: OBFUSCATED_2 + displayName: Obfuscated 2 + catchChance: 20 + regions: [ ] + requiredFishingLevel: 0 + requiredBaitId: BRONZE_OBFUSCATED_1 + bronzeItemId: BRONZE_OBFUSCATED_2 + silverItemId: SILVER_OBFUSCATED_2 + goldItemId: GOLD_OBFUSCATED_2 + diamondItemId: DIAMOND_OBFUSCATED_2 + - id: SLUGFISH + displayName: Slugfish + catchChance: 15 + regions: [ ] + requiredFishingLevel: 0 + minimumCastTimeMs: 20000 + bronzeItemId: BRONZE_SLUGFISH + silverItemId: SILVER_SLUGFISH + goldItemId: GOLD_SLUGFISH + diamondItemId: DIAMOND_SLUGFISH + - id: OBFUSCATED_3 + displayName: Obfuscated 3 + catchChance: 10 + regions: [ ] + requiredFishingLevel: 0 + requiredBaitId: BRONZE_OBFUSCATED_2 + bronzeItemId: BRONZE_OBFUSCATED_3 + silverItemId: SILVER_OBFUSCATED_3 + goldItemId: GOLD_OBFUSCATED_3 + diamondItemId: DIAMOND_OBFUSCATED_3 + - id: FLYFISH + displayName: Flyfish + catchChance: 8 + regions: [BLAZING_VOLCANO] + requiredFishingLevel: 0 + minimumBobberDepth: 8 + bronzeItemId: BRONZE_FLYFISH + silverItemId: SILVER_FLYFISH + goldItemId: GOLD_FLYFISH + diamondItemId: DIAMOND_FLYFISH + - id: VANILLE + displayName: Vanille + catchChance: 8 + regions: [ ] + requiredFishingLevel: 0 + requiresStarterRodWithoutEnchantments: true + bronzeItemId: BRONZE_VANILLE + silverItemId: SILVER_VANILLE + goldItemId: GOLD_VANILLE + diamondItemId: DIAMOND_VANILLE + - id: LAVAHORSE + displayName: Lavahorse + catchChance: 4 + regions: [ ] + requiredFishingLevel: 0 + bronzeItemId: BRONZE_LAVAHORSE + silverItemId: SILVER_LAVAHORSE + goldItemId: GOLD_LAVAHORSE + diamondItemId: DIAMOND_LAVAHORSE + - id: MANA_RAY + displayName: Mana Ray + catchChance: 0 + regions: [ ] + requiredFishingLevel: 0 + minimumMana: 1200 + bronzeItemId: BRONZE_MANA_RAY + silverItemId: SILVER_MANA_RAY + goldItemId: GOLD_MANA_RAY + diamondItemId: DIAMOND_MANA_RAY + - id: VOLCANIC_STONEFISH + displayName: Volcanic Stonefish + catchChance: 3 + regions: [BLAZING_VOLCANO] + requiredFishingLevel: 0 + bronzeItemId: BRONZE_VOLCANIC_STONEFISH + silverItemId: SILVER_VOLCANIC_STONEFISH + goldItemId: GOLD_VOLCANIC_STONEFISH + diamondItemId: DIAMOND_VOLCANIC_STONEFISH + - id: SKELETON_FISH + displayName: Skeleton Fish + catchChance: 2 + regions: [BURNING_DESERT] + requiredFishingLevel: 0 + bronzeItemId: BRONZE_SKELETON_FISH + silverItemId: SILVER_SKELETON_FISH + goldItemId: GOLD_SKELETON_FISH + diamondItemId: DIAMOND_SKELETON_FISH + - id: MOLDFIN + displayName: Moldfin + catchChance: 2 + regions: [MYSTIC_MARSH] + requiredFishingLevel: 0 + bronzeItemId: BRONZE_MOLDFIN + silverItemId: SILVER_MOLDFIN + goldItemId: GOLD_MOLDFIN + diamondItemId: DIAMOND_MOLDFIN + - id: SOUL_FISH + displayName: Soul Fish + catchChance: 2 + regions: [STRONGHOLD] + requiredFishingLevel: 0 + bronzeItemId: BRONZE_SOUL_FISH + silverItemId: SILVER_SOUL_FISH + goldItemId: GOLD_SOUL_FISH + diamondItemId: DIAMOND_SOUL_FISH + - id: KARATE_FISH + displayName: Karate Fish + catchChance: 2 + regions: [DOJO] + requiredFishingLevel: 0 + bronzeItemId: BRONZE_KARATE_FISH + silverItemId: SILVER_KARATE_FISH + goldItemId: GOLD_KARATE_FISH + diamondItemId: DIAMOND_KARATE_FISH + - id: GOLDEN_FISH + displayName: Golden Fish + catchChance: 0 + regions: [ ] + requiredFishingLevel: 0 + specialGoldenFish: true + bronzeItemId: BRONZE_GOLDEN_FISH + silverItemId: SILVER_GOLDEN_FISH + goldItemId: GOLD_GOLDEN_FISH + diamondItemId: DIAMOND_GOLDEN_FISH diff --git a/configuration/skyblock/items/fishing/trophy_fish.yml b/configuration/skyblock/items/fishing/trophy_fish.yml new file mode 100644 index 000000000..1ec3e5aa4 --- /dev/null +++ b/configuration/skyblock/items/fishing/trophy_fish.yml @@ -0,0 +1,223 @@ +items: + - id: BRONZE_SULPHUR_SKITTER + material: PLAYER_HEAD + rarity: COMMON + - id: SILVER_SULPHUR_SKITTER + material: PLAYER_HEAD + rarity: COMMON + - id: GOLD_SULPHUR_SKITTER + material: PLAYER_HEAD + rarity: COMMON + - id: DIAMOND_SULPHUR_SKITTER + material: PLAYER_HEAD + rarity: COMMON + - id: BRONZE_BLOBFISH + material: PLAYER_HEAD + rarity: COMMON + - id: SILVER_BLOBFISH + material: PLAYER_HEAD + rarity: COMMON + - id: GOLD_BLOBFISH + material: PLAYER_HEAD + rarity: COMMON + - id: DIAMOND_BLOBFISH + material: PLAYER_HEAD + rarity: COMMON + - id: BRONZE_OBFUSCATED_1 + material: PLAYER_HEAD + rarity: COMMON + components: + - id: FISHING_BAIT + mediums: [LAVA] + - id: SILVER_OBFUSCATED_1 + material: PLAYER_HEAD + rarity: COMMON + - id: GOLD_OBFUSCATED_1 + material: PLAYER_HEAD + rarity: COMMON + - id: DIAMOND_OBFUSCATED_1 + material: PLAYER_HEAD + rarity: COMMON + - id: BRONZE_STEAMING_HOT_FLOUNDER + material: PLAYER_HEAD + rarity: COMMON + - id: SILVER_STEAMING_HOT_FLOUNDER + material: PLAYER_HEAD + rarity: COMMON + - id: GOLD_STEAMING_HOT_FLOUNDER + material: PLAYER_HEAD + rarity: COMMON + - id: DIAMOND_STEAMING_HOT_FLOUNDER + material: PLAYER_HEAD + rarity: COMMON + - id: BRONZE_GUSHER + material: PLAYER_HEAD + rarity: COMMON + - id: SILVER_GUSHER + material: PLAYER_HEAD + rarity: COMMON + - id: GOLD_GUSHER + material: PLAYER_HEAD + rarity: COMMON + - id: DIAMOND_GUSHER + material: PLAYER_HEAD + rarity: COMMON + - id: BRONZE_OBFUSCATED_2 + material: PLAYER_HEAD + rarity: COMMON + components: + - id: FISHING_BAIT + mediums: [LAVA] + - id: SILVER_OBFUSCATED_2 + material: PLAYER_HEAD + rarity: COMMON + - id: GOLD_OBFUSCATED_2 + material: PLAYER_HEAD + rarity: COMMON + - id: DIAMOND_OBFUSCATED_2 + material: PLAYER_HEAD + rarity: COMMON + - id: BRONZE_SLUGFISH + material: PLAYER_HEAD + rarity: COMMON + - id: SILVER_SLUGFISH + material: PLAYER_HEAD + rarity: COMMON + - id: GOLD_SLUGFISH + material: PLAYER_HEAD + rarity: COMMON + - id: DIAMOND_SLUGFISH + material: PLAYER_HEAD + rarity: COMMON + - id: BRONZE_OBFUSCATED_3 + material: PLAYER_HEAD + rarity: COMMON + - id: SILVER_OBFUSCATED_3 + material: PLAYER_HEAD + rarity: COMMON + - id: GOLD_OBFUSCATED_3 + material: PLAYER_HEAD + rarity: COMMON + - id: DIAMOND_OBFUSCATED_3 + material: PLAYER_HEAD + rarity: COMMON + - id: BRONZE_FLYFISH + material: PLAYER_HEAD + rarity: COMMON + - id: SILVER_FLYFISH + material: PLAYER_HEAD + rarity: COMMON + - id: GOLD_FLYFISH + material: PLAYER_HEAD + rarity: COMMON + - id: DIAMOND_FLYFISH + material: PLAYER_HEAD + rarity: COMMON + - id: BRONZE_VANILLE + material: PLAYER_HEAD + rarity: COMMON + - id: SILVER_VANILLE + material: PLAYER_HEAD + rarity: COMMON + - id: GOLD_VANILLE + material: PLAYER_HEAD + rarity: COMMON + - id: DIAMOND_VANILLE + material: PLAYER_HEAD + rarity: COMMON + - id: BRONZE_LAVAHORSE + material: PLAYER_HEAD + rarity: COMMON + - id: SILVER_LAVAHORSE + material: PLAYER_HEAD + rarity: COMMON + - id: GOLD_LAVAHORSE + material: PLAYER_HEAD + rarity: COMMON + - id: DIAMOND_LAVAHORSE + material: PLAYER_HEAD + rarity: COMMON + - id: BRONZE_MANA_RAY + material: PLAYER_HEAD + rarity: COMMON + - id: SILVER_MANA_RAY + material: PLAYER_HEAD + rarity: COMMON + - id: GOLD_MANA_RAY + material: PLAYER_HEAD + rarity: COMMON + - id: DIAMOND_MANA_RAY + material: PLAYER_HEAD + rarity: COMMON + - id: BRONZE_VOLCANIC_STONEFISH + material: PLAYER_HEAD + rarity: COMMON + - id: SILVER_VOLCANIC_STONEFISH + material: PLAYER_HEAD + rarity: COMMON + - id: GOLD_VOLCANIC_STONEFISH + material: PLAYER_HEAD + rarity: COMMON + - id: DIAMOND_VOLCANIC_STONEFISH + material: PLAYER_HEAD + rarity: COMMON + - id: BRONZE_SKELETON_FISH + material: PLAYER_HEAD + rarity: COMMON + - id: SILVER_SKELETON_FISH + material: PLAYER_HEAD + rarity: COMMON + - id: GOLD_SKELETON_FISH + material: PLAYER_HEAD + rarity: COMMON + - id: DIAMOND_SKELETON_FISH + material: PLAYER_HEAD + rarity: COMMON + - id: BRONZE_MOLDFIN + material: PLAYER_HEAD + rarity: COMMON + - id: SILVER_MOLDFIN + material: PLAYER_HEAD + rarity: COMMON + - id: GOLD_MOLDFIN + material: PLAYER_HEAD + rarity: COMMON + - id: DIAMOND_MOLDFIN + material: PLAYER_HEAD + rarity: COMMON + - id: BRONZE_SOUL_FISH + material: PLAYER_HEAD + rarity: COMMON + - id: SILVER_SOUL_FISH + material: PLAYER_HEAD + rarity: COMMON + - id: GOLD_SOUL_FISH + material: PLAYER_HEAD + rarity: COMMON + - id: DIAMOND_SOUL_FISH + material: PLAYER_HEAD + rarity: COMMON + - id: BRONZE_KARATE_FISH + material: PLAYER_HEAD + rarity: COMMON + - id: SILVER_KARATE_FISH + material: PLAYER_HEAD + rarity: COMMON + - id: GOLD_KARATE_FISH + material: PLAYER_HEAD + rarity: COMMON + - id: DIAMOND_KARATE_FISH + material: PLAYER_HEAD + rarity: COMMON + - id: BRONZE_GOLDEN_FISH + material: PLAYER_HEAD + rarity: COMMON + - id: SILVER_GOLDEN_FISH + material: PLAYER_HEAD + rarity: COMMON + - id: GOLD_GOLDEN_FISH + material: PLAYER_HEAD + rarity: COMMON + - id: DIAMOND_GOLDEN_FISH + material: PLAYER_HEAD + rarity: COMMON diff --git a/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/fishing/FishingContext.java b/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/fishing/FishingContext.java index 232130275..d2d02c305 100644 --- a/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/fishing/FishingContext.java +++ b/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/fishing/FishingContext.java @@ -1,5 +1,6 @@ package net.swofty.type.skyblockgeneric.fishing; +import net.minestom.server.coordinate.Pos; import net.swofty.commons.skyblock.statistics.ItemStatistics; import net.swofty.type.skyblockgeneric.item.SkyBlockItem; import net.swofty.type.skyblockgeneric.item.components.FishingBaitComponent; @@ -16,6 +17,7 @@ public record FishingContext( @Nullable FishingRodPartComponent line, @Nullable FishingRodPartComponent sinker, @Nullable String regionId, + Pos hookPosition, boolean hotspotActive, ItemStatistics hotspotBuffs, long castDurationMs diff --git a/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/fishing/FishingService.java b/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/fishing/FishingService.java index 1e8cf7bab..de07d0cf5 100644 --- a/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/fishing/FishingService.java +++ b/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/fishing/FishingService.java @@ -90,6 +90,7 @@ public static long computeWaitTicks(SkyBlockPlayer player, SkyBlockItem rod, @Nu FishingRodPartService.getLine(rod), FishingRodPartService.getSinker(rod), region == null ? null : region.getType().name(), + hook.getSpawnPosition(), hotspotActive, hotspotBuffs, System.currentTimeMillis() - session.castAt() diff --git a/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/fishing/catches/CatchPayload.java b/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/fishing/catches/CatchPayload.java index 1990c6e80..aff39b4b1 100644 --- a/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/fishing/catches/CatchPayload.java +++ b/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/fishing/catches/CatchPayload.java @@ -9,6 +9,8 @@ import net.swofty.type.skyblockgeneric.fishing.FishingService; import net.swofty.type.skyblockgeneric.user.SkyBlockPlayer; +import java.util.List; + /** * Sealed view of what the rod can pull out of the water. Each variant * carries exactly its own fields — no bag of nullable @Nullable strings — @@ -30,6 +32,12 @@ public sealed interface CatchPayload { /* Variants */ /* ------------------------------------------------------------------ */ + record Multi(List payloads) implements CatchPayload { + @Override public double skillXp() { return payloads.stream().mapToDouble(CatchPayload::skillXp).sum(); } + @Override public String summary() { return payloads.stream().map(CatchPayload::summary).toList().toString(); } + @Override public void apply(CatchAwardContext ctx) { payloads.forEach(payload -> payload.apply(ctx)); } + } + record Item(String itemId, int amount, double skillXp, boolean fromTreasure) implements CatchPayload { @Override public String summary() { return (fromTreasure ? "treasure " : "") + amount + "x " + itemId; } diff --git a/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/fishing/registry/FishingRegistry.java b/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/fishing/registry/FishingRegistry.java index ecb5bb764..cc317d47a 100644 --- a/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/fishing/registry/FishingRegistry.java +++ b/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/fishing/registry/FishingRegistry.java @@ -112,6 +112,7 @@ private static void loadTrophyFish(File file) throws IOException { intValue(entry, "requiredFishingLevel", 0), longValue(entry, "minimumCastTimeMs", 0L), nullableString(entry, "requiredRodId"), + nullableString(entry, "requiredBaitId"), nullableDouble(entry.get("minimumMana")), nullableDouble(entry.get("minimumBobberDepth")), nullableDouble(entry.get("maximumPlayerDistance")), diff --git a/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/fishing/registry/TrophyFishDefinition.java b/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/fishing/registry/TrophyFishDefinition.java index b3ea9a5c6..a9df79e4f 100644 --- a/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/fishing/registry/TrophyFishDefinition.java +++ b/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/fishing/registry/TrophyFishDefinition.java @@ -11,6 +11,7 @@ public record TrophyFishDefinition( int requiredFishingLevel, long minimumCastTimeMs, @Nullable String requiredRodId, + @Nullable String requiredBaitId, @Nullable Double minimumMana, @Nullable Double minimumBobberDepth, @Nullable Double maximumPlayerDistance, diff --git a/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/fishing/resolver/FishingLootResolver.java b/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/fishing/resolver/FishingLootResolver.java index 5224c92af..d07b12954 100644 --- a/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/fishing/resolver/FishingLootResolver.java +++ b/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/fishing/resolver/FishingLootResolver.java @@ -4,7 +4,6 @@ import java.util.Comparator; import java.util.List; import java.util.Optional; -import java.util.function.Function; import net.swofty.commons.skyblock.item.ItemType; import net.swofty.commons.skyblock.statistics.ItemStatistic; import net.swofty.type.generic.data.datapoints.DatapointToggles; @@ -23,12 +22,6 @@ public final class FishingLootResolver { - private static final List>> SPECIAL_CATCHES = List.of( - FishingLootResolver::tryResolveQuestCatch, - FishingLootResolver::tryResolveTrophyFish, - FishingLootResolver::tryResolveSeaCreature - ); - private static final CatchPayload DEFAULT_CATCH = new CatchPayload.Item("RAW_FISH", 1, 5.0D, false); @@ -36,11 +29,23 @@ private FishingLootResolver() { } public static CatchPayload resolve(FishingContext context) { - return SPECIAL_CATCHES.stream() - .map(resolver -> resolver.apply(context)) - .flatMap(Optional::stream) - .findFirst() - .orElseGet(() -> resolveItem(context)); + Optional questCatch = tryResolveQuestCatch(context); + if (questCatch.isPresent()) { + return questCatch.get(); + } + + Optional seaCreature = tryResolveSeaCreature(context); + Optional trophyFish = tryResolveTrophyFish(context); + if (seaCreature.isPresent() && trophyFish.isPresent()) { + return new CatchPayload.Multi(List.of(seaCreature.get(), trophyFish.get())); + } + if (seaCreature.isPresent()) { + return seaCreature.get(); + } + if (trophyFish.isPresent()) { + return trophyFish.get(); + } + return resolveItem(context); } private static Optional tryResolveTrophyFish(FishingContext context) { @@ -55,21 +60,15 @@ private static Optional tryResolveTrophyFish(FishingContext contex List eligible = new ArrayList<>(); for (TrophyFishDefinition definition : FishingRegistry.getTrophyFish()) { - if (!definition.regions().isEmpty() && context.regionId() != null && !definition.regions().contains(context.regionId())) { - continue; - } - if (context.player().getSkills().getCurrentLevel(net.swofty.type.skyblockgeneric.skill.SkillCategories.FISHING) < definition.requiredFishingLevel()) { - continue; - } - if (context.castDurationMs() < definition.minimumCastTimeMs()) { + if (!isEligibleForTrophyFish(context, definition)) { continue; } eligible.add(definition); } - eligible.sort(Comparator.comparingDouble(TrophyFishDefinition::catchChance)); + eligible.sort(Comparator.comparingDouble(TrophyFishDefinition::catchChance).thenComparing(TrophyFishDefinition::id)); for (TrophyFishDefinition definition : eligible) { - if (Math.random() * 100 <= definition.catchChance() + bonus) { + if (Math.random() * 100 <= effectiveTrophyChance(context, definition, bonus)) { TrophyTier tier = rollTrophyTier(context, definition); String itemId = switch (tier) { case DIAMOND -> definition.diamondItemId(); @@ -87,6 +86,53 @@ private static Optional tryResolveTrophyFish(FishingContext contex return Optional.empty(); } + private static boolean isEligibleForTrophyFish(FishingContext context, TrophyFishDefinition definition) { + if (!definition.regions().isEmpty() && (context.regionId() == null || !definition.regions().contains(context.regionId()))) { + return false; + } + if (context.player().getSkills().getCurrentLevel(net.swofty.type.skyblockgeneric.skill.SkillCategories.FISHING) < definition.requiredFishingLevel()) { + return false; + } + if (context.castDurationMs() < definition.minimumCastTimeMs()) { + return false; + } + if (definition.requiredRodId() != null && !definition.requiredRodId().equals(context.rod().getAttributeHandler().getPotentialType().name())) { + return false; + } + if (definition.requiredBaitId() != null && (context.bait() == null || !definition.requiredBaitId().equals(context.bait().getItemId()))) { + return false; + } + if (definition.requiresStarterRodWithoutEnchantments() + && (!"STARTER_LAVA_ROD".equals(context.rod().getAttributeHandler().getPotentialType().name()) + || context.rod().getAttributeHandler().getEnchantments().findAny().isPresent())) { + return false; + } + if (definition.minimumMana() != null && context.player().getMaxMana() < definition.minimumMana()) { + return false; + } + if (definition.minimumBobberDepth() != null && context.player().getPosition().y() - context.hookPosition().y() < definition.minimumBobberDepth()) { + return false; + } + if (definition.maximumPlayerDistance() != null && context.player().getPosition().distance(context.hookPosition()) > definition.maximumPlayerDistance()) { + return false; + } + return true; + } + + private static double effectiveTrophyChance(FishingContext context, TrophyFishDefinition definition, double bonus) { + if (!definition.specialGoldenFish()) { + if ("MANA_RAY".equals(definition.id())) { + return (context.player().getMaxMana() / 1000.0D) * (1.0D + bonus / 100.0D); + } + return definition.catchChance() * (1.0D + bonus / 100.0D); + } + long duration = context.castDurationMs(); + if (duration < 480_000L) { + return 0.0D; + } + return Math.min(100.0D, ((duration - 480_000L) / 240_000.0D) * 100.0D); + } + private static Optional tryResolveQuestCatch(FishingContext context) { if (context.medium() != FishingMedium.WATER) return Optional.empty(); if (context.regionId() == null) return Optional.empty(); From ab1f0b201d67efdd44fa9123981b6294ac18f0a4 Mon Sep 17 00:00:00 2001 From: "Jacob Nardella (Swofty)" Date: Fri, 15 May 2026 13:55:50 +1000 Subject: [PATCH 108/113] feat(slayer): add configurable Slayer quest system --- configuration/skyblock/slayers.yml | 112 +++++++++ .../SkyBlockGenericLoader.java | 2 + .../commands/SlayerCommand.java | 65 +++++ .../data/SkyBlockDataHandler.java | 3 + .../data/datapoints/DatapointSlayer.java | 139 ++++++++++ .../mob/mobs/slayer/SlayerBossBehaviour.java | 31 +++ .../entity/mob/mobs/slayer/SlayerBossMob.java | 66 +++++ .../mob/mobs/slayer/SlayerBossProfile.java | 59 +++++ .../actions/custom/ActionSlayerMobKill.java | 15 ++ .../slayer/SlayerDefinition.java | 29 +++ .../slayer/SlayerLevelReward.java | 4 + .../skyblockgeneric/slayer/SlayerQuest.java | 21 ++ .../slayer/SlayerRegistry.java | 140 +++++++++++ .../skyblockgeneric/slayer/SlayerService.java | 237 ++++++++++++++++++ .../skyblockgeneric/slayer/SlayerTier.java | 25 ++ .../slayer/SlayerTierDefinition.java | 21 ++ .../skyblockgeneric/slayer/SlayerType.java | 47 ++++ .../slayer/SlayerUnlockRequirement.java | 4 + .../skyblockgeneric/user/SkyBlockPlayer.java | 4 + 19 files changed, 1024 insertions(+) create mode 100644 configuration/skyblock/slayers.yml create mode 100644 type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/commands/SlayerCommand.java create mode 100644 type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/data/datapoints/DatapointSlayer.java create mode 100644 type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/entity/mob/mobs/slayer/SlayerBossBehaviour.java create mode 100644 type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/entity/mob/mobs/slayer/SlayerBossMob.java create mode 100644 type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/entity/mob/mobs/slayer/SlayerBossProfile.java create mode 100644 type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/event/actions/custom/ActionSlayerMobKill.java create mode 100644 type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/slayer/SlayerDefinition.java create mode 100644 type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/slayer/SlayerLevelReward.java create mode 100644 type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/slayer/SlayerQuest.java create mode 100644 type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/slayer/SlayerRegistry.java create mode 100644 type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/slayer/SlayerService.java create mode 100644 type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/slayer/SlayerTier.java create mode 100644 type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/slayer/SlayerTierDefinition.java create mode 100644 type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/slayer/SlayerType.java create mode 100644 type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/slayer/SlayerUnlockRequirement.java diff --git a/configuration/skyblock/slayers.yml b/configuration/skyblock/slayers.yml new file mode 100644 index 000000000..7b3658afc --- /dev/null +++ b/configuration/skyblock/slayers.yml @@ -0,0 +1,112 @@ +slayers: + - id: REVENANT_HORROR + enabled: true + targetMobTypes: [UNDEAD] + levels: + - { level: 1, requiredXp: 5, title: Noob } + - { level: 2, requiredXp: 15, title: Novice } + - { level: 3, requiredXp: 200, title: Skilled } + - { level: 4, requiredXp: 1000, title: Destroyer } + - { level: 5, requiredXp: 5000, title: Bulldozer } + - { level: 6, requiredXp: 20000, title: Savage } + - { level: 7, requiredXp: 100000, title: Deathripper } + - { level: 8, requiredXp: 400000, title: Necromancer } + - { level: 9, requiredXp: 1000000, title: Grim Reaper } + tiers: + - { tier: I, cost: 100, requiredCombatXp: 150, slayerXp: 5, bossLevel: 1, bossHealth: 500, bossDamage: 15, bossSpeed: 100, tokenItem: REVENANT_FLESH, tokenDrops: 1 } + - { tier: II, cost: 2000, requiredCombatXp: 1440, slayerXp: 25, bossLevel: 2, bossHealth: 20000, bossDamage: 50, bossSpeed: 110, tokenItem: REVENANT_FLESH, tokenDrops: 8 } + - { tier: III, cost: 10000, requiredCombatXp: 2400, slayerXp: 100, bossLevel: 3, bossHealth: 400000, bossDamage: 120, bossSpeed: 120, tokenItem: REVENANT_FLESH, tokenDrops: 32 } + - { tier: IV, cost: 50000, requiredCombatXp: 4800, slayerXp: 500, bossLevel: 4, bossHealth: 1500000, bossDamage: 400, bossSpeed: 130, tokenItem: REVENANT_FLESH, tokenDrops: 64 } + - { tier: V, cost: 100000, requiredCombatXp: 6000, slayerXp: 1500, bossLevel: 5, bossHealth: 10000000, bossDamage: 2400, bossSpeed: 135, tokenItem: REVENANT_FLESH, tokenDrops: 128 } + + - id: TARANTULA_BROODFATHER + enabled: true + unlock: { type: REVENANT_HORROR, tier: II } + targetMobTypes: [ARTHROPOD] + levels: + - { level: 1, requiredXp: 5, title: Noob } + - { level: 2, requiredXp: 25, title: Novice } + - { level: 3, requiredXp: 200, title: Skilled } + - { level: 4, requiredXp: 1000, title: Destroyer } + - { level: 5, requiredXp: 5000, title: Bulldozer } + - { level: 6, requiredXp: 20000, title: Savage } + - { level: 7, requiredXp: 100000, title: Pest Control Genius } + - { level: 8, requiredXp: 400000, title: Tarantula Exterminator } + - { level: 9, requiredXp: 1000000, title: Spider Annihilator } + tiers: + - { tier: I, cost: 100, requiredCombatXp: 250, slayerXp: 5, bossLevel: 1, bossHealth: 750, bossDamage: 35, bossSpeed: 120, tokenItem: TARANTULA_WEB, tokenDrops: 1 } + - { tier: II, cost: 2000, requiredCombatXp: 600, slayerXp: 25, bossLevel: 2, bossHealth: 30000, bossDamage: 110, bossSpeed: 125, tokenItem: TARANTULA_WEB, tokenDrops: 8 } + - { tier: III, cost: 10000, requiredCombatXp: 1000, slayerXp: 100, bossLevel: 3, bossHealth: 900000, bossDamage: 525, bossSpeed: 135, tokenItem: TARANTULA_WEB, tokenDrops: 32 } + - { tier: IV, cost: 50000, requiredCombatXp: 2000, slayerXp: 500, bossLevel: 4, bossHealth: 2400000, bossDamage: 1325, bossSpeed: 145, tokenItem: TARANTULA_WEB, tokenDrops: 64 } + + - id: SVEN_PACKMASTER + enabled: true + unlock: { type: TARANTULA_BROODFATHER, tier: II } + targetMobTypes: [WOODLAND] + levels: + - { level: 1, requiredXp: 10, title: Noob } + - { level: 2, requiredXp: 30, title: Novice } + - { level: 3, requiredXp: 250, title: Skilled } + - { level: 4, requiredXp: 1500, title: Destroyer } + - { level: 5, requiredXp: 5000, title: Bulldozer } + - { level: 6, requiredXp: 20000, title: Savage } + - { level: 7, requiredXp: 100000, title: King Hunter } + - { level: 8, requiredXp: 400000, title: Pack Leader } + - { level: 9, requiredXp: 1000000, title: Alpha Wolf } + tiers: + - { tier: I, cost: 2000, requiredCombatXp: 250, slayerXp: 5, bossLevel: 1, bossHealth: 2000, bossDamage: 60, bossSpeed: 130, tokenItem: WOLF_TOOTH, tokenDrops: 1 } + - { tier: II, cost: 7500, requiredCombatXp: 600, slayerXp: 25, bossLevel: 2, bossHealth: 40000, bossDamage: 200, bossSpeed: 135, tokenItem: WOLF_TOOTH, tokenDrops: 4 } + - { tier: III, cost: 20000, requiredCombatXp: 1000, slayerXp: 100, bossLevel: 3, bossHealth: 750000, bossDamage: 450, bossSpeed: 145, tokenItem: WOLF_TOOTH, tokenDrops: 16 } + - { tier: IV, cost: 50000, requiredCombatXp: 2000, slayerXp: 500, bossLevel: 4, bossHealth: 2000000, bossDamage: 1100, bossSpeed: 155, tokenItem: WOLF_TOOTH, tokenDrops: 64 } + + - id: VOIDGLOOM_SERAPH + enabled: true + unlock: { type: SVEN_PACKMASTER, tier: IV } + targetMobTypes: [ENDER] + levels: + - { level: 1, requiredXp: 10, title: Noob } + - { level: 2, requiredXp: 30, title: Novice } + - { level: 3, requiredXp: 250, title: Skilled } + - { level: 4, requiredXp: 1500, title: Destroyer } + - { level: 5, requiredXp: 5000, title: Bulldozer } + - { level: 6, requiredXp: 20000, title: Savage } + - { level: 7, requiredXp: 100000, title: Voidwracker } + - { level: 8, requiredXp: 400000, title: Tall Purple Hater } + - { level: 9, requiredXp: 1000000, title: Definition of End } + tiers: + - { tier: I, cost: 2000, requiredCombatXp: 250, slayerXp: 5, bossLevel: 1, bossHealth: 300000, bossDamage: 1200, bossSpeed: 140, tokenItem: NULL_SPHERE, tokenDrops: 1 } + - { tier: II, cost: 7500, requiredCombatXp: 600, slayerXp: 25, bossLevel: 2, bossHealth: 15000000, bossDamage: 5000, bossSpeed: 145, tokenItem: NULL_SPHERE, tokenDrops: 2 } + - { tier: III, cost: 20000, requiredCombatXp: 1000, slayerXp: 100, bossLevel: 3, bossHealth: 66000000, bossDamage: 12000, bossSpeed: 150, tokenItem: NULL_SPHERE, tokenDrops: 3 } + - { tier: IV, cost: 50000, requiredCombatXp: 2000, slayerXp: 500, bossLevel: 4, bossHealth: 300000000, bossDamage: 21000, bossSpeed: 160, tokenItem: NULL_SPHERE, tokenDrops: 4 } + + - id: RIFTSTALKER_BLOODFIEND + enabled: false + unlock: { type: SVEN_PACKMASTER, tier: II } + targetMobTypes: [UNDEAD] + levels: + - { level: 1, requiredXp: 20, title: Noob } + - { level: 2, requiredXp: 75, title: Novice } + - { level: 3, requiredXp: 240, title: Alum } + - { level: 4, requiredXp: 840, title: Heartpiercer } + - { level: 5, requiredXp: 2400, title: Lord of Night } + tiers: [] + + - id: INFERNO_DEMONLORD + enabled: true + unlock: { type: VOIDGLOOM_SERAPH, tier: III } + targetMobTypes: [INFERNAL, MAGMATIC] + levels: + - { level: 1, requiredXp: 10, title: Noob } + - { level: 2, requiredXp: 30, title: Novice } + - { level: 3, requiredXp: 250, title: Skilled } + - { level: 4, requiredXp: 1500, title: Destroyer } + - { level: 5, requiredXp: 5000, title: Bulldozer } + - { level: 6, requiredXp: 20000, title: Savage } + - { level: 7, requiredXp: 100000, title: Hellsplitter } + - { level: 8, requiredXp: 400000, title: Demon Eater } + - { level: 9, requiredXp: 1000000, title: Gabagool King } + tiers: + - { tier: I, cost: 10000, requiredCombatXp: 250, slayerXp: 10, bossLevel: 1, bossHealth: 2500000, bossDamage: 1500, bossSpeed: 130, tokenItem: DERELICT_ASHE, tokenDrops: 1 } + - { tier: II, cost: 25000, requiredCombatXp: 600, slayerXp: 25, bossLevel: 2, bossHealth: 12000000, bossDamage: 3600, bossSpeed: 135, tokenItem: DERELICT_ASHE, tokenDrops: 2 } + - { tier: III, cost: 50000, requiredCombatXp: 1000, slayerXp: 100, bossLevel: 3, bossHealth: 60000000, bossDamage: 7200, bossSpeed: 145, tokenItem: DERELICT_ASHE, tokenDrops: 3 } + - { tier: IV, cost: 100000, requiredCombatXp: 2000, slayerXp: 500, bossLevel: 4, bossHealth: 150000000, bossDamage: 15000, bossSpeed: 150, tokenItem: DERELICT_ASHE, tokenDrops: 4 } diff --git a/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/SkyBlockGenericLoader.java b/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/SkyBlockGenericLoader.java index e97cfbe4f..1a1480c6a 100644 --- a/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/SkyBlockGenericLoader.java +++ b/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/SkyBlockGenericLoader.java @@ -73,6 +73,7 @@ import net.swofty.type.skyblockgeneric.item.set.impl.SetRepeatable; import net.swofty.type.skyblockgeneric.item.updater.PlayerItemUpdater; import net.swofty.type.skyblockgeneric.levels.CustomLevelAward; +import net.swofty.type.skyblockgeneric.slayer.SlayerRegistry; import net.swofty.type.skyblockgeneric.levels.SkyBlockLevelCause; import net.swofty.type.skyblockgeneric.levels.SkyBlockLevelRequirement; import net.swofty.type.skyblockgeneric.levels.unlocks.CustomLevelUnlock; @@ -178,6 +179,7 @@ public void initialize(MinecraftServer server) { Logger.error("Failed to scan for YAML files", e); } FishingRegistry.loadAll(); + SlayerRegistry.loadAll(); /** * Register commands diff --git a/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/commands/SlayerCommand.java b/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/commands/SlayerCommand.java new file mode 100644 index 000000000..077340a10 --- /dev/null +++ b/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/commands/SlayerCommand.java @@ -0,0 +1,65 @@ +package net.swofty.type.skyblockgeneric.commands; + +import net.minestom.server.command.builder.arguments.ArgumentEnum; +import net.minestom.server.command.builder.arguments.ArgumentType; +import net.swofty.type.generic.command.CommandParameters; +import net.swofty.type.generic.command.HypixelCommand; +import net.swofty.type.generic.user.categories.Rank; +import net.swofty.type.skyblockgeneric.slayer.SlayerService; +import net.swofty.type.skyblockgeneric.slayer.SlayerTier; +import net.swofty.type.skyblockgeneric.slayer.SlayerTierDefinition; +import net.swofty.type.skyblockgeneric.slayer.SlayerType; +import net.swofty.type.skyblockgeneric.user.SkyBlockPlayer; + +@CommandParameters(description = "Starts and manages Slayer quests", + usage = "/slayer ", + permission = Rank.DEFAULT, + allowsConsole = false) +public class SlayerCommand extends HypixelCommand { + @Override + public void registerUsage(MinestomCommand command) { + ArgumentEnum typeArgument = ArgumentType.Enum("type", SlayerType.class); + ArgumentEnum tierArgument = ArgumentType.Enum("tier", SlayerTier.class); + + command.addSyntax((sender, context) -> { + if (!permissionCheck(sender)) return; + + SkyBlockPlayer player = (SkyBlockPlayer) sender; + SlayerService.StartResult result = SlayerService.startQuest( + player, + context.get(typeArgument), + context.get(tierArgument) + ); + if (!result.success()) { + player.sendMessage("§c" + result.message()); + } + }, ArgumentType.Literal("start"), typeArgument, tierArgument); + + command.addSyntax((sender, context) -> { + if (!permissionCheck(sender)) return; + + SkyBlockPlayer player = (SkyBlockPlayer) sender; + SlayerService.QuestStatus status = SlayerService.status(player); + if (!status.active()) { + player.sendMessage("§cYou do not have an active Slayer quest."); + return; + } + + SlayerTierDefinition tier = status.tier(); + if (tier == null) { + player.sendMessage("§cYour active Slayer quest is no longer configured."); + return; + } + + player.sendMessage("§5§lSLAYER QUEST"); + player.sendMessage("§7Boss: §c" + tier.displayName(status.quest().type())); + player.sendMessage("§7Progress: §e" + status.quest().combatXp() + "§8/§e" + tier.requiredCombatXp() + " Combat XP"); + player.sendMessage(status.quest().bossSpawned() ? "§cBoss spawned!" : "§7Kill matching mobs to summon your boss."); + }, ArgumentType.Literal("status")); + + command.addSyntax((sender, context) -> { + if (!permissionCheck(sender)) return; + SlayerService.cancelQuest((SkyBlockPlayer) sender); + }, ArgumentType.Literal("cancel")); + } +} diff --git a/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/data/SkyBlockDataHandler.java b/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/data/SkyBlockDataHandler.java index 4f8493e28..5bd336526 100644 --- a/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/data/SkyBlockDataHandler.java +++ b/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/data/SkyBlockDataHandler.java @@ -379,6 +379,9 @@ DatapointShipState.class, new DatapointShipState("ship_state")), TROPHY_FISH("trophy_fish", false, false, false, DatapointTrophyFish.class, new DatapointTrophyFish("trophy_fish")), + SLAYER("slayer", false, false, false, + DatapointSlayer.class, new DatapointSlayer("slayer")), + RACE_BEST_TIME("race_best_time", false, false, false, DatapointMapStringLong.class, new DatapointMapStringLong("race_best_time")), diff --git a/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/data/datapoints/DatapointSlayer.java b/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/data/datapoints/DatapointSlayer.java new file mode 100644 index 000000000..77428f429 --- /dev/null +++ b/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/data/datapoints/DatapointSlayer.java @@ -0,0 +1,139 @@ +package net.swofty.type.skyblockgeneric.data.datapoints; + +import java.util.EnumMap; +import java.util.Map; +import java.util.UUID; +import lombok.AllArgsConstructor; +import lombok.Getter; +import lombok.NoArgsConstructor; +import lombok.Setter; +import net.swofty.commons.protocol.Serializer; +import net.swofty.type.skyblockgeneric.data.SkyBlockDatapoint; +import net.swofty.type.skyblockgeneric.slayer.SlayerQuest; +import net.swofty.type.skyblockgeneric.slayer.SlayerTier; +import net.swofty.type.skyblockgeneric.slayer.SlayerType; +import org.jetbrains.annotations.Nullable; +import org.json.JSONObject; + +public class DatapointSlayer extends SkyBlockDatapoint { + private static final Serializer serializer = new Serializer<>() { + @Override + public String serialize(SlayerData value) { + JSONObject object = new JSONObject(); + JSONObject progressObject = new JSONObject(); + value.getProgress().forEach((type, progress) -> { + JSONObject entry = new JSONObject(); + entry.put("xp", progress.getXp()); + JSONObject completions = new JSONObject(); + progress.getCompletions().forEach((tier, amount) -> completions.put(tier.name(), amount)); + entry.put("completions", completions); + progressObject.put(type.name(), entry); + }); + object.put("progress", progressObject); + + if (value.getActiveQuest() != null) { + SlayerQuest quest = value.getActiveQuest(); + JSONObject questObject = new JSONObject(); + questObject.put("type", quest.type().name()); + questObject.put("tier", quest.tier().name()); + questObject.put("startedAt", quest.startedAt()); + questObject.put("combatXp", quest.combatXp()); + questObject.put("bossSpawned", quest.bossSpawned()); + if (quest.bossUuid() != null) { + questObject.put("bossUuid", quest.bossUuid().toString()); + } + object.put("activeQuest", questObject); + } + + return object.toString(); + } + + @Override + public SlayerData deserialize(String json) { + SlayerData data = new SlayerData(); + if (json == null || json.isEmpty()) { + return data; + } + + JSONObject object = new JSONObject(json); + JSONObject progressObject = object.optJSONObject("progress"); + if (progressObject != null) { + for (String typeId : progressObject.keySet()) { + SlayerType type = SlayerType.valueOf(typeId); + JSONObject entry = progressObject.getJSONObject(typeId); + SlayerProgress progress = new SlayerProgress(); + progress.setXp(entry.optInt("xp", 0)); + JSONObject completions = entry.optJSONObject("completions"); + if (completions != null) { + for (String tierId : completions.keySet()) { + progress.getCompletions().put(SlayerTier.valueOf(tierId), completions.optInt(tierId, 0)); + } + } + data.getProgress().put(type, progress); + } + } + + JSONObject questObject = object.optJSONObject("activeQuest"); + if (questObject != null) { + data.setActiveQuest(new SlayerQuest( + SlayerType.valueOf(questObject.getString("type")), + SlayerTier.valueOf(questObject.getString("tier")), + questObject.optLong("startedAt", System.currentTimeMillis()), + questObject.optInt("combatXp", 0), + questObject.optBoolean("bossSpawned", false), + questObject.has("bossUuid") ? UUID.fromString(questObject.getString("bossUuid")) : null + )); + } + return data; + } + + @Override + public SlayerData clone(SlayerData value) { + SlayerData clone = new SlayerData(); + value.getProgress().forEach((type, progress) -> { + SlayerProgress copied = new SlayerProgress(progress.getXp(), new EnumMap<>(progress.getCompletions())); + clone.getProgress().put(type, copied); + }); + clone.setActiveQuest(value.getActiveQuest()); + return clone; + } + }; + + public DatapointSlayer(String key, SlayerData value) { + super(key, value, serializer); + } + + public DatapointSlayer(String key) { + this(key, new SlayerData()); + } + + @Getter + @Setter + @NoArgsConstructor + @AllArgsConstructor + public static class SlayerData { + private Map progress = new EnumMap<>(SlayerType.class); + private @Nullable SlayerQuest activeQuest; + + public SlayerProgress progress(SlayerType type) { + return progress.computeIfAbsent(type, ignored -> new SlayerProgress()); + } + } + + @Getter + @Setter + @NoArgsConstructor + @AllArgsConstructor + public static class SlayerProgress { + private int xp; + private Map completions = new EnumMap<>(SlayerTier.class); + + public int completions(SlayerTier tier) { + return completions.getOrDefault(tier, 0); + } + + public void addCompletion(SlayerTier tier) { + completions.put(tier, completions(tier) + 1); + } + } +} diff --git a/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/entity/mob/mobs/slayer/SlayerBossBehaviour.java b/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/entity/mob/mobs/slayer/SlayerBossBehaviour.java new file mode 100644 index 000000000..10c4a7698 --- /dev/null +++ b/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/entity/mob/mobs/slayer/SlayerBossBehaviour.java @@ -0,0 +1,31 @@ +package net.swofty.type.skyblockgeneric.entity.mob.mobs.slayer; + +import java.util.List; +import net.minestom.server.entity.ai.GoalSelector; +import net.minestom.server.entity.ai.TargetSelector; +import net.minestom.server.entity.ai.goal.MeleeAttackGoal; +import net.minestom.server.entity.ai.goal.RandomStrollGoal; +import net.minestom.server.entity.ai.target.ClosestEntityTarget; +import net.minestom.server.entity.ai.target.LastEntityDamagerTarget; +import net.minestom.server.utils.time.TimeUnit; +import net.swofty.type.skyblockgeneric.entity.mob.SkyBlockMob; +import net.swofty.type.skyblockgeneric.user.SkyBlockPlayer; + +public final class SlayerBossBehaviour { + private SlayerBossBehaviour() { + } + + public static List goals(SkyBlockMob self) { + return List.of( + new MeleeAttackGoal(self, 1.8, 16, TimeUnit.SERVER_TICK), + new RandomStrollGoal(self, 12) + ); + } + + public static List targets(SkyBlockMob self) { + return List.of( + new LastEntityDamagerTarget(self, 24), + new ClosestEntityTarget(self, 24, entity -> entity instanceof SkyBlockPlayer) + ); + } +} diff --git a/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/entity/mob/mobs/slayer/SlayerBossMob.java b/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/entity/mob/mobs/slayer/SlayerBossMob.java new file mode 100644 index 000000000..8b1f08ea9 --- /dev/null +++ b/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/entity/mob/mobs/slayer/SlayerBossMob.java @@ -0,0 +1,66 @@ +package net.swofty.type.skyblockgeneric.entity.mob.mobs.slayer; + +import java.util.List; +import java.util.UUID; +import net.minestom.server.entity.ai.GoalSelector; +import net.minestom.server.entity.ai.TargetSelector; +import net.swofty.commons.skyblock.statistics.ItemStatistics; +import net.swofty.type.skyblockgeneric.entity.mob.MobType; +import net.swofty.type.skyblockgeneric.entity.mob.SkyBlockMob; +import net.swofty.type.skyblockgeneric.loottable.OtherLoot; +import net.swofty.type.skyblockgeneric.loottable.SkyBlockLootTable; +import net.swofty.type.skyblockgeneric.skill.SkillCategories; +import org.jetbrains.annotations.Nullable; + +public final class SlayerBossMob extends SkyBlockMob { + private static final ThreadLocal IN_CONSTRUCTION = new ThreadLocal<>(); + + private final SlayerBossProfile profile; + private final UUID ownerUuid; + + private SlayerBossMob(UUID ownerUuid, SlayerBossProfile profile) { + super(profile.entityType()); + this.ownerUuid = ownerUuid; + this.profile = profile; + } + + public static SlayerBossMob create(UUID ownerUuid, SlayerBossProfile profile) { + IN_CONSTRUCTION.set(profile); + try { + return new SlayerBossMob(ownerUuid, profile); + } finally { + IN_CONSTRUCTION.remove(); + } + } + + public UUID getOwnerUuid() { + return ownerUuid; + } + + public SlayerBossProfile getProfile() { + return live(); + } + + @Override public String getDisplayName() { return live().displayName(); } + @Override public Integer getLevel() { return live().tier().bossLevel(); } + @Override public List getMobTypes() { return live().mobTypes(); } + @Override public ItemStatistics getBaseStatistics() { return live().asBaseStatistics(); } + @Override public OtherLoot getOtherLoot() { return live().asOtherLoot(); } + @Override public long damageCooldown() { return 500L; } + @Override public @Nullable SkyBlockLootTable getLootTable() { return live().asLootTable(); } + @Override public SkillCategories getSkillCategory() { return SkillCategories.COMBAT; } + + @Override + public List getGoalSelectors() { + return SlayerBossBehaviour.goals(this); + } + + @Override + public List getTargetSelectors() { + return SlayerBossBehaviour.targets(this); + } + + private SlayerBossProfile live() { + return profile != null ? profile : IN_CONSTRUCTION.get(); + } +} diff --git a/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/entity/mob/mobs/slayer/SlayerBossProfile.java b/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/entity/mob/mobs/slayer/SlayerBossProfile.java new file mode 100644 index 000000000..59a828f7d --- /dev/null +++ b/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/entity/mob/mobs/slayer/SlayerBossProfile.java @@ -0,0 +1,59 @@ +package net.swofty.type.skyblockgeneric.entity.mob.mobs.slayer; + +import java.util.List; +import java.util.Optional; +import net.minestom.server.entity.EntityType; +import net.swofty.commons.skyblock.item.ItemType; +import net.swofty.commons.skyblock.statistics.ItemStatistic; +import net.swofty.commons.skyblock.statistics.ItemStatistics; +import net.swofty.type.skyblockgeneric.entity.mob.MobType; +import net.swofty.type.skyblockgeneric.loottable.OtherLoot; +import net.swofty.type.skyblockgeneric.loottable.SkyBlockLootTable; +import net.swofty.type.skyblockgeneric.slayer.SlayerTierDefinition; +import net.swofty.type.skyblockgeneric.slayer.SlayerType; + +public record SlayerBossProfile( + SlayerType type, + SlayerTierDefinition tier, + List mobTypes, + EntityType entityType +) { + public String id() { + return type.name() + "_" + tier.tier().name(); + } + + public String displayName() { + return type.displayName() + " " + tier.tier().numeral(); + } + + public ItemStatistics asBaseStatistics() { + return ItemStatistics.builder() + .withBase(ItemStatistic.HEALTH, tier.bossHealth()) + .withBase(ItemStatistic.DAMAGE, tier.bossDamage()) + .withBase(ItemStatistic.SPEED, tier.bossSpeed()) + .build(); + } + + public OtherLoot asOtherLoot() { + return new OtherLoot(tier.requiredCombatXp(), 0, Math.max(1, tier.slayerXp() / 5)); + } + + public SkyBlockLootTable asLootTable() { + Optional item = tier.tokenItem(); + if (item.isEmpty() || tier.tokenDrops() <= 0) { + return null; + } + + return new SkyBlockLootTable() { + @Override + public List getLootTable() { + return List.of(new LootRecord(item.get(), tier.tokenDrops(), 100)); + } + + @Override + public CalculationMode getCalculationMode() { + return CalculationMode.CALCULATE_INDIVIDUAL; + } + }; + } +} diff --git a/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/event/actions/custom/ActionSlayerMobKill.java b/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/event/actions/custom/ActionSlayerMobKill.java new file mode 100644 index 000000000..415e4b95f --- /dev/null +++ b/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/event/actions/custom/ActionSlayerMobKill.java @@ -0,0 +1,15 @@ +package net.swofty.type.skyblockgeneric.event.actions.custom; + +import net.swofty.type.generic.event.EventNodes; +import net.swofty.type.generic.event.HypixelEventClass; +import net.swofty.type.generic.event.phase.EventPhase; +import net.swofty.type.generic.event.phase.PhasedEvent; +import net.swofty.type.skyblockgeneric.event.custom.PlayerKilledSkyBlockMobEvent; +import net.swofty.type.skyblockgeneric.slayer.SlayerService; + +public class ActionSlayerMobKill implements HypixelEventClass { + @PhasedEvent(node = EventNodes.CUSTOM, requireDataLoaded = true, phase = EventPhase.GAMEPLAY) + public void run(PlayerKilledSkyBlockMobEvent event) { + SlayerService.handleMobKill(event.getPlayer(), event.getKilledMob()); + } +} diff --git a/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/slayer/SlayerDefinition.java b/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/slayer/SlayerDefinition.java new file mode 100644 index 000000000..3d5304e3d --- /dev/null +++ b/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/slayer/SlayerDefinition.java @@ -0,0 +1,29 @@ +package net.swofty.type.skyblockgeneric.slayer; + +import java.util.List; +import java.util.Map; +import java.util.Optional; +import net.swofty.type.skyblockgeneric.entity.mob.MobType; + +public record SlayerDefinition( + SlayerType type, + boolean enabled, + Optional unlockRequirement, + List targetMobTypes, + List levels, + Map tiers +) { + public boolean accepts(List mobTypes) { + return mobTypes.stream().anyMatch(targetMobTypes::contains); + } + + public int levelForXp(int xp) { + int level = 0; + for (SlayerLevelReward reward : levels) { + if (xp >= reward.requiredXp()) { + level = reward.level(); + } + } + return level; + } +} diff --git a/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/slayer/SlayerLevelReward.java b/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/slayer/SlayerLevelReward.java new file mode 100644 index 000000000..babff5ac1 --- /dev/null +++ b/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/slayer/SlayerLevelReward.java @@ -0,0 +1,4 @@ +package net.swofty.type.skyblockgeneric.slayer; + +public record SlayerLevelReward(int level, int requiredXp, String title) { +} diff --git a/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/slayer/SlayerQuest.java b/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/slayer/SlayerQuest.java new file mode 100644 index 000000000..03a78d9ea --- /dev/null +++ b/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/slayer/SlayerQuest.java @@ -0,0 +1,21 @@ +package net.swofty.type.skyblockgeneric.slayer; + +import java.util.UUID; +import org.jetbrains.annotations.Nullable; + +public record SlayerQuest( + SlayerType type, + SlayerTier tier, + long startedAt, + int combatXp, + boolean bossSpawned, + @Nullable UUID bossUuid +) { + public SlayerQuest addCombatXp(int amount, int requiredCombatXp) { + return new SlayerQuest(type, tier, startedAt, Math.min(requiredCombatXp, combatXp + amount), false, null); + } + + public SlayerQuest markBossSpawned(UUID bossUuid) { + return new SlayerQuest(type, tier, startedAt, combatXp, true, bossUuid); + } +} diff --git a/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/slayer/SlayerRegistry.java b/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/slayer/SlayerRegistry.java new file mode 100644 index 000000000..b4b974fd2 --- /dev/null +++ b/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/slayer/SlayerRegistry.java @@ -0,0 +1,140 @@ +package net.swofty.type.skyblockgeneric.slayer; + +import java.io.File; +import java.io.IOException; +import java.util.ArrayList; +import java.util.Collections; +import java.util.EnumMap; +import java.util.LinkedHashMap; +import java.util.List; +import java.util.Map; +import java.util.Optional; +import net.swofty.commons.YamlFileUtils; +import net.swofty.commons.skyblock.item.ItemType; +import net.swofty.type.skyblockgeneric.entity.mob.MobType; +import org.jetbrains.annotations.Nullable; +import org.tinylog.Logger; + +public final class SlayerRegistry { + private static final File SLAYERS_FILE = new File("./configuration/skyblock/slayers.yml"); + private static final Map DEFINITIONS = new LinkedHashMap<>(); + + private SlayerRegistry() { + } + + public static void loadAll() { + DEFINITIONS.clear(); + + try { + Map root = YamlFileUtils.loadYaml(SLAYERS_FILE); + List> slayers = (List>) root.getOrDefault("slayers", Collections.emptyList()); + for (Map entry : slayers) { + SlayerType type = SlayerType.valueOf(string(entry, "id")); + DEFINITIONS.put(type, new SlayerDefinition( + type, + booleanValue(entry, "enabled", true), + unlock((Map) entry.get("unlock")), + mobTypes((List) entry.getOrDefault("targetMobTypes", Collections.emptyList())), + levels((List>) entry.getOrDefault("levels", Collections.emptyList())), + tiers((List>) entry.getOrDefault("tiers", Collections.emptyList())) + )); + } + } catch (Exception exception) { + Logger.error(exception, "Failed to load slayer configuration"); + } + } + + public static @Nullable SlayerDefinition get(SlayerType type) { + return DEFINITIONS.get(type); + } + + public static List all() { + return List.copyOf(DEFINITIONS.values()); + } + + private static List mobTypes(List values) { + List result = new ArrayList<>(); + for (Object value : values) { + result.add(MobType.valueOf(String.valueOf(value))); + } + return result; + } + + private static Optional unlock(@Nullable Map entry) { + if (entry == null || entry.isEmpty()) { + return Optional.empty(); + } + return Optional.of(new SlayerUnlockRequirement( + SlayerType.valueOf(string(entry, "type")), + SlayerTier.valueOf(string(entry, "tier")) + )); + } + + private static List levels(List> entries) { + List result = new ArrayList<>(); + for (Map entry : entries) { + result.add(new SlayerLevelReward( + intValue(entry, "level", 0), + intValue(entry, "requiredXp", 0), + string(entry, "title") + )); + } + return result; + } + + private static Map tiers(List> entries) { + Map result = new EnumMap<>(SlayerTier.class); + for (Map entry : entries) { + SlayerTier tier = SlayerTier.valueOf(string(entry, "tier")); + result.put(tier, new SlayerTierDefinition( + tier, + intValue(entry, "cost", 0), + intValue(entry, "requiredCombatXp", 0), + intValue(entry, "slayerXp", 0), + intValue(entry, "bossLevel", 1), + doubleValue(entry, "bossHealth", 100D), + doubleValue(entry, "bossDamage", 5D), + doubleValue(entry, "bossSpeed", 100D), + intValue(entry, "tokenDrops", 0), + optionalItem(entry.get("tokenItem")) + )); + } + return result; + } + + private static Optional optionalItem(Object value) { + if (value == null || String.valueOf(value).isBlank()) { + return Optional.empty(); + } + return Optional.of(ItemType.valueOf(String.valueOf(value))); + } + + private static String string(Map map, String key) { + Object value = map.get(key); + if (value == null) { + throw new IllegalArgumentException("Missing required slayer key '" + key + "'"); + } + return String.valueOf(value); + } + + private static int intValue(Map map, String key, int fallback) { + Object value = map.get(key); + if (value == null) return fallback; + if (value instanceof Number number) return number.intValue(); + return Integer.parseInt(String.valueOf(value)); + } + + private static double doubleValue(Map map, String key, double fallback) { + Object value = map.get(key); + if (value == null) return fallback; + if (value instanceof Number number) return number.doubleValue(); + return Double.parseDouble(String.valueOf(value)); + } + + private static boolean booleanValue(Map map, String key, boolean fallback) { + Object value = map.get(key); + if (value == null) return fallback; + if (value instanceof Boolean bool) return bool; + return Boolean.parseBoolean(String.valueOf(value)); + } +} diff --git a/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/slayer/SlayerService.java b/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/slayer/SlayerService.java new file mode 100644 index 000000000..8a49ef594 --- /dev/null +++ b/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/slayer/SlayerService.java @@ -0,0 +1,237 @@ +package net.swofty.type.skyblockgeneric.slayer; + +import java.util.Optional; +import net.kyori.adventure.text.Component; +import net.minestom.server.coordinate.Pos; +import net.minestom.server.instance.Instance; +import net.swofty.type.skyblockgeneric.data.SkyBlockDataHandler; +import net.swofty.type.skyblockgeneric.data.datapoints.DatapointSlayer; +import net.swofty.type.skyblockgeneric.elections.ElectionManager; +import net.swofty.type.skyblockgeneric.elections.SkyBlockMayor; +import net.swofty.type.skyblockgeneric.entity.mob.SkyBlockMob; +import net.swofty.type.skyblockgeneric.entity.mob.mobs.slayer.SlayerBossMob; +import net.swofty.type.skyblockgeneric.entity.mob.mobs.slayer.SlayerBossProfile; +import net.swofty.type.skyblockgeneric.user.SkyBlockPlayer; +import org.jetbrains.annotations.Nullable; + +public final class SlayerService { + private SlayerService() { + } + + public static StartResult startQuest(SkyBlockPlayer player, SlayerType type, SlayerTier tier) { + DatapointSlayer.SlayerData data = data(player); + if (data.getActiveQuest() != null) { + return StartResult.alreadyActive(data.getActiveQuest()); + } + + SlayerDefinition definition = SlayerRegistry.get(type); + if (definition == null || !definition.enabled()) { + return StartResult.unavailable(type); + } + + SlayerTierDefinition tierDefinition = definition.tiers().get(tier); + if (tierDefinition == null) { + return StartResult.missingTier(type, tier); + } + + if (definition.unlockRequirement().isPresent()) { + SlayerUnlockRequirement requirement = definition.unlockRequirement().get(); + if (data.progress(requirement.type()).completions(requirement.tier()) <= 0) { + return StartResult.locked(requirement); + } + } + + int cost = questCost(tierDefinition); + if (player.getCoins() < cost) { + return StartResult.notEnoughCoins(cost); + } + + player.removeCoins(cost); + SlayerQuest quest = new SlayerQuest(type, tier, System.currentTimeMillis(), 0, false, null); + data.setActiveQuest(quest); + save(player, data); + player.sendMessage("§5§lSLAYER QUEST STARTED!"); + player.sendMessage("§7Slay " + type.categoryName() + " mobs to summon §c" + tierDefinition.displayName(type) + "§7."); + return StartResult.started(quest); + } + + public static void cancelQuest(SkyBlockPlayer player) { + DatapointSlayer.SlayerData data = data(player); + if (data.getActiveQuest() == null) { + player.sendMessage("§cYou do not have an active Slayer quest."); + return; + } + data.setActiveQuest(null); + save(player, data); + player.sendMessage("§cSlayer quest cancelled!"); + } + + public static void handleMobKill(SkyBlockPlayer player, SkyBlockMob mob) { + DatapointSlayer.SlayerData data = data(player); + SlayerQuest quest = data.getActiveQuest(); + if (quest == null || mob == null) { + return; + } + + if (mob instanceof SlayerBossMob bossMob) { + completeBoss(player, data, quest, bossMob); + return; + } + + if (quest.bossSpawned()) { + return; + } + + SlayerDefinition definition = SlayerRegistry.get(quest.type()); + if (definition == null || !definition.accepts(mob.getMobTypes())) { + return; + } + + SlayerTierDefinition tierDefinition = definition.tiers().get(quest.tier()); + if (tierDefinition == null) { + return; + } + + int gainedXp = Math.max(1, (int) mob.getOtherLoot().getSkillXPAmount()); + SlayerQuest progressedQuest = quest.addCombatXp(gainedXp, tierDefinition.requiredCombatXp()); + if (progressedQuest.combatXp() >= tierDefinition.requiredCombatXp()) { + SlayerBossMob boss = spawnBoss(player, definition, tierDefinition, mob.getPosition()); + if (boss != null) { + progressedQuest = progressedQuest.markBossSpawned(boss.getUuid()); + player.sendMessage("§c§lSLAYER BOSS SPAWNED!"); + player.sendMessage("§7Kill §c" + tierDefinition.displayName(quest.type()) + "§7 to complete your quest."); + } + } else { + int remaining = tierDefinition.requiredCombatXp() - progressedQuest.combatXp(); + player.sendMessage("§5Slayer Quest §7" + progressedQuest.combatXp() + "§8/§7" + + tierDefinition.requiredCombatXp() + " Combat XP §8(§e" + remaining + " left§8)"); + } + + data.setActiveQuest(progressedQuest); + save(player, data); + } + + public static QuestStatus status(SkyBlockPlayer player) { + DatapointSlayer.SlayerData data = data(player); + SlayerQuest quest = data.getActiveQuest(); + if (quest == null) { + return QuestStatus.none(); + } + + SlayerDefinition definition = SlayerRegistry.get(quest.type()); + SlayerTierDefinition tier = definition == null ? null : definition.tiers().get(quest.tier()); + return new QuestStatus(quest, definition, tier); + } + + private static void completeBoss(SkyBlockPlayer player, DatapointSlayer.SlayerData data, SlayerQuest quest, SlayerBossMob bossMob) { + if (!bossMob.getOwnerUuid().equals(player.getUuid())) { + return; + } + + SlayerDefinition definition = SlayerRegistry.get(quest.type()); + SlayerTierDefinition tierDefinition = definition == null ? null : definition.tiers().get(quest.tier()); + if (definition == null || tierDefinition == null) { + return; + } + + DatapointSlayer.SlayerProgress progress = data.progress(quest.type()); + int slayerXp = slayerXpReward(tierDefinition); + progress.setXp(progress.getXp() + slayerXp); + progress.addCompletion(quest.tier()); + data.setActiveQuest(null); + save(player, data); + + int level = definition.levelForXp(progress.getXp()); + player.sendMessage("§a§lSLAYER QUEST COMPLETE!"); + player.sendMessage("§7You gained §d" + slayerXp + " " + quest.type().categoryName() + " Slayer XP§7."); + player.sendMessage("§7" + quest.type().categoryName() + " Slayer Level: §e" + level + " §8(§d" + progress.getXp() + " XP§8)"); + } + + private static int questCost(SlayerTierDefinition tierDefinition) { + if (ElectionManager.isPerkActive(SkyBlockMayor.Perk.SLASHED_PRICING)) { + return Math.max(1, tierDefinition.cost() / 2); + } + return tierDefinition.cost(); + } + + private static int slayerXpReward(SlayerTierDefinition tierDefinition) { + if (ElectionManager.isPerkActive(SkyBlockMayor.Perk.SLAYER_XP_BUFF)) { + return (int) Math.round(tierDefinition.slayerXp() * 1.25D); + } + return tierDefinition.slayerXp(); + } + + private static @Nullable SlayerBossMob spawnBoss(SkyBlockPlayer player, SlayerDefinition definition, SlayerTierDefinition tierDefinition, Pos position) { + Instance instance = player.getInstance(); + if (instance == null) { + return null; + } + + SlayerBossProfile profile = new SlayerBossProfile( + definition.type(), + tierDefinition, + definition.targetMobTypes(), + definition.type().entityType() + ); + SlayerBossMob mob = SlayerBossMob.create(player.getUuid(), profile); + mob.setInstance(instance, position); + broadcastSpawn(player, tierDefinition.displayName(definition.type()), instance, position); + return mob; + } + + private static void broadcastSpawn(SkyBlockPlayer player, String bossName, Instance instance, Pos position) { + Component message = Component.text("§c§lSLAYER BOSS! §7" + player.getUsername() + " spawned §c" + bossName + "§7!"); + instance.getPlayers().stream() + .filter(nearby -> nearby.getPosition().distance(position) <= 32) + .forEach(nearby -> nearby.sendMessage(message)); + } + + private static DatapointSlayer.SlayerData data(SkyBlockPlayer player) { + return player.getSkyblockDataHandler().get(SkyBlockDataHandler.Data.SLAYER, DatapointSlayer.class).getValue(); + } + + private static void save(SkyBlockPlayer player, DatapointSlayer.SlayerData data) { + player.getSkyblockDataHandler().get(SkyBlockDataHandler.Data.SLAYER, DatapointSlayer.class).setValue(data); + } + + public record QuestStatus( + @Nullable SlayerQuest quest, + @Nullable SlayerDefinition definition, + @Nullable SlayerTierDefinition tier + ) { + public static QuestStatus none() { + return new QuestStatus(null, null, null); + } + + public boolean active() { + return quest != null; + } + } + + public record StartResult(boolean success, String message, Optional quest) { + public static StartResult started(SlayerQuest quest) { + return new StartResult(true, "Started", Optional.of(quest)); + } + + public static StartResult alreadyActive(SlayerQuest quest) { + return new StartResult(false, "You already have an active Slayer quest.", Optional.of(quest)); + } + + public static StartResult unavailable(SlayerType type) { + return new StartResult(false, type.displayName() + " is not available here.", Optional.empty()); + } + + public static StartResult missingTier(SlayerType type, SlayerTier tier) { + return new StartResult(false, type.displayName() + " " + tier.numeral() + " is not configured.", Optional.empty()); + } + + public static StartResult notEnoughCoins(int cost) { + return new StartResult(false, "You need " + cost + " coins to start this quest.", Optional.empty()); + } + + public static StartResult locked(SlayerUnlockRequirement requirement) { + return new StartResult(false, "You must slay " + requirement.type().displayName() + " " + + requirement.tier().numeral() + " first.", Optional.empty()); + } + } +} diff --git a/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/slayer/SlayerTier.java b/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/slayer/SlayerTier.java new file mode 100644 index 000000000..ae630c172 --- /dev/null +++ b/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/slayer/SlayerTier.java @@ -0,0 +1,25 @@ +package net.swofty.type.skyblockgeneric.slayer; + +public enum SlayerTier { + I(1, "I"), + II(2, "II"), + III(3, "III"), + IV(4, "IV"), + V(5, "V"); + + private final int number; + private final String numeral; + + SlayerTier(int number, String numeral) { + this.number = number; + this.numeral = numeral; + } + + public int number() { + return number; + } + + public String numeral() { + return numeral; + } +} diff --git a/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/slayer/SlayerTierDefinition.java b/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/slayer/SlayerTierDefinition.java new file mode 100644 index 000000000..84eb8f31f --- /dev/null +++ b/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/slayer/SlayerTierDefinition.java @@ -0,0 +1,21 @@ +package net.swofty.type.skyblockgeneric.slayer; + +import java.util.Optional; +import net.swofty.commons.skyblock.item.ItemType; + +public record SlayerTierDefinition( + SlayerTier tier, + int cost, + int requiredCombatXp, + int slayerXp, + int bossLevel, + double bossHealth, + double bossDamage, + double bossSpeed, + int tokenDrops, + Optional tokenItem +) { + public String displayName(SlayerType type) { + return type.displayName() + " " + tier.numeral(); + } +} diff --git a/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/slayer/SlayerType.java b/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/slayer/SlayerType.java new file mode 100644 index 000000000..6a8000bda --- /dev/null +++ b/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/slayer/SlayerType.java @@ -0,0 +1,47 @@ +package net.swofty.type.skyblockgeneric.slayer; + +import net.minestom.server.entity.EntityType; +import net.minestom.server.item.Material; + +public enum SlayerType { + REVENANT_HORROR("Zombie", "Revenant Horror", "§c", EntityType.ZOMBIE, Material.ROTTEN_FLESH), + TARANTULA_BROODFATHER("Spider", "Tarantula Broodfather", "§5", EntityType.SPIDER, Material.SPIDER_EYE), + SVEN_PACKMASTER("Wolf", "Sven Packmaster", "§f", EntityType.WOLF, Material.BONE), + VOIDGLOOM_SERAPH("Enderman", "Voidgloom Seraph", "§5", EntityType.ENDERMAN, Material.ENDER_PEARL), + RIFTSTALKER_BLOODFIEND("Vampire", "Riftstalker Bloodfiend", "§4", EntityType.ZOMBIE, Material.RED_DYE), + INFERNO_DEMONLORD("Blaze", "Inferno Demonlord", "§6", EntityType.BLAZE, Material.BLAZE_ROD); + + private final String categoryName; + private final String displayName; + private final String color; + private final EntityType entityType; + private final Material menuMaterial; + + SlayerType(String categoryName, String displayName, String color, EntityType entityType, Material menuMaterial) { + this.categoryName = categoryName; + this.displayName = displayName; + this.color = color; + this.entityType = entityType; + this.menuMaterial = menuMaterial; + } + + public String categoryName() { + return categoryName; + } + + public String displayName() { + return displayName; + } + + public String coloredName() { + return color + displayName; + } + + public EntityType entityType() { + return entityType; + } + + public Material menuMaterial() { + return menuMaterial; + } +} diff --git a/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/slayer/SlayerUnlockRequirement.java b/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/slayer/SlayerUnlockRequirement.java new file mode 100644 index 000000000..289ca8a2b --- /dev/null +++ b/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/slayer/SlayerUnlockRequirement.java @@ -0,0 +1,4 @@ +package net.swofty.type.skyblockgeneric.slayer; + +public record SlayerUnlockRequirement(SlayerType type, SlayerTier tier) { +} diff --git a/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/user/SkyBlockPlayer.java b/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/user/SkyBlockPlayer.java index 7578e72a2..82eb87372 100644 --- a/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/user/SkyBlockPlayer.java +++ b/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/user/SkyBlockPlayer.java @@ -560,6 +560,10 @@ public DatapointTrophyFish.TrophyFishData getTrophyFishData() { return getSkyblockDataHandler().get(SkyBlockDataHandler.Data.TROPHY_FISH, DatapointTrophyFish.class).getValue(); } + public DatapointSlayer.SlayerData getSlayerData() { + return getSkyblockDataHandler().get(SkyBlockDataHandler.Data.SLAYER, DatapointSlayer.class).getValue(); + } + public DatapointAccessoryBag.PlayerAccessoryBag getAccessoryBag() { return getSkyblockDataHandler().get(SkyBlockDataHandler.Data.ACCESSORY_BAG, DatapointAccessoryBag.class).getValue(); } From bff869ed85d1d89725a05589065e0ebd4b0e83e6 Mon Sep 17 00:00:00 2001 From: "Jacob Nardella (Swofty)" Date: Fri, 15 May 2026 14:25:13 +1000 Subject: [PATCH 109/113] feat(slayer): add boss ability behaviours --- configuration/skyblock/slayers.yml | 37 +++-- .../entity/mob/mobs/slayer/SlayerBossMob.java | 44 +++++ .../mob/mobs/slayer/SlayerMinionMob.java | 83 ++++++++++ .../ability/InfernoDemonlordAbility.java | 132 +++++++++++++++ .../slayer/ability/NoopSlayerBossAbility.java | 18 ++ .../slayer/ability/RevenantHorrorAbility.java | 88 ++++++++++ .../slayer/ability/SlayerAbilitySupport.java | 156 ++++++++++++++++++ .../slayer/ability/SlayerBossAbility.java | 21 +++ .../ability/SlayerBossAbilityFactory.java | 19 +++ .../slayer/ability/SvenPackmasterAbility.java | 55 ++++++ .../ability/TarantulaBroodfatherAbility.java | 105 ++++++++++++ .../ability/VoidgloomSeraphAbility.java | 115 +++++++++++++ .../PlayerActionDamagedAttacked.java | 5 + 13 files changed, 860 insertions(+), 18 deletions(-) create mode 100644 type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/entity/mob/mobs/slayer/SlayerMinionMob.java create mode 100644 type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/entity/mob/mobs/slayer/ability/InfernoDemonlordAbility.java create mode 100644 type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/entity/mob/mobs/slayer/ability/NoopSlayerBossAbility.java create mode 100644 type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/entity/mob/mobs/slayer/ability/RevenantHorrorAbility.java create mode 100644 type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/entity/mob/mobs/slayer/ability/SlayerAbilitySupport.java create mode 100644 type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/entity/mob/mobs/slayer/ability/SlayerBossAbility.java create mode 100644 type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/entity/mob/mobs/slayer/ability/SlayerBossAbilityFactory.java create mode 100644 type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/entity/mob/mobs/slayer/ability/SvenPackmasterAbility.java create mode 100644 type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/entity/mob/mobs/slayer/ability/TarantulaBroodfatherAbility.java create mode 100644 type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/entity/mob/mobs/slayer/ability/VoidgloomSeraphAbility.java diff --git a/configuration/skyblock/slayers.yml b/configuration/skyblock/slayers.yml index 7b3658afc..9ba6c7f26 100644 --- a/configuration/skyblock/slayers.yml +++ b/configuration/skyblock/slayers.yml @@ -13,9 +13,9 @@ slayers: - { level: 8, requiredXp: 400000, title: Necromancer } - { level: 9, requiredXp: 1000000, title: Grim Reaper } tiers: - - { tier: I, cost: 100, requiredCombatXp: 150, slayerXp: 5, bossLevel: 1, bossHealth: 500, bossDamage: 15, bossSpeed: 100, tokenItem: REVENANT_FLESH, tokenDrops: 1 } - - { tier: II, cost: 2000, requiredCombatXp: 1440, slayerXp: 25, bossLevel: 2, bossHealth: 20000, bossDamage: 50, bossSpeed: 110, tokenItem: REVENANT_FLESH, tokenDrops: 8 } - - { tier: III, cost: 10000, requiredCombatXp: 2400, slayerXp: 100, bossLevel: 3, bossHealth: 400000, bossDamage: 120, bossSpeed: 120, tokenItem: REVENANT_FLESH, tokenDrops: 32 } + - { tier: I, cost: 2000, requiredCombatXp: 150, slayerXp: 5, bossLevel: 1, bossHealth: 500, bossDamage: 15, bossSpeed: 100, tokenItem: REVENANT_FLESH, tokenDrops: 1 } + - { tier: II, cost: 7500, requiredCombatXp: 1440, slayerXp: 25, bossLevel: 2, bossHealth: 20000, bossDamage: 50, bossSpeed: 110, tokenItem: REVENANT_FLESH, tokenDrops: 8 } + - { tier: III, cost: 20000, requiredCombatXp: 2400, slayerXp: 100, bossLevel: 3, bossHealth: 400000, bossDamage: 120, bossSpeed: 120, tokenItem: REVENANT_FLESH, tokenDrops: 32 } - { tier: IV, cost: 50000, requiredCombatXp: 4800, slayerXp: 500, bossLevel: 4, bossHealth: 1500000, bossDamage: 400, bossSpeed: 130, tokenItem: REVENANT_FLESH, tokenDrops: 64 } - { tier: V, cost: 100000, requiredCombatXp: 6000, slayerXp: 1500, bossLevel: 5, bossHealth: 10000000, bossDamage: 2400, bossSpeed: 135, tokenItem: REVENANT_FLESH, tokenDrops: 128 } @@ -34,10 +34,11 @@ slayers: - { level: 8, requiredXp: 400000, title: Tarantula Exterminator } - { level: 9, requiredXp: 1000000, title: Spider Annihilator } tiers: - - { tier: I, cost: 100, requiredCombatXp: 250, slayerXp: 5, bossLevel: 1, bossHealth: 750, bossDamage: 35, bossSpeed: 120, tokenItem: TARANTULA_WEB, tokenDrops: 1 } - - { tier: II, cost: 2000, requiredCombatXp: 600, slayerXp: 25, bossLevel: 2, bossHealth: 30000, bossDamage: 110, bossSpeed: 125, tokenItem: TARANTULA_WEB, tokenDrops: 8 } - - { tier: III, cost: 10000, requiredCombatXp: 1000, slayerXp: 100, bossLevel: 3, bossHealth: 900000, bossDamage: 525, bossSpeed: 135, tokenItem: TARANTULA_WEB, tokenDrops: 32 } + - { tier: I, cost: 2000, requiredCombatXp: 225, slayerXp: 5, bossLevel: 1, bossHealth: 750, bossDamage: 35, bossSpeed: 120, tokenItem: TARANTULA_WEB, tokenDrops: 1 } + - { tier: II, cost: 7500, requiredCombatXp: 540, slayerXp: 25, bossLevel: 2, bossHealth: 30000, bossDamage: 110, bossSpeed: 125, tokenItem: TARANTULA_WEB, tokenDrops: 8 } + - { tier: III, cost: 20000, requiredCombatXp: 1320, slayerXp: 100, bossLevel: 3, bossHealth: 900000, bossDamage: 525, bossSpeed: 135, tokenItem: TARANTULA_WEB, tokenDrops: 32 } - { tier: IV, cost: 50000, requiredCombatXp: 2000, slayerXp: 500, bossLevel: 4, bossHealth: 2400000, bossDamage: 1325, bossSpeed: 145, tokenItem: TARANTULA_WEB, tokenDrops: 64 } + - { tier: V, cost: 100000, requiredCombatXp: 10000, slayerXp: 1500, bossLevel: 5, bossHealth: 10000000, bossDamage: 3500, bossSpeed: 150, tokenItem: TARANTULA_WEB, tokenDrops: 128 } - id: SVEN_PACKMASTER enabled: true @@ -54,10 +55,10 @@ slayers: - { level: 8, requiredXp: 400000, title: Pack Leader } - { level: 9, requiredXp: 1000000, title: Alpha Wolf } tiers: - - { tier: I, cost: 2000, requiredCombatXp: 250, slayerXp: 5, bossLevel: 1, bossHealth: 2000, bossDamage: 60, bossSpeed: 130, tokenItem: WOLF_TOOTH, tokenDrops: 1 } - - { tier: II, cost: 7500, requiredCombatXp: 600, slayerXp: 25, bossLevel: 2, bossHealth: 40000, bossDamage: 200, bossSpeed: 135, tokenItem: WOLF_TOOTH, tokenDrops: 4 } - - { tier: III, cost: 20000, requiredCombatXp: 1000, slayerXp: 100, bossLevel: 3, bossHealth: 750000, bossDamage: 450, bossSpeed: 145, tokenItem: WOLF_TOOTH, tokenDrops: 16 } - - { tier: IV, cost: 50000, requiredCombatXp: 2000, slayerXp: 500, bossLevel: 4, bossHealth: 2000000, bossDamage: 1100, bossSpeed: 155, tokenItem: WOLF_TOOTH, tokenDrops: 64 } + - { tier: I, cost: 2000, requiredCombatXp: 270, slayerXp: 5, bossLevel: 1, bossHealth: 2000, bossDamage: 60, bossSpeed: 130, tokenItem: WOLF_TOOTH, tokenDrops: 1 } + - { tier: II, cost: 7500, requiredCombatXp: 648, slayerXp: 25, bossLevel: 2, bossHealth: 40000, bossDamage: 200, bossSpeed: 135, tokenItem: WOLF_TOOTH, tokenDrops: 4 } + - { tier: III, cost: 20000, requiredCombatXp: 1584, slayerXp: 100, bossLevel: 3, bossHealth: 750000, bossDamage: 450, bossSpeed: 145, tokenItem: WOLF_TOOTH, tokenDrops: 16 } + - { tier: IV, cost: 50000, requiredCombatXp: 3168, slayerXp: 500, bossLevel: 4, bossHealth: 2000000, bossDamage: 1100, bossSpeed: 155, tokenItem: WOLF_TOOTH, tokenDrops: 64 } - id: VOIDGLOOM_SERAPH enabled: true @@ -74,10 +75,10 @@ slayers: - { level: 8, requiredXp: 400000, title: Tall Purple Hater } - { level: 9, requiredXp: 1000000, title: Definition of End } tiers: - - { tier: I, cost: 2000, requiredCombatXp: 250, slayerXp: 5, bossLevel: 1, bossHealth: 300000, bossDamage: 1200, bossSpeed: 140, tokenItem: NULL_SPHERE, tokenDrops: 1 } - - { tier: II, cost: 7500, requiredCombatXp: 600, slayerXp: 25, bossLevel: 2, bossHealth: 15000000, bossDamage: 5000, bossSpeed: 145, tokenItem: NULL_SPHERE, tokenDrops: 2 } - - { tier: III, cost: 20000, requiredCombatXp: 1000, slayerXp: 100, bossLevel: 3, bossHealth: 66000000, bossDamage: 12000, bossSpeed: 150, tokenItem: NULL_SPHERE, tokenDrops: 3 } - - { tier: IV, cost: 50000, requiredCombatXp: 2000, slayerXp: 500, bossLevel: 4, bossHealth: 300000000, bossDamage: 21000, bossSpeed: 160, tokenItem: NULL_SPHERE, tokenDrops: 4 } + - { tier: I, cost: 2000, requiredCombatXp: 2750, slayerXp: 5, bossLevel: 1, bossHealth: 300000, bossDamage: 1200, bossSpeed: 140, tokenItem: NULL_SPHERE, tokenDrops: 1 } + - { tier: II, cost: 7500, requiredCombatXp: 6600, slayerXp: 25, bossLevel: 2, bossHealth: 15000000, bossDamage: 5000, bossSpeed: 145, tokenItem: NULL_SPHERE, tokenDrops: 2 } + - { tier: III, cost: 20000, requiredCombatXp: 11000, slayerXp: 100, bossLevel: 3, bossHealth: 66000000, bossDamage: 12000, bossSpeed: 150, tokenItem: NULL_SPHERE, tokenDrops: 3 } + - { tier: IV, cost: 50000, requiredCombatXp: 22000, slayerXp: 500, bossLevel: 4, bossHealth: 300000000, bossDamage: 21000, bossSpeed: 160, tokenItem: NULL_SPHERE, tokenDrops: 4 } - id: RIFTSTALKER_BLOODFIEND enabled: false @@ -106,7 +107,7 @@ slayers: - { level: 8, requiredXp: 400000, title: Demon Eater } - { level: 9, requiredXp: 1000000, title: Gabagool King } tiers: - - { tier: I, cost: 10000, requiredCombatXp: 250, slayerXp: 10, bossLevel: 1, bossHealth: 2500000, bossDamage: 1500, bossSpeed: 130, tokenItem: DERELICT_ASHE, tokenDrops: 1 } - - { tier: II, cost: 25000, requiredCombatXp: 600, slayerXp: 25, bossLevel: 2, bossHealth: 12000000, bossDamage: 3600, bossSpeed: 135, tokenItem: DERELICT_ASHE, tokenDrops: 2 } - - { tier: III, cost: 50000, requiredCombatXp: 1000, slayerXp: 100, bossLevel: 3, bossHealth: 60000000, bossDamage: 7200, bossSpeed: 145, tokenItem: DERELICT_ASHE, tokenDrops: 3 } - - { tier: IV, cost: 100000, requiredCombatXp: 2000, slayerXp: 500, bossLevel: 4, bossHealth: 150000000, bossDamage: 15000, bossSpeed: 150, tokenItem: DERELICT_ASHE, tokenDrops: 4 } + - { tier: I, cost: 10000, requiredCombatXp: 6000, slayerXp: 5, bossLevel: 1, bossHealth: 2500000, bossDamage: 1500, bossSpeed: 130, tokenItem: DERELICT_ASHE, tokenDrops: 1 } + - { tier: II, cost: 25000, requiredCombatXp: 14400, slayerXp: 25, bossLevel: 2, bossHealth: 12000000, bossDamage: 3600, bossSpeed: 135, tokenItem: DERELICT_ASHE, tokenDrops: 2 } + - { tier: III, cost: 60000, requiredCombatXp: 18000, slayerXp: 100, bossLevel: 3, bossHealth: 60000000, bossDamage: 7200, bossSpeed: 145, tokenItem: DERELICT_ASHE, tokenDrops: 3 } + - { tier: IV, cost: 150000, requiredCombatXp: 36000, slayerXp: 500, bossLevel: 4, bossHealth: 150000000, bossDamage: 15000, bossSpeed: 150, tokenItem: DERELICT_ASHE, tokenDrops: 4 } diff --git a/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/entity/mob/mobs/slayer/SlayerBossMob.java b/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/entity/mob/mobs/slayer/SlayerBossMob.java index 8b1f08ea9..d39c7b2f2 100644 --- a/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/entity/mob/mobs/slayer/SlayerBossMob.java +++ b/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/entity/mob/mobs/slayer/SlayerBossMob.java @@ -4,9 +4,13 @@ import java.util.UUID; import net.minestom.server.entity.ai.GoalSelector; import net.minestom.server.entity.ai.TargetSelector; +import net.minestom.server.entity.damage.Damage; +import net.minestom.server.timer.Task; import net.swofty.commons.skyblock.statistics.ItemStatistics; import net.swofty.type.skyblockgeneric.entity.mob.MobType; import net.swofty.type.skyblockgeneric.entity.mob.SkyBlockMob; +import net.swofty.type.skyblockgeneric.entity.mob.mobs.slayer.ability.SlayerBossAbility; +import net.swofty.type.skyblockgeneric.entity.mob.mobs.slayer.ability.SlayerBossAbilityFactory; import net.swofty.type.skyblockgeneric.loottable.OtherLoot; import net.swofty.type.skyblockgeneric.loottable.SkyBlockLootTable; import net.swofty.type.skyblockgeneric.skill.SkillCategories; @@ -17,11 +21,14 @@ public final class SlayerBossMob extends SkyBlockMob { private final SlayerBossProfile profile; private final UUID ownerUuid; + private final SlayerBossAbility ability; + private final List abilityTasks = new java.util.concurrent.CopyOnWriteArrayList<>(); private SlayerBossMob(UUID ownerUuid, SlayerBossProfile profile) { super(profile.entityType()); this.ownerUuid = ownerUuid; this.profile = profile; + this.ability = SlayerBossAbilityFactory.create(profile.type()); } public static SlayerBossMob create(UUID ownerUuid, SlayerBossProfile profile) { @@ -41,6 +48,14 @@ public SlayerBossProfile getProfile() { return live(); } + public SlayerBossAbility getAbility() { + return ability; + } + + public void trackAbilityTask(Task task) { + abilityTasks.add(task); + } + @Override public String getDisplayName() { return live().displayName(); } @Override public Integer getLevel() { return live().tier().bossLevel(); } @Override public List getMobTypes() { return live().mobTypes(); } @@ -60,6 +75,35 @@ public List getTargetSelectors() { return SlayerBossBehaviour.targets(this); } + @Override + public void onSpawn() { + ability.onSpawn(this); + } + + @Override + public boolean damage(@org.jetbrains.annotations.NotNull Damage damage) { + float amount = damage.getAmount(); + float modified = ability.modifyIncomingDamage(this, damage, amount); + if (modified <= 0F) { + return false; + } + + Damage applied = modified == amount + ? damage + : new Damage(damage.getType(), damage.getSource(), damage.getAttacker(), damage.getSourcePosition(), modified); + boolean result = super.damage(applied); + ability.onDamaged(this, applied, modified); + return result; + } + + @Override + public void kill() { + ability.onDeath(this); + abilityTasks.forEach(Task::cancel); + abilityTasks.clear(); + super.kill(); + } + private SlayerBossProfile live() { return profile != null ? profile : IN_CONSTRUCTION.get(); } diff --git a/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/entity/mob/mobs/slayer/SlayerMinionMob.java b/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/entity/mob/mobs/slayer/SlayerMinionMob.java new file mode 100644 index 000000000..c086b03d8 --- /dev/null +++ b/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/entity/mob/mobs/slayer/SlayerMinionMob.java @@ -0,0 +1,83 @@ +package net.swofty.type.skyblockgeneric.entity.mob.mobs.slayer; + +import java.util.List; +import java.util.UUID; +import net.minestom.server.entity.EntityType; +import net.minestom.server.entity.ai.GoalSelector; +import net.minestom.server.entity.ai.TargetSelector; +import net.swofty.commons.skyblock.statistics.ItemStatistic; +import net.swofty.commons.skyblock.statistics.ItemStatistics; +import net.swofty.type.skyblockgeneric.entity.mob.MobType; +import net.swofty.type.skyblockgeneric.entity.mob.SkyBlockMob; +import net.swofty.type.skyblockgeneric.loottable.OtherLoot; +import net.swofty.type.skyblockgeneric.loottable.SkyBlockLootTable; +import net.swofty.type.skyblockgeneric.skill.SkillCategories; +import org.jetbrains.annotations.Nullable; + +public final class SlayerMinionMob extends SkyBlockMob { + private static final ThreadLocal IN_CONSTRUCTION = new ThreadLocal<>(); + + private final SlayerMinionProfile profile; + private final UUID ownerUuid; + + private SlayerMinionMob(UUID ownerUuid, SlayerMinionProfile profile) { + super(profile.entityType()); + this.ownerUuid = ownerUuid; + this.profile = profile; + } + + public static SlayerMinionMob create(UUID ownerUuid, SlayerMinionProfile profile) { + IN_CONSTRUCTION.set(profile); + try { + return new SlayerMinionMob(ownerUuid, profile); + } finally { + IN_CONSTRUCTION.remove(); + } + } + + public UUID getOwnerUuid() { + return ownerUuid; + } + + @Override public String getDisplayName() { return live().displayName(); } + @Override public Integer getLevel() { return live().level(); } + @Override public List getMobTypes() { return live().mobTypes(); } + @Override public @Nullable SkyBlockLootTable getLootTable() { return null; } + @Override public SkillCategories getSkillCategory() { return SkillCategories.COMBAT; } + @Override public long damageCooldown() { return 700L; } + @Override public OtherLoot getOtherLoot() { return new OtherLoot(0, 0, 0); } + + @Override + public List getGoalSelectors() { + return SlayerBossBehaviour.goals(this); + } + + @Override + public List getTargetSelectors() { + return SlayerBossBehaviour.targets(this); + } + + @Override + public ItemStatistics getBaseStatistics() { + return ItemStatistics.builder() + .withBase(ItemStatistic.HEALTH, live().health()) + .withBase(ItemStatistic.DAMAGE, live().damage()) + .withBase(ItemStatistic.SPEED, live().speed()) + .build(); + } + + private SlayerMinionProfile live() { + return profile != null ? profile : IN_CONSTRUCTION.get(); + } + + public record SlayerMinionProfile( + String displayName, + int level, + EntityType entityType, + double health, + double damage, + double speed, + List mobTypes + ) { + } +} diff --git a/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/entity/mob/mobs/slayer/ability/InfernoDemonlordAbility.java b/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/entity/mob/mobs/slayer/ability/InfernoDemonlordAbility.java new file mode 100644 index 000000000..5cac4c15e --- /dev/null +++ b/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/entity/mob/mobs/slayer/ability/InfernoDemonlordAbility.java @@ -0,0 +1,132 @@ +package net.swofty.type.skyblockgeneric.entity.mob.mobs.slayer.ability; + +import java.util.List; +import net.minestom.server.coordinate.Pos; +import net.minestom.server.entity.EntityType; +import net.minestom.server.entity.damage.Damage; +import net.minestom.server.particle.Particle; +import net.swofty.type.skyblockgeneric.entity.mob.MobType; +import net.swofty.type.skyblockgeneric.entity.mob.mobs.slayer.SlayerBossMob; +import net.swofty.type.skyblockgeneric.entity.mob.mobs.slayer.SlayerMinionMob; +import net.swofty.type.skyblockgeneric.user.SkyBlockPlayer; + +final class InfernoDemonlordAbility extends SlayerAbilitySupport { + private final String[] attunements = {"ASHEN", "SPIRIT", "AURIC", "CRYSTAL"}; + private int attunementIndex; + private int shieldHits; + private boolean split66; + private boolean split50; + private boolean split33; + private boolean pillars; + private boolean apocalypse; + + @Override + public void onSpawn(SlayerBossMob boss) { + repeating(boss, 20, 20, () -> { + nearbyPlayers(boss, 6).forEach(player -> trueDamage(boss, player, immolateDamage(boss, player), "Immolate")); + particles(boss, Particle.FLAME, 1.3f, 35); + + if (boss.getProfile().tier().tier().number() >= 3 && !split66 && healthRatio(boss) <= 0.66D) { + split66 = true; + demonSplit(boss); + } + if (!split50 && healthRatio(boss) <= 0.50D) { + split50 = true; + demonSplit(boss); + } + if (boss.getProfile().tier().tier().number() >= 3 && !split33 && healthRatio(boss) <= 0.33D) { + split33 = true; + demonSplit(boss); + } + if (!pillars && healthRatio(boss) <= (boss.getProfile().tier().tier().number() >= 4 ? 0.66D : 0.50D)) { + pillars = true; + firePillars(boss); + } + if (boss.getProfile().tier().tier().number() >= 3 && !apocalypse && healthRatio(boss) <= 0.33D) { + apocalypse = true; + ddrApocalypse(boss); + } + }); + } + + @Override + public float modifyIncomingDamage(SlayerBossMob boss, Damage damage, float amount) { + shieldHits++; + if (shieldHits >= 8) { + shieldHits = 0; + attunementIndex = (attunementIndex + 1) % attunements.length; + nearbyPlayers(boss, 16).forEach(player -> player.sendMessage("§6Hellion Shield attuned to §e" + attunements[attunementIndex] + "§6!")); + } + + if (boss.getProfile().tier().tier().number() >= 2) { + return amount * 0.35F; + } + return amount; + } + + private double immolateDamage(SlayerBossMob boss, SkyBlockPlayer player) { + double percent = switch (boss.getProfile().tier().tier()) { + case I -> healthRatio(boss) <= 0.33D ? 0.12D : healthRatio(boss) <= 0.66D ? 0.08D : 0.05D; + case II -> healthRatio(boss) <= 0.33D ? 0.15D : healthRatio(boss) <= 0.66D ? 0.10D : 0.05D; + case III -> healthRatio(boss) <= 0.33D ? 0.20D : healthRatio(boss) <= 0.66D ? 0.10D : 0.05D; + case IV, V -> healthRatio(boss) <= 0.33D ? 0.50D : healthRatio(boss) <= 0.66D ? 0.30D : 0.20D; + }; + return 100D + player.getMaxHealth() * percent; + } + + private void demonSplit(SlayerBossMob boss) { + nearbyPlayers(boss, 18).forEach(player -> player.sendMessage("§6Demonsplit! §eQuazii and Typhoeus join the fight.")); + spawnMinion(boss, new SlayerMinionMob.SlayerMinionProfile( + "Quazii", + boss.getLevel(), + EntityType.BLAZE, + boss.getProfile().tier().bossHealth() * 0.08D, + boss.getProfile().tier().bossDamage() * 0.5D, + 120D, + List.of(MobType.INFERNAL, MobType.MAGMATIC) + ), boss.getPosition().add(2, 0, 0), 260); + spawnMinion(boss, new SlayerMinionMob.SlayerMinionProfile( + "Typhoeus", + boss.getLevel(), + EntityType.BLAZE, + boss.getProfile().tier().bossHealth() * 0.08D, + boss.getProfile().tier().bossDamage() * 0.5D, + 120D, + List.of(MobType.INFERNAL, MobType.MAGMATIC) + ), boss.getPosition().add(-2, 0, 0), 260); + repeating(boss, 20, 20, () -> nearbyPlayers(boss, 7).forEach(player -> + trueDamage(boss, player, scorchedAngerDamage(boss), "Scorched Anger"))); + } + + private void firePillars(SlayerBossMob boss) { + repeating(boss, 140, 160, () -> { + SkyBlockPlayer owner = owner(boss); + if (owner == null) { + return; + } + + Pos pillar = owner.getPosition().add((Math.random() - 0.5D) * 6D, 0, (Math.random() - 0.5D) * 6D); + nearbyPlayers(boss, 18).forEach(player -> player.sendMessage("§6Fire Pillar! §eClear it before it explodes.")); + delayed(boss, 140, () -> { + if (owner.getPosition().distance(pillar) <= 4D) { + trueDamage(boss, owner, owner.getMaxHealth() * 10D, "Fire Pillar"); + } + }); + }); + } + + private void ddrApocalypse(SlayerBossMob boss) { + nearbyPlayers(boss, 18).forEach(player -> player.sendMessage("§cDDR Apocalypse!")); + repeating(boss, 20, 20, () -> nearbyPlayers(boss, 8).forEach(player -> + trueDamage(boss, player, player.getMaxHealth() * 2D, "DDR Apocalypse"))); + } + + private double scorchedAngerDamage(SlayerBossMob boss) { + return switch (boss.getProfile().tier().tier()) { + case I -> 1250D; + case II -> 4000D; + case III -> 7500D; + case IV, V -> 15000D; + }; + } +} diff --git a/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/entity/mob/mobs/slayer/ability/NoopSlayerBossAbility.java b/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/entity/mob/mobs/slayer/ability/NoopSlayerBossAbility.java new file mode 100644 index 000000000..1c2d75a0b --- /dev/null +++ b/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/entity/mob/mobs/slayer/ability/NoopSlayerBossAbility.java @@ -0,0 +1,18 @@ +package net.swofty.type.skyblockgeneric.entity.mob.mobs.slayer.ability; + +import net.minestom.server.entity.damage.Damage; +import net.swofty.type.skyblockgeneric.entity.mob.mobs.slayer.SlayerBossMob; +import net.swofty.type.skyblockgeneric.user.SkyBlockPlayer; + +final class NoopSlayerBossAbility implements SlayerBossAbility { + static final NoopSlayerBossAbility INSTANCE = new NoopSlayerBossAbility(); + + private NoopSlayerBossAbility() { + } + + @Override public void onSpawn(SlayerBossMob boss) {} + @Override public float modifyIncomingDamage(SlayerBossMob boss, Damage damage, float amount) { return amount; } + @Override public void onDamaged(SlayerBossMob boss, Damage damage, float appliedDamage) {} + @Override public void onMeleeHit(SlayerBossMob boss, SkyBlockPlayer target) {} + @Override public void onDeath(SlayerBossMob boss) {} +} diff --git a/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/entity/mob/mobs/slayer/ability/RevenantHorrorAbility.java b/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/entity/mob/mobs/slayer/ability/RevenantHorrorAbility.java new file mode 100644 index 000000000..d012791d7 --- /dev/null +++ b/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/entity/mob/mobs/slayer/ability/RevenantHorrorAbility.java @@ -0,0 +1,88 @@ +package net.swofty.type.skyblockgeneric.entity.mob.mobs.slayer.ability; + +import net.minestom.server.particle.Particle; +import net.swofty.type.skyblockgeneric.entity.mob.mobs.slayer.SlayerBossMob; +import net.swofty.type.skyblockgeneric.user.SkyBlockPlayer; + +final class RevenantHorrorAbility extends SlayerAbilitySupport { + private boolean enrage; + private boolean thermonuclear; + private long spawnedAt; + + @Override + public void onSpawn(SlayerBossMob boss) { + spawnedAt = System.currentTimeMillis(); + + repeating(boss, 50, 50, () -> { + double damage = lifeDrainDamage(boss); + nearbyPlayers(boss, 5.5).forEach(player -> trueDamage(boss, player, damage, "Life Drain")); + particles(boss, Particle.SOUL, 0.7f, 12); + }); + + if (boss.getProfile().tier().tier().number() >= 3) { + repeating(boss, 20, 20, () -> { + double damage = pestilenceDamage(boss) * (enrage ? 6D : 1D); + nearbyPlayers(boss, 8.5).forEach(player -> trueDamage(boss, player, damage, "Pestilence")); + particles(boss, Particle.ASH, 1.2f, 20); + }); + } + + if (boss.getProfile().tier().tier().number() >= 4) { + repeating(boss, 800, 800, () -> { + enrage = true; + nearbyPlayers(boss, 16).forEach(player -> player.sendMessage("§c" + boss.getDisplayName() + " is enraged!")); + delayed(boss, 240, () -> enrage = false); + }); + } + + if (boss.getProfile().tier().tier().number() >= 5) { + repeating(boss, 40, 40, () -> heal(boss, boss.getProfile().tier().bossHealth() * 0.015D)); + repeating(boss, 160, 160, () -> nearbyPlayers(boss, 6).forEach(player -> { + player.sendMessage("§cExplosive Assault!"); + trueDamage(boss, player, 4800, "Explosive Assault"); + })); + } + } + + @Override + public void onDamaged(SlayerBossMob boss, net.minestom.server.entity.damage.Damage damage, float appliedDamage) { + if (boss.getProfile().tier().tier().number() < 5 || thermonuclear || healthRatio(boss) > 0.33D) { + return; + } + + thermonuclear = true; + nearbyPlayers(boss, 16).forEach(player -> player.sendMessage("§4§lTHERMONUCLEAR! §cMove away!")); + delayed(boss, 45, () -> { + nearbyPlayers(boss, 7).forEach(player -> { + lightning(player.getPosition(), player.getInstance()); + trueDamage(boss, player, 24000, "Thermonuclear"); + }); + }); + } + + @Override + public void onMeleeHit(SlayerBossMob boss, SkyBlockPlayer target) { + if (enrage) { + trueDamage(boss, target, boss.getProfile().tier().bossDamage() * 0.5D, "Enrage"); + } + } + + private double lifeDrainDamage(SlayerBossMob boss) { + return switch (boss.getProfile().tier().tier()) { + case I -> 15D; + case II -> 40D; + case III -> 100D; + case IV -> 260D; + case V -> 900D; + }; + } + + private double pestilenceDamage(SlayerBossMob boss) { + return switch (boss.getProfile().tier().tier()) { + case I, II -> 0D; + case III -> 35D; + case IV -> 120D; + case V -> 400D; + }; + } +} diff --git a/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/entity/mob/mobs/slayer/ability/SlayerAbilitySupport.java b/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/entity/mob/mobs/slayer/ability/SlayerAbilitySupport.java new file mode 100644 index 000000000..f9d842579 --- /dev/null +++ b/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/entity/mob/mobs/slayer/ability/SlayerAbilitySupport.java @@ -0,0 +1,156 @@ +package net.swofty.type.skyblockgeneric.entity.mob.mobs.slayer.ability; + +import java.util.List; +import net.kyori.adventure.key.Key; +import net.kyori.adventure.sound.Sound; +import net.minestom.server.MinecraftServer; +import net.minestom.server.coordinate.Pos; +import net.minestom.server.entity.LivingEntity; +import net.minestom.server.entity.damage.EntityDamage; +import net.minestom.server.instance.Instance; +import net.minestom.server.network.packet.server.play.ParticlePacket; +import net.minestom.server.particle.Particle; +import net.minestom.server.timer.Task; +import net.minestom.server.timer.TaskSchedule; +import net.swofty.type.skyblockgeneric.entity.mob.mobs.slayer.SlayerBossMob; +import net.swofty.type.skyblockgeneric.entity.mob.mobs.slayer.SlayerMinionMob; +import net.swofty.type.skyblockgeneric.user.SkyBlockPlayer; +import net.swofty.type.skyblockgeneric.utility.DamageIndicator; + +abstract class SlayerAbilitySupport implements SlayerBossAbility { + protected Task repeating(SlayerBossMob boss, int delayTicks, int repeatTicks, Runnable runnable) { + Task task = boss.scheduler().buildTask(() -> { + if (boss.isRemoved() || boss.getInstance() == null) { + return; + } + runnable.run(); + }).delay(TaskSchedule.tick(delayTicks)).repeat(TaskSchedule.tick(repeatTicks)).schedule(); + boss.trackAbilityTask(task); + return task; + } + + protected Task delayed(SlayerBossMob boss, int delayTicks, Runnable runnable) { + Task task = boss.scheduler().buildTask(() -> { + if (boss.isRemoved() || boss.getInstance() == null) { + return; + } + runnable.run(); + }).delay(TaskSchedule.tick(delayTicks)).schedule(); + boss.trackAbilityTask(task); + return task; + } + + protected List nearbyPlayers(SlayerBossMob boss, double range) { + Instance instance = boss.getInstance(); + if (instance == null) { + return List.of(); + } + + return instance.getPlayers().stream() + .filter(player -> player instanceof SkyBlockPlayer) + .map(player -> (SkyBlockPlayer) player) + .filter(player -> player.getPosition().distance(boss.getPosition()) <= range) + .toList(); + } + + protected SkyBlockPlayer owner(SlayerBossMob boss) { + Instance instance = boss.getInstance(); + if (instance == null) { + return null; + } + + return instance.getPlayers().stream() + .filter(player -> player.getUuid().equals(boss.getOwnerUuid())) + .filter(player -> player instanceof SkyBlockPlayer) + .map(player -> (SkyBlockPlayer) player) + .findFirst() + .orElse(null); + } + + protected void trueDamage(SlayerBossMob boss, SkyBlockPlayer player, double damage, String source) { + if (damage <= 0 || player.isRemoved()) { + return; + } + + player.setHealth((float) Math.max(0, player.getHealth() - damage)); + new DamageIndicator().damage((float) damage).pos(player.getPosition()).critical(false).display(player.getInstance()); + player.sendMessage("§c" + source + " dealt " + Math.round(damage) + " true damage!"); + player.playSound(Sound.sound(Key.key("entity.player.hurt"), Sound.Source.PLAYER, 0.8f, 0.8f), Sound.Emitter.self()); + } + + protected void damage(SlayerBossMob boss, SkyBlockPlayer player, double damage) { + if (damage <= 0 || player.isRemoved()) { + return; + } + player.damage(new EntityDamage(boss, (float) damage)); + new DamageIndicator().damage((float) damage).pos(player.getPosition()).critical(false).display(player.getInstance()); + } + + protected void heal(SlayerBossMob boss, double amount) { + float max = (float) boss.getBaseStatistics().getOverall(net.swofty.commons.skyblock.statistics.ItemStatistic.HEALTH).doubleValue(); + boss.setHealth(Math.min(max, boss.getHealth() + (float) amount)); + } + + protected double healthRatio(SlayerBossMob boss) { + double max = boss.getBaseStatistics().getOverall(net.swofty.commons.skyblock.statistics.ItemStatistic.HEALTH); + if (max <= 0) { + return 0D; + } + return boss.getHealth() / max; + } + + protected void particles(SlayerBossMob boss, Particle particle, float spread, int count) { + Instance instance = boss.getInstance(); + if (instance == null) { + return; + } + + Pos position = boss.getPosition().add(0, 1, 0); + instance.getPlayers().forEach(player -> player.sendPacket(new ParticlePacket( + particle, + true, + true, + position.x(), + position.y(), + position.z(), + spread, + spread, + spread, + 0.1f, + count + ))); + } + + protected void lightning(Pos position, Instance instance) { + if (instance == null) { + return; + } + + LivingEntity lightning = new LivingEntity(net.minestom.server.entity.EntityType.LIGHTNING_BOLT); + lightning.setInstance(instance, position); + MinecraftServer.getSchedulerManager().scheduleTask(lightning::remove, TaskSchedule.seconds(1), TaskSchedule.stop()); + } + + protected SlayerMinionMob spawnMinion(SlayerBossMob boss, SlayerMinionMob.SlayerMinionProfile profile, Pos position, int lifespanTicks) { + Instance instance = boss.getInstance(); + if (instance == null) { + return null; + } + + SlayerMinionMob minion = SlayerMinionMob.create(boss.getOwnerUuid(), profile); + minion.setInstance(instance, position); + if (lifespanTicks > 0) { + delayed(boss, lifespanTicks, () -> { + if (!minion.isRemoved()) { + minion.remove(); + } + }); + } + return minion; + } + + @Override public float modifyIncomingDamage(SlayerBossMob boss, net.minestom.server.entity.damage.Damage damage, float amount) { return amount; } + @Override public void onDamaged(SlayerBossMob boss, net.minestom.server.entity.damage.Damage damage, float appliedDamage) {} + @Override public void onMeleeHit(SlayerBossMob boss, SkyBlockPlayer target) {} + @Override public void onDeath(SlayerBossMob boss) {} +} diff --git a/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/entity/mob/mobs/slayer/ability/SlayerBossAbility.java b/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/entity/mob/mobs/slayer/ability/SlayerBossAbility.java new file mode 100644 index 000000000..7810f4d95 --- /dev/null +++ b/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/entity/mob/mobs/slayer/ability/SlayerBossAbility.java @@ -0,0 +1,21 @@ +package net.swofty.type.skyblockgeneric.entity.mob.mobs.slayer.ability; + +import net.minestom.server.entity.damage.Damage; +import net.swofty.type.skyblockgeneric.entity.mob.mobs.slayer.SlayerBossMob; +import net.swofty.type.skyblockgeneric.user.SkyBlockPlayer; + +public interface SlayerBossAbility { + void onSpawn(SlayerBossMob boss); + + float modifyIncomingDamage(SlayerBossMob boss, Damage damage, float amount); + + void onDamaged(SlayerBossMob boss, Damage damage, float appliedDamage); + + void onMeleeHit(SlayerBossMob boss, SkyBlockPlayer target); + + void onDeath(SlayerBossMob boss); + + static SlayerBossAbility none() { + return NoopSlayerBossAbility.INSTANCE; + } +} diff --git a/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/entity/mob/mobs/slayer/ability/SlayerBossAbilityFactory.java b/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/entity/mob/mobs/slayer/ability/SlayerBossAbilityFactory.java new file mode 100644 index 000000000..bc17b3f0d --- /dev/null +++ b/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/entity/mob/mobs/slayer/ability/SlayerBossAbilityFactory.java @@ -0,0 +1,19 @@ +package net.swofty.type.skyblockgeneric.entity.mob.mobs.slayer.ability; + +import net.swofty.type.skyblockgeneric.slayer.SlayerType; + +public final class SlayerBossAbilityFactory { + private SlayerBossAbilityFactory() { + } + + public static SlayerBossAbility create(SlayerType type) { + return switch (type) { + case REVENANT_HORROR -> new RevenantHorrorAbility(); + case TARANTULA_BROODFATHER -> new TarantulaBroodfatherAbility(); + case SVEN_PACKMASTER -> new SvenPackmasterAbility(); + case VOIDGLOOM_SERAPH -> new VoidgloomSeraphAbility(); + case INFERNO_DEMONLORD -> new InfernoDemonlordAbility(); + case RIFTSTALKER_BLOODFIEND -> SlayerBossAbility.none(); + }; + } +} diff --git a/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/entity/mob/mobs/slayer/ability/SvenPackmasterAbility.java b/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/entity/mob/mobs/slayer/ability/SvenPackmasterAbility.java new file mode 100644 index 000000000..06ddf6a1e --- /dev/null +++ b/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/entity/mob/mobs/slayer/ability/SvenPackmasterAbility.java @@ -0,0 +1,55 @@ +package net.swofty.type.skyblockgeneric.entity.mob.mobs.slayer.ability; + +import java.util.List; +import net.minestom.server.entity.EntityType; +import net.minestom.server.particle.Particle; +import net.swofty.type.skyblockgeneric.entity.mob.MobType; +import net.swofty.type.skyblockgeneric.entity.mob.mobs.slayer.SlayerBossMob; +import net.swofty.type.skyblockgeneric.entity.mob.mobs.slayer.SlayerMinionMob; +import net.swofty.type.skyblockgeneric.user.SkyBlockPlayer; + +final class SvenPackmasterAbility extends SlayerAbilitySupport { + private boolean pupsCalled; + + @Override + public void onSpawn(SlayerBossMob boss) { + repeating(boss, 20, 20, () -> { + if (boss.getProfile().tier().tier().number() >= 3 && !pupsCalled && healthRatio(boss) <= 0.50D) { + pupsCalled = true; + callPups(boss); + } + particles(boss, Particle.CRIT, 0.5f, 4); + }); + } + + @Override + public void onMeleeHit(SlayerBossMob boss, SkyBlockPlayer target) { + double trueDamage = switch (boss.getProfile().tier().tier()) { + case I -> 0D; + case II -> 10D; + case III -> 50D; + case IV, V -> 200D; + }; + if (trueDamage > 0) { + trueDamage(boss, target, trueDamage, "True Damage"); + } + } + + private void callPups(SlayerBossMob boss) { + int pups = boss.getProfile().tier().tier().number() >= 4 ? 6 : 5; + double damage = boss.getProfile().tier().tier().number() >= 4 ? 220D : 90D; + nearbyPlayers(boss, 16).forEach(player -> player.sendMessage("§fCall the pups!")); + for (int i = 0; i < pups; i++) { + int index = i; + delayed(boss, i * 10, () -> spawnMinion(boss, new SlayerMinionMob.SlayerMinionProfile( + "Pack Pup", + boss.getLevel(), + EntityType.WOLF, + boss.getProfile().tier().bossHealth() * 0.02D, + damage, + 160D, + List.of(MobType.WOODLAND) + ), boss.getPosition().add(index - pups / 2D, 0, 1.5), 360)); + } + } +} diff --git a/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/entity/mob/mobs/slayer/ability/TarantulaBroodfatherAbility.java b/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/entity/mob/mobs/slayer/ability/TarantulaBroodfatherAbility.java new file mode 100644 index 000000000..39bd45c61 --- /dev/null +++ b/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/entity/mob/mobs/slayer/ability/TarantulaBroodfatherAbility.java @@ -0,0 +1,105 @@ +package net.swofty.type.skyblockgeneric.entity.mob.mobs.slayer.ability; + +import java.util.List; +import net.minestom.server.coordinate.Pos; +import net.minestom.server.entity.EntityType; +import net.minestom.server.entity.damage.Damage; +import net.minestom.server.particle.Particle; +import net.swofty.type.skyblockgeneric.entity.mob.MobType; +import net.swofty.type.skyblockgeneric.entity.mob.mobs.slayer.SlayerBossMob; +import net.swofty.type.skyblockgeneric.entity.mob.mobs.slayer.SlayerMinionMob; +import net.swofty.type.skyblockgeneric.user.SkyBlockPlayer; + +final class TarantulaBroodfatherAbility extends SlayerAbilitySupport { + private boolean web66; + private boolean web33; + private boolean barrage; + private boolean conjoined; + + @Override + public void onSpawn(SlayerBossMob boss) { + repeating(boss, 80, 120, () -> { + SkyBlockPlayer owner = owner(boss); + if (owner == null) { + return; + } + Pos behind = owner.getPosition().sub(owner.getPosition().direction().mul(2)).withY(owner.getPosition().y()); + boss.teleport(behind); + owner.sendMessage("§5Backstab!"); + }); + + repeating(boss, 20, 20, () -> { + int tier = boss.getProfile().tier().tier().number(); + if (tier >= 3 && !web66 && healthRatio(boss) <= 0.66D) { + web66 = true; + webOfLies(boss); + } + if (tier >= 3 && !web33 && healthRatio(boss) <= 0.33D) { + web33 = true; + webOfLies(boss); + } + if (tier >= 4 && !barrage && healthRatio(boss) <= (tier == 4 ? 0.50D : 0.66D)) { + barrage = true; + batBarrage(boss); + } + }); + } + + @Override + public float modifyIncomingDamage(SlayerBossMob boss, Damage damage, float amount) { + if (boss.getProfile().tier().tier().number() >= 5 && !conjoined && amount >= boss.getHealth()) { + conjoined = true; + boss.setHealth((float) boss.getProfile().tier().bossHealth()); + boss.getAttribute(net.minestom.server.entity.attribute.Attribute.MAX_HEALTH).setBaseValue(boss.getProfile().tier().bossHealth() * 2D); + nearbyPlayers(boss, 16).forEach(player -> player.sendMessage("§5Til Death Do Us Part! §dThe Conjoined Brood awakens!")); + return 0F; + } + return amount; + } + + @Override + public void onMeleeHit(SlayerBossMob boss, SkyBlockPlayer target) { + int tier = boss.getProfile().tier().tier().number(); + if (tier >= 2) { + trueDamage(boss, target, tier * 25D, "Noxious Paralysis"); + } + } + + private void webOfLies(SlayerBossMob boss) { + nearbyPlayers(boss, 16).forEach(player -> player.sendMessage("§5Web of Lies! §dDestroy the egg sacs!")); + heal(boss, boss.getProfile().tier().bossHealth() * 0.05D); + int sacs = boss.getProfile().tier().tier().number() >= 5 ? 3 : 2; + for (int i = 0; i < sacs; i++) { + Pos pos = boss.getPosition().add(i - 1, 2, i % 2 == 0 ? 1 : -1); + spawnMinion(boss, new SlayerMinionMob.SlayerMinionProfile( + "Tarantula Egg Sac", + boss.getLevel(), + EntityType.SPIDER, + boss.getProfile().tier().bossHealth() * 0.04D, + boss.getProfile().tier().bossDamage() * 0.25D, + 60D, + List.of(MobType.ARTHROPOD) + ), pos, 220); + } + particles(boss, Particle.ITEM_COBWEB, 1.5f, 40); + } + + private void batBarrage(SlayerBossMob boss) { + nearbyPlayers(boss, 16).forEach(player -> player.sendMessage("§5Bat Barrage!")); + int bats = boss.getProfile().tier().tier().number() >= 5 ? 6 : 4; + for (int i = 0; i < bats; i++) { + spawnMinion(boss, new SlayerMinionMob.SlayerMinionProfile( + "Brood Bat", + boss.getLevel(), + EntityType.BAT, + boss.getProfile().tier().bossHealth() * 0.015D, + boss.getProfile().tier().bossDamage() * 0.2D, + 160D, + List.of(MobType.ARTHROPOD) + ), boss.getPosition().add(i - 2, 1, i % 2 == 0 ? 2 : -2), 300); + } + + repeating(boss, 20, 20, () -> nearbyPlayers(boss, 7).forEach(player -> + trueDamage(boss, player, player.getMaxHealth() * (boss.getProfile().tier().tier().number() >= 5 ? 0.04D : 0.02D), "Bat Barrage"))); + } +} diff --git a/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/entity/mob/mobs/slayer/ability/VoidgloomSeraphAbility.java b/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/entity/mob/mobs/slayer/ability/VoidgloomSeraphAbility.java new file mode 100644 index 000000000..0328ddf8f --- /dev/null +++ b/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/entity/mob/mobs/slayer/ability/VoidgloomSeraphAbility.java @@ -0,0 +1,115 @@ +package net.swofty.type.skyblockgeneric.entity.mob.mobs.slayer.ability; + +import java.util.HashSet; +import java.util.Set; +import net.minestom.server.coordinate.Pos; +import net.minestom.server.entity.damage.Damage; +import net.minestom.server.particle.Particle; +import net.swofty.type.skyblockgeneric.entity.mob.mobs.slayer.SlayerBossMob; +import net.swofty.type.skyblockgeneric.user.SkyBlockPlayer; + +final class VoidgloomSeraphAbility extends SlayerAbilitySupport { + private final Set triggeredShields = new HashSet<>(); + private int shieldHits; + private boolean glyphStarted; + private int fixationHeads; + + @Override + public void onSpawn(SlayerBossMob boss) { + triggerShield(boss, 100); + + repeating(boss, 20, 20, () -> { + SkyBlockPlayer owner = owner(boss); + if (owner != null) { + Pos side = owner.getPosition().add((Math.random() - 0.5D) * 3D, 0, (Math.random() - 0.5D) * 3D); + boss.teleport(side); + } + nearbyPlayers(boss, 6.5).forEach(player -> trueDamage(boss, player, dissonanceDamage(boss), "Dissonance")); + particles(boss, Particle.PORTAL, 1.2f, 25); + + if (healthRatio(boss) <= 0.66D) { + triggerShield(boss, 66); + } + if (healthRatio(boss) <= 0.33D) { + triggerShield(boss, 33); + } + if (boss.getProfile().tier().tier().number() >= 2 && !glyphStarted && healthRatio(boss) <= 0.50D) { + glyphStarted = true; + startGlyphs(boss); + } + }); + + if (boss.getProfile().tier().tier().number() >= 3) { + repeating(boss, 120, 120, () -> { + if (healthRatio(boss) <= 0.33D && fixationHeads < 6) { + fixationHeads++; + nearbyPlayers(boss, 12).forEach(player -> player.sendMessage("§5Nukekubi Fixation spawned!")); + } + }); + repeating(boss, 20, 20, () -> { + if (fixationHeads > 0) { + double damage = Math.min(dissonanceDamage(boss), 800D * (fixationHeads * Math.pow(2, fixationHeads - 1))); + nearbyPlayers(boss, 8).forEach(player -> trueDamage(boss, player, damage, "Nukekubi Fixation")); + } + }); + } + } + + @Override + public float modifyIncomingDamage(SlayerBossMob boss, Damage damage, float amount) { + if (shieldHits <= 0) { + return amount; + } + + shieldHits--; + if (shieldHits == 0) { + nearbyPlayers(boss, 16).forEach(player -> player.sendMessage("§dMalevolent Hitshield broken!")); + } else { + nearbyPlayers(boss, 12).forEach(player -> player.sendMessage("§5Hitshield: §d" + shieldHits + " hits left")); + } + boss.teleport(boss.getPosition().add((Math.random() - 0.5D) * 1.5D, 0, (Math.random() - 0.5D) * 1.5D)); + return 0F; + } + + private void triggerShield(SlayerBossMob boss, int threshold) { + if (!triggeredShields.add(threshold)) { + return; + } + + shieldHits = switch (boss.getProfile().tier().tier()) { + case I -> 15; + case II -> 30; + case III -> 60; + case IV, V -> 100; + }; + nearbyPlayers(boss, 16).forEach(player -> player.sendMessage("§5Malevolent Hitshield! §d" + shieldHits + " hits required.")); + } + + private void startGlyphs(SlayerBossMob boss) { + repeating(boss, 160, 160, () -> { + SkyBlockPlayer owner = owner(boss); + if (owner == null) { + return; + } + + Pos glyph = owner.getPosition().add((Math.random() - 0.5D) * 7D, 0, (Math.random() - 0.5D) * 7D); + nearbyPlayers(boss, 16).forEach(player -> player.sendMessage("§eYang Glyph! §7Stand on it before it detonates.")); + delayed(boss, 100, () -> { + if (owner.getPosition().distance(glyph) > 1.5D) { + trueDamage(boss, owner, owner.getMaxHealth() * 1000D, "Yang Glyph"); + } else { + owner.sendMessage("§aYang Glyph shattered!"); + } + }); + }); + } + + private double dissonanceDamage(SlayerBossMob boss) { + return switch (boss.getProfile().tier().tier()) { + case I -> 720D; + case II -> 3000D; + case III -> 7200D; + case IV, V -> 12600D; + }; + } +} diff --git a/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/event/actions/player/mobdamage/PlayerActionDamagedAttacked.java b/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/event/actions/player/mobdamage/PlayerActionDamagedAttacked.java index b712086f4..813def025 100644 --- a/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/event/actions/player/mobdamage/PlayerActionDamagedAttacked.java +++ b/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/event/actions/player/mobdamage/PlayerActionDamagedAttacked.java @@ -9,6 +9,7 @@ import net.swofty.type.generic.event.phase.EventPhase; import net.swofty.type.generic.event.phase.PhasedEvent; import net.swofty.type.skyblockgeneric.entity.mob.SkyBlockMob; +import net.swofty.type.skyblockgeneric.entity.mob.mobs.slayer.SlayerBossMob; import net.swofty.type.skyblockgeneric.event.value.SkyBlockValueEvent; import net.swofty.type.skyblockgeneric.event.value.events.PlayerDamagedByMobValueUpdateEvent; import net.swofty.type.skyblockgeneric.user.SkyBlockPlayer; @@ -39,6 +40,10 @@ public void run(EntityAttackEvent event) { ((SkyBlockPlayer) event.getTarget()).damage(new EntityDamage(mob, (float) valueEvent.getValue())); + if (mob instanceof SlayerBossMob slayerBoss) { + slayerBoss.getAbility().onMeleeHit(slayerBoss, (SkyBlockPlayer) event.getTarget()); + } + new DamageIndicator() .damage((float) valueEvent.getValue()) .pos(event.getTarget().getPosition()) From f25150c231cbd12359335858e2dbf880f03a4c00 Mon Sep 17 00:00:00 2001 From: "Jacob Nardella (Swofty)" Date: Fri, 15 May 2026 14:41:56 +1000 Subject: [PATCH 110/113] style(slayer): use lombok for private constructors --- .../entity/mob/mobs/slayer/SlayerBossBehaviour.java | 6 +++--- .../mob/mobs/slayer/ability/NoopSlayerBossAbility.java | 6 +++--- .../mob/mobs/slayer/ability/SlayerBossAbilityFactory.java | 6 +++--- .../swofty/type/skyblockgeneric/slayer/SlayerRegistry.java | 6 +++--- .../swofty/type/skyblockgeneric/slayer/SlayerService.java | 6 +++--- 5 files changed, 15 insertions(+), 15 deletions(-) diff --git a/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/entity/mob/mobs/slayer/SlayerBossBehaviour.java b/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/entity/mob/mobs/slayer/SlayerBossBehaviour.java index 10c4a7698..15bb33cce 100644 --- a/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/entity/mob/mobs/slayer/SlayerBossBehaviour.java +++ b/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/entity/mob/mobs/slayer/SlayerBossBehaviour.java @@ -1,6 +1,8 @@ package net.swofty.type.skyblockgeneric.entity.mob.mobs.slayer; import java.util.List; +import lombok.AccessLevel; +import lombok.NoArgsConstructor; import net.minestom.server.entity.ai.GoalSelector; import net.minestom.server.entity.ai.TargetSelector; import net.minestom.server.entity.ai.goal.MeleeAttackGoal; @@ -11,10 +13,8 @@ import net.swofty.type.skyblockgeneric.entity.mob.SkyBlockMob; import net.swofty.type.skyblockgeneric.user.SkyBlockPlayer; +@NoArgsConstructor(access = AccessLevel.PRIVATE) public final class SlayerBossBehaviour { - private SlayerBossBehaviour() { - } - public static List goals(SkyBlockMob self) { return List.of( new MeleeAttackGoal(self, 1.8, 16, TimeUnit.SERVER_TICK), diff --git a/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/entity/mob/mobs/slayer/ability/NoopSlayerBossAbility.java b/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/entity/mob/mobs/slayer/ability/NoopSlayerBossAbility.java index 1c2d75a0b..f28b6c5a0 100644 --- a/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/entity/mob/mobs/slayer/ability/NoopSlayerBossAbility.java +++ b/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/entity/mob/mobs/slayer/ability/NoopSlayerBossAbility.java @@ -1,15 +1,15 @@ package net.swofty.type.skyblockgeneric.entity.mob.mobs.slayer.ability; +import lombok.AccessLevel; +import lombok.NoArgsConstructor; import net.minestom.server.entity.damage.Damage; import net.swofty.type.skyblockgeneric.entity.mob.mobs.slayer.SlayerBossMob; import net.swofty.type.skyblockgeneric.user.SkyBlockPlayer; +@NoArgsConstructor(access = AccessLevel.PRIVATE) final class NoopSlayerBossAbility implements SlayerBossAbility { static final NoopSlayerBossAbility INSTANCE = new NoopSlayerBossAbility(); - private NoopSlayerBossAbility() { - } - @Override public void onSpawn(SlayerBossMob boss) {} @Override public float modifyIncomingDamage(SlayerBossMob boss, Damage damage, float amount) { return amount; } @Override public void onDamaged(SlayerBossMob boss, Damage damage, float appliedDamage) {} diff --git a/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/entity/mob/mobs/slayer/ability/SlayerBossAbilityFactory.java b/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/entity/mob/mobs/slayer/ability/SlayerBossAbilityFactory.java index bc17b3f0d..aa86ac4b0 100644 --- a/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/entity/mob/mobs/slayer/ability/SlayerBossAbilityFactory.java +++ b/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/entity/mob/mobs/slayer/ability/SlayerBossAbilityFactory.java @@ -1,11 +1,11 @@ package net.swofty.type.skyblockgeneric.entity.mob.mobs.slayer.ability; +import lombok.AccessLevel; +import lombok.NoArgsConstructor; import net.swofty.type.skyblockgeneric.slayer.SlayerType; +@NoArgsConstructor(access = AccessLevel.PRIVATE) public final class SlayerBossAbilityFactory { - private SlayerBossAbilityFactory() { - } - public static SlayerBossAbility create(SlayerType type) { return switch (type) { case REVENANT_HORROR -> new RevenantHorrorAbility(); diff --git a/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/slayer/SlayerRegistry.java b/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/slayer/SlayerRegistry.java index b4b974fd2..48ee62148 100644 --- a/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/slayer/SlayerRegistry.java +++ b/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/slayer/SlayerRegistry.java @@ -9,19 +9,19 @@ import java.util.List; import java.util.Map; import java.util.Optional; +import lombok.AccessLevel; +import lombok.NoArgsConstructor; import net.swofty.commons.YamlFileUtils; import net.swofty.commons.skyblock.item.ItemType; import net.swofty.type.skyblockgeneric.entity.mob.MobType; import org.jetbrains.annotations.Nullable; import org.tinylog.Logger; +@NoArgsConstructor(access = AccessLevel.PRIVATE) public final class SlayerRegistry { private static final File SLAYERS_FILE = new File("./configuration/skyblock/slayers.yml"); private static final Map DEFINITIONS = new LinkedHashMap<>(); - private SlayerRegistry() { - } - public static void loadAll() { DEFINITIONS.clear(); diff --git a/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/slayer/SlayerService.java b/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/slayer/SlayerService.java index 8a49ef594..b7a12a20d 100644 --- a/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/slayer/SlayerService.java +++ b/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/slayer/SlayerService.java @@ -1,6 +1,8 @@ package net.swofty.type.skyblockgeneric.slayer; import java.util.Optional; +import lombok.AccessLevel; +import lombok.NoArgsConstructor; import net.kyori.adventure.text.Component; import net.minestom.server.coordinate.Pos; import net.minestom.server.instance.Instance; @@ -14,10 +16,8 @@ import net.swofty.type.skyblockgeneric.user.SkyBlockPlayer; import org.jetbrains.annotations.Nullable; +@NoArgsConstructor(access = AccessLevel.PRIVATE) public final class SlayerService { - private SlayerService() { - } - public static StartResult startQuest(SkyBlockPlayer player, SlayerType type, SlayerTier tier) { DatapointSlayer.SlayerData data = data(player); if (data.getActiveQuest() != null) { From b4d52a26cd6a9464c9a38e2bedb55999e7d5eb4e Mon Sep 17 00:00:00 2001 From: "Jacob Nardella (Swofty)" Date: Fri, 15 May 2026 14:43:52 +1000 Subject: [PATCH 111/113] style: use lombok for utility constructors --- .../main/java/net/swofty/anticheat/math/ChunkUtils.java | 6 ++++-- commons/src/main/java/net/swofty/commons/ChatUtility.java | 6 ++++-- .../src/main/java/net/swofty/commons/StringUtility.java | 6 ++++-- .../src/main/java/net/swofty/commons/YamlFileUtils.java | 6 ++++-- .../java/net/swofty/commons/bedwars/BedwarsLevelUtil.java | 6 ++++-- .../main/java/net/swofty/commons/redis/RedisChannels.java | 7 ++++--- .../main/java/net/swofty/commons/redis/RedisClient.java | 7 ++++--- .../java/net/swofty/commons/redis/RedisConnectionPool.java | 6 ++++-- .../java/net/swofty/commons/redis/RedisMessageBus.java | 7 ++++--- .../java/net/swofty/commons/skywars/SkywarsLevelUtil.java | 6 ++++-- .../main/java/net/swofty/dungeons/DungeonUtilities.java | 6 ++++-- .../java/net/swofty/pvp/feature/food/ChorusFruitUtil.java | 6 ++++-- pvp/src/main/java/net/swofty/pvp/utils/EffectUtil.java | 6 ++++-- pvp/src/main/java/net/swofty/pvp/utils/EntityUtil.java | 6 ++++-- pvp/src/main/java/net/swofty/pvp/utils/FluidUtil.java | 6 ++++-- pvp/src/main/java/net/swofty/pvp/utils/ProjectileUtil.java | 6 ++++-- pvp/src/main/java/net/swofty/pvp/utils/ViewUtil.java | 6 ++++-- .../java/net/swofty/type/bedwarsgame/util/ColorUtil.java | 6 ++++-- .../main/java/net/swofty/type/generic/chat/StaffChat.java | 5 ++++- .../swofty/type/generic/presence/PresenceHeartbeat.java | 5 ++++- .../type/generic/user/flow/GenericPlayerDataFlow.java | 6 ++++-- .../java/net/swofty/type/generic/user/flow/PlayerFlow.java | 6 ++++-- .../java/net/swofty/type/generic/utility/BlockUtility.java | 6 ++++-- .../net/swofty/type/generic/utility/BufferUtility.java | 6 ++++-- .../java/net/swofty/type/generic/utility/ChestUtility.java | 6 ++++-- .../java/net/swofty/type/generic/utility/MathUtility.java | 6 ++++-- .../swofty/type/island/lifecycle/IslandLifecycleSteps.java | 7 ++++--- .../entity/mob/mobs/seacreature/SeaCreatureProfiles.java | 7 ++++--- .../entity/mob/mobs/seacreature/SeaCreatureSpawner.java | 7 ++++--- .../type/skyblockgeneric/fishing/FishingService.java | 7 ++++--- .../skyblockgeneric/fishing/bait/FishingBaitService.java | 6 ++++-- .../fishing/hotspot/FishingHotspotService.java | 7 ++++--- .../skyblockgeneric/fishing/item/FishingItemSupport.java | 6 ++++-- .../skyblockgeneric/fishing/registry/FishingRegistry.java | 7 ++++--- .../fishing/resolver/FishingCatchResolver.java | 6 ++++-- .../fishing/resolver/FishingLootResolver.java | 7 ++++--- .../skyblockgeneric/fishing/rod/FishingRodLoreBuilder.java | 7 ++++--- .../skyblockgeneric/fishing/rod/FishingRodPartService.java | 6 ++++-- .../skyblockgeneric/fishing/ship/FishingShipService.java | 6 ++++-- .../skyblockgeneric/fishing/tag/FishingTagRegistry.java | 7 ++++--- .../gui/inventories/fishing/FishingGuideStackFactory.java | 7 ++++--- .../skyblockgeneric/user/flow/SkyBlockPlayerDataFlow.java | 6 ++++-- .../type/skyblockgeneric/user/island/IslandLifecycle.java | 7 ++++--- .../type/skyblockgeneric/user/island/IslandMembers.java | 6 ++++-- .../skyblockgeneric/user/island/IslandWorldStorage.java | 7 ++++--- .../swofty/velocity/gamemanager/BalanceConfigurations.java | 7 ++++--- .../net/swofty/velocity/presence/PresencePublisher.java | 6 ++++-- .../net/swofty/velocity/redis/RedisHandlerRegistry.java | 6 ++++-- 48 files changed, 192 insertions(+), 110 deletions(-) diff --git a/anticheat/src/main/java/net/swofty/anticheat/math/ChunkUtils.java b/anticheat/src/main/java/net/swofty/anticheat/math/ChunkUtils.java index e4bb8b787..895d59db1 100644 --- a/anticheat/src/main/java/net/swofty/anticheat/math/ChunkUtils.java +++ b/anticheat/src/main/java/net/swofty/anticheat/math/ChunkUtils.java @@ -1,8 +1,10 @@ package net.swofty.anticheat.math; -public final class ChunkUtils { +import lombok.AccessLevel; +import lombok.NoArgsConstructor; - private ChunkUtils() {} +@NoArgsConstructor(access = AccessLevel.PRIVATE) +public final class ChunkUtils { public static int getChunkCoordinate(double xz) { return getChunkCoordinate((int) Math.floor(xz)); diff --git a/commons/src/main/java/net/swofty/commons/ChatUtility.java b/commons/src/main/java/net/swofty/commons/ChatUtility.java index 1242246c5..5d20b226a 100644 --- a/commons/src/main/java/net/swofty/commons/ChatUtility.java +++ b/commons/src/main/java/net/swofty/commons/ChatUtility.java @@ -1,13 +1,15 @@ package net.swofty.commons; +import lombok.AccessLevel; +import lombok.NoArgsConstructor; + import lombok.Getter; import java.util.List; +@NoArgsConstructor(access = AccessLevel.PRIVATE) public final class ChatUtility { - private ChatUtility() {} - public enum FontInfo { A('A', 5), diff --git a/commons/src/main/java/net/swofty/commons/StringUtility.java b/commons/src/main/java/net/swofty/commons/StringUtility.java index 997f2ac35..6f4756cec 100644 --- a/commons/src/main/java/net/swofty/commons/StringUtility.java +++ b/commons/src/main/java/net/swofty/commons/StringUtility.java @@ -1,5 +1,8 @@ package net.swofty.commons; +import lombok.AccessLevel; +import lombok.NoArgsConstructor; + import net.kyori.adventure.text.Component; import net.kyori.adventure.text.TextComponent; import net.kyori.adventure.text.serializer.plain.PlainTextComponentSerializer; @@ -16,10 +19,9 @@ import java.util.regex.Matcher; import java.util.regex.Pattern; +@NoArgsConstructor(access = AccessLevel.PRIVATE) public final class StringUtility { - private StringUtility() {} - public static final char[] ALPHABET = { 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'W', 'X', 'Y', 'Z' }; diff --git a/commons/src/main/java/net/swofty/commons/YamlFileUtils.java b/commons/src/main/java/net/swofty/commons/YamlFileUtils.java index 714cd59f3..2dac76e30 100644 --- a/commons/src/main/java/net/swofty/commons/YamlFileUtils.java +++ b/commons/src/main/java/net/swofty/commons/YamlFileUtils.java @@ -1,5 +1,8 @@ package net.swofty.commons; +import lombok.AccessLevel; +import lombok.NoArgsConstructor; + import org.yaml.snakeyaml.Yaml; import java.io.*; @@ -13,10 +16,9 @@ import java.util.stream.Collectors; import java.util.stream.Stream; +@NoArgsConstructor(access = AccessLevel.PRIVATE) public final class YamlFileUtils { - private YamlFileUtils() {} - /** * Get all YAML files in a directory and its subdirectories * @param directory The base directory to search in diff --git a/commons/src/main/java/net/swofty/commons/bedwars/BedwarsLevelUtil.java b/commons/src/main/java/net/swofty/commons/bedwars/BedwarsLevelUtil.java index c447269ef..5fcdc101d 100644 --- a/commons/src/main/java/net/swofty/commons/bedwars/BedwarsLevelUtil.java +++ b/commons/src/main/java/net/swofty/commons/bedwars/BedwarsLevelUtil.java @@ -1,11 +1,13 @@ package net.swofty.commons.bedwars; +import lombok.AccessLevel; +import lombok.NoArgsConstructor; + import java.text.DecimalFormat; +@NoArgsConstructor(access = AccessLevel.PRIVATE) public final class BedwarsLevelUtil { - private BedwarsLevelUtil() {} - private static final DecimalFormat FORMAT = new DecimalFormat("#,###.#"); public static String suffix(double value) { diff --git a/commons/src/main/java/net/swofty/commons/redis/RedisChannels.java b/commons/src/main/java/net/swofty/commons/redis/RedisChannels.java index b67ca10b2..434a7a059 100644 --- a/commons/src/main/java/net/swofty/commons/redis/RedisChannels.java +++ b/commons/src/main/java/net/swofty/commons/redis/RedisChannels.java @@ -1,16 +1,17 @@ package net.swofty.commons.redis; +import lombok.AccessLevel; +import lombok.NoArgsConstructor; + import net.swofty.commons.protocol.RedisProtocol; +@NoArgsConstructor(access = AccessLevel.PRIVATE) public final class RedisChannels { public static final String PROXY_RESPONSE = "proxy"; public static final String SERVICE_RESPONSE = "service_response"; public static final String SERVICE_BROADCAST_RESPONSE = "service_broadcast_response"; public static final String ALL_SERVERS = "all"; - private RedisChannels() { - } - public static String protocol(RedisProtocol protocol) { return protocol.channel(); } diff --git a/commons/src/main/java/net/swofty/commons/redis/RedisClient.java b/commons/src/main/java/net/swofty/commons/redis/RedisClient.java index e00573d19..2489302a8 100644 --- a/commons/src/main/java/net/swofty/commons/redis/RedisClient.java +++ b/commons/src/main/java/net/swofty/commons/redis/RedisClient.java @@ -1,5 +1,8 @@ package net.swofty.commons.redis; +import lombok.AccessLevel; +import lombok.NoArgsConstructor; + import net.swofty.commons.ServiceType; import net.swofty.commons.protocol.RedisProtocol; import net.swofty.commons.protocol.objects.PingProtocol; @@ -13,13 +16,11 @@ import java.util.concurrent.TimeUnit; import java.util.concurrent.atomic.AtomicBoolean; +@NoArgsConstructor(access = AccessLevel.PRIVATE) public final class RedisClient { private static final Map> protocolsByRequest = new ConcurrentHashMap<>(); private static volatile RedisEndpoint localEndpoint; - private RedisClient() { - } - public static void identify(RedisEndpoint endpoint) { localEndpoint = endpoint; } diff --git a/commons/src/main/java/net/swofty/commons/redis/RedisConnectionPool.java b/commons/src/main/java/net/swofty/commons/redis/RedisConnectionPool.java index 553c89b64..07517a083 100644 --- a/commons/src/main/java/net/swofty/commons/redis/RedisConnectionPool.java +++ b/commons/src/main/java/net/swofty/commons/redis/RedisConnectionPool.java @@ -1,5 +1,8 @@ package net.swofty.commons.redis; +import lombok.AccessLevel; +import lombok.NoArgsConstructor; + import redis.clients.jedis.Jedis; import redis.clients.jedis.JedisPool; import redis.clients.jedis.JedisPoolConfig; @@ -7,9 +10,8 @@ import java.net.URI; import java.time.Duration; +@NoArgsConstructor(access = AccessLevel.PRIVATE) public final class RedisConnectionPool { - private RedisConnectionPool() { - } public static JedisPool connect(String redisUri, Settings settings) { JedisPoolConfig poolConfig = new JedisPoolConfig(); diff --git a/commons/src/main/java/net/swofty/commons/redis/RedisMessageBus.java b/commons/src/main/java/net/swofty/commons/redis/RedisMessageBus.java index eeb9a8cbd..62d85f834 100644 --- a/commons/src/main/java/net/swofty/commons/redis/RedisMessageBus.java +++ b/commons/src/main/java/net/swofty/commons/redis/RedisMessageBus.java @@ -1,5 +1,8 @@ package net.swofty.commons.redis; +import lombok.AccessLevel; +import lombok.NoArgsConstructor; + import net.swofty.commons.protocol.RedisProtocol; import net.swofty.redisapi.api.ChannelRegistry; import net.swofty.redisapi.api.RedisAPI; @@ -16,6 +19,7 @@ import java.util.concurrent.TimeUnit; import java.util.function.Function; +@NoArgsConstructor(access = AccessLevel.PRIVATE) public final class RedisMessageBus { private static final Map>> handlers = new ConcurrentHashMap<>(); private static final Map> pendingResponses = new ConcurrentHashMap<>(); @@ -27,9 +31,6 @@ public final class RedisMessageBus { return thread; }); - private RedisMessageBus() { - } - public static void registerHandler(RedisEndpoint localEndpoint, String channel, RedisMessageHandler handler, diff --git a/commons/src/main/java/net/swofty/commons/skywars/SkywarsLevelUtil.java b/commons/src/main/java/net/swofty/commons/skywars/SkywarsLevelUtil.java index 9468f4400..9cdfb954f 100644 --- a/commons/src/main/java/net/swofty/commons/skywars/SkywarsLevelUtil.java +++ b/commons/src/main/java/net/swofty/commons/skywars/SkywarsLevelUtil.java @@ -1,11 +1,13 @@ package net.swofty.commons.skywars; +import lombok.AccessLevel; +import lombok.NoArgsConstructor; + import java.text.DecimalFormat; +@NoArgsConstructor(access = AccessLevel.PRIVATE) public final class SkywarsLevelUtil { - private SkywarsLevelUtil() {} - private static final DecimalFormat FORMAT = new DecimalFormat("#,###.#"); public static String suffix(double value) { diff --git a/dungeons/src/main/java/net/swofty/dungeons/DungeonUtilities.java b/dungeons/src/main/java/net/swofty/dungeons/DungeonUtilities.java index 91536c340..fdda17b26 100644 --- a/dungeons/src/main/java/net/swofty/dungeons/DungeonUtilities.java +++ b/dungeons/src/main/java/net/swofty/dungeons/DungeonUtilities.java @@ -1,12 +1,14 @@ package net.swofty.dungeons; +import lombok.AccessLevel; +import lombok.NoArgsConstructor; + import java.util.*; import java.util.stream.Stream; +@NoArgsConstructor(access = AccessLevel.PRIVATE) public final class DungeonUtilities { - private DungeonUtilities() {} - public static Stream> loopOverDungeonRooms(DungeonsData data) { return Stream.iterate(0, i -> i < data.getWidth() * data.getHeight(), i -> i + 1) .map(i -> Map.entry(i % data.getWidth(), i / data.getHeight())); diff --git a/pvp/src/main/java/net/swofty/pvp/feature/food/ChorusFruitUtil.java b/pvp/src/main/java/net/swofty/pvp/feature/food/ChorusFruitUtil.java index c720f8dbc..3a43b2b3b 100644 --- a/pvp/src/main/java/net/swofty/pvp/feature/food/ChorusFruitUtil.java +++ b/pvp/src/main/java/net/swofty/pvp/feature/food/ChorusFruitUtil.java @@ -1,5 +1,8 @@ package net.swofty.pvp.feature.food; +import lombok.AccessLevel; +import lombok.NoArgsConstructor; + import net.swofty.pvp.utils.ViewUtil; import net.kyori.adventure.sound.Sound; import net.minestom.server.MinecraftServer; @@ -13,10 +16,9 @@ import java.util.concurrent.ThreadLocalRandom; +@NoArgsConstructor(access = AccessLevel.PRIVATE) public final class ChorusFruitUtil { - private ChorusFruitUtil() {} - private static boolean randomTeleport(Entity entity, Pos to) { Instance instance = entity.getInstance(); assert instance != null; diff --git a/pvp/src/main/java/net/swofty/pvp/utils/EffectUtil.java b/pvp/src/main/java/net/swofty/pvp/utils/EffectUtil.java index bd9923440..84e668fb9 100644 --- a/pvp/src/main/java/net/swofty/pvp/utils/EffectUtil.java +++ b/pvp/src/main/java/net/swofty/pvp/utils/EffectUtil.java @@ -1,5 +1,8 @@ package net.swofty.pvp.utils; +import lombok.AccessLevel; +import lombok.NoArgsConstructor; + import net.minestom.server.network.packet.server.play.WorldEventPacket; import net.minestom.server.worldevent.WorldEvent; import org.jetbrains.annotations.NotNull; @@ -8,10 +11,9 @@ import net.minestom.server.instance.Instance; import net.minestom.server.utils.PacketSendingUtils; +@NoArgsConstructor(access = AccessLevel.PRIVATE) public final class EffectUtil { - private EffectUtil() {} - public static void sendNearby(@NotNull Instance instance, @NotNull WorldEvent effect, int x, int y, int z, int data, double distance, boolean global) { WorldEventPacket packet = new WorldEventPacket(effect.id(), new Pos(x, y, z), data, global); diff --git a/pvp/src/main/java/net/swofty/pvp/utils/EntityUtil.java b/pvp/src/main/java/net/swofty/pvp/utils/EntityUtil.java index 775c26e35..52c9c65d9 100644 --- a/pvp/src/main/java/net/swofty/pvp/utils/EntityUtil.java +++ b/pvp/src/main/java/net/swofty/pvp/utils/EntityUtil.java @@ -1,5 +1,8 @@ package net.swofty.pvp.utils; +import lombok.AccessLevel; +import lombok.NoArgsConstructor; + import io.sentry.Sentry; import net.kyori.adventure.text.Component; import net.kyori.adventure.text.event.HoverEvent; @@ -15,10 +18,9 @@ import java.lang.reflect.Field; import java.util.Objects; +@NoArgsConstructor(access = AccessLevel.PRIVATE) public final class EntityUtil { - private EntityUtil() {} - public static void spawnItemAtLocation(Entity entity, ItemStack itemStack, double up) { if (itemStack.isAir()) return; diff --git a/pvp/src/main/java/net/swofty/pvp/utils/FluidUtil.java b/pvp/src/main/java/net/swofty/pvp/utils/FluidUtil.java index 6249cf7b6..a7b26eadb 100644 --- a/pvp/src/main/java/net/swofty/pvp/utils/FluidUtil.java +++ b/pvp/src/main/java/net/swofty/pvp/utils/FluidUtil.java @@ -1,5 +1,8 @@ package net.swofty.pvp.utils; +import lombok.AccessLevel; +import lombok.NoArgsConstructor; + import net.minestom.server.coordinate.Pos; import net.minestom.server.entity.Player; import net.minestom.server.instance.Instance; @@ -8,10 +11,9 @@ import java.util.ArrayList; import java.util.List; +@NoArgsConstructor(access = AccessLevel.PRIVATE) public final class FluidUtil { - private FluidUtil() {} - public static int getLevel(Block block) { String levelStr = block.getProperty("level"); if (levelStr == null) return 8; diff --git a/pvp/src/main/java/net/swofty/pvp/utils/ProjectileUtil.java b/pvp/src/main/java/net/swofty/pvp/utils/ProjectileUtil.java index e4896c023..ac067a96b 100644 --- a/pvp/src/main/java/net/swofty/pvp/utils/ProjectileUtil.java +++ b/pvp/src/main/java/net/swofty/pvp/utils/ProjectileUtil.java @@ -1,5 +1,8 @@ package net.swofty.pvp.utils; +import lombok.AccessLevel; +import lombok.NoArgsConstructor; + import net.minestom.server.collision.BoundingBox; import net.minestom.server.collision.CollisionUtils; import net.minestom.server.collision.PhysicsResult; @@ -11,10 +14,9 @@ import org.jetbrains.annotations.Nullable; // Copied from Minestom, added singleCollision parameter and removed velocity update +@NoArgsConstructor(access = AccessLevel.PRIVATE) public final class ProjectileUtil { - private ProjectileUtil() {} - public static @NotNull PhysicsResult simulateMovement(@NotNull Pos entityPosition, @NotNull Vec entityVelocityPerTick, @NotNull BoundingBox entityBoundingBox, @NotNull WorldBorder worldBorder, @NotNull Block.Getter blockGetter, boolean entityHasPhysics, diff --git a/pvp/src/main/java/net/swofty/pvp/utils/ViewUtil.java b/pvp/src/main/java/net/swofty/pvp/utils/ViewUtil.java index 266ecc989..4635fa86b 100644 --- a/pvp/src/main/java/net/swofty/pvp/utils/ViewUtil.java +++ b/pvp/src/main/java/net/swofty/pvp/utils/ViewUtil.java @@ -1,15 +1,17 @@ package net.swofty.pvp.utils; +import lombok.AccessLevel; +import lombok.NoArgsConstructor; + import net.kyori.adventure.audience.Audience; import net.minestom.server.adventure.audience.PacketGroupingAudience; import net.minestom.server.entity.Entity; import java.util.Collections; +@NoArgsConstructor(access = AccessLevel.PRIVATE) public final class ViewUtil { - private ViewUtil() {} - public static Audience viewersAndSelf(Entity origin) { if (origin.getChunk() == null) return Audience.empty(); return origin.getChunk().getViewersAsAudience(); diff --git a/type.bedwarsgame/src/main/java/net/swofty/type/bedwarsgame/util/ColorUtil.java b/type.bedwarsgame/src/main/java/net/swofty/type/bedwarsgame/util/ColorUtil.java index e17556c78..9d044c604 100644 --- a/type.bedwarsgame/src/main/java/net/swofty/type/bedwarsgame/util/ColorUtil.java +++ b/type.bedwarsgame/src/main/java/net/swofty/type/bedwarsgame/util/ColorUtil.java @@ -1,5 +1,8 @@ package net.swofty.type.bedwarsgame.util; +import lombok.AccessLevel; +import lombok.NoArgsConstructor; + import net.kyori.adventure.text.format.NamedTextColor; import net.kyori.adventure.text.format.TextColor; import org.jetbrains.annotations.Nullable; @@ -7,10 +10,9 @@ import java.awt.*; import java.lang.reflect.Field; +@NoArgsConstructor(access = AccessLevel.PRIVATE) public final class ColorUtil { - private ColorUtil() {} - @Nullable public static Color getColorByName(String name) { diff --git a/type.generic/src/main/java/net/swofty/type/generic/chat/StaffChat.java b/type.generic/src/main/java/net/swofty/type/generic/chat/StaffChat.java index 6d8bd2850..18e7a3ae7 100644 --- a/type.generic/src/main/java/net/swofty/type/generic/chat/StaffChat.java +++ b/type.generic/src/main/java/net/swofty/type/generic/chat/StaffChat.java @@ -1,11 +1,14 @@ package net.swofty.type.generic.chat; +import lombok.AccessLevel; +import lombok.NoArgsConstructor; + import net.swofty.commons.protocol.objects.proxy.to.StaffChatProtocol; import net.swofty.commons.redis.RedisClient; import net.swofty.type.generic.user.HypixelPlayer; +@NoArgsConstructor(access = AccessLevel.PRIVATE) public final class StaffChat { - private StaffChat() {} private static final StaffChatProtocol PROTOCOL = new StaffChatProtocol(); diff --git a/type.generic/src/main/java/net/swofty/type/generic/presence/PresenceHeartbeat.java b/type.generic/src/main/java/net/swofty/type/generic/presence/PresenceHeartbeat.java index 4a0c72be5..9f77b400f 100644 --- a/type.generic/src/main/java/net/swofty/type/generic/presence/PresenceHeartbeat.java +++ b/type.generic/src/main/java/net/swofty/type/generic/presence/PresenceHeartbeat.java @@ -1,5 +1,8 @@ package net.swofty.type.generic.presence; +import lombok.AccessLevel; +import lombok.NoArgsConstructor; + import net.minestom.server.MinecraftServer; import net.minestom.server.timer.TaskSchedule; import net.swofty.commons.ServiceType; @@ -13,8 +16,8 @@ /** * Periodically refreshes player presence to the friend service to avoid stale status. */ +@NoArgsConstructor(access = AccessLevel.PRIVATE) public final class PresenceHeartbeat { - private PresenceHeartbeat() {} public static void start() { MinecraftServer.getSchedulerManager().buildTask(PresenceHeartbeat::pulse) diff --git a/type.generic/src/main/java/net/swofty/type/generic/user/flow/GenericPlayerDataFlow.java b/type.generic/src/main/java/net/swofty/type/generic/user/flow/GenericPlayerDataFlow.java index 46e08510f..137661a40 100644 --- a/type.generic/src/main/java/net/swofty/type/generic/user/flow/GenericPlayerDataFlow.java +++ b/type.generic/src/main/java/net/swofty/type/generic/user/flow/GenericPlayerDataFlow.java @@ -1,5 +1,8 @@ package net.swofty.type.generic.user.flow; +import lombok.AccessLevel; +import lombok.NoArgsConstructor; + import net.swofty.commons.protocol.objects.proxy.to.FinishedWithPlayerProtocol; import net.swofty.commons.redis.RedisClient; import net.swofty.type.generic.HypixelConst; @@ -26,9 +29,8 @@ import java.util.Map; import java.util.UUID; +@NoArgsConstructor(access = AccessLevel.PRIVATE) public final class GenericPlayerDataFlow { - private GenericPlayerDataFlow() { - } public static void load(HypixelPlayer player) { UUID playerUuid = player.getUuid(); diff --git a/type.generic/src/main/java/net/swofty/type/generic/user/flow/PlayerFlow.java b/type.generic/src/main/java/net/swofty/type/generic/user/flow/PlayerFlow.java index c3365acdc..cb19945b5 100644 --- a/type.generic/src/main/java/net/swofty/type/generic/user/flow/PlayerFlow.java +++ b/type.generic/src/main/java/net/swofty/type/generic/user/flow/PlayerFlow.java @@ -1,11 +1,13 @@ package net.swofty.type.generic.user.flow; +import lombok.AccessLevel; +import lombok.NoArgsConstructor; + import net.swofty.type.generic.user.HypixelPlayer; import org.tinylog.Logger; +@NoArgsConstructor(access = AccessLevel.PRIVATE) public final class PlayerFlow { - private PlayerFlow() { - } public static void run(HypixelPlayer player, String stage, Runnable action) { long started = System.currentTimeMillis(); diff --git a/type.generic/src/main/java/net/swofty/type/generic/utility/BlockUtility.java b/type.generic/src/main/java/net/swofty/type/generic/utility/BlockUtility.java index d72de76a9..c9980a1bf 100644 --- a/type.generic/src/main/java/net/swofty/type/generic/utility/BlockUtility.java +++ b/type.generic/src/main/java/net/swofty/type/generic/utility/BlockUtility.java @@ -1,13 +1,15 @@ package net.swofty.type.generic.utility; +import lombok.AccessLevel; +import lombok.NoArgsConstructor; + import net.minestom.server.coordinate.Pos; import net.minestom.server.instance.block.Block; import org.json.JSONObject; +@NoArgsConstructor(access = AccessLevel.PRIVATE) public final class BlockUtility { - private BlockUtility() {} - public static Block applyTexture(Block block, String texture) { JSONObject json = new JSONObject(); diff --git a/type.generic/src/main/java/net/swofty/type/generic/utility/BufferUtility.java b/type.generic/src/main/java/net/swofty/type/generic/utility/BufferUtility.java index cdbff83c0..b7437469f 100644 --- a/type.generic/src/main/java/net/swofty/type/generic/utility/BufferUtility.java +++ b/type.generic/src/main/java/net/swofty/type/generic/utility/BufferUtility.java @@ -1,12 +1,14 @@ package net.swofty.type.generic.utility; +import lombok.AccessLevel; +import lombok.NoArgsConstructor; + import java.nio.ByteBuffer; import java.nio.charset.StandardCharsets; +@NoArgsConstructor(access = AccessLevel.PRIVATE) public final class BufferUtility { - private BufferUtility() {} - public static int getUnsignedShort(ByteBuffer buffer) { byte[] bytes = new byte[2]; buffer.get(bytes); diff --git a/type.generic/src/main/java/net/swofty/type/generic/utility/ChestUtility.java b/type.generic/src/main/java/net/swofty/type/generic/utility/ChestUtility.java index 70e9cb30f..47334d823 100644 --- a/type.generic/src/main/java/net/swofty/type/generic/utility/ChestUtility.java +++ b/type.generic/src/main/java/net/swofty/type/generic/utility/ChestUtility.java @@ -1,14 +1,16 @@ package net.swofty.type.generic.utility; +import lombok.AccessLevel; +import lombok.NoArgsConstructor; + import net.minestom.server.coordinate.Point; import net.minestom.server.coordinate.Pos; import net.minestom.server.instance.Instance; import net.minestom.server.instance.block.Block; +@NoArgsConstructor(access = AccessLevel.PRIVATE) public final class ChestUtility { - private ChestUtility() {} - public static Point[] getDoubleChestPositions(Instance instance, Point point) { Point[] positions = new Point[2]; diff --git a/type.generic/src/main/java/net/swofty/type/generic/utility/MathUtility.java b/type.generic/src/main/java/net/swofty/type/generic/utility/MathUtility.java index 212e48774..76cf9d1f8 100644 --- a/type.generic/src/main/java/net/swofty/type/generic/utility/MathUtility.java +++ b/type.generic/src/main/java/net/swofty/type/generic/utility/MathUtility.java @@ -1,5 +1,8 @@ package net.swofty.type.generic.utility; +import lombok.AccessLevel; +import lombok.NoArgsConstructor; + import net.minestom.server.MinecraftServer; import net.minestom.server.coordinate.Pos; import net.minestom.server.instance.Instance; @@ -12,10 +15,9 @@ import java.util.ArrayList; import java.util.List; +@NoArgsConstructor(access = AccessLevel.PRIVATE) public final class MathUtility { - private MathUtility() {} - public static double normalizeAngle(double angle, double maximum) { return (angle % maximum + maximum) % maximum - (maximum / 2); } diff --git a/type.island/src/main/java/net/swofty/type/island/lifecycle/IslandLifecycleSteps.java b/type.island/src/main/java/net/swofty/type/island/lifecycle/IslandLifecycleSteps.java index 033280014..716dd68eb 100644 --- a/type.island/src/main/java/net/swofty/type/island/lifecycle/IslandLifecycleSteps.java +++ b/type.island/src/main/java/net/swofty/type/island/lifecycle/IslandLifecycleSteps.java @@ -1,13 +1,14 @@ package net.swofty.type.island.lifecycle; +import lombok.AccessLevel; +import lombok.NoArgsConstructor; + import net.swofty.type.skyblockgeneric.user.island.IslandLifecycle; +@NoArgsConstructor(access = AccessLevel.PRIVATE) public final class IslandLifecycleSteps { private static boolean registered = false; - private IslandLifecycleSteps() { - } - public static void register() { if (registered) return; diff --git a/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/entity/mob/mobs/seacreature/SeaCreatureProfiles.java b/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/entity/mob/mobs/seacreature/SeaCreatureProfiles.java index d0c8c2d1d..250a09241 100644 --- a/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/entity/mob/mobs/seacreature/SeaCreatureProfiles.java +++ b/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/entity/mob/mobs/seacreature/SeaCreatureProfiles.java @@ -1,5 +1,8 @@ package net.swofty.type.skyblockgeneric.entity.mob.mobs.seacreature; +import lombok.AccessLevel; +import lombok.NoArgsConstructor; + import java.util.List; import net.minestom.server.entity.EntityType; import net.swofty.type.skyblockgeneric.entity.mob.MobType; @@ -9,6 +12,7 @@ * declarative spec for one creature: stats, AI flavour, fishing rewards. * Adding a new creature is one builder chain, not a new class. */ +@NoArgsConstructor(access = AccessLevel.PRIVATE) public final class SeaCreatureProfiles { /* ---------- water ---------- */ @@ -253,7 +257,4 @@ public final class SeaCreatureProfiles { MAGMA_SLUG, MOOGMA, LAVA_LEECH, PYROCLASTIC_WORM, FIRE_EEL, LAVA_BLAZE, TAURUS, LORD_JAWBUS ); - - private SeaCreatureProfiles() { - } } diff --git a/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/entity/mob/mobs/seacreature/SeaCreatureSpawner.java b/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/entity/mob/mobs/seacreature/SeaCreatureSpawner.java index c5288c554..1d51b0a50 100644 --- a/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/entity/mob/mobs/seacreature/SeaCreatureSpawner.java +++ b/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/entity/mob/mobs/seacreature/SeaCreatureSpawner.java @@ -1,5 +1,8 @@ package net.swofty.type.skyblockgeneric.entity.mob.mobs.seacreature; +import lombok.AccessLevel; +import lombok.NoArgsConstructor; + import java.util.LinkedHashMap; import java.util.Map; import net.kyori.adventure.text.Component; @@ -9,6 +12,7 @@ import org.jetbrains.annotations.Nullable; import org.tinylog.Logger; +@NoArgsConstructor(access = AccessLevel.PRIVATE) public final class SeaCreatureSpawner { private static final Map PROFILES = new LinkedHashMap<>(); @@ -17,9 +21,6 @@ public final class SeaCreatureSpawner { SeaCreatureProfiles.CANONICAL.forEach(SeaCreatureSpawner::register); } - private SeaCreatureSpawner() { - } - public static void register(SeaCreatureProfile profile) { PROFILES.put(profile.id(), profile); } diff --git a/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/fishing/FishingService.java b/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/fishing/FishingService.java index de07d0cf5..0c3b318fc 100644 --- a/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/fishing/FishingService.java +++ b/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/fishing/FishingService.java @@ -1,5 +1,8 @@ package net.swofty.type.skyblockgeneric.fishing; +import lombok.AccessLevel; +import lombok.NoArgsConstructor; + import java.util.Map; import java.util.UUID; import java.util.concurrent.ConcurrentHashMap; @@ -19,12 +22,10 @@ import net.swofty.type.skyblockgeneric.user.SkyBlockPlayer; import org.jetbrains.annotations.Nullable; +@NoArgsConstructor(access = AccessLevel.PRIVATE) public final class FishingService { private static final Map SESSIONS = new ConcurrentHashMap<>(); - private FishingService() { - } - public static FishingSession beginCast(SkyBlockPlayer player, SkyBlockItem rod, FishingMedium medium) { FishingBaitComponent bait = FishingBaitService.getFirstAvailableBait(player, medium); FishingSession session = new FishingSession( diff --git a/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/fishing/bait/FishingBaitService.java b/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/fishing/bait/FishingBaitService.java index 889039d19..d63975ffd 100644 --- a/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/fishing/bait/FishingBaitService.java +++ b/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/fishing/bait/FishingBaitService.java @@ -1,5 +1,8 @@ package net.swofty.type.skyblockgeneric.fishing.bait; +import lombok.AccessLevel; +import lombok.NoArgsConstructor; + import net.minestom.server.item.ItemStack; import net.swofty.commons.skyblock.item.ItemType; import net.swofty.type.skyblockgeneric.fishing.FishingMedium; @@ -9,9 +12,8 @@ import net.swofty.type.skyblockgeneric.user.SkyBlockPlayer; import org.jetbrains.annotations.Nullable; +@NoArgsConstructor(access = AccessLevel.PRIVATE) public final class FishingBaitService { - private FishingBaitService() { - } public static @Nullable FishingBaitComponent getFirstAvailableBait(SkyBlockPlayer player, FishingMedium medium) { for (int slot = 0; slot < 36; slot++) { diff --git a/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/fishing/hotspot/FishingHotspotService.java b/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/fishing/hotspot/FishingHotspotService.java index c92abab42..6a3d57322 100644 --- a/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/fishing/hotspot/FishingHotspotService.java +++ b/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/fishing/hotspot/FishingHotspotService.java @@ -1,5 +1,8 @@ package net.swofty.type.skyblockgeneric.fishing.hotspot; +import lombok.AccessLevel; +import lombok.NoArgsConstructor; + import net.minestom.server.coordinate.Pos; import net.swofty.commons.skyblock.statistics.ItemStatistic; import net.swofty.commons.skyblock.statistics.ItemStatistics; @@ -10,12 +13,10 @@ import net.swofty.type.skyblockgeneric.region.SkyBlockRegion; import net.swofty.type.skyblockgeneric.user.SkyBlockPlayer; +@NoArgsConstructor(access = AccessLevel.PRIVATE) public final class FishingHotspotService { private static final double HOTSPOT_RADIUS_SQUARED = 25.0D; - private FishingHotspotService() { - } - public static boolean isBobberInHotspot(SkyBlockPlayer player, FishingMedium medium, Pos bobberPos) { ItemStatistics buffs = getActiveHotspotBuffs(player, medium, bobberPos); for (ItemStatistic statistic : ItemStatistic.values()) { diff --git a/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/fishing/item/FishingItemSupport.java b/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/fishing/item/FishingItemSupport.java index 87ab6ab64..28e3f30f6 100644 --- a/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/fishing/item/FishingItemSupport.java +++ b/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/fishing/item/FishingItemSupport.java @@ -1,5 +1,8 @@ package net.swofty.type.skyblockgeneric.fishing.item; +import lombok.AccessLevel; +import lombok.NoArgsConstructor; + import java.util.ArrayList; import java.util.Comparator; import java.util.List; @@ -13,9 +16,8 @@ import net.swofty.type.skyblockgeneric.item.components.FishingShipPartComponent; import org.jetbrains.annotations.Nullable; +@NoArgsConstructor(access = AccessLevel.PRIVATE) public final class FishingItemSupport { - private FishingItemSupport() { - } public static @Nullable FishingRodMetadataComponent getRodMetadata(@Nullable String itemId) { return getComponent(itemId, FishingRodMetadataComponent.class); diff --git a/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/fishing/registry/FishingRegistry.java b/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/fishing/registry/FishingRegistry.java index cc317d47a..eb33fca0c 100644 --- a/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/fishing/registry/FishingRegistry.java +++ b/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/fishing/registry/FishingRegistry.java @@ -1,5 +1,8 @@ package net.swofty.type.skyblockgeneric.fishing.registry; +import lombok.AccessLevel; +import lombok.NoArgsConstructor; + import java.io.File; import java.io.IOException; import java.util.ArrayList; @@ -16,6 +19,7 @@ import org.jetbrains.annotations.Nullable; import org.tinylog.Logger; +@NoArgsConstructor(access = AccessLevel.PRIVATE) public final class FishingRegistry { private static final File FISHING_DIR = new File("./configuration/skyblock/fishing"); @@ -24,9 +28,6 @@ public final class FishingRegistry { private static final Map SEA_CREATURES = new LinkedHashMap<>(); private static final Map HOTSPOTS = new LinkedHashMap<>(); - private FishingRegistry() { - } - public static void loadAll() { TABLES.clear(); TROPHY_FISH.clear(); diff --git a/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/fishing/resolver/FishingCatchResolver.java b/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/fishing/resolver/FishingCatchResolver.java index 24818fa40..2db68a4c6 100644 --- a/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/fishing/resolver/FishingCatchResolver.java +++ b/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/fishing/resolver/FishingCatchResolver.java @@ -1,11 +1,13 @@ package net.swofty.type.skyblockgeneric.fishing.resolver; +import lombok.AccessLevel; +import lombok.NoArgsConstructor; + import net.swofty.type.skyblockgeneric.fishing.FishingContext; import net.swofty.type.skyblockgeneric.fishing.catches.CatchPayload; +@NoArgsConstructor(access = AccessLevel.PRIVATE) public final class FishingCatchResolver { - private FishingCatchResolver() { - } public static CatchPayload resolve(FishingContext context) { return FishingLootResolver.resolve(context); diff --git a/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/fishing/resolver/FishingLootResolver.java b/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/fishing/resolver/FishingLootResolver.java index d07b12954..fa53febf5 100644 --- a/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/fishing/resolver/FishingLootResolver.java +++ b/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/fishing/resolver/FishingLootResolver.java @@ -1,5 +1,8 @@ package net.swofty.type.skyblockgeneric.fishing.resolver; +import lombok.AccessLevel; +import lombok.NoArgsConstructor; + import java.util.ArrayList; import java.util.Comparator; import java.util.List; @@ -20,14 +23,12 @@ import net.swofty.type.skyblockgeneric.fishing.tag.FishingTag; import net.swofty.type.skyblockgeneric.item.SkyBlockItem; +@NoArgsConstructor(access = AccessLevel.PRIVATE) public final class FishingLootResolver { private static final CatchPayload DEFAULT_CATCH = new CatchPayload.Item("RAW_FISH", 1, 5.0D, false); - private FishingLootResolver() { - } - public static CatchPayload resolve(FishingContext context) { Optional questCatch = tryResolveQuestCatch(context); if (questCatch.isPresent()) { diff --git a/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/fishing/rod/FishingRodLoreBuilder.java b/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/fishing/rod/FishingRodLoreBuilder.java index 06f6afda6..edd0dfb45 100644 --- a/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/fishing/rod/FishingRodLoreBuilder.java +++ b/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/fishing/rod/FishingRodLoreBuilder.java @@ -1,5 +1,8 @@ package net.swofty.type.skyblockgeneric.fishing.rod; +import lombok.AccessLevel; +import lombok.NoArgsConstructor; + import java.util.ArrayList; import java.util.List; import net.swofty.commons.StringUtility; @@ -12,6 +15,7 @@ import net.swofty.type.skyblockgeneric.user.SkyBlockPlayer; import org.jetbrains.annotations.Nullable; +@NoArgsConstructor(access = AccessLevel.PRIVATE) public final class FishingRodLoreBuilder { private static final List STAT_ORDER = List.of( ItemStatistic.DAMAGE, @@ -23,9 +27,6 @@ public final class FishingRodLoreBuilder { ItemStatistic.TROPHY_FISH_CHANCE ); - private FishingRodLoreBuilder() { - } - public static @Nullable FishingRodLore build(SkyBlockItem item, @Nullable SkyBlockPlayer player) { if (!item.hasComponent(FishingRodMetadataComponent.class)) { return null; diff --git a/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/fishing/rod/FishingRodPartService.java b/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/fishing/rod/FishingRodPartService.java index 42aedb327..b7d64707a 100644 --- a/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/fishing/rod/FishingRodPartService.java +++ b/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/fishing/rod/FishingRodPartService.java @@ -1,14 +1,16 @@ package net.swofty.type.skyblockgeneric.fishing.rod; +import lombok.AccessLevel; +import lombok.NoArgsConstructor; + import net.swofty.commons.skyblock.statistics.ItemStatistics; import net.swofty.type.skyblockgeneric.fishing.item.FishingItemSupport; import net.swofty.type.skyblockgeneric.item.SkyBlockItem; import net.swofty.type.skyblockgeneric.item.components.FishingRodPartComponent; import org.jetbrains.annotations.Nullable; +@NoArgsConstructor(access = AccessLevel.PRIVATE) public final class FishingRodPartService { - private FishingRodPartService() { - } public static @Nullable FishingRodPartComponent getHook(SkyBlockItem rod) { return FishingItemSupport.getRodPart(rod.getAttributeHandler().getFishingHook()); diff --git a/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/fishing/ship/FishingShipService.java b/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/fishing/ship/FishingShipService.java index e497ede0a..653a507a9 100644 --- a/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/fishing/ship/FishingShipService.java +++ b/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/fishing/ship/FishingShipService.java @@ -1,13 +1,15 @@ package net.swofty.type.skyblockgeneric.fishing.ship; +import lombok.AccessLevel; +import lombok.NoArgsConstructor; + import net.swofty.type.skyblockgeneric.data.SkyBlockDataHandler; import net.swofty.type.skyblockgeneric.data.datapoints.DatapointShipState; import net.swofty.type.skyblockgeneric.item.components.FishingShipPartComponent; import net.swofty.type.skyblockgeneric.user.SkyBlockPlayer; +@NoArgsConstructor(access = AccessLevel.PRIVATE) public final class FishingShipService { - private FishingShipService() { - } public static DatapointShipState.ShipState getState(SkyBlockPlayer player) { return player.getSkyblockDataHandler().get(SkyBlockDataHandler.Data.SHIP_STATE, DatapointShipState.class).getValue(); diff --git a/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/fishing/tag/FishingTagRegistry.java b/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/fishing/tag/FishingTagRegistry.java index 946686e5b..8f8761a87 100644 --- a/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/fishing/tag/FishingTagRegistry.java +++ b/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/fishing/tag/FishingTagRegistry.java @@ -1,5 +1,8 @@ package net.swofty.type.skyblockgeneric.fishing.tag; +import lombok.AccessLevel; +import lombok.NoArgsConstructor; + import java.util.LinkedHashMap; import java.util.List; import java.util.Map; @@ -13,6 +16,7 @@ * the resolver uses. Built-in tags are pre-registered; custom tags (events, * project-specific regions) can be added via {@link #register}. */ +@NoArgsConstructor(access = AccessLevel.PRIVATE) public final class FishingTagRegistry { private static final Map TAGS = new LinkedHashMap<>(); @@ -43,9 +47,6 @@ public final class FishingTagRegistry { ); } - private FishingTagRegistry() { - } - public static void register(FishingTag tag) { TAGS.put(tag.id(), tag); } diff --git a/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/gui/inventories/fishing/FishingGuideStackFactory.java b/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/gui/inventories/fishing/FishingGuideStackFactory.java index 2857b9bd1..f3a6070a6 100644 --- a/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/gui/inventories/fishing/FishingGuideStackFactory.java +++ b/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/gui/inventories/fishing/FishingGuideStackFactory.java @@ -1,5 +1,8 @@ package net.swofty.type.skyblockgeneric.gui.inventories.fishing; +import lombok.AccessLevel; +import lombok.NoArgsConstructor; + import net.swofty.commons.StringUtility; import net.swofty.commons.skyblock.item.ItemType; import net.swofty.commons.skyblock.statistics.ItemStatistic; @@ -14,6 +17,7 @@ import java.util.List; import java.util.Map; +@NoArgsConstructor(access = AccessLevel.PRIVATE) public final class FishingGuideStackFactory { private static final List GUIDE_STAT_ORDER = List.of( ItemStatistic.DAMAGE, @@ -27,9 +31,6 @@ public final class FishingGuideStackFactory { ItemStatistic.MAGIC_FIND ); - private FishingGuideStackFactory() { - } - public static net.minestom.server.item.ItemStack.Builder buildBaitStack(SkyBlockItem baitItem) { FishingBaitComponent bait = baitItem.getComponent(FishingBaitComponent.class); List lore = new ArrayList<>(); diff --git a/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/user/flow/SkyBlockPlayerDataFlow.java b/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/user/flow/SkyBlockPlayerDataFlow.java index 57b3d65a8..af7afe754 100644 --- a/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/user/flow/SkyBlockPlayerDataFlow.java +++ b/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/user/flow/SkyBlockPlayerDataFlow.java @@ -1,5 +1,8 @@ package net.swofty.type.skyblockgeneric.user.flow; +import lombok.AccessLevel; +import lombok.NoArgsConstructor; + import net.kyori.adventure.text.Component; import net.kyori.adventure.title.Title; import net.minestom.server.MinecraftServer; @@ -33,9 +36,8 @@ import java.util.Objects; import java.util.UUID; +@NoArgsConstructor(access = AccessLevel.PRIVATE) public final class SkyBlockPlayerDataFlow { - private SkyBlockPlayerDataFlow() { - } public static void load(SkyBlockPlayer player) { UUID playerUuid = player.getUuid(); diff --git a/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/user/island/IslandLifecycle.java b/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/user/island/IslandLifecycle.java index 85984ac2d..fdbe2fc07 100644 --- a/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/user/island/IslandLifecycle.java +++ b/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/user/island/IslandLifecycle.java @@ -1,16 +1,17 @@ package net.swofty.type.skyblockgeneric.user.island; +import lombok.AccessLevel; +import lombok.NoArgsConstructor; + import java.util.Comparator; import java.util.List; import java.util.concurrent.CopyOnWriteArrayList; import org.tinylog.Logger; +@NoArgsConstructor(access = AccessLevel.PRIVATE) public final class IslandLifecycle { private static final List steps = new CopyOnWriteArrayList<>(); - private IslandLifecycle() { - } - public static void register(IslandLifecycleStep step) { steps.add(step); steps.sort(Comparator.comparing(IslandLifecycleStep::phase).thenComparingInt(IslandLifecycleStep::order)); diff --git a/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/user/island/IslandMembers.java b/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/user/island/IslandMembers.java index 4ebffbade..c65feabf1 100644 --- a/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/user/island/IslandMembers.java +++ b/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/user/island/IslandMembers.java @@ -1,5 +1,8 @@ package net.swofty.type.skyblockgeneric.user.island; +import lombok.AccessLevel; +import lombok.NoArgsConstructor; + import net.swofty.type.skyblockgeneric.SkyBlockGenericLoader; import net.swofty.type.skyblockgeneric.data.monogdb.CoopDatabase; import net.swofty.type.skyblockgeneric.user.SkyBlockPlayer; @@ -7,9 +10,8 @@ import java.util.List; import java.util.UUID; +@NoArgsConstructor(access = AccessLevel.PRIVATE) public final class IslandMembers { - private IslandMembers() { - } public static List onlineMembers(UUID islandId, CoopDatabase.Coop coop) { if (coop != null) { diff --git a/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/user/island/IslandWorldStorage.java b/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/user/island/IslandWorldStorage.java index cbeb0d2d9..a92ffbf0d 100644 --- a/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/user/island/IslandWorldStorage.java +++ b/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/user/island/IslandWorldStorage.java @@ -1,5 +1,8 @@ package net.swofty.type.skyblockgeneric.user.island; +import lombok.AccessLevel; +import lombok.NoArgsConstructor; + import net.hollowcube.polar.PolarLoader; import net.hollowcube.polar.PolarReader; import net.hollowcube.polar.PolarWorld; @@ -13,12 +16,10 @@ import java.io.IOException; import java.nio.file.Path; +@NoArgsConstructor(access = AccessLevel.PRIVATE) public final class IslandWorldStorage { private static final Path TEMPLATE_PATH = CustomWorlds.SKYBLOCK_ISLAND_TEMPLATE.getPath(); - private IslandWorldStorage() { - } - public static LoadedIslandWorld load(IslandDatabase database) { if (!database.exists()) { return new LoadedIslandWorld(templateWorld(), HypixelConst.getCurrentIslandVersion(), 0, true); diff --git a/velocity.extension/src/main/java/net/swofty/velocity/gamemanager/BalanceConfigurations.java b/velocity.extension/src/main/java/net/swofty/velocity/gamemanager/BalanceConfigurations.java index b993b1ce1..a7813c198 100644 --- a/velocity.extension/src/main/java/net/swofty/velocity/gamemanager/BalanceConfigurations.java +++ b/velocity.extension/src/main/java/net/swofty/velocity/gamemanager/BalanceConfigurations.java @@ -1,5 +1,8 @@ package net.swofty.velocity.gamemanager; +import lombok.AccessLevel; +import lombok.NoArgsConstructor; + import com.velocitypowered.api.proxy.Player; import net.swofty.commons.ServerType; import net.swofty.velocity.gamemanager.impl.IslandCheck; @@ -11,6 +14,7 @@ import java.util.List; import java.util.Map; +@NoArgsConstructor(access = AccessLevel.PRIVATE) public final class BalanceConfigurations { // Shared singletons — the strategies are stateless, so there's no reason to @@ -47,9 +51,6 @@ public final class BalanceConfigurations { Map.entry(ServerType.RAVENGARD_LOBBY, DEFAULT_CHAIN) ); - private BalanceConfigurations() { - } - public static @Nullable GameManager.GameServer getServerFor(Player player, ServerType type) { final boolean inTestFlow = TestFlowManager.isPlayerInTestFlow(player.getUsername()); if (inTestFlow) { diff --git a/velocity.extension/src/main/java/net/swofty/velocity/presence/PresencePublisher.java b/velocity.extension/src/main/java/net/swofty/velocity/presence/PresencePublisher.java index 79027305f..75fc23bc6 100644 --- a/velocity.extension/src/main/java/net/swofty/velocity/presence/PresencePublisher.java +++ b/velocity.extension/src/main/java/net/swofty/velocity/presence/PresencePublisher.java @@ -1,5 +1,8 @@ package net.swofty.velocity.presence; +import lombok.AccessLevel; +import lombok.NoArgsConstructor; + import com.velocitypowered.api.proxy.Player; import com.velocitypowered.api.proxy.server.RegisteredServer; import net.swofty.commons.presence.PresenceInfo; @@ -8,10 +11,9 @@ import java.util.UUID; +@NoArgsConstructor(access = AccessLevel.PRIVATE) public final class PresencePublisher { - private PresencePublisher() {} - public static void publish(Player player, boolean online, String serverType, UUID serverId) { PresenceInfo info = new PresenceInfo( player.getUniqueId(), diff --git a/velocity.extension/src/main/java/net/swofty/velocity/redis/RedisHandlerRegistry.java b/velocity.extension/src/main/java/net/swofty/velocity/redis/RedisHandlerRegistry.java index 049fd185e..b29787275 100644 --- a/velocity.extension/src/main/java/net/swofty/velocity/redis/RedisHandlerRegistry.java +++ b/velocity.extension/src/main/java/net/swofty/velocity/redis/RedisHandlerRegistry.java @@ -1,5 +1,8 @@ package net.swofty.velocity.redis; +import lombok.AccessLevel; +import lombok.NoArgsConstructor; + import net.swofty.commons.protocol.RedisProtocol; import net.swofty.commons.redis.RedisChannels; import net.swofty.commons.redis.RedisEndpoint; @@ -9,9 +12,8 @@ import java.util.UUID; +@NoArgsConstructor(access = AccessLevel.PRIVATE) public final class RedisHandlerRegistry { - private RedisHandlerRegistry() { - } public static void register(RedisMessageHandler handler) { RedisProtocol protocol = handler.protocol(); From 2f839cccbcf77666f71c4c01317ef2c3721b0989 Mon Sep 17 00:00:00 2001 From: "Jacob Nardella (Swofty)" Date: Fri, 15 May 2026 15:02:53 +1000 Subject: [PATCH 112/113] feat(dungeons): add Catacombs domain foundation --- .../net/swofty/dungeons/DungeonRoomType.java | 2 + .../dungeons/catacombs/CatacombsAPI.java | 44 ++++ .../catacombs/CatacombsDungeonSize.java | 25 ++ .../dungeons/catacombs/CatacombsFloor.java | 67 +++++ .../catacombs/CatacombsFloorDefinition.java | 25 ++ .../dungeons/catacombs/CatacombsMode.java | 6 + .../dungeons/catacombs/CatacombsRegistry.java | 94 +++++++ .../catacombs/blessing/BlessingEffect.java | 11 + .../catacombs/blessing/BlessingSet.java | 33 +++ .../catacombs/blessing/BlessingStat.java | 12 + .../catacombs/blessing/BlessingType.java | 39 +++ .../catacombs/boss/BossPhaseTrigger.java | 10 + .../boss/CatacombsBossEncounter.java | 14 + .../catacombs/boss/CatacombsBossPhase.java | 15 ++ .../catacombs/boss/CatacombsBosses.java | 117 +++++++++ .../classes/DungeonClassAbility.java | 9 + .../classes/DungeonClassAbilityType.java | 8 + .../classes/DungeonClassDefinition.java | 19 ++ .../classes/DungeonClassRegistry.java | 79 ++++++ .../catacombs/classes/DungeonClassType.java | 19 ++ .../generation/CatacombsGenerator.java | 27 ++ .../catacombs/item/DungeonHotbarAction.java | 8 + .../catacombs/item/DungeonHotbarSlot.java | 9 + .../catacombs/item/DungeonOrbProfile.java | 45 ++++ .../catacombs/puzzle/CatacombsPuzzle.java | 42 +++ .../catacombs/run/CatacombsRunConfig.java | 21 ++ .../catacombs/run/CatacombsRunState.java | 244 ++++++++++++++++++ .../catacombs/run/DungeonRoomState.java | 9 + .../catacombs/run/DungeonRunPhase.java | 11 + .../catacombs/run/DungeonRunRules.java | 15 ++ .../catacombs/run/DungeonScoreBreakdown.java | 16 ++ .../catacombs/run/DungeonScoreRank.java | 38 +++ .../secret/CatacombsSecretReward.java | 19 ++ .../secret/CatacombsSecretRewards.java | 37 +++ .../catacombs/secret/CatacombsSecretType.java | 10 + .../catacombs/secret/SecretRewardType.java | 17 ++ 36 files changed, 1216 insertions(+) create mode 100644 dungeons/src/main/java/net/swofty/dungeons/catacombs/CatacombsAPI.java create mode 100644 dungeons/src/main/java/net/swofty/dungeons/catacombs/CatacombsDungeonSize.java create mode 100644 dungeons/src/main/java/net/swofty/dungeons/catacombs/CatacombsFloor.java create mode 100644 dungeons/src/main/java/net/swofty/dungeons/catacombs/CatacombsFloorDefinition.java create mode 100644 dungeons/src/main/java/net/swofty/dungeons/catacombs/CatacombsMode.java create mode 100644 dungeons/src/main/java/net/swofty/dungeons/catacombs/CatacombsRegistry.java create mode 100644 dungeons/src/main/java/net/swofty/dungeons/catacombs/blessing/BlessingEffect.java create mode 100644 dungeons/src/main/java/net/swofty/dungeons/catacombs/blessing/BlessingSet.java create mode 100644 dungeons/src/main/java/net/swofty/dungeons/catacombs/blessing/BlessingStat.java create mode 100644 dungeons/src/main/java/net/swofty/dungeons/catacombs/blessing/BlessingType.java create mode 100644 dungeons/src/main/java/net/swofty/dungeons/catacombs/boss/BossPhaseTrigger.java create mode 100644 dungeons/src/main/java/net/swofty/dungeons/catacombs/boss/CatacombsBossEncounter.java create mode 100644 dungeons/src/main/java/net/swofty/dungeons/catacombs/boss/CatacombsBossPhase.java create mode 100644 dungeons/src/main/java/net/swofty/dungeons/catacombs/boss/CatacombsBosses.java create mode 100644 dungeons/src/main/java/net/swofty/dungeons/catacombs/classes/DungeonClassAbility.java create mode 100644 dungeons/src/main/java/net/swofty/dungeons/catacombs/classes/DungeonClassAbilityType.java create mode 100644 dungeons/src/main/java/net/swofty/dungeons/catacombs/classes/DungeonClassDefinition.java create mode 100644 dungeons/src/main/java/net/swofty/dungeons/catacombs/classes/DungeonClassRegistry.java create mode 100644 dungeons/src/main/java/net/swofty/dungeons/catacombs/classes/DungeonClassType.java create mode 100644 dungeons/src/main/java/net/swofty/dungeons/catacombs/generation/CatacombsGenerator.java create mode 100644 dungeons/src/main/java/net/swofty/dungeons/catacombs/item/DungeonHotbarAction.java create mode 100644 dungeons/src/main/java/net/swofty/dungeons/catacombs/item/DungeonHotbarSlot.java create mode 100644 dungeons/src/main/java/net/swofty/dungeons/catacombs/item/DungeonOrbProfile.java create mode 100644 dungeons/src/main/java/net/swofty/dungeons/catacombs/puzzle/CatacombsPuzzle.java create mode 100644 dungeons/src/main/java/net/swofty/dungeons/catacombs/run/CatacombsRunConfig.java create mode 100644 dungeons/src/main/java/net/swofty/dungeons/catacombs/run/CatacombsRunState.java create mode 100644 dungeons/src/main/java/net/swofty/dungeons/catacombs/run/DungeonRoomState.java create mode 100644 dungeons/src/main/java/net/swofty/dungeons/catacombs/run/DungeonRunPhase.java create mode 100644 dungeons/src/main/java/net/swofty/dungeons/catacombs/run/DungeonRunRules.java create mode 100644 dungeons/src/main/java/net/swofty/dungeons/catacombs/run/DungeonScoreBreakdown.java create mode 100644 dungeons/src/main/java/net/swofty/dungeons/catacombs/run/DungeonScoreRank.java create mode 100644 dungeons/src/main/java/net/swofty/dungeons/catacombs/secret/CatacombsSecretReward.java create mode 100644 dungeons/src/main/java/net/swofty/dungeons/catacombs/secret/CatacombsSecretRewards.java create mode 100644 dungeons/src/main/java/net/swofty/dungeons/catacombs/secret/CatacombsSecretType.java create mode 100644 dungeons/src/main/java/net/swofty/dungeons/catacombs/secret/SecretRewardType.java diff --git a/dungeons/src/main/java/net/swofty/dungeons/DungeonRoomType.java b/dungeons/src/main/java/net/swofty/dungeons/DungeonRoomType.java index 1a0b8afe1..075d4a3b8 100644 --- a/dungeons/src/main/java/net/swofty/dungeons/DungeonRoomType.java +++ b/dungeons/src/main/java/net/swofty/dungeons/DungeonRoomType.java @@ -9,6 +9,8 @@ public enum DungeonRoomType { FAIRY(true, false), PUZZLE(true), MINI_BOSS(true), + TRAP(), + BLOOD(), EXIT(), ; diff --git a/dungeons/src/main/java/net/swofty/dungeons/catacombs/CatacombsAPI.java b/dungeons/src/main/java/net/swofty/dungeons/catacombs/CatacombsAPI.java new file mode 100644 index 000000000..1b06d8579 --- /dev/null +++ b/dungeons/src/main/java/net/swofty/dungeons/catacombs/CatacombsAPI.java @@ -0,0 +1,44 @@ +package net.swofty.dungeons.catacombs; + +import lombok.AccessLevel; +import lombok.NoArgsConstructor; +import net.swofty.dungeons.GeneratorService; +import net.swofty.dungeons.catacombs.classes.DungeonClassDefinition; +import net.swofty.dungeons.catacombs.classes.DungeonClassRegistry; +import net.swofty.dungeons.catacombs.classes.DungeonClassType; +import net.swofty.dungeons.catacombs.generation.CatacombsGenerator; +import net.swofty.dungeons.catacombs.item.DungeonOrbProfile; +import net.swofty.dungeons.catacombs.run.CatacombsRunConfig; +import net.swofty.dungeons.catacombs.run.CatacombsRunState; + +import java.util.Map; + +@NoArgsConstructor(access = AccessLevel.PRIVATE) +public final class CatacombsAPI { + private static final DungeonClassRegistry CLASS_REGISTRY = DungeonClassRegistry.defaults(); + private static final CatacombsRegistry CATACOMBS_REGISTRY = CatacombsRegistry.defaults(); + + public static CatacombsFloorDefinition floor(CatacombsFloor floor, CatacombsMode mode) { + return CATACOMBS_REGISTRY.floor(floor, mode); + } + + public static DungeonClassDefinition dungeonClass(DungeonClassType type) { + return CLASS_REGISTRY.definition(type); + } + + public static Map classes() { + return CLASS_REGISTRY.definitions(); + } + + public static DungeonOrbProfile dungeonOrb(DungeonClassType type) { + return DungeonOrbProfile.forClass(dungeonClass(type)); + } + + public static GeneratorService generator(CatacombsFloorDefinition definition) { + return CatacombsGenerator.generator(definition); + } + + public static CatacombsRunState startRun(CatacombsRunConfig config) { + return CatacombsRunState.start(config); + } +} diff --git a/dungeons/src/main/java/net/swofty/dungeons/catacombs/CatacombsDungeonSize.java b/dungeons/src/main/java/net/swofty/dungeons/catacombs/CatacombsDungeonSize.java new file mode 100644 index 000000000..723e59218 --- /dev/null +++ b/dungeons/src/main/java/net/swofty/dungeons/catacombs/CatacombsDungeonSize.java @@ -0,0 +1,25 @@ +package net.swofty.dungeons.catacombs; + +public enum CatacombsDungeonSize { + TINY(4, 4), + SMALL(5, 5), + MEDIUM_TALL(5, 6), + MEDIUM(6, 6), + LARGE(6, 6); + + private final int width; + private final int height; + + CatacombsDungeonSize(int width, int height) { + this.width = width; + this.height = height; + } + + public int width() { + return width; + } + + public int height() { + return height; + } +} diff --git a/dungeons/src/main/java/net/swofty/dungeons/catacombs/CatacombsFloor.java b/dungeons/src/main/java/net/swofty/dungeons/catacombs/CatacombsFloor.java new file mode 100644 index 000000000..02509a07f --- /dev/null +++ b/dungeons/src/main/java/net/swofty/dungeons/catacombs/CatacombsFloor.java @@ -0,0 +1,67 @@ +package net.swofty.dungeons.catacombs; + +import java.util.Arrays; + +public enum CatacombsFloor { + ENTRANCE("Entrance", "The Watcher", CatacombsDungeonSize.TINY, 0, -1), + FLOOR_ONE("Floor I", "Bonzo", CatacombsDungeonSize.TINY, 1, 24), + FLOOR_TWO("Floor II", "Scarf", CatacombsDungeonSize.SMALL, 3, 26), + FLOOR_THREE("Floor III", "The Professor", CatacombsDungeonSize.SMALL, 5, 28), + FLOOR_FOUR("Floor IV", "Thorn", CatacombsDungeonSize.SMALL, 9, 30), + FLOOR_FIVE("Floor V", "Livid", CatacombsDungeonSize.MEDIUM_TALL, 14, 32), + FLOOR_SIX("Floor VI", "Sadan", CatacombsDungeonSize.MEDIUM, 19, 34), + FLOOR_SEVEN("Floor VII", "The Wither Lords", CatacombsDungeonSize.LARGE, 24, 36); + + private final String displayName; + private final String bossName; + private final CatacombsDungeonSize dungeonSize; + private final int normalRequirement; + private final int masterRequirement; + + CatacombsFloor(String displayName, String bossName, CatacombsDungeonSize dungeonSize, + int normalRequirement, int masterRequirement) { + this.displayName = displayName; + this.bossName = bossName; + this.dungeonSize = dungeonSize; + this.normalRequirement = normalRequirement; + this.masterRequirement = masterRequirement; + } + + public String displayName() { + return displayName; + } + + public String bossName() { + return bossName; + } + + public CatacombsDungeonSize dungeonSize() { + return dungeonSize; + } + + public int normalRequirement() { + return normalRequirement; + } + + public int masterRequirement() { + return masterRequirement; + } + + public boolean supports(CatacombsMode mode) { + return mode == CatacombsMode.NORMAL || masterRequirement >= 0; + } + + public int requirement(CatacombsMode mode) { + if (mode == CatacombsMode.MASTER && masterRequirement < 0) { + throw new IllegalArgumentException(displayName + " does not support Master Mode"); + } + return mode == CatacombsMode.MASTER ? masterRequirement : normalRequirement; + } + + public static CatacombsFloor byNumber(int floor) { + return Arrays.stream(values()) + .filter(value -> value.ordinal() == floor) + .findFirst() + .orElseThrow(() -> new IllegalArgumentException("Unknown Catacombs floor " + floor)); + } +} diff --git a/dungeons/src/main/java/net/swofty/dungeons/catacombs/CatacombsFloorDefinition.java b/dungeons/src/main/java/net/swofty/dungeons/catacombs/CatacombsFloorDefinition.java new file mode 100644 index 000000000..3557bde03 --- /dev/null +++ b/dungeons/src/main/java/net/swofty/dungeons/catacombs/CatacombsFloorDefinition.java @@ -0,0 +1,25 @@ +package net.swofty.dungeons.catacombs; + +import net.swofty.dungeons.catacombs.boss.CatacombsBossEncounter; +import net.swofty.dungeons.catacombs.puzzle.CatacombsPuzzle; +import net.swofty.dungeons.catacombs.run.DungeonRunRules; + +import java.util.Set; + +public record CatacombsFloorDefinition( + CatacombsFloor floor, + CatacombsMode mode, + CatacombsBossEncounter boss, + DungeonRunRules rules, + int puzzleRooms, + int minibossRooms, + int trapRooms, + Set possiblePuzzles +) { + public CatacombsFloorDefinition { + possiblePuzzles = Set.copyOf(possiblePuzzles); + if (!floor.supports(mode)) { + throw new IllegalArgumentException(floor.displayName() + " does not support " + mode); + } + } +} diff --git a/dungeons/src/main/java/net/swofty/dungeons/catacombs/CatacombsMode.java b/dungeons/src/main/java/net/swofty/dungeons/catacombs/CatacombsMode.java new file mode 100644 index 000000000..0f46b8ed3 --- /dev/null +++ b/dungeons/src/main/java/net/swofty/dungeons/catacombs/CatacombsMode.java @@ -0,0 +1,6 @@ +package net.swofty.dungeons.catacombs; + +public enum CatacombsMode { + NORMAL, + MASTER +} diff --git a/dungeons/src/main/java/net/swofty/dungeons/catacombs/CatacombsRegistry.java b/dungeons/src/main/java/net/swofty/dungeons/catacombs/CatacombsRegistry.java new file mode 100644 index 000000000..6ae8a530c --- /dev/null +++ b/dungeons/src/main/java/net/swofty/dungeons/catacombs/CatacombsRegistry.java @@ -0,0 +1,94 @@ +package net.swofty.dungeons.catacombs; + +import net.swofty.dungeons.catacombs.boss.CatacombsBosses; +import net.swofty.dungeons.catacombs.puzzle.CatacombsPuzzle; +import net.swofty.dungeons.catacombs.run.DungeonRunRules; + +import java.util.Arrays; +import java.util.EnumMap; +import java.util.Map; +import java.util.Set; +import java.util.stream.Collectors; + +public record CatacombsRegistry(Map> floors) { + public CatacombsRegistry { + floors = Map.copyOf(floors); + } + + public CatacombsFloorDefinition floor(CatacombsFloor floor, CatacombsMode mode) { + Map byFloor = floors.get(mode); + if (byFloor == null || !byFloor.containsKey(floor)) { + throw new IllegalArgumentException("No Catacombs definition for " + mode + " " + floor.displayName()); + } + return byFloor.get(floor); + } + + public static CatacombsRegistry defaults() { + Map> floors = new EnumMap<>(CatacombsMode.class); + floors.put(CatacombsMode.NORMAL, normalFloors()); + floors.put(CatacombsMode.MASTER, masterFloors()); + return new CatacombsRegistry(floors); + } + + private static Map normalFloors() { + Map floors = new EnumMap<>(CatacombsFloor.class); + floors.put(CatacombsFloor.ENTRANCE, definition(CatacombsFloor.ENTRANCE, CatacombsMode.NORMAL, + CatacombsBosses.watcher(), 1, 0, 0, 600, true)); + floors.put(CatacombsFloor.FLOOR_ONE, definition(CatacombsFloor.FLOOR_ONE, CatacombsMode.NORMAL, + CatacombsBosses.bonzo(), 2, 1, 0, 600, true)); + floors.put(CatacombsFloor.FLOOR_TWO, definition(CatacombsFloor.FLOOR_TWO, CatacombsMode.NORMAL, + CatacombsBosses.scarf(), 2, 1, 0, 600, true)); + floors.put(CatacombsFloor.FLOOR_THREE, definition(CatacombsFloor.FLOOR_THREE, CatacombsMode.NORMAL, + CatacombsBosses.professor(), 2, 1, 1, 600, false)); + floors.put(CatacombsFloor.FLOOR_FOUR, definition(CatacombsFloor.FLOOR_FOUR, CatacombsMode.NORMAL, + CatacombsBosses.thorn(), 2, 1, 1, 720, false)); + floors.put(CatacombsFloor.FLOOR_FIVE, definition(CatacombsFloor.FLOOR_FIVE, CatacombsMode.NORMAL, + CatacombsBosses.livid(), 3, 2, 1, 720, false)); + floors.put(CatacombsFloor.FLOOR_SIX, definition(CatacombsFloor.FLOOR_SIX, CatacombsMode.NORMAL, + CatacombsBosses.sadan(), 3, 2, 1, 840, false)); + floors.put(CatacombsFloor.FLOOR_SEVEN, definition(CatacombsFloor.FLOOR_SEVEN, CatacombsMode.NORMAL, + CatacombsBosses.witherLords(false), 3, 2, 1, 840, false)); + return floors; + } + + private static Map masterFloors() { + Map floors = new EnumMap<>(CatacombsFloor.class); + floors.put(CatacombsFloor.FLOOR_ONE, master(CatacombsFloor.FLOOR_ONE, CatacombsBosses.bonzo(), 2, 1, 0, 540)); + floors.put(CatacombsFloor.FLOOR_TWO, master(CatacombsFloor.FLOOR_TWO, CatacombsBosses.scarf(), 2, 1, 0, 540)); + floors.put(CatacombsFloor.FLOOR_THREE, master(CatacombsFloor.FLOOR_THREE, CatacombsBosses.professor(), 2, 1, 1, 540)); + floors.put(CatacombsFloor.FLOOR_FOUR, master(CatacombsFloor.FLOOR_FOUR, CatacombsBosses.thorn(), 2, 1, 1, 660)); + floors.put(CatacombsFloor.FLOOR_FIVE, master(CatacombsFloor.FLOOR_FIVE, CatacombsBosses.livid(), 3, 2, 1, 660)); + floors.put(CatacombsFloor.FLOOR_SIX, master(CatacombsFloor.FLOOR_SIX, CatacombsBosses.sadan(), 3, 2, 1, 780)); + floors.put(CatacombsFloor.FLOOR_SEVEN, master(CatacombsFloor.FLOOR_SEVEN, CatacombsBosses.witherLords(true), 3, 2, 1, 780)); + return floors; + } + + private static CatacombsFloorDefinition master(CatacombsFloor floor, + net.swofty.dungeons.catacombs.boss.CatacombsBossEncounter boss, + int puzzleRooms, int minibossRooms, int trapRooms, + int speedScoreSeconds) { + return definition(floor, CatacombsMode.MASTER, boss, puzzleRooms, minibossRooms, trapRooms, + speedScoreSeconds, false); + } + + private static CatacombsFloorDefinition definition(CatacombsFloor floor, CatacombsMode mode, + net.swofty.dungeons.catacombs.boss.CatacombsBossEncounter boss, + int puzzleRooms, int minibossRooms, int trapRooms, + int speedScoreSeconds, boolean automaticGhostRevive) { + return new CatacombsFloorDefinition( + floor, + mode, + boss, + new DungeonRunRules(speedScoreSeconds, 4200, 2, 5, 17, automaticGhostRevive, trapRooms > 0), + puzzleRooms, + minibossRooms, + trapRooms, + puzzlesFor(floor)); + } + + private static Set puzzlesFor(CatacombsFloor floor) { + return Arrays.stream(CatacombsPuzzle.values()) + .filter(puzzle -> puzzle.canGenerate(floor)) + .collect(Collectors.toUnmodifiableSet()); + } +} diff --git a/dungeons/src/main/java/net/swofty/dungeons/catacombs/blessing/BlessingEffect.java b/dungeons/src/main/java/net/swofty/dungeons/catacombs/blessing/BlessingEffect.java new file mode 100644 index 000000000..4f1712b12 --- /dev/null +++ b/dungeons/src/main/java/net/swofty/dungeons/catacombs/blessing/BlessingEffect.java @@ -0,0 +1,11 @@ +package net.swofty.dungeons.catacombs.blessing; + +public record BlessingEffect(BlessingStat stat, double percentPerLevel, double flatPerLevel) { + public double percent(int level) { + return percentPerLevel * level; + } + + public double flat(int level) { + return flatPerLevel * level; + } +} diff --git a/dungeons/src/main/java/net/swofty/dungeons/catacombs/blessing/BlessingSet.java b/dungeons/src/main/java/net/swofty/dungeons/catacombs/blessing/BlessingSet.java new file mode 100644 index 000000000..884803728 --- /dev/null +++ b/dungeons/src/main/java/net/swofty/dungeons/catacombs/blessing/BlessingSet.java @@ -0,0 +1,33 @@ +package net.swofty.dungeons.catacombs.blessing; + +import java.util.EnumMap; +import java.util.Map; + +public final class BlessingSet { + private final Map levels = new EnumMap<>(BlessingType.class); + + public void add(BlessingType type, int level) { + levels.merge(type, level, Integer::sum); + } + + public int level(BlessingType type) { + return levels.getOrDefault(type, 0); + } + + public Map levels() { + return Map.copyOf(levels); + } + + public Map appliedStats(double effectivenessMultiplier) { + Map applied = new EnumMap<>(BlessingStat.class); + levels.forEach((type, level) -> type.effects().forEach(effect -> { + AppliedBlessingStat current = applied.getOrDefault(effect.stat(), new AppliedBlessingStat(0, 0)); + applied.put(effect.stat(), new AppliedBlessingStat( + current.percent() + effect.percent(level) * effectivenessMultiplier, + current.flat() + effect.flat(level) * effectivenessMultiplier)); + })); + return Map.copyOf(applied); + } + + public record AppliedBlessingStat(double percent, double flat) {} +} diff --git a/dungeons/src/main/java/net/swofty/dungeons/catacombs/blessing/BlessingStat.java b/dungeons/src/main/java/net/swofty/dungeons/catacombs/blessing/BlessingStat.java new file mode 100644 index 000000000..d5d7be259 --- /dev/null +++ b/dungeons/src/main/java/net/swofty/dungeons/catacombs/blessing/BlessingStat.java @@ -0,0 +1,12 @@ +package net.swofty.dungeons.catacombs.blessing; + +public enum BlessingStat { + HEALTH, + HEALTH_REGEN, + STRENGTH, + CRIT_DAMAGE, + DEFENSE, + DAMAGE, + INTELLIGENCE, + SPEED +} diff --git a/dungeons/src/main/java/net/swofty/dungeons/catacombs/blessing/BlessingType.java b/dungeons/src/main/java/net/swofty/dungeons/catacombs/blessing/BlessingType.java new file mode 100644 index 000000000..709423d1d --- /dev/null +++ b/dungeons/src/main/java/net/swofty/dungeons/catacombs/blessing/BlessingType.java @@ -0,0 +1,39 @@ +package net.swofty.dungeons.catacombs.blessing; + +import java.util.List; + +public enum BlessingType { + LIFE("Blessing of Life", List.of( + new BlessingEffect(BlessingStat.HEALTH, 3, 0), + new BlessingEffect(BlessingStat.HEALTH_REGEN, 3, 0))), + POWER("Blessing of Power", List.of( + new BlessingEffect(BlessingStat.STRENGTH, 2, 4), + new BlessingEffect(BlessingStat.CRIT_DAMAGE, 2, 4))), + STONE("Blessing of Stone", List.of( + new BlessingEffect(BlessingStat.DEFENSE, 2, 4), + new BlessingEffect(BlessingStat.DAMAGE, 0, 6))), + WISDOM("Blessing of Wisdom", List.of( + new BlessingEffect(BlessingStat.INTELLIGENCE, 2, 4), + new BlessingEffect(BlessingStat.SPEED, 0, 0))), + TIME("Blessing of Time", List.of( + new BlessingEffect(BlessingStat.HEALTH, 2, 4), + new BlessingEffect(BlessingStat.INTELLIGENCE, 2, 4), + new BlessingEffect(BlessingStat.STRENGTH, 2, 4), + new BlessingEffect(BlessingStat.DEFENSE, 2, 4))); + + private final String displayName; + private final List effects; + + BlessingType(String displayName, List effects) { + this.displayName = displayName; + this.effects = effects; + } + + public String displayName() { + return displayName; + } + + public List effects() { + return effects; + } +} diff --git a/dungeons/src/main/java/net/swofty/dungeons/catacombs/boss/BossPhaseTrigger.java b/dungeons/src/main/java/net/swofty/dungeons/catacombs/boss/BossPhaseTrigger.java new file mode 100644 index 000000000..0ac144b20 --- /dev/null +++ b/dungeons/src/main/java/net/swofty/dungeons/catacombs/boss/BossPhaseTrigger.java @@ -0,0 +1,10 @@ +package net.swofty.dungeons.catacombs.boss; + +public enum BossPhaseTrigger { + ENTER_BOSS_ROOM, + BOSS_HEALTH_THRESHOLD, + ADDS_DEFEATED, + PLAYER_OBJECTIVE, + TIMER, + PHASE_COMPLETE +} diff --git a/dungeons/src/main/java/net/swofty/dungeons/catacombs/boss/CatacombsBossEncounter.java b/dungeons/src/main/java/net/swofty/dungeons/catacombs/boss/CatacombsBossEncounter.java new file mode 100644 index 000000000..a8e978d7b --- /dev/null +++ b/dungeons/src/main/java/net/swofty/dungeons/catacombs/boss/CatacombsBossEncounter.java @@ -0,0 +1,14 @@ +package net.swofty.dungeons.catacombs.boss; + +import java.util.List; + +public record CatacombsBossEncounter( + String id, + String displayName, + String status, + List phases +) { + public CatacombsBossEncounter { + phases = List.copyOf(phases); + } +} diff --git a/dungeons/src/main/java/net/swofty/dungeons/catacombs/boss/CatacombsBossPhase.java b/dungeons/src/main/java/net/swofty/dungeons/catacombs/boss/CatacombsBossPhase.java new file mode 100644 index 000000000..5df2ae808 --- /dev/null +++ b/dungeons/src/main/java/net/swofty/dungeons/catacombs/boss/CatacombsBossPhase.java @@ -0,0 +1,15 @@ +package net.swofty.dungeons.catacombs.boss; + +import java.util.Set; + +public record CatacombsBossPhase( + String id, + String displayName, + BossPhaseTrigger trigger, + int triggerValue, + Set mechanics +) { + public CatacombsBossPhase { + mechanics = Set.copyOf(mechanics); + } +} diff --git a/dungeons/src/main/java/net/swofty/dungeons/catacombs/boss/CatacombsBosses.java b/dungeons/src/main/java/net/swofty/dungeons/catacombs/boss/CatacombsBosses.java new file mode 100644 index 000000000..2a27f23e6 --- /dev/null +++ b/dungeons/src/main/java/net/swofty/dungeons/catacombs/boss/CatacombsBosses.java @@ -0,0 +1,117 @@ +package net.swofty.dungeons.catacombs.boss; + +import lombok.AccessLevel; +import lombok.NoArgsConstructor; + +import java.util.List; +import java.util.Set; + +@NoArgsConstructor(access = AccessLevel.PRIVATE) +public final class CatacombsBosses { + public static CatacombsBossEncounter watcher() { + return encounter("WATCHER", "The Watcher", "Stalker", + phase("WATCHER_SUMMONS", "Undead Collection", BossPhaseTrigger.ENTER_BOSS_ROOM, 0, + "Summons waves of undead enemies", + "Opens the blood portal once every summoned enemy is defeated")); + } + + public static CatacombsBossEncounter bonzo() { + return encounter("BONZO", "Bonzo", "New Necromancer", + phase("BONZO_SHOWTIME", "Showtime", BossPhaseTrigger.ENTER_BOSS_ROOM, 0, + "Throws balloons", + "Summons undead performers"), + phase("BONZO_UNDEAD", "Undead Finale", BossPhaseTrigger.BOSS_HEALTH_THRESHOLD, 0, + "Revives after the first defeat", + "Uses stronger balloon barrages")); + } + + public static CatacombsBossEncounter scarf() { + return encounter("SCARF", "Scarf", "Apprentice Necromancer", + phase("SCARF_STUDENTS", "Undead Students", BossPhaseTrigger.ENTER_BOSS_ROOM, 0, + "Warrior, Priest, Mage, Archer, and Scarf must be fought as a group"), + phase("SCARF_REVIVE", "Second Lesson", BossPhaseTrigger.ADDS_DEFEATED, 0, + "Revives defeated students", + "Ends when Scarf is defeated after the revive")); + } + + public static CatacombsBossEncounter professor() { + return encounter("PROFESSOR", "The Professor", "Professor", + phase("PROFESSOR_GUARDIANS", "Guardian Experiment", BossPhaseTrigger.ENTER_BOSS_ROOM, 0, + "Four guardians protect the professor", + "Guardians must be defeated close together"), + phase("PROFESSOR_GIANT", "Frenzy", BossPhaseTrigger.ADDS_DEFEATED, 0, + "Professor enters a giant guardian body", + "Arena floods during the final phase")); + } + + public static CatacombsBossEncounter thorn() { + return encounter("THORN", "Thorn", "Shaman Necromancer", + phase("THORN_SPIRITS", "Spirit Animals", BossPhaseTrigger.ENTER_BOSS_ROOM, 0, + "Animal waves fill the arena", + "Spirit Bears drop Spirit Bows"), + phase("THORN_SHOT", "Spirit Shot", BossPhaseTrigger.PLAYER_OBJECTIVE, 4, + "Players damage Thorn by shooting him with Spirit Bow charges")); + } + + public static CatacombsBossEncounter livid() { + return encounter("LIVID", "Livid", "Master Necromancer", + phase("LIVID_CLONES", "Clone Ambush", BossPhaseTrigger.ENTER_BOSS_ROOM, 0, + "Multiple Livid clones spawn", + "Only the correct Livid must be killed to finish the fight")); + } + + public static CatacombsBossEncounter sadan() { + return encounter("SADAN", "Sadan", "Necromancer Lord", + phase("SADAN_TERRACOTTAS", "Terracotta Army", BossPhaseTrigger.ENTER_BOSS_ROOM, 0, + "Survive the terracotta army"), + phase("SADAN_GIANTS", "Giant Reanimation", BossPhaseTrigger.TIMER, 0, + "Ancient Giants awaken one by one"), + phase("SADAN_FINAL", "Necromancer Lord", BossPhaseTrigger.ADDS_DEFEATED, 0, + "Sadan enters the arena after the giants fall")); + } + + public static CatacombsBossEncounter witherLords(boolean masterMode) { + CatacombsBossEncounter encounter = encounter("WITHER_LORDS", "The Wither Lords", "The Wither Lords", + phase("MAXOR", "Maxor", BossPhaseTrigger.ENTER_BOSS_ROOM, 0, + "Complete crystal objectives", + "Damage Maxor after he is stunned"), + phase("STORM", "Storm", BossPhaseTrigger.PHASE_COMPLETE, 0, + "Shelter from lightning", + "Use crusher objectives to expose Storm"), + phase("GOLDOR", "Goldor", BossPhaseTrigger.PHASE_COMPLETE, 0, + "Advance through terminal sections", + "Complete devices while Goldor approaches"), + phase("NECRON", "Necron", BossPhaseTrigger.PHASE_COMPLETE, 0, + "Final arena against Necron", + "Defeat Necron to complete normal Floor VII")); + + if (!masterMode) { + return encounter; + } + + return encounter("MASTER_WITHER_LORDS", "The Wither Lords", "The Wither Lords", + phase("MAXOR", "Maxor", BossPhaseTrigger.ENTER_BOSS_ROOM, 0, + "Complete crystal objectives", + "Damage Maxor after he is stunned"), + phase("STORM", "Storm", BossPhaseTrigger.PHASE_COMPLETE, 0, + "Shelter from lightning", + "Use crusher objectives to expose Storm"), + phase("GOLDOR", "Goldor", BossPhaseTrigger.PHASE_COMPLETE, 0, + "Advance through terminal sections", + "Complete devices while Goldor approaches"), + phase("NECRON", "Necron", BossPhaseTrigger.PHASE_COMPLETE, 0, + "Final arena against Necron"), + phase("WITHER_KING", "Wither King", BossPhaseTrigger.PHASE_COMPLETE, 0, + "Master Mode adds the Wither King after Necron")); + } + + private static CatacombsBossEncounter encounter(String id, String displayName, String status, + CatacombsBossPhase... phases) { + return new CatacombsBossEncounter(id, displayName, status, List.of(phases)); + } + + private static CatacombsBossPhase phase(String id, String displayName, BossPhaseTrigger trigger, + int triggerValue, String... mechanics) { + return new CatacombsBossPhase(id, displayName, trigger, triggerValue, Set.of(mechanics)); + } +} diff --git a/dungeons/src/main/java/net/swofty/dungeons/catacombs/classes/DungeonClassAbility.java b/dungeons/src/main/java/net/swofty/dungeons/catacombs/classes/DungeonClassAbility.java new file mode 100644 index 000000000..b496d4173 --- /dev/null +++ b/dungeons/src/main/java/net/swofty/dungeons/catacombs/classes/DungeonClassAbility.java @@ -0,0 +1,9 @@ +package net.swofty.dungeons.catacombs.classes; + +public record DungeonClassAbility( + String id, + String displayName, + DungeonClassAbilityType type, + int cooldownSeconds, + String description +) {} diff --git a/dungeons/src/main/java/net/swofty/dungeons/catacombs/classes/DungeonClassAbilityType.java b/dungeons/src/main/java/net/swofty/dungeons/catacombs/classes/DungeonClassAbilityType.java new file mode 100644 index 000000000..2289b0c5d --- /dev/null +++ b/dungeons/src/main/java/net/swofty/dungeons/catacombs/classes/DungeonClassAbilityType.java @@ -0,0 +1,8 @@ +package net.swofty.dungeons.catacombs.classes; + +public enum DungeonClassAbilityType { + PASSIVE, + ORB, + ULTIMATE, + GHOST +} diff --git a/dungeons/src/main/java/net/swofty/dungeons/catacombs/classes/DungeonClassDefinition.java b/dungeons/src/main/java/net/swofty/dungeons/catacombs/classes/DungeonClassDefinition.java new file mode 100644 index 000000000..b377158c7 --- /dev/null +++ b/dungeons/src/main/java/net/swofty/dungeons/catacombs/classes/DungeonClassDefinition.java @@ -0,0 +1,19 @@ +package net.swofty.dungeons.catacombs.classes; + +import java.util.List; + +public record DungeonClassDefinition( + DungeonClassType type, + String role, + List abilities +) { + public DungeonClassDefinition { + abilities = List.copyOf(abilities); + } + + public List abilities(DungeonClassAbilityType type) { + return abilities.stream() + .filter(ability -> ability.type() == type) + .toList(); + } +} diff --git a/dungeons/src/main/java/net/swofty/dungeons/catacombs/classes/DungeonClassRegistry.java b/dungeons/src/main/java/net/swofty/dungeons/catacombs/classes/DungeonClassRegistry.java new file mode 100644 index 000000000..a57c2f94b --- /dev/null +++ b/dungeons/src/main/java/net/swofty/dungeons/catacombs/classes/DungeonClassRegistry.java @@ -0,0 +1,79 @@ +package net.swofty.dungeons.catacombs.classes; + +import java.util.EnumMap; +import java.util.List; +import java.util.Map; + +public record DungeonClassRegistry(Map definitions) { + public DungeonClassRegistry { + definitions = Map.copyOf(definitions); + } + + public DungeonClassDefinition definition(DungeonClassType type) { + DungeonClassDefinition definition = definitions.get(type); + if (definition == null) { + throw new IllegalArgumentException("No dungeon class registered for " + type); + } + return definition; + } + + public static DungeonClassRegistry defaults() { + Map definitions = new EnumMap<>(DungeonClassType.class); + definitions.put(DungeonClassType.HEALER, new DungeonClassDefinition(DungeonClassType.HEALER, + "Healing and revive support", + abilities( + passive("HEALING_AURA", "Healing Aura", "Periodically heals nearby teammates"), + ultimate("WISH", "Wish", 120, "Heals all teammates and grants absorption"), + orb("HEALING_CIRCLE", "Healing Circle", 2, "Creates a healing circle at the caster"), + ghost("REVIVE", "Revive", 60, "Revives a dead teammate")))); + definitions.put(DungeonClassType.MAGE, new DungeonClassDefinition(DungeonClassType.MAGE, + "Magic damage", + abilities( + passive("MAGE_STAFF", "Mage Staff", "Left click beam attack while holding a dungeon item"), + ultimate("THUNDERSTORM", "Thunderstorm", 120, "Strikes nearby enemies with lightning"), + orb("GUIDED_SHEEP", "Guided Sheep", 30, "Launches an explosive sheep"), + ghost("WALL", "Wall", 60, "Creates a temporary wall")))); + definitions.put(DungeonClassType.BERSERK, new DungeonClassDefinition(DungeonClassType.BERSERK, + "Melee damage", + abilities( + passive("BLOODLUST", "Bloodlust", "Kills increase outgoing melee damage briefly"), + ultimate("RAGNAROK", "Ragnarok", 120, "Summons allied zombies"), + orb("THROWING_AXE", "Throwing Axe", 10, "Throws an axe at a target"), + ghost("VENGEFUL_SPIRIT", "Vengeful Spirit", 30, "Damages enemies while dead")))); + definitions.put(DungeonClassType.ARCHER, new DungeonClassDefinition(DungeonClassType.ARCHER, + "Ranged damage", + abilities( + passive("DOUBLE_SHOT", "Double Shot", "Arrows have a chance to fire twice"), + orb("EXPLOSIVE_SHOT", "Explosive Shot", 40, "Fires an explosive arrow"), + ultimate("RAPID_FIRE", "Rapid Fire", 120, "Rapidly fires arrows in the targeted direction"), + ghost("STUN_BOW", "Stun Bow", 15, "Stuns a target while dead")))); + definitions.put(DungeonClassType.TANK, new DungeonClassDefinition(DungeonClassType.TANK, + "Damage mitigation and enemy control", + abilities( + passive("DIVERSION", "Diversion", "Redirects a portion of teammate damage to the Tank"), + orb("SEISMIC_WAVE", "Seismic Wave", 15, "Sends a damaging wave forward"), + ultimate("CASTLE_OF_STONE", "Castle of Stone", 120, "Greatly reduces incoming damage"), + ghost("ABSORPTION", "Absorption", 60, "Grants teammates absorption while dead")))); + return new DungeonClassRegistry(definitions); + } + + private static DungeonClassAbility passive(String id, String displayName, String description) { + return new DungeonClassAbility(id, displayName, DungeonClassAbilityType.PASSIVE, 0, description); + } + + private static DungeonClassAbility orb(String id, String displayName, int cooldownSeconds, String description) { + return new DungeonClassAbility(id, displayName, DungeonClassAbilityType.ORB, cooldownSeconds, description); + } + + private static DungeonClassAbility ultimate(String id, String displayName, int cooldownSeconds, String description) { + return new DungeonClassAbility(id, displayName, DungeonClassAbilityType.ULTIMATE, cooldownSeconds, description); + } + + private static DungeonClassAbility ghost(String id, String displayName, int cooldownSeconds, String description) { + return new DungeonClassAbility(id, displayName, DungeonClassAbilityType.GHOST, cooldownSeconds, description); + } + + private static List abilities(DungeonClassAbility... abilities) { + return List.of(abilities); + } +} diff --git a/dungeons/src/main/java/net/swofty/dungeons/catacombs/classes/DungeonClassType.java b/dungeons/src/main/java/net/swofty/dungeons/catacombs/classes/DungeonClassType.java new file mode 100644 index 000000000..69b2fcee1 --- /dev/null +++ b/dungeons/src/main/java/net/swofty/dungeons/catacombs/classes/DungeonClassType.java @@ -0,0 +1,19 @@ +package net.swofty.dungeons.catacombs.classes; + +public enum DungeonClassType { + HEALER("Healer"), + MAGE("Mage"), + BERSERK("Berserk"), + ARCHER("Archer"), + TANK("Tank"); + + private final String displayName; + + DungeonClassType(String displayName) { + this.displayName = displayName; + } + + public String displayName() { + return displayName; + } +} diff --git a/dungeons/src/main/java/net/swofty/dungeons/catacombs/generation/CatacombsGenerator.java b/dungeons/src/main/java/net/swofty/dungeons/catacombs/generation/CatacombsGenerator.java new file mode 100644 index 000000000..0300713ec --- /dev/null +++ b/dungeons/src/main/java/net/swofty/dungeons/catacombs/generation/CatacombsGenerator.java @@ -0,0 +1,27 @@ +package net.swofty.dungeons.catacombs.generation; + +import lombok.AccessLevel; +import lombok.NoArgsConstructor; +import net.swofty.dungeons.DungeonRoomType; +import net.swofty.dungeons.DungeonsAPI; +import net.swofty.dungeons.DungeonsData; +import net.swofty.dungeons.GeneratorService; +import net.swofty.dungeons.catacombs.CatacombsFloorDefinition; + +@NoArgsConstructor(access = AccessLevel.PRIVATE) +public final class CatacombsGenerator { + public static GeneratorService generator(CatacombsFloorDefinition definition) { + DungeonsData data = new DungeonsData( + definition.floor().dungeonSize().width(), + definition.floor().dungeonSize().height()) + .with(DungeonRoomType.FAIRY, new DungeonsData.RoomData(1, 1)) + .with(DungeonRoomType.PUZZLE, new DungeonsData.RoomData(definition.puzzleRooms(), definition.puzzleRooms())) + .with(DungeonRoomType.MINI_BOSS, new DungeonsData.RoomData(definition.minibossRooms(), definition.minibossRooms())); + + if (definition.trapRooms() > 0) { + data.with(DungeonRoomType.TRAP, new DungeonsData.RoomData(definition.trapRooms(), definition.trapRooms())); + } + + return DungeonsAPI.getGeneratorService(data); + } +} diff --git a/dungeons/src/main/java/net/swofty/dungeons/catacombs/item/DungeonHotbarAction.java b/dungeons/src/main/java/net/swofty/dungeons/catacombs/item/DungeonHotbarAction.java new file mode 100644 index 000000000..623273e43 --- /dev/null +++ b/dungeons/src/main/java/net/swofty/dungeons/catacombs/item/DungeonHotbarAction.java @@ -0,0 +1,8 @@ +package net.swofty.dungeons.catacombs.item; + +public enum DungeonHotbarAction { + DROP_KEY_ULTIMATE, + DROP_STACK_KEY_ABILITY, + RIGHT_CLICK_ORB, + GHOST_HOTBAR_SLOT +} diff --git a/dungeons/src/main/java/net/swofty/dungeons/catacombs/item/DungeonHotbarSlot.java b/dungeons/src/main/java/net/swofty/dungeons/catacombs/item/DungeonHotbarSlot.java new file mode 100644 index 000000000..cadb77576 --- /dev/null +++ b/dungeons/src/main/java/net/swofty/dungeons/catacombs/item/DungeonHotbarSlot.java @@ -0,0 +1,9 @@ +package net.swofty.dungeons.catacombs.item; + +import net.swofty.dungeons.catacombs.classes.DungeonClassAbility; + +public record DungeonHotbarSlot( + int slot, + DungeonHotbarAction action, + DungeonClassAbility ability +) {} diff --git a/dungeons/src/main/java/net/swofty/dungeons/catacombs/item/DungeonOrbProfile.java b/dungeons/src/main/java/net/swofty/dungeons/catacombs/item/DungeonOrbProfile.java new file mode 100644 index 000000000..f34601c1f --- /dev/null +++ b/dungeons/src/main/java/net/swofty/dungeons/catacombs/item/DungeonOrbProfile.java @@ -0,0 +1,45 @@ +package net.swofty.dungeons.catacombs.item; + +import net.swofty.dungeons.catacombs.CatacombsFloor; +import net.swofty.dungeons.catacombs.classes.DungeonClassAbilityType; +import net.swofty.dungeons.catacombs.classes.DungeonClassDefinition; + +import java.util.List; + +public record DungeonOrbProfile( + String itemId, + String displayName, + boolean requiredForAbilities, + List mortGrantFloors, + List livingSlots, + List ghostSlots +) { + public DungeonOrbProfile { + mortGrantFloors = List.copyOf(mortGrantFloors); + livingSlots = List.copyOf(livingSlots); + ghostSlots = List.copyOf(ghostSlots); + } + + public static DungeonOrbProfile forClass(DungeonClassDefinition definition) { + List livingSlots = definition.abilities().stream() + .filter(ability -> ability.type() == DungeonClassAbilityType.ORB + || ability.type() == DungeonClassAbilityType.ULTIMATE) + .map(ability -> new DungeonHotbarSlot( + ability.type() == DungeonClassAbilityType.ULTIMATE ? 8 : 7, + ability.type() == DungeonClassAbilityType.ULTIMATE + ? DungeonHotbarAction.DROP_KEY_ULTIMATE + : DungeonHotbarAction.DROP_STACK_KEY_ABILITY, + ability)) + .toList(); + List ghostSlots = definition.abilities(DungeonClassAbilityType.GHOST).stream() + .map(ability -> new DungeonHotbarSlot(0, DungeonHotbarAction.GHOST_HOTBAR_SLOT, ability)) + .toList(); + return new DungeonOrbProfile( + "DUNGEON_STONE", + definition.type().displayName() + " Dungeon Orb", + false, + List.of(CatacombsFloor.ENTRANCE, CatacombsFloor.FLOOR_ONE, CatacombsFloor.FLOOR_TWO), + livingSlots, + ghostSlots); + } +} diff --git a/dungeons/src/main/java/net/swofty/dungeons/catacombs/puzzle/CatacombsPuzzle.java b/dungeons/src/main/java/net/swofty/dungeons/catacombs/puzzle/CatacombsPuzzle.java new file mode 100644 index 000000000..39d989099 --- /dev/null +++ b/dungeons/src/main/java/net/swofty/dungeons/catacombs/puzzle/CatacombsPuzzle.java @@ -0,0 +1,42 @@ +package net.swofty.dungeons.catacombs.puzzle; + +import net.swofty.dungeons.catacombs.CatacombsFloor; + +public enum CatacombsPuzzle { + CREEPER_BEAMS("Creeper Beams", CatacombsFloor.ENTRANCE, false), + THREE_WEIRDOS("Three Weirdos", CatacombsFloor.ENTRANCE, true), + TIC_TAC_TOE("Tic Tac Toe", CatacombsFloor.ENTRANCE, true), + WATER_BOARD("Water Board", CatacombsFloor.ENTRANCE, false), + TELEPORT_MAZE("Teleport Maze", CatacombsFloor.ENTRANCE, false), + HIGHER_OR_LOWER("Higher or Lower", CatacombsFloor.FLOOR_THREE, true), + BOULDER("Boulder", CatacombsFloor.FLOOR_THREE, true), + ICE_FILL("Ice Fill", CatacombsFloor.FLOOR_SEVEN, false), + ICE_PATH("Ice Path", CatacombsFloor.FLOOR_THREE, true), + QUIZ("Quiz", CatacombsFloor.FLOOR_FOUR, true); + + private final String displayName; + private final CatacombsFloor minimumFloor; + private final boolean failable; + + CatacombsPuzzle(String displayName, CatacombsFloor minimumFloor, boolean failable) { + this.displayName = displayName; + this.minimumFloor = minimumFloor; + this.failable = failable; + } + + public String displayName() { + return displayName; + } + + public CatacombsFloor minimumFloor() { + return minimumFloor; + } + + public boolean failable() { + return failable; + } + + public boolean canGenerate(CatacombsFloor floor) { + return floor.ordinal() >= minimumFloor.ordinal(); + } +} diff --git a/dungeons/src/main/java/net/swofty/dungeons/catacombs/run/CatacombsRunConfig.java b/dungeons/src/main/java/net/swofty/dungeons/catacombs/run/CatacombsRunConfig.java new file mode 100644 index 000000000..1113e3a43 --- /dev/null +++ b/dungeons/src/main/java/net/swofty/dungeons/catacombs/run/CatacombsRunConfig.java @@ -0,0 +1,21 @@ +package net.swofty.dungeons.catacombs.run; + +import net.swofty.dungeons.catacombs.CatacombsFloorDefinition; +import net.swofty.dungeons.catacombs.classes.DungeonClassType; + +import java.util.Map; +import java.util.UUID; + +public record CatacombsRunConfig( + CatacombsFloorDefinition floor, + Map partyClasses, + int totalRooms, + int totalSecrets +) { + public CatacombsRunConfig { + partyClasses = Map.copyOf(partyClasses); + if (!floor.rules().allowsPartySize(partyClasses.size())) { + throw new IllegalArgumentException("Invalid Catacombs party size " + partyClasses.size()); + } + } +} diff --git a/dungeons/src/main/java/net/swofty/dungeons/catacombs/run/CatacombsRunState.java b/dungeons/src/main/java/net/swofty/dungeons/catacombs/run/CatacombsRunState.java new file mode 100644 index 000000000..3c9f9b690 --- /dev/null +++ b/dungeons/src/main/java/net/swofty/dungeons/catacombs/run/CatacombsRunState.java @@ -0,0 +1,244 @@ +package net.swofty.dungeons.catacombs.run; + +import net.swofty.dungeons.catacombs.blessing.BlessingSet; +import net.swofty.dungeons.catacombs.blessing.BlessingType; + +import java.time.Duration; +import java.time.Instant; +import java.util.EnumMap; +import java.util.HashMap; +import java.util.Map; + +public final class CatacombsRunState { + private final CatacombsRunConfig config; + private final Instant startedAt; + private final Map rooms = new HashMap<>(); + private final BlessingSet blessings = new BlessingSet(); + private DungeonRunPhase phase = DungeonRunPhase.START_ROOM; + private int deaths; + private int crypts; + private int completedRooms; + private int secretsFound; + private int failedPuzzles; + private boolean spiritPetFirstDeathReduction; + private Instant finishedAt; + + private CatacombsRunState(CatacombsRunConfig config) { + this.config = config; + this.startedAt = Instant.now(); + for (int room = 0; room < config.totalRooms(); room++) { + rooms.put(room, DungeonRoomState.UNDISCOVERED); + } + } + + public static CatacombsRunState start(CatacombsRunConfig config) { + return new CatacombsRunState(config); + } + + public CatacombsRunConfig config() { + return config; + } + + public DungeonRunPhase phase() { + return phase; + } + + public int deaths() { + return deaths; + } + + public int crypts() { + return crypts; + } + + public int completedRooms() { + return completedRooms; + } + + public int secretsFound() { + return secretsFound; + } + + public int failedPuzzles() { + return failedPuzzles; + } + + public Map rooms() { + return Map.copyOf(rooms); + } + + public BlessingSet blessings() { + return blessings; + } + + public Duration elapsed() { + return Duration.between(startedAt, finishedAt == null ? Instant.now() : finishedAt); + } + + public CatacombsRunState enterClearing() { + phase = DungeonRunPhase.CLEARING; + return this; + } + + public CatacombsRunState enterBloodRoom() { + phase = DungeonRunPhase.BLOOD_ROOM; + return this; + } + + public CatacombsRunState enterBoss() { + phase = DungeonRunPhase.BOSS; + return this; + } + + public CatacombsRunState complete() { + phase = DungeonRunPhase.COMPLETED; + finishedAt = Instant.now(); + return this; + } + + public CatacombsRunState fail() { + phase = DungeonRunPhase.FAILED; + finishedAt = Instant.now(); + return this; + } + + public CatacombsRunState markRoom(int roomId, DungeonRoomState state) { + DungeonRoomState previous = rooms.put(roomId, state); + if (previous != DungeonRoomState.COMPLETED && state == DungeonRoomState.COMPLETED) { + completedRooms++; + } + return this; + } + + public CatacombsRunState recordDeath(boolean spiritPetReduced) { + if (spiritPetReduced && !spiritPetFirstDeathReduction) { + spiritPetFirstDeathReduction = true; + } + deaths++; + return this; + } + + public CatacombsRunState recordCrypt() { + crypts++; + return this; + } + + public CatacombsRunState recordSecret() { + secretsFound++; + return this; + } + + public CatacombsRunState failPuzzle(int roomId) { + failedPuzzles++; + markRoom(roomId, DungeonRoomState.FAILED); + return this; + } + + public CatacombsRunState addBlessing(BlessingType type, int level) { + blessings.add(type, level); + return this; + } + + public DungeonScoreBreakdown score() { + return new DungeonScoreBreakdown(skillScore(), explorationScore(), speedScore(), bonusScore()); + } + + public Map scoreTrace() { + Map trace = new HashMap<>(); + trace.put("deaths", deaths); + trace.put("failedPuzzles", failedPuzzles); + trace.put("completedRooms", completedRooms); + trace.put("totalRooms", config.totalRooms()); + trace.put("secretsFound", secretsFound); + trace.put("totalSecrets", config.totalSecrets()); + trace.put("crypts", crypts); + trace.put("elapsedSeconds", (int) elapsed().toSeconds()); + trace.put("speedScoreSeconds", config.floor().rules().speedScoreSeconds()); + trace.put("skill", skillScore()); + trace.put("exploration", explorationScore()); + trace.put("speed", speedScore()); + trace.put("bonus", bonusScore()); + trace.put("total", score().total()); + return Map.copyOf(trace); + } + + public Map progressionTrace() { + Map trace = new EnumMap<>(DungeonRunPhase.class); + for (DungeonRunPhase value : DungeonRunPhase.values()) { + trace.put(value, hasReached(value)); + } + return Map.copyOf(trace); + } + + private boolean hasReached(DungeonRunPhase value) { + if (phase == DungeonRunPhase.FAILED) { + return value != DungeonRunPhase.COMPLETED; + } + return value.ordinal() <= phase.ordinal(); + } + + private int skillScore() { + int deathPenalty = deaths * 2; + if (spiritPetFirstDeathReduction && deaths > 0) { + deathPenalty--; + } + return clamp(100 - deathPenalty - failedPuzzles * 10, 20, 100); + } + + private int explorationScore() { + double roomCompletion = ratio(completedRooms, config.totalRooms()); + double secretCompletion = ratio(secretsFound, config.totalSecrets()); + return clamp((int) Math.floor(roomCompletion * 60 + secretCompletion * 40), 0, 100); + } + + private int speedScore() { + int target = config.floor().rules().speedScoreSeconds(); + long elapsedSeconds = elapsed().toSeconds(); + if (elapsedSeconds <= target) { + return 100; + } + double percentOver = ((double) elapsedSeconds / target - 1) * 100; + return clamp(100 - speedPenalty(percentOver), 0, 100); + } + + private int bonusScore() { + int bonus = Math.min(5, crypts); + if (secretsFound >= config.totalSecrets()) { + bonus += 5; + } + return clamp(bonus, 0, config.floor().rules().bonusScoreCap()); + } + + private int speedPenalty(double percentOver) { + double remaining = percentOver; + int penalty = 0; + penalty += consumeSpeedBand(remaining, 20, 2); + remaining -= Math.min(remaining, 20); + penalty += consumeSpeedBand(remaining, 20, 4); + remaining -= Math.min(remaining, 20); + penalty += consumeSpeedBand(remaining, 10, 5); + remaining -= Math.min(remaining, 10); + penalty += consumeSpeedBand(remaining, 10, 6); + remaining -= Math.min(remaining, 10); + penalty += consumeSpeedBand(remaining, Double.MAX_VALUE, 7); + return penalty; + } + + private int consumeSpeedBand(double remainingPercent, double bandSize, double percentPerPoint) { + if (remainingPercent <= 0) { + return 0; + } + return (int) Math.floor(Math.min(remainingPercent, bandSize) / percentPerPoint); + } + + private double ratio(int current, int total) { + if (total <= 0) { + return 1; + } + return Math.min(1, Math.max(0, (double) current / total)); + } + + private int clamp(int value, int min, int max) { + return Math.max(min, Math.min(max, value)); + } +} diff --git a/dungeons/src/main/java/net/swofty/dungeons/catacombs/run/DungeonRoomState.java b/dungeons/src/main/java/net/swofty/dungeons/catacombs/run/DungeonRoomState.java new file mode 100644 index 000000000..99a6b742c --- /dev/null +++ b/dungeons/src/main/java/net/swofty/dungeons/catacombs/run/DungeonRoomState.java @@ -0,0 +1,9 @@ +package net.swofty.dungeons.catacombs.run; + +public enum DungeonRoomState { + UNDISCOVERED, + DISCOVERED, + CLEARED, + COMPLETED, + FAILED +} diff --git a/dungeons/src/main/java/net/swofty/dungeons/catacombs/run/DungeonRunPhase.java b/dungeons/src/main/java/net/swofty/dungeons/catacombs/run/DungeonRunPhase.java new file mode 100644 index 000000000..c97ca9622 --- /dev/null +++ b/dungeons/src/main/java/net/swofty/dungeons/catacombs/run/DungeonRunPhase.java @@ -0,0 +1,11 @@ +package net.swofty.dungeons.catacombs.run; + +public enum DungeonRunPhase { + QUEUED, + START_ROOM, + CLEARING, + BLOOD_ROOM, + BOSS, + COMPLETED, + FAILED +} diff --git a/dungeons/src/main/java/net/swofty/dungeons/catacombs/run/DungeonRunRules.java b/dungeons/src/main/java/net/swofty/dungeons/catacombs/run/DungeonRunRules.java new file mode 100644 index 000000000..db1eab028 --- /dev/null +++ b/dungeons/src/main/java/net/swofty/dungeons/catacombs/run/DungeonRunRules.java @@ -0,0 +1,15 @@ +package net.swofty.dungeons.catacombs.run; + +public record DungeonRunRules( + int speedScoreSeconds, + int maximumDurationSeconds, + int minimumPartySize, + int maximumPartySize, + int bonusScoreCap, + boolean automaticGhostRevive, + boolean trapRoomsEnabled +) { + public boolean allowsPartySize(int size) { + return size >= minimumPartySize && size <= maximumPartySize; + } +} diff --git a/dungeons/src/main/java/net/swofty/dungeons/catacombs/run/DungeonScoreBreakdown.java b/dungeons/src/main/java/net/swofty/dungeons/catacombs/run/DungeonScoreBreakdown.java new file mode 100644 index 000000000..089ef650d --- /dev/null +++ b/dungeons/src/main/java/net/swofty/dungeons/catacombs/run/DungeonScoreBreakdown.java @@ -0,0 +1,16 @@ +package net.swofty.dungeons.catacombs.run; + +public record DungeonScoreBreakdown( + int skill, + int exploration, + int speed, + int bonus +) { + public int total() { + return skill + exploration + speed + bonus; + } + + public DungeonScoreRank rank() { + return DungeonScoreRank.fromScore(total()); + } +} diff --git a/dungeons/src/main/java/net/swofty/dungeons/catacombs/run/DungeonScoreRank.java b/dungeons/src/main/java/net/swofty/dungeons/catacombs/run/DungeonScoreRank.java new file mode 100644 index 000000000..d66da0a4f --- /dev/null +++ b/dungeons/src/main/java/net/swofty/dungeons/catacombs/run/DungeonScoreRank.java @@ -0,0 +1,38 @@ +package net.swofty.dungeons.catacombs.run; + +import java.util.Arrays; +import java.util.Comparator; + +public enum DungeonScoreRank { + S_PLUS("S+", 300), + S("S", 270), + A("A", 230), + B("B", 160), + C("C", 100), + D("D", 40), + NONE("", 0); + + private final String displayName; + private final int minimumScore; + + DungeonScoreRank(String displayName, int minimumScore) { + this.displayName = displayName; + this.minimumScore = minimumScore; + } + + public String displayName() { + return displayName; + } + + public int minimumScore() { + return minimumScore; + } + + public static DungeonScoreRank fromScore(int score) { + return Arrays.stream(values()) + .sorted(Comparator.comparingInt(DungeonScoreRank::minimumScore).reversed()) + .filter(rank -> score >= rank.minimumScore) + .findFirst() + .orElse(NONE); + } +} diff --git a/dungeons/src/main/java/net/swofty/dungeons/catacombs/secret/CatacombsSecretReward.java b/dungeons/src/main/java/net/swofty/dungeons/catacombs/secret/CatacombsSecretReward.java new file mode 100644 index 000000000..739b74b77 --- /dev/null +++ b/dungeons/src/main/java/net/swofty/dungeons/catacombs/secret/CatacombsSecretReward.java @@ -0,0 +1,19 @@ +package net.swofty.dungeons.catacombs.secret; + +import net.swofty.dungeons.catacombs.CatacombsFloor; + +import java.util.Set; + +public record CatacombsSecretReward( + SecretRewardType type, + CatacombsFloor minimumFloor, + Set secretTypes +) { + public CatacombsSecretReward { + secretTypes = Set.copyOf(secretTypes); + } + + public boolean canDrop(CatacombsFloor floor, CatacombsSecretType secretType) { + return floor.ordinal() >= minimumFloor.ordinal() && secretTypes.contains(secretType); + } +} diff --git a/dungeons/src/main/java/net/swofty/dungeons/catacombs/secret/CatacombsSecretRewards.java b/dungeons/src/main/java/net/swofty/dungeons/catacombs/secret/CatacombsSecretRewards.java new file mode 100644 index 000000000..c4e4be845 --- /dev/null +++ b/dungeons/src/main/java/net/swofty/dungeons/catacombs/secret/CatacombsSecretRewards.java @@ -0,0 +1,37 @@ +package net.swofty.dungeons.catacombs.secret; + +import lombok.AccessLevel; +import lombok.NoArgsConstructor; +import net.swofty.dungeons.catacombs.CatacombsFloor; + +import java.util.List; +import java.util.Set; + +@NoArgsConstructor(access = AccessLevel.PRIVATE) +public final class CatacombsSecretRewards { + private static final Set COMMON = Set.of( + CatacombsSecretType.CHEST, + CatacombsSecretType.GROUND_ITEM, + CatacombsSecretType.BAT); + + public static List defaults() { + return List.of( + new CatacombsSecretReward(SecretRewardType.RANDOM_BLESSING, CatacombsFloor.ENTRANCE, + Set.of(CatacombsSecretType.CHEST, CatacombsSecretType.BAT)), + new CatacombsSecretReward(SecretRewardType.HEALING_POTION, CatacombsFloor.ENTRANCE, COMMON), + new CatacombsSecretReward(SecretRewardType.DECOY, CatacombsFloor.ENTRANCE, COMMON), + new CatacombsSecretReward(SecretRewardType.TRAINING_WEIGHTS, CatacombsFloor.ENTRANCE, COMMON), + new CatacombsSecretReward(SecretRewardType.SPIRIT_LEAP, CatacombsFloor.ENTRANCE, COMMON), + new CatacombsSecretReward(SecretRewardType.INFLATABLE_JERRY, CatacombsFloor.ENTRANCE, COMMON), + new CatacombsSecretReward(SecretRewardType.TRAP, CatacombsFloor.ENTRANCE, COMMON), + new CatacombsSecretReward(SecretRewardType.DEFUSE_KIT, CatacombsFloor.ENTRANCE, COMMON), + new CatacombsSecretReward(SecretRewardType.DUNGEON_CHEST_KEY, CatacombsFloor.FLOOR_FOUR, COMMON), + new CatacombsSecretReward(SecretRewardType.TREASURE_TALISMAN, CatacombsFloor.FLOOR_FOUR, COMMON), + new CatacombsSecretReward(SecretRewardType.ARCHITECTS_FIRST_DRAFT, CatacombsFloor.ENTRANCE, + Set.of(CatacombsSecretType.CHEST)), + new CatacombsSecretReward(SecretRewardType.SECRET_DYE, CatacombsFloor.ENTRANCE, + Set.of(CatacombsSecretType.CHEST)), + new CatacombsSecretReward(SecretRewardType.WITHER_ESSENCE, CatacombsFloor.ENTRANCE, + Set.of(CatacombsSecretType.WITHER_ESSENCE))); + } +} diff --git a/dungeons/src/main/java/net/swofty/dungeons/catacombs/secret/CatacombsSecretType.java b/dungeons/src/main/java/net/swofty/dungeons/catacombs/secret/CatacombsSecretType.java new file mode 100644 index 000000000..2fb5dbe28 --- /dev/null +++ b/dungeons/src/main/java/net/swofty/dungeons/catacombs/secret/CatacombsSecretType.java @@ -0,0 +1,10 @@ +package net.swofty.dungeons.catacombs.secret; + +public enum CatacombsSecretType { + CHEST, + GROUND_ITEM, + REDSTONE_KEY, + BAT, + WITHER_ESSENCE, + JOURNAL +} diff --git a/dungeons/src/main/java/net/swofty/dungeons/catacombs/secret/SecretRewardType.java b/dungeons/src/main/java/net/swofty/dungeons/catacombs/secret/SecretRewardType.java new file mode 100644 index 000000000..6ce6922b0 --- /dev/null +++ b/dungeons/src/main/java/net/swofty/dungeons/catacombs/secret/SecretRewardType.java @@ -0,0 +1,17 @@ +package net.swofty.dungeons.catacombs.secret; + +public enum SecretRewardType { + RANDOM_BLESSING, + HEALING_POTION, + DECOY, + TRAINING_WEIGHTS, + SPIRIT_LEAP, + INFLATABLE_JERRY, + TRAP, + DEFUSE_KIT, + DUNGEON_CHEST_KEY, + TREASURE_TALISMAN, + ARCHITECTS_FIRST_DRAFT, + SECRET_DYE, + WITHER_ESSENCE +} From 04b704e7a70e2b303b2489afb3a3c401111aa93b Mon Sep 17 00:00:00 2001 From: "Jacob Nardella (Swofty)" Date: Fri, 15 May 2026 15:10:19 +1000 Subject: [PATCH 113/113] feat(dungeons): model Catacombs gameplay flow --- .../net/swofty/dungeons/SkyBlockDungeon.java | 8 ++ .../dungeons/catacombs/CatacombsAPI.java | 51 ++++++++ .../boss/state/BossFightController.java | 95 +++++++++++++++ .../catacombs/boss/state/BossFightEvent.java | 11 ++ .../catacombs/boss/state/BossFightState.java | 9 ++ .../catacombs/boss/state/BossFightTrace.java | 9 ++ .../catacombs/flow/CatacombsJoinSession.java | 109 +++++++++++++++++ .../catacombs/flow/CatacombsJoinStep.java | 14 +++ .../catacombs/flow/CatacombsJoinTrace.java | 9 ++ .../catacombs/instance/CatacombsInstance.java | 27 +++++ .../instance/CatacombsInstanceService.java | 70 +++++++++++ .../instance/DungeonRoomEncounter.java | 41 +++++++ .../catacombs/kit/DungeonClassKit.java | 16 +++ .../catacombs/kit/DungeonKitItem.java | 3 + .../catacombs/kit/DungeonKitRegistry.java | 67 +++++++++++ .../catacombs/map/DungeonMapPalette.java | 37 ++++++ .../catacombs/map/DungeonMapRenderResult.java | 5 + .../catacombs/map/DungeonMapRenderer.java | 62 ++++++++++ .../catacombs/mob/DungeonMobAbility.java | 22 ++++ .../catacombs/mob/DungeonMobDefinition.java | 36 ++++++ .../catacombs/mob/DungeonMobInstance.java | 34 ++++++ .../catacombs/mob/DungeonMobRegistry.java | 79 +++++++++++++ .../catacombs/mob/DungeonMobRole.java | 12 ++ .../catacombs/party/PartyFinderListing.java | 111 ++++++++++++++++++ .../catacombs/party/PartyFinderMember.java | 21 ++++ .../catacombs/party/PartyFinderRole.java | 6 + .../catacombs/party/PartyFinderService.java | 35 ++++++ .../puzzle/CatacombsPuzzleFactory.java | 25 ++++ .../puzzle/ObjectivePuzzleController.java | 62 ++++++++++ .../puzzle/OrderedPuzzleController.java | 60 ++++++++++ .../catacombs/puzzle/PuzzleAction.java | 7 ++ .../catacombs/puzzle/PuzzleController.java | 15 +++ .../catacombs/puzzle/PuzzleState.java | 9 ++ .../catacombs/puzzle/PuzzleTrace.java | 9 ++ 34 files changed, 1186 insertions(+) create mode 100644 dungeons/src/main/java/net/swofty/dungeons/catacombs/boss/state/BossFightController.java create mode 100644 dungeons/src/main/java/net/swofty/dungeons/catacombs/boss/state/BossFightEvent.java create mode 100644 dungeons/src/main/java/net/swofty/dungeons/catacombs/boss/state/BossFightState.java create mode 100644 dungeons/src/main/java/net/swofty/dungeons/catacombs/boss/state/BossFightTrace.java create mode 100644 dungeons/src/main/java/net/swofty/dungeons/catacombs/flow/CatacombsJoinSession.java create mode 100644 dungeons/src/main/java/net/swofty/dungeons/catacombs/flow/CatacombsJoinStep.java create mode 100644 dungeons/src/main/java/net/swofty/dungeons/catacombs/flow/CatacombsJoinTrace.java create mode 100644 dungeons/src/main/java/net/swofty/dungeons/catacombs/instance/CatacombsInstance.java create mode 100644 dungeons/src/main/java/net/swofty/dungeons/catacombs/instance/CatacombsInstanceService.java create mode 100644 dungeons/src/main/java/net/swofty/dungeons/catacombs/instance/DungeonRoomEncounter.java create mode 100644 dungeons/src/main/java/net/swofty/dungeons/catacombs/kit/DungeonClassKit.java create mode 100644 dungeons/src/main/java/net/swofty/dungeons/catacombs/kit/DungeonKitItem.java create mode 100644 dungeons/src/main/java/net/swofty/dungeons/catacombs/kit/DungeonKitRegistry.java create mode 100644 dungeons/src/main/java/net/swofty/dungeons/catacombs/map/DungeonMapPalette.java create mode 100644 dungeons/src/main/java/net/swofty/dungeons/catacombs/map/DungeonMapRenderResult.java create mode 100644 dungeons/src/main/java/net/swofty/dungeons/catacombs/map/DungeonMapRenderer.java create mode 100644 dungeons/src/main/java/net/swofty/dungeons/catacombs/mob/DungeonMobAbility.java create mode 100644 dungeons/src/main/java/net/swofty/dungeons/catacombs/mob/DungeonMobDefinition.java create mode 100644 dungeons/src/main/java/net/swofty/dungeons/catacombs/mob/DungeonMobInstance.java create mode 100644 dungeons/src/main/java/net/swofty/dungeons/catacombs/mob/DungeonMobRegistry.java create mode 100644 dungeons/src/main/java/net/swofty/dungeons/catacombs/mob/DungeonMobRole.java create mode 100644 dungeons/src/main/java/net/swofty/dungeons/catacombs/party/PartyFinderListing.java create mode 100644 dungeons/src/main/java/net/swofty/dungeons/catacombs/party/PartyFinderMember.java create mode 100644 dungeons/src/main/java/net/swofty/dungeons/catacombs/party/PartyFinderRole.java create mode 100644 dungeons/src/main/java/net/swofty/dungeons/catacombs/party/PartyFinderService.java create mode 100644 dungeons/src/main/java/net/swofty/dungeons/catacombs/puzzle/CatacombsPuzzleFactory.java create mode 100644 dungeons/src/main/java/net/swofty/dungeons/catacombs/puzzle/ObjectivePuzzleController.java create mode 100644 dungeons/src/main/java/net/swofty/dungeons/catacombs/puzzle/OrderedPuzzleController.java create mode 100644 dungeons/src/main/java/net/swofty/dungeons/catacombs/puzzle/PuzzleAction.java create mode 100644 dungeons/src/main/java/net/swofty/dungeons/catacombs/puzzle/PuzzleController.java create mode 100644 dungeons/src/main/java/net/swofty/dungeons/catacombs/puzzle/PuzzleState.java create mode 100644 dungeons/src/main/java/net/swofty/dungeons/catacombs/puzzle/PuzzleTrace.java diff --git a/dungeons/src/main/java/net/swofty/dungeons/SkyBlockDungeon.java b/dungeons/src/main/java/net/swofty/dungeons/SkyBlockDungeon.java index e959d36e3..e5b84ae01 100644 --- a/dungeons/src/main/java/net/swofty/dungeons/SkyBlockDungeon.java +++ b/dungeons/src/main/java/net/swofty/dungeons/SkyBlockDungeon.java @@ -22,6 +22,14 @@ public DungeonRoom getRoom(int x, int y) { return rooms.get(Map.entry(x, y)); } + public Map, DungeonRoom> getRooms() { + return Map.copyOf(rooms); + } + + public List getDoorConnections() { + return List.copyOf(doors); + } + public boolean isConnected(int x1, int y1, int x2, int y2) { return doors.stream().anyMatch(door -> (door.x1() == x1 && door.y1() == y1 && door.x2() == x2 && door.y2() == y2) || (door.x1() == x2 && door.y1() == y2 && door.x2() == x1 && door.y2() == y1)); } diff --git a/dungeons/src/main/java/net/swofty/dungeons/catacombs/CatacombsAPI.java b/dungeons/src/main/java/net/swofty/dungeons/catacombs/CatacombsAPI.java index 1b06d8579..638445115 100644 --- a/dungeons/src/main/java/net/swofty/dungeons/catacombs/CatacombsAPI.java +++ b/dungeons/src/main/java/net/swofty/dungeons/catacombs/CatacombsAPI.java @@ -3,20 +3,39 @@ import lombok.AccessLevel; import lombok.NoArgsConstructor; import net.swofty.dungeons.GeneratorService; +import net.swofty.dungeons.SkyBlockDungeon; import net.swofty.dungeons.catacombs.classes.DungeonClassDefinition; import net.swofty.dungeons.catacombs.classes.DungeonClassRegistry; import net.swofty.dungeons.catacombs.classes.DungeonClassType; import net.swofty.dungeons.catacombs.generation.CatacombsGenerator; +import net.swofty.dungeons.catacombs.instance.CatacombsInstanceService; import net.swofty.dungeons.catacombs.item.DungeonOrbProfile; +import net.swofty.dungeons.catacombs.kit.DungeonClassKit; +import net.swofty.dungeons.catacombs.kit.DungeonKitRegistry; +import net.swofty.dungeons.catacombs.map.DungeonMapRenderResult; +import net.swofty.dungeons.catacombs.map.DungeonMapRenderer; +import net.swofty.dungeons.catacombs.mob.DungeonMobDefinition; +import net.swofty.dungeons.catacombs.mob.DungeonMobRegistry; +import net.swofty.dungeons.catacombs.mob.DungeonMobRole; +import net.swofty.dungeons.catacombs.party.PartyFinderService; +import net.swofty.dungeons.catacombs.puzzle.CatacombsPuzzle; +import net.swofty.dungeons.catacombs.puzzle.CatacombsPuzzleFactory; +import net.swofty.dungeons.catacombs.puzzle.PuzzleController; import net.swofty.dungeons.catacombs.run.CatacombsRunConfig; import net.swofty.dungeons.catacombs.run.CatacombsRunState; +import java.io.IOException; +import java.nio.file.Path; +import java.util.List; import java.util.Map; @NoArgsConstructor(access = AccessLevel.PRIVATE) public final class CatacombsAPI { private static final DungeonClassRegistry CLASS_REGISTRY = DungeonClassRegistry.defaults(); private static final CatacombsRegistry CATACOMBS_REGISTRY = CatacombsRegistry.defaults(); + private static final DungeonMobRegistry MOB_REGISTRY = DungeonMobRegistry.defaults(); + private static final DungeonKitRegistry KIT_REGISTRY = DungeonKitRegistry.defaults(); + private static final DungeonMapRenderer MAP_RENDERER = new DungeonMapRenderer(); public static CatacombsFloorDefinition floor(CatacombsFloor floor, CatacombsMode mode) { return CATACOMBS_REGISTRY.floor(floor, mode); @@ -34,10 +53,42 @@ public static DungeonOrbProfile dungeonOrb(DungeonClassType type) { return DungeonOrbProfile.forClass(dungeonClass(type)); } + public static List kits(DungeonClassType type) { + return KIT_REGISTRY.kits(type); + } + + public static DungeonClassKit kit(String id) { + return KIT_REGISTRY.kit(id); + } + + public static PartyFinderService partyFinder() { + return new PartyFinderService(); + } + + public static CatacombsInstanceService instances() { + return new CatacombsInstanceService(); + } + + public static List mobs(CatacombsFloor floor, DungeonMobRole role) { + return MOB_REGISTRY.spawnable(floor, role); + } + + public static DungeonMobDefinition mob(String id) { + return MOB_REGISTRY.mob(id); + } + + public static PuzzleController puzzle(CatacombsPuzzle puzzle) { + return CatacombsPuzzleFactory.create(puzzle); + } + public static GeneratorService generator(CatacombsFloorDefinition definition) { return CatacombsGenerator.generator(definition); } + public static DungeonMapRenderResult renderMap(SkyBlockDungeon dungeon, Path outputPath) throws IOException { + return MAP_RENDERER.renderPng(dungeon, outputPath); + } + public static CatacombsRunState startRun(CatacombsRunConfig config) { return CatacombsRunState.start(config); } diff --git a/dungeons/src/main/java/net/swofty/dungeons/catacombs/boss/state/BossFightController.java b/dungeons/src/main/java/net/swofty/dungeons/catacombs/boss/state/BossFightController.java new file mode 100644 index 000000000..83788fa12 --- /dev/null +++ b/dungeons/src/main/java/net/swofty/dungeons/catacombs/boss/state/BossFightController.java @@ -0,0 +1,95 @@ +package net.swofty.dungeons.catacombs.boss.state; + +import net.swofty.dungeons.catacombs.boss.BossPhaseTrigger; +import net.swofty.dungeons.catacombs.boss.CatacombsBossEncounter; +import net.swofty.dungeons.catacombs.boss.CatacombsBossPhase; + +import java.util.ArrayList; +import java.util.List; + +public final class BossFightController { + private final CatacombsBossEncounter encounter; + private final List traces = new ArrayList<>(); + private BossFightState state = BossFightState.NOT_STARTED; + private int phaseIndex; + private int objectiveProgress; + + public BossFightController(CatacombsBossEncounter encounter) { + this.encounter = encounter; + } + + public CatacombsBossEncounter encounter() { + return encounter; + } + + public BossFightState state() { + return state; + } + + public CatacombsBossPhase currentPhase() { + return encounter.phases().get(Math.min(phaseIndex, encounter.phases().size() - 1)); + } + + public List traces() { + return List.copyOf(traces); + } + + public void start() { + state = BossFightState.ACTIVE; + traces.add(BossFightTrace.of(currentPhase().id(), BossFightEvent.START, currentPhase().displayName())); + } + + public void accept(BossFightEvent event, int value) { + if (state == BossFightState.COMPLETED || state == BossFightState.FAILED) { + return; + } + if (event == BossFightEvent.PLAYER_WIPED) { + state = BossFightState.FAILED; + traces.add(BossFightTrace.of(currentPhase().id(), event, "Party wiped")); + return; + } + if (event == BossFightEvent.FORCE_COMPLETE) { + completePhase(); + return; + } + + CatacombsBossPhase phase = currentPhase(); + traces.add(BossFightTrace.of(phase.id(), event, String.valueOf(value))); + if (matches(phase, event, value)) { + completePhase(); + } + } + + private boolean matches(CatacombsBossPhase phase, BossFightEvent event, int value) { + if (phase.trigger() == BossPhaseTrigger.ENTER_BOSS_ROOM && event == BossFightEvent.START) { + return true; + } + if (phase.trigger() == BossPhaseTrigger.BOSS_HEALTH_THRESHOLD && event == BossFightEvent.BOSS_DAMAGED) { + return value <= phase.triggerValue(); + } + if (phase.trigger() == BossPhaseTrigger.ADDS_DEFEATED && event == BossFightEvent.ADD_DEFEATED) { + objectiveProgress += value; + return phase.triggerValue() <= 0 || objectiveProgress >= phase.triggerValue(); + } + if (phase.trigger() == BossPhaseTrigger.PLAYER_OBJECTIVE && event == BossFightEvent.OBJECTIVE_COMPLETED) { + objectiveProgress += value; + return objectiveProgress >= phase.triggerValue(); + } + if (phase.trigger() == BossPhaseTrigger.TIMER && event == BossFightEvent.TIMER_EXPIRED) { + return true; + } + return phase.trigger() == BossPhaseTrigger.PHASE_COMPLETE && event == BossFightEvent.OBJECTIVE_COMPLETED; + } + + private void completePhase() { + traces.add(BossFightTrace.of(currentPhase().id(), BossFightEvent.FORCE_COMPLETE, "Phase complete")); + objectiveProgress = 0; + phaseIndex++; + if (phaseIndex >= encounter.phases().size()) { + state = BossFightState.COMPLETED; + } else { + state = BossFightState.PHASE_TRANSITION; + state = BossFightState.ACTIVE; + } + } +} diff --git a/dungeons/src/main/java/net/swofty/dungeons/catacombs/boss/state/BossFightEvent.java b/dungeons/src/main/java/net/swofty/dungeons/catacombs/boss/state/BossFightEvent.java new file mode 100644 index 000000000..bc0b4c5db --- /dev/null +++ b/dungeons/src/main/java/net/swofty/dungeons/catacombs/boss/state/BossFightEvent.java @@ -0,0 +1,11 @@ +package net.swofty.dungeons.catacombs.boss.state; + +public enum BossFightEvent { + START, + BOSS_DAMAGED, + ADD_DEFEATED, + OBJECTIVE_COMPLETED, + TIMER_EXPIRED, + PLAYER_WIPED, + FORCE_COMPLETE +} diff --git a/dungeons/src/main/java/net/swofty/dungeons/catacombs/boss/state/BossFightState.java b/dungeons/src/main/java/net/swofty/dungeons/catacombs/boss/state/BossFightState.java new file mode 100644 index 000000000..66781d0e6 --- /dev/null +++ b/dungeons/src/main/java/net/swofty/dungeons/catacombs/boss/state/BossFightState.java @@ -0,0 +1,9 @@ +package net.swofty.dungeons.catacombs.boss.state; + +public enum BossFightState { + NOT_STARTED, + ACTIVE, + PHASE_TRANSITION, + COMPLETED, + FAILED +} diff --git a/dungeons/src/main/java/net/swofty/dungeons/catacombs/boss/state/BossFightTrace.java b/dungeons/src/main/java/net/swofty/dungeons/catacombs/boss/state/BossFightTrace.java new file mode 100644 index 000000000..1210108a4 --- /dev/null +++ b/dungeons/src/main/java/net/swofty/dungeons/catacombs/boss/state/BossFightTrace.java @@ -0,0 +1,9 @@ +package net.swofty.dungeons.catacombs.boss.state; + +import java.time.Instant; + +public record BossFightTrace(String phaseId, BossFightEvent event, Instant happenedAt, String detail) { + public static BossFightTrace of(String phaseId, BossFightEvent event, String detail) { + return new BossFightTrace(phaseId, event, Instant.now(), detail); + } +} diff --git a/dungeons/src/main/java/net/swofty/dungeons/catacombs/flow/CatacombsJoinSession.java b/dungeons/src/main/java/net/swofty/dungeons/catacombs/flow/CatacombsJoinSession.java new file mode 100644 index 000000000..3e999ef3a --- /dev/null +++ b/dungeons/src/main/java/net/swofty/dungeons/catacombs/flow/CatacombsJoinSession.java @@ -0,0 +1,109 @@ +package net.swofty.dungeons.catacombs.flow; + +import net.swofty.dungeons.catacombs.CatacombsFloor; +import net.swofty.dungeons.catacombs.CatacombsFloorDefinition; +import net.swofty.dungeons.catacombs.CatacombsMode; +import net.swofty.dungeons.catacombs.classes.DungeonClassType; +import net.swofty.dungeons.catacombs.party.PartyFinderListing; + +import java.util.ArrayList; +import java.util.List; +import java.util.UUID; + +public final class CatacombsJoinSession { + private final UUID playerId; + private final List traces = new ArrayList<>(); + private CatacombsMode mode; + private CatacombsFloor floor; + private DungeonClassType selectedClass; + private String selectedKitId; + private PartyFinderListing listing; + + private CatacombsJoinSession(UUID playerId) { + this.playerId = playerId; + traces.add(CatacombsJoinTrace.of(CatacombsJoinStep.CLICK_MORT, "Mort opened Catacombs menu")); + } + + public static CatacombsJoinSession clickedMort(UUID playerId) { + return new CatacombsJoinSession(playerId); + } + + public UUID playerId() { + return playerId; + } + + public CatacombsMode mode() { + return mode; + } + + public CatacombsFloor floor() { + return floor; + } + + public DungeonClassType selectedClass() { + return selectedClass; + } + + public String selectedKitId() { + return selectedKitId; + } + + public PartyFinderListing listing() { + return listing; + } + + public List traces() { + return List.copyOf(traces); + } + + public CatacombsJoinSession selectMode(CatacombsMode mode) { + this.mode = mode; + traces.add(CatacombsJoinTrace.of(CatacombsJoinStep.SELECT_MODE, mode.name())); + return this; + } + + public CatacombsJoinSession selectFloor(CatacombsFloorDefinition definition) { + this.floor = definition.floor(); + this.mode = definition.mode(); + traces.add(CatacombsJoinTrace.of(CatacombsJoinStep.SELECT_FLOOR, definition.floor().displayName())); + return this; + } + + public CatacombsJoinSession joinPartyFinder(PartyFinderListing listing) { + this.listing = listing; + traces.add(CatacombsJoinTrace.of(CatacombsJoinStep.PARTY_FINDER, listing.id().toString())); + return this; + } + + public CatacombsJoinSession readyCheck() { + traces.add(CatacombsJoinTrace.of(CatacombsJoinStep.READY_CHECK, "Player ready")); + return this; + } + + public CatacombsJoinSession selectClass(DungeonClassType type) { + this.selectedClass = type; + traces.add(CatacombsJoinTrace.of(CatacombsJoinStep.CLASS_SELECTION, type.displayName())); + return this; + } + + public CatacombsJoinSession selectKit(String kitId) { + this.selectedKitId = kitId; + traces.add(CatacombsJoinTrace.of(CatacombsJoinStep.KIT_SELECTION, kitId)); + return this; + } + + public CatacombsJoinSession instanceCreated() { + traces.add(CatacombsJoinTrace.of(CatacombsJoinStep.INSTANCE_CREATE, "Dungeon instance allocated")); + return this; + } + + public CatacombsJoinSession startRoom() { + traces.add(CatacombsJoinTrace.of(CatacombsJoinStep.START_ROOM, "Players spawned in start room")); + return this; + } + + public CatacombsJoinSession runStarted() { + traces.add(CatacombsJoinTrace.of(CatacombsJoinStep.RUN_STARTED, "Blood door locked, run timer started")); + return this; + } +} diff --git a/dungeons/src/main/java/net/swofty/dungeons/catacombs/flow/CatacombsJoinStep.java b/dungeons/src/main/java/net/swofty/dungeons/catacombs/flow/CatacombsJoinStep.java new file mode 100644 index 000000000..48c119ef1 --- /dev/null +++ b/dungeons/src/main/java/net/swofty/dungeons/catacombs/flow/CatacombsJoinStep.java @@ -0,0 +1,14 @@ +package net.swofty.dungeons.catacombs.flow; + +public enum CatacombsJoinStep { + CLICK_MORT, + SELECT_MODE, + SELECT_FLOOR, + PARTY_FINDER, + READY_CHECK, + CLASS_SELECTION, + KIT_SELECTION, + INSTANCE_CREATE, + START_ROOM, + RUN_STARTED +} diff --git a/dungeons/src/main/java/net/swofty/dungeons/catacombs/flow/CatacombsJoinTrace.java b/dungeons/src/main/java/net/swofty/dungeons/catacombs/flow/CatacombsJoinTrace.java new file mode 100644 index 000000000..1d03f66e8 --- /dev/null +++ b/dungeons/src/main/java/net/swofty/dungeons/catacombs/flow/CatacombsJoinTrace.java @@ -0,0 +1,9 @@ +package net.swofty.dungeons.catacombs.flow; + +import java.time.Instant; + +public record CatacombsJoinTrace(CatacombsJoinStep step, Instant happenedAt, String detail) { + public static CatacombsJoinTrace of(CatacombsJoinStep step, String detail) { + return new CatacombsJoinTrace(step, Instant.now(), detail); + } +} diff --git a/dungeons/src/main/java/net/swofty/dungeons/catacombs/instance/CatacombsInstance.java b/dungeons/src/main/java/net/swofty/dungeons/catacombs/instance/CatacombsInstance.java new file mode 100644 index 000000000..778655dec --- /dev/null +++ b/dungeons/src/main/java/net/swofty/dungeons/catacombs/instance/CatacombsInstance.java @@ -0,0 +1,27 @@ +package net.swofty.dungeons.catacombs.instance; + +import net.swofty.dungeons.SkyBlockDungeon; +import net.swofty.dungeons.catacombs.CatacombsFloorDefinition; +import net.swofty.dungeons.catacombs.boss.state.BossFightController; +import net.swofty.dungeons.catacombs.kit.DungeonClassKit; +import net.swofty.dungeons.catacombs.run.CatacombsRunState; + +import java.nio.file.Path; +import java.util.Map; +import java.util.UUID; + +public record CatacombsInstance( + UUID id, + CatacombsFloorDefinition floor, + SkyBlockDungeon dungeon, + CatacombsRunState runState, + BossFightController bossFight, + Map kits, + Map encounters, + Path renderedMap +) { + public CatacombsInstance { + kits = Map.copyOf(kits); + encounters = Map.copyOf(encounters); + } +} diff --git a/dungeons/src/main/java/net/swofty/dungeons/catacombs/instance/CatacombsInstanceService.java b/dungeons/src/main/java/net/swofty/dungeons/catacombs/instance/CatacombsInstanceService.java new file mode 100644 index 000000000..6fbe4fbdf --- /dev/null +++ b/dungeons/src/main/java/net/swofty/dungeons/catacombs/instance/CatacombsInstanceService.java @@ -0,0 +1,70 @@ +package net.swofty.dungeons.catacombs.instance; + +import net.swofty.dungeons.DungeonRoomType; +import net.swofty.dungeons.SkyBlockDungeon; +import net.swofty.dungeons.catacombs.CatacombsAPI; +import net.swofty.dungeons.catacombs.CatacombsFloorDefinition; +import net.swofty.dungeons.catacombs.boss.state.BossFightController; +import net.swofty.dungeons.catacombs.kit.DungeonClassKit; +import net.swofty.dungeons.catacombs.mob.DungeonMobDefinition; +import net.swofty.dungeons.catacombs.mob.DungeonMobRole; +import net.swofty.dungeons.catacombs.run.CatacombsRunConfig; +import net.swofty.dungeons.catacombs.run.CatacombsRunState; + +import java.io.IOException; +import java.nio.file.Path; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.UUID; + +public final class CatacombsInstanceService { + public CatacombsInstance create(CatacombsFloorDefinition floor, + Map kits, + Path mapOutput) throws IOException { + SkyBlockDungeon dungeon = CatacombsAPI.generator(floor).generate().join(); + Map encounters = encounters(floor, dungeon); + CatacombsRunState runState = CatacombsRunState.start(new CatacombsRunConfig( + floor, + kits.entrySet().stream().collect(HashMap::new, + (map, entry) -> map.put(entry.getKey(), entry.getValue().type()), + HashMap::putAll), + dungeon.getRooms().size(), + estimateSecrets(floor, dungeon))); + Path renderedMap = null; + if (mapOutput != null) { + renderedMap = CatacombsAPI.renderMap(dungeon, mapOutput).path(); + } + return new CatacombsInstance(UUID.randomUUID(), floor, dungeon, runState, + new BossFightController(floor.boss()), kits, encounters, renderedMap); + } + + private Map encounters(CatacombsFloorDefinition floor, SkyBlockDungeon dungeon) { + Map encounters = new HashMap<>(); + int roomId = 0; + for (SkyBlockDungeon.DungeonRoom room : dungeon.getRooms().values()) { + List mobs = switch (room.getRoomType()) { + case MINI_BOSS -> CatacombsAPI.mobs(floor.floor(), DungeonMobRole.MINIBOSS).stream().limit(1).toList(); + case PUZZLE -> CatacombsAPI.mobs(floor.floor(), DungeonMobRole.PUZZLE).stream().limit(1).toList(); + case EXIT, BLOOD -> CatacombsAPI.mobs(floor.floor(), DungeonMobRole.BLOOD).stream().limit(5).toList(); + case BASE -> CatacombsAPI.mobs(floor.floor(), DungeonMobRole.STARRED).stream().limit(3).toList(); + default -> List.of(); + }; + if (!mobs.isEmpty()) { + encounters.put(roomId, new DungeonRoomEncounter(roomId, mobs)); + } + if (room.getRoomType() == DungeonRoomType.EXIT) { + room.setRoomType(DungeonRoomType.BLOOD); + } + roomId++; + } + return encounters; + } + + private int estimateSecrets(CatacombsFloorDefinition floor, SkyBlockDungeon dungeon) { + int baseRooms = (int) dungeon.getRooms().values().stream() + .filter(room -> room.getRoomType() == DungeonRoomType.BASE) + .count(); + return Math.max(5, baseRooms * 4 + floor.puzzleRooms()); + } +} diff --git a/dungeons/src/main/java/net/swofty/dungeons/catacombs/instance/DungeonRoomEncounter.java b/dungeons/src/main/java/net/swofty/dungeons/catacombs/instance/DungeonRoomEncounter.java new file mode 100644 index 000000000..dba3fa9b4 --- /dev/null +++ b/dungeons/src/main/java/net/swofty/dungeons/catacombs/instance/DungeonRoomEncounter.java @@ -0,0 +1,41 @@ +package net.swofty.dungeons.catacombs.instance; + +import net.swofty.dungeons.catacombs.mob.DungeonMobDefinition; +import net.swofty.dungeons.catacombs.mob.DungeonMobInstance; + +import java.util.ArrayList; +import java.util.List; + +public final class DungeonRoomEncounter { + private final int roomId; + private final List mobs = new ArrayList<>(); + private boolean keyDropped; + + public DungeonRoomEncounter(int roomId, List definitions) { + this.roomId = roomId; + definitions.forEach(definition -> mobs.add(new DungeonMobInstance(definition))); + } + + public int roomId() { + return roomId; + } + + public List mobs() { + return List.copyOf(mobs); + } + + public boolean cleared() { + return mobs.stream().allMatch(DungeonMobInstance::dead); + } + + public boolean keyDropped() { + return keyDropped; + } + + public void damageMob(int index, long amount) { + mobs.get(index).damage(amount); + if (cleared()) { + keyDropped = true; + } + } +} diff --git a/dungeons/src/main/java/net/swofty/dungeons/catacombs/kit/DungeonClassKit.java b/dungeons/src/main/java/net/swofty/dungeons/catacombs/kit/DungeonClassKit.java new file mode 100644 index 000000000..49c982401 --- /dev/null +++ b/dungeons/src/main/java/net/swofty/dungeons/catacombs/kit/DungeonClassKit.java @@ -0,0 +1,16 @@ +package net.swofty.dungeons.catacombs.kit; + +import net.swofty.dungeons.catacombs.classes.DungeonClassType; + +import java.util.List; + +public record DungeonClassKit( + String id, + String displayName, + DungeonClassType type, + List items +) { + public DungeonClassKit { + items = List.copyOf(items); + } +} diff --git a/dungeons/src/main/java/net/swofty/dungeons/catacombs/kit/DungeonKitItem.java b/dungeons/src/main/java/net/swofty/dungeons/catacombs/kit/DungeonKitItem.java new file mode 100644 index 000000000..2719bea21 --- /dev/null +++ b/dungeons/src/main/java/net/swofty/dungeons/catacombs/kit/DungeonKitItem.java @@ -0,0 +1,3 @@ +package net.swofty.dungeons.catacombs.kit; + +public record DungeonKitItem(String itemId, int slot, int amount) {} diff --git a/dungeons/src/main/java/net/swofty/dungeons/catacombs/kit/DungeonKitRegistry.java b/dungeons/src/main/java/net/swofty/dungeons/catacombs/kit/DungeonKitRegistry.java new file mode 100644 index 000000000..701fba8e2 --- /dev/null +++ b/dungeons/src/main/java/net/swofty/dungeons/catacombs/kit/DungeonKitRegistry.java @@ -0,0 +1,67 @@ +package net.swofty.dungeons.catacombs.kit; + +import net.swofty.dungeons.catacombs.classes.DungeonClassType; + +import java.util.ArrayList; +import java.util.List; +import java.util.Map; +import java.util.function.Function; +import java.util.stream.Collectors; + +public record DungeonKitRegistry(Map kits) { + public DungeonKitRegistry { + kits = Map.copyOf(kits); + } + + public DungeonClassKit kit(String id) { + DungeonClassKit kit = kits.get(id); + if (kit == null) { + throw new IllegalArgumentException("Unknown dungeon kit " + id); + } + return kit; + } + + public List kits(DungeonClassType type) { + return kits.values().stream() + .filter(kit -> kit.type() == type) + .toList(); + } + + public static DungeonKitRegistry defaults() { + List kits = new ArrayList<>(); + kits.add(kit("HEALER_STARTER", "Healer Starter", DungeonClassType.HEALER, + item("DUNGEON_STONE", 8), + item("ORNATE_ZOMBIE_SWORD", 0), + item("WAND_OF_MENDING", 1), + item("REVIVE_STONE", 7))); + kits.add(kit("MAGE_STARTER", "Mage Starter", DungeonClassType.MAGE, + item("DUNGEON_STONE", 8), + item("DREADLORD_SWORD", 0), + item("CONJURING", 1), + item("DECOY", 7))); + kits.add(kit("BERSERK_STARTER", "Berserk Starter", DungeonClassType.BERSERK, + item("DUNGEON_STONE", 8), + item("ZOMBIE_KNIGHT_SWORD", 0), + item("FEL_SWORD", 1), + item("SPIRIT_LEAP", 7))); + kits.add(kit("ARCHER_STARTER", "Archer Starter", DungeonClassType.ARCHER, + item("DUNGEON_STONE", 8), + item("MACHINE_GUN_BOW", 0), + item("SUPER_UNDEAD_BOW", 1), + item("DECOY", 7))); + kits.add(kit("TANK_STARTER", "Tank Starter", DungeonClassType.TANK, + item("DUNGEON_STONE", 8), + item("EARTH_SHARD", 0), + item("SUPERBOOM_TNT", 1), + item("SPIRIT_LEAP", 7))); + return new DungeonKitRegistry(kits.stream().collect(Collectors.toMap(DungeonClassKit::id, Function.identity()))); + } + + private static DungeonClassKit kit(String id, String displayName, DungeonClassType type, DungeonKitItem... items) { + return new DungeonClassKit(id, displayName, type, List.of(items)); + } + + private static DungeonKitItem item(String itemId, int slot) { + return new DungeonKitItem(itemId, slot, 1); + } +} diff --git a/dungeons/src/main/java/net/swofty/dungeons/catacombs/map/DungeonMapPalette.java b/dungeons/src/main/java/net/swofty/dungeons/catacombs/map/DungeonMapPalette.java new file mode 100644 index 000000000..03a0da7d5 --- /dev/null +++ b/dungeons/src/main/java/net/swofty/dungeons/catacombs/map/DungeonMapPalette.java @@ -0,0 +1,37 @@ +package net.swofty.dungeons.catacombs.map; + +import net.swofty.dungeons.DungeonRoomType; + +import java.awt.Color; + +public enum DungeonMapPalette { + ENTRANCE(DungeonRoomType.ENTRANCE, new Color(0x55CC55)), + BASE(DungeonRoomType.BASE, new Color(0x8A6D54)), + FAIRY(DungeonRoomType.FAIRY, new Color(0xFF77DD)), + PUZZLE(DungeonRoomType.PUZZLE, new Color(0xAA66CC)), + MINI_BOSS(DungeonRoomType.MINI_BOSS, new Color(0xFFAA00)), + TRAP(DungeonRoomType.TRAP, new Color(0xCC3333)), + BLOOD(DungeonRoomType.BLOOD, new Color(0xAA0000)), + EXIT(DungeonRoomType.EXIT, new Color(0x333333)); + + private final DungeonRoomType roomType; + private final Color color; + + DungeonMapPalette(DungeonRoomType roomType, Color color) { + this.roomType = roomType; + this.color = color; + } + + public Color color() { + return color; + } + + public static Color forRoom(DungeonRoomType type) { + for (DungeonMapPalette value : values()) { + if (value.roomType == type) { + return value.color; + } + } + return BASE.color; + } +} diff --git a/dungeons/src/main/java/net/swofty/dungeons/catacombs/map/DungeonMapRenderResult.java b/dungeons/src/main/java/net/swofty/dungeons/catacombs/map/DungeonMapRenderResult.java new file mode 100644 index 000000000..fd93ca082 --- /dev/null +++ b/dungeons/src/main/java/net/swofty/dungeons/catacombs/map/DungeonMapRenderResult.java @@ -0,0 +1,5 @@ +package net.swofty.dungeons.catacombs.map; + +import java.nio.file.Path; + +public record DungeonMapRenderResult(Path path, int width, int height) {} diff --git a/dungeons/src/main/java/net/swofty/dungeons/catacombs/map/DungeonMapRenderer.java b/dungeons/src/main/java/net/swofty/dungeons/catacombs/map/DungeonMapRenderer.java new file mode 100644 index 000000000..bd82780a3 --- /dev/null +++ b/dungeons/src/main/java/net/swofty/dungeons/catacombs/map/DungeonMapRenderer.java @@ -0,0 +1,62 @@ +package net.swofty.dungeons.catacombs.map; + +import net.swofty.dungeons.SkyBlockDungeon; + +import javax.imageio.ImageIO; +import java.awt.BasicStroke; +import java.awt.Color; +import java.awt.Graphics2D; +import java.awt.RenderingHints; +import java.awt.image.BufferedImage; +import java.io.IOException; +import java.nio.file.Files; +import java.nio.file.Path; +import java.util.Map; + +public final class DungeonMapRenderer { + private static final int TILE = 48; + private static final int GAP = 14; + private static final int PADDING = 24; + + public DungeonMapRenderResult renderPng(SkyBlockDungeon dungeon, Path outputPath) throws IOException { + int maxX = dungeon.getRooms().keySet().stream().mapToInt(Map.Entry::getKey).max().orElse(0); + int maxY = dungeon.getRooms().keySet().stream().mapToInt(Map.Entry::getValue).max().orElse(0); + int width = PADDING * 2 + (maxX + 1) * TILE + maxX * GAP; + int height = PADDING * 2 + (maxY + 1) * TILE + maxY * GAP; + BufferedImage image = new BufferedImage(width, height, BufferedImage.TYPE_INT_ARGB); + Graphics2D graphics = image.createGraphics(); + graphics.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON); + graphics.setColor(new Color(0x151515)); + graphics.fillRect(0, 0, width, height); + graphics.setStroke(new BasicStroke(6, BasicStroke.CAP_ROUND, BasicStroke.JOIN_ROUND)); + graphics.setColor(new Color(0xD9C7A7)); + for (SkyBlockDungeon.DungeonDoor door : dungeon.getDoorConnections()) { + int x1 = center(door.x1()); + int y1 = center(door.y1()); + int x2 = center(door.x2()); + int y2 = center(door.y2()); + graphics.drawLine(x1, y1, x2, y2); + } + dungeon.getRooms().forEach((point, room) -> { + int x = origin(point.getKey()); + int y = origin(point.getValue()); + graphics.setColor(DungeonMapPalette.forRoom(room.getRoomType())); + graphics.fillRoundRect(x, y, TILE, TILE, 8, 8); + graphics.setColor(room.isCritical() ? Color.WHITE : new Color(0x2A2A2A)); + graphics.setStroke(new BasicStroke(room.isCritical() ? 3 : 1)); + graphics.drawRoundRect(x, y, TILE, TILE, 8, 8); + }); + graphics.dispose(); + Files.createDirectories(outputPath.getParent()); + ImageIO.write(image, "png", outputPath.toFile()); + return new DungeonMapRenderResult(outputPath, width, height); + } + + private int origin(int coordinate) { + return PADDING + coordinate * (TILE + GAP); + } + + private int center(int coordinate) { + return origin(coordinate) + TILE / 2; + } +} diff --git a/dungeons/src/main/java/net/swofty/dungeons/catacombs/mob/DungeonMobAbility.java b/dungeons/src/main/java/net/swofty/dungeons/catacombs/mob/DungeonMobAbility.java new file mode 100644 index 000000000..523d40456 --- /dev/null +++ b/dungeons/src/main/java/net/swofty/dungeons/catacombs/mob/DungeonMobAbility.java @@ -0,0 +1,22 @@ +package net.swofty.dungeons.catacombs.mob; + +public enum DungeonMobAbility { + MELEE, + BOW, + MAGIC_PROJECTILE, + TELEPORT, + INVISIBILITY, + SLOW, + EXPLOSION, + HEALING, + SUMMON_UNDEAD, + KNOCKBACK, + TRUE_DAMAGE, + WITHER_SKULL, + CHARGE, + SHIELD, + REVIVE, + SPLIT_CLONES, + TERMINAL_OBJECTIVE, + SPIRIT_BOW_VULNERABILITY +} diff --git a/dungeons/src/main/java/net/swofty/dungeons/catacombs/mob/DungeonMobDefinition.java b/dungeons/src/main/java/net/swofty/dungeons/catacombs/mob/DungeonMobDefinition.java new file mode 100644 index 000000000..0efbc48f7 --- /dev/null +++ b/dungeons/src/main/java/net/swofty/dungeons/catacombs/mob/DungeonMobDefinition.java @@ -0,0 +1,36 @@ +package net.swofty.dungeons.catacombs.mob; + +import net.swofty.dungeons.catacombs.CatacombsFloor; + +import java.util.Set; + +public record DungeonMobDefinition( + String id, + String displayName, + CatacombsFloor minimumFloor, + DungeonMobRole role, + long health, + long damage, + int defense, + Set abilities +) { + public DungeonMobDefinition { + abilities = Set.copyOf(abilities); + } + + public boolean canSpawn(CatacombsFloor floor) { + return floor.ordinal() >= minimumFloor.ordinal(); + } + + public DungeonMobDefinition scale(double healthMultiplier, double damageMultiplier, double defenseMultiplier) { + return new DungeonMobDefinition( + id, + displayName, + minimumFloor, + role, + Math.round(health * healthMultiplier), + Math.round(damage * damageMultiplier), + (int) Math.round(defense * defenseMultiplier), + abilities); + } +} diff --git a/dungeons/src/main/java/net/swofty/dungeons/catacombs/mob/DungeonMobInstance.java b/dungeons/src/main/java/net/swofty/dungeons/catacombs/mob/DungeonMobInstance.java new file mode 100644 index 000000000..74d8cebbf --- /dev/null +++ b/dungeons/src/main/java/net/swofty/dungeons/catacombs/mob/DungeonMobInstance.java @@ -0,0 +1,34 @@ +package net.swofty.dungeons.catacombs.mob; + +import java.util.UUID; + +public final class DungeonMobInstance { + private final UUID id = UUID.randomUUID(); + private final DungeonMobDefinition definition; + private long health; + + public DungeonMobInstance(DungeonMobDefinition definition) { + this.definition = definition; + this.health = definition.health(); + } + + public UUID id() { + return id; + } + + public DungeonMobDefinition definition() { + return definition; + } + + public long health() { + return health; + } + + public boolean dead() { + return health <= 0; + } + + public void damage(long amount) { + health = Math.max(0, health - amount); + } +} diff --git a/dungeons/src/main/java/net/swofty/dungeons/catacombs/mob/DungeonMobRegistry.java b/dungeons/src/main/java/net/swofty/dungeons/catacombs/mob/DungeonMobRegistry.java new file mode 100644 index 000000000..7fec63272 --- /dev/null +++ b/dungeons/src/main/java/net/swofty/dungeons/catacombs/mob/DungeonMobRegistry.java @@ -0,0 +1,79 @@ +package net.swofty.dungeons.catacombs.mob; + +import net.swofty.dungeons.catacombs.CatacombsFloor; + +import java.util.ArrayList; +import java.util.List; +import java.util.Map; +import java.util.Set; +import java.util.function.Function; +import java.util.stream.Collectors; + +public record DungeonMobRegistry(Map mobs) { + public DungeonMobRegistry { + mobs = Map.copyOf(mobs); + } + + public DungeonMobDefinition mob(String id) { + DungeonMobDefinition mob = mobs.get(id); + if (mob == null) { + throw new IllegalArgumentException("Unknown dungeon mob " + id); + } + return mob; + } + + public List spawnable(CatacombsFloor floor, DungeonMobRole role) { + return mobs.values().stream() + .filter(mob -> mob.role() == role) + .filter(mob -> mob.canSpawn(floor)) + .toList(); + } + + public static DungeonMobRegistry defaults() { + List mobs = new ArrayList<>(); + mobs.add(mob("BAT", "Bat", CatacombsFloor.ENTRANCE, DungeonMobRole.SECRET, 100, 0, 0)); + mobs.add(mob("CRYPT_UNDEAD", "Crypt Undead", CatacombsFloor.ENTRANCE, DungeonMobRole.NORMAL, 1200, 120, 0)); + mobs.add(mob("UNDEAD_SKELETON", "Undead Skeleton", CatacombsFloor.ENTRANCE, DungeonMobRole.NORMAL, 1000, 100, 0, DungeonMobAbility.BOW)); + mobs.add(mob("SCARED_SKELETON", "Scared Skeleton", CatacombsFloor.ENTRANCE, DungeonMobRole.NORMAL, 1100, 90, 0, DungeonMobAbility.BOW)); + mobs.add(mob("ZOMBIE_GRUNT", "Zombie Grunt", CatacombsFloor.FLOOR_ONE, DungeonMobRole.NORMAL, 2500, 220, 0)); + mobs.add(mob("SKELETON_GRUNT", "Skeleton Grunt", CatacombsFloor.FLOOR_ONE, DungeonMobRole.NORMAL, 2200, 200, 0, DungeonMobAbility.BOW)); + mobs.add(mob("SNIPER", "Sniper", CatacombsFloor.FLOOR_ONE, DungeonMobRole.STARRED, 3500, 350, 0, DungeonMobAbility.BOW)); + mobs.add(mob("CRYPT_DREADLORD", "Crypt Dreadlord", CatacombsFloor.FLOOR_ONE, DungeonMobRole.STARRED, 4500, 420, 0, DungeonMobAbility.MAGIC_PROJECTILE)); + mobs.add(mob("CRYPT_LURKER", "Crypt Lurker", CatacombsFloor.FLOOR_ONE, DungeonMobRole.STARRED, 5000, 380, 0, DungeonMobAbility.INVISIBILITY)); + mobs.add(mob("CELLAR_SPIDER", "Cellar Spider", CatacombsFloor.FLOOR_ONE, DungeonMobRole.NORMAL, 2500, 180, 0)); + mobs.add(mob("LONELY_SPIDER", "Lonely Spider", CatacombsFloor.FLOOR_ONE, DungeonMobRole.NORMAL, 3000, 210, 0)); + mobs.add(mob("LOST_ADVENTURER", "Lost Adventurer", CatacombsFloor.FLOOR_ONE, DungeonMobRole.MINIBOSS, 120000, 1600, 100, DungeonMobAbility.HEALING, DungeonMobAbility.MELEE)); + mobs.add(mob("ANGRY_ARCHAEOLOGIST", "Angry Archaeologist", CatacombsFloor.FLOOR_ONE, DungeonMobRole.MINIBOSS, 100000, 1500, 75, DungeonMobAbility.MELEE)); + mobs.add(mob("SKELETON_SOLDIER", "Skeleton Soldier", CatacombsFloor.FLOOR_ONE, DungeonMobRole.STARRED, 7000, 520, 0, DungeonMobAbility.BOW)); + mobs.add(mob("ZOMBIE_SOLDIER", "Zombie Soldier", CatacombsFloor.FLOOR_TWO, DungeonMobRole.STARRED, 9000, 580, 0)); + mobs.add(mob("SKELETON_MASTER", "Skeleton Master", CatacombsFloor.FLOOR_THREE, DungeonMobRole.STARRED, 12000, 650, 0, DungeonMobAbility.BOW, DungeonMobAbility.TRUE_DAMAGE)); + mobs.add(mob("PUZZLE_BLAZE", "Puzzle Blaze", CatacombsFloor.FLOOR_THREE, DungeonMobRole.PUZZLE, 1500, 0, 0)); + mobs.add(mob("SHADOW_ASSASSIN", "Shadow Assassin", CatacombsFloor.FLOOR_THREE, DungeonMobRole.MINIBOSS, 250000, 2800, 200, DungeonMobAbility.TELEPORT, DungeonMobAbility.INVISIBILITY)); + mobs.add(mob("FROZEN_ADVENTURER", "Frozen Adventurer", CatacombsFloor.FLOOR_FOUR, DungeonMobRole.MINIBOSS, 400000, 3200, 250, DungeonMobAbility.MAGIC_PROJECTILE, DungeonMobAbility.SLOW)); + mobs.add(mob("KING_MIDAS", "King Midas", CatacombsFloor.FLOOR_FIVE, DungeonMobRole.MINIBOSS, 500000, 3500, 300, DungeonMobAbility.MELEE)); + mobs.add(mob("SKELETOR", "Skeletor", CatacombsFloor.FLOOR_FIVE, DungeonMobRole.STARRED, 30000, 900, 120, DungeonMobAbility.BOW)); + mobs.add(mob("SUPER_ARCHER", "Super Archer", CatacombsFloor.FLOOR_FIVE, DungeonMobRole.STARRED, 40000, 1100, 150, DungeonMobAbility.BOW)); + mobs.add(mob("SUPER_TANK_ZOMBIE", "Super Tank Zombie", CatacombsFloor.FLOOR_FIVE, DungeonMobRole.STARRED, 60000, 900, 600, DungeonMobAbility.SHIELD)); + mobs.add(mob("FEL", "Fel", CatacombsFloor.FLOOR_FIVE, DungeonMobRole.NORMAL, 35000, 1300, 100, DungeonMobAbility.TELEPORT)); + mobs.add(mob("DEATHMITE", "Deathmite", CatacombsFloor.FLOOR_FIVE, DungeonMobRole.NORMAL, 10000000, 100000, 0, DungeonMobAbility.TRUE_DAMAGE)); + mobs.add(mob("WATCHER_UNDEAD", "Watcher Undead", CatacombsFloor.ENTRANCE, DungeonMobRole.BLOOD, 5000, 500, 0, DungeonMobAbility.SUMMON_UNDEAD)); + mobs.add(mob("BONZO", "Bonzo", CatacombsFloor.FLOOR_ONE, DungeonMobRole.BOSS, 350000, 1600, 0, DungeonMobAbility.EXPLOSION, DungeonMobAbility.REVIVE)); + mobs.add(mob("SCARF", "Scarf", CatacombsFloor.FLOOR_TWO, DungeonMobRole.BOSS, 1000000, 2500, 0, DungeonMobAbility.SUMMON_UNDEAD)); + mobs.add(mob("PROFESSOR", "The Professor", CatacombsFloor.FLOOR_THREE, DungeonMobRole.BOSS, 2500000, 3000, 0, DungeonMobAbility.SUMMON_UNDEAD)); + mobs.add(mob("THORN", "Thorn", CatacombsFloor.FLOOR_FOUR, DungeonMobRole.BOSS, 3000000, 3500, 0, DungeonMobAbility.SPIRIT_BOW_VULNERABILITY)); + mobs.add(mob("LIVID", "Livid", CatacombsFloor.FLOOR_FIVE, DungeonMobRole.BOSS, 7000000, 5000, 0, DungeonMobAbility.SPLIT_CLONES)); + mobs.add(mob("SADAN", "Sadan", CatacombsFloor.FLOOR_SIX, DungeonMobRole.BOSS, 40000000, 12000, 0, DungeonMobAbility.SUMMON_UNDEAD)); + mobs.add(mob("MAXOR", "Maxor", CatacombsFloor.FLOOR_SEVEN, DungeonMobRole.BOSS, 75000000, 15000, 0, DungeonMobAbility.WITHER_SKULL)); + mobs.add(mob("STORM", "Storm", CatacombsFloor.FLOOR_SEVEN, DungeonMobRole.BOSS, 75000000, 15000, 0, DungeonMobAbility.WITHER_SKULL)); + mobs.add(mob("GOLDOR", "Goldor", CatacombsFloor.FLOOR_SEVEN, DungeonMobRole.BOSS, 75000000, 15000, 0, DungeonMobAbility.TERMINAL_OBJECTIVE)); + mobs.add(mob("NECRON", "Necron", CatacombsFloor.FLOOR_SEVEN, DungeonMobRole.BOSS, 100000000, 20000, 0, DungeonMobAbility.WITHER_SKULL, DungeonMobAbility.CHARGE)); + mobs.add(mob("WITHER_KING", "Wither King", CatacombsFloor.FLOOR_SEVEN, DungeonMobRole.BOSS, 1000000000L, 50000, 0, DungeonMobAbility.WITHER_SKULL)); + return new DungeonMobRegistry(mobs.stream().collect(Collectors.toMap(DungeonMobDefinition::id, Function.identity()))); + } + + private static DungeonMobDefinition mob(String id, String displayName, CatacombsFloor minimumFloor, + DungeonMobRole role, long health, long damage, int defense, + DungeonMobAbility... abilities) { + return new DungeonMobDefinition(id, displayName, minimumFloor, role, health, damage, defense, Set.of(abilities)); + } +} diff --git a/dungeons/src/main/java/net/swofty/dungeons/catacombs/mob/DungeonMobRole.java b/dungeons/src/main/java/net/swofty/dungeons/catacombs/mob/DungeonMobRole.java new file mode 100644 index 000000000..09253e7c6 --- /dev/null +++ b/dungeons/src/main/java/net/swofty/dungeons/catacombs/mob/DungeonMobRole.java @@ -0,0 +1,12 @@ +package net.swofty.dungeons.catacombs.mob; + +public enum DungeonMobRole { + NORMAL, + STARRED, + MINIBOSS, + BLOOD, + PUZZLE, + BOSS, + BOSS_ADD, + SECRET +} diff --git a/dungeons/src/main/java/net/swofty/dungeons/catacombs/party/PartyFinderListing.java b/dungeons/src/main/java/net/swofty/dungeons/catacombs/party/PartyFinderListing.java new file mode 100644 index 000000000..71b63114d --- /dev/null +++ b/dungeons/src/main/java/net/swofty/dungeons/catacombs/party/PartyFinderListing.java @@ -0,0 +1,111 @@ +package net.swofty.dungeons.catacombs.party; + +import net.swofty.dungeons.catacombs.CatacombsFloor; +import net.swofty.dungeons.catacombs.CatacombsMode; +import net.swofty.dungeons.catacombs.classes.DungeonClassType; + +import java.util.EnumSet; +import java.util.LinkedHashMap; +import java.util.Map; +import java.util.Set; +import java.util.UUID; + +public final class PartyFinderListing { + private final UUID id; + private final UUID leaderId; + private final CatacombsFloor floor; + private final CatacombsMode mode; + private final int minimumCatacombsLevel; + private final Set allowedClasses; + private final Map members = new LinkedHashMap<>(); + private boolean open = true; + + public PartyFinderListing(UUID id, PartyFinderMember leader, CatacombsFloor floor, CatacombsMode mode, + int minimumCatacombsLevel, Set allowedClasses) { + this.id = id; + this.leaderId = leader.playerId(); + this.floor = floor; + this.mode = mode; + this.minimumCatacombsLevel = minimumCatacombsLevel; + this.allowedClasses = allowedClasses.isEmpty() + ? EnumSet.allOf(DungeonClassType.class) + : EnumSet.copyOf(allowedClasses); + members.put(leader.playerId(), leader); + } + + public UUID id() { + return id; + } + + public UUID leaderId() { + return leaderId; + } + + public CatacombsFloor floor() { + return floor; + } + + public CatacombsMode mode() { + return mode; + } + + public int minimumCatacombsLevel() { + return minimumCatacombsLevel; + } + + public boolean open() { + return open; + } + + public Map members() { + return Map.copyOf(members); + } + + public boolean full() { + return members.size() >= 5; + } + + public boolean ready() { + return members.size() >= 2 && members.values().stream().allMatch(PartyFinderMember::ready); + } + + public void join(PartyFinderMember member, int catacombsLevel) { + if (!open) { + throw new IllegalStateException("Party finder listing is closed"); + } + if (full()) { + throw new IllegalStateException("Party finder listing is full"); + } + if (catacombsLevel < minimumCatacombsLevel) { + throw new IllegalArgumentException("Catacombs level " + catacombsLevel + " is below " + minimumCatacombsLevel); + } + if (member.selectedClass() != null && !allowedClasses.contains(member.selectedClass())) { + throw new IllegalArgumentException(member.selectedClass() + " is not allowed in this listing"); + } + members.put(member.playerId(), member); + } + + public void updateClass(UUID playerId, DungeonClassType type) { + PartyFinderMember member = member(playerId); + if (!allowedClasses.contains(type)) { + throw new IllegalArgumentException(type + " is not allowed in this listing"); + } + members.put(playerId, member.withClass(type)); + } + + public void ready(UUID playerId, boolean ready) { + members.put(playerId, member(playerId).withReady(ready)); + } + + public void close() { + open = false; + } + + private PartyFinderMember member(UUID playerId) { + PartyFinderMember member = members.get(playerId); + if (member == null) { + throw new IllegalArgumentException("Player is not in this party finder listing"); + } + return member; + } +} diff --git a/dungeons/src/main/java/net/swofty/dungeons/catacombs/party/PartyFinderMember.java b/dungeons/src/main/java/net/swofty/dungeons/catacombs/party/PartyFinderMember.java new file mode 100644 index 000000000..4af7b765c --- /dev/null +++ b/dungeons/src/main/java/net/swofty/dungeons/catacombs/party/PartyFinderMember.java @@ -0,0 +1,21 @@ +package net.swofty.dungeons.catacombs.party; + +import net.swofty.dungeons.catacombs.classes.DungeonClassType; + +import java.util.UUID; + +public record PartyFinderMember( + UUID playerId, + String name, + PartyFinderRole role, + DungeonClassType selectedClass, + boolean ready +) { + public PartyFinderMember withClass(DungeonClassType selectedClass) { + return new PartyFinderMember(playerId, name, role, selectedClass, ready); + } + + public PartyFinderMember withReady(boolean ready) { + return new PartyFinderMember(playerId, name, role, selectedClass, ready); + } +} diff --git a/dungeons/src/main/java/net/swofty/dungeons/catacombs/party/PartyFinderRole.java b/dungeons/src/main/java/net/swofty/dungeons/catacombs/party/PartyFinderRole.java new file mode 100644 index 000000000..89faa8810 --- /dev/null +++ b/dungeons/src/main/java/net/swofty/dungeons/catacombs/party/PartyFinderRole.java @@ -0,0 +1,6 @@ +package net.swofty.dungeons.catacombs.party; + +public enum PartyFinderRole { + LEADER, + MEMBER +} diff --git a/dungeons/src/main/java/net/swofty/dungeons/catacombs/party/PartyFinderService.java b/dungeons/src/main/java/net/swofty/dungeons/catacombs/party/PartyFinderService.java new file mode 100644 index 000000000..69d80fdb4 --- /dev/null +++ b/dungeons/src/main/java/net/swofty/dungeons/catacombs/party/PartyFinderService.java @@ -0,0 +1,35 @@ +package net.swofty.dungeons.catacombs.party; + +import net.swofty.dungeons.catacombs.CatacombsFloorDefinition; +import net.swofty.dungeons.catacombs.classes.DungeonClassType; + +import java.util.HashMap; +import java.util.Map; +import java.util.Set; +import java.util.UUID; + +public final class PartyFinderService { + private final Map listings = new HashMap<>(); + + public PartyFinderListing create(PartyFinderMember leader, CatacombsFloorDefinition floor, + int minimumCatacombsLevel, Set allowedClasses) { + PartyFinderListing listing = new PartyFinderListing(UUID.randomUUID(), leader, floor.floor(), floor.mode(), + minimumCatacombsLevel, allowedClasses); + listings.put(listing.id(), listing); + return listing; + } + + public PartyFinderListing listing(UUID id) { + PartyFinderListing listing = listings.get(id); + if (listing == null) { + throw new IllegalArgumentException("Unknown party finder listing " + id); + } + return listing; + } + + public Map openListings() { + return Map.copyOf(listings.entrySet().stream() + .filter(entry -> entry.getValue().open()) + .collect(HashMap::new, (map, entry) -> map.put(entry.getKey(), entry.getValue()), HashMap::putAll)); + } +} diff --git a/dungeons/src/main/java/net/swofty/dungeons/catacombs/puzzle/CatacombsPuzzleFactory.java b/dungeons/src/main/java/net/swofty/dungeons/catacombs/puzzle/CatacombsPuzzleFactory.java new file mode 100644 index 000000000..beea3771a --- /dev/null +++ b/dungeons/src/main/java/net/swofty/dungeons/catacombs/puzzle/CatacombsPuzzleFactory.java @@ -0,0 +1,25 @@ +package net.swofty.dungeons.catacombs.puzzle; + +import lombok.AccessLevel; +import lombok.NoArgsConstructor; + +import java.util.List; + +@NoArgsConstructor(access = AccessLevel.PRIVATE) +public final class CatacombsPuzzleFactory { + public static PuzzleController create(CatacombsPuzzle puzzle) { + return switch (puzzle) { + case CREEPER_BEAMS -> new ObjectivePuzzleController(puzzle, "beam", 4); + case WATER_BOARD -> new ObjectivePuzzleController(puzzle, "gate", 5); + case TELEPORT_MAZE -> new ObjectivePuzzleController(puzzle, "finish", 1); + case ICE_FILL -> new ObjectivePuzzleController(puzzle, "layer", 3); + case ICE_PATH -> new ObjectivePuzzleController(puzzle, "detonate", 1); + case THREE_WEIRDOS -> new OrderedPuzzleController(puzzle, List.of("correct_chest")); + case TIC_TAC_TOE -> new OrderedPuzzleController(puzzle, List.of("tie")); + case HIGHER_OR_LOWER -> new OrderedPuzzleController(puzzle, + List.of("1", "2", "3", "4", "5", "6", "7", "8", "9", "10")); + case BOULDER -> new ObjectivePuzzleController(puzzle, "path_open", 1); + case QUIZ -> new OrderedPuzzleController(puzzle, List.of("question_1", "question_2", "question_3")); + }; + } +} diff --git a/dungeons/src/main/java/net/swofty/dungeons/catacombs/puzzle/ObjectivePuzzleController.java b/dungeons/src/main/java/net/swofty/dungeons/catacombs/puzzle/ObjectivePuzzleController.java new file mode 100644 index 000000000..cb73be93b --- /dev/null +++ b/dungeons/src/main/java/net/swofty/dungeons/catacombs/puzzle/ObjectivePuzzleController.java @@ -0,0 +1,62 @@ +package net.swofty.dungeons.catacombs.puzzle; + +import java.util.ArrayList; +import java.util.List; + +public final class ObjectivePuzzleController implements PuzzleController { + private final CatacombsPuzzle puzzle; + private final String objectiveType; + private final int requiredProgress; + private final List traces = new ArrayList<>(); + private PuzzleState state = PuzzleState.READY; + private int progress; + + public ObjectivePuzzleController(CatacombsPuzzle puzzle, String objectiveType, int requiredProgress) { + this.puzzle = puzzle; + this.objectiveType = objectiveType; + this.requiredProgress = requiredProgress; + } + + @Override + public CatacombsPuzzle puzzle() { + return puzzle; + } + + @Override + public PuzzleState state() { + return state; + } + + @Override + public List traces() { + return List.copyOf(traces); + } + + @Override + public void accept(PuzzleAction action) { + if (state == PuzzleState.SOLVED || state == PuzzleState.FAILED) { + return; + } + state = PuzzleState.ACTIVE; + if ("fail".equals(action.type()) && puzzle.failable()) { + state = PuzzleState.FAILED; + traces.add(PuzzleTrace.of(state, action.value())); + return; + } + if (objectiveType.equals(action.type())) { + progress++; + traces.add(PuzzleTrace.of(state, action.type() + "=" + progress)); + if (progress >= requiredProgress) { + state = PuzzleState.SOLVED; + traces.add(PuzzleTrace.of(state, puzzle.displayName())); + } + } + } + + @Override + public void reset() { + progress = 0; + state = PuzzleState.RESET; + traces.add(PuzzleTrace.of(state, "Architect's First Draft")); + } +} diff --git a/dungeons/src/main/java/net/swofty/dungeons/catacombs/puzzle/OrderedPuzzleController.java b/dungeons/src/main/java/net/swofty/dungeons/catacombs/puzzle/OrderedPuzzleController.java new file mode 100644 index 000000000..8f940ceb2 --- /dev/null +++ b/dungeons/src/main/java/net/swofty/dungeons/catacombs/puzzle/OrderedPuzzleController.java @@ -0,0 +1,60 @@ +package net.swofty.dungeons.catacombs.puzzle; + +import java.util.ArrayList; +import java.util.List; + +public final class OrderedPuzzleController implements PuzzleController { + private final CatacombsPuzzle puzzle; + private final List expected; + private final List traces = new ArrayList<>(); + private PuzzleState state = PuzzleState.READY; + private int index; + + public OrderedPuzzleController(CatacombsPuzzle puzzle, List expected) { + this.puzzle = puzzle; + this.expected = List.copyOf(expected); + } + + @Override + public CatacombsPuzzle puzzle() { + return puzzle; + } + + @Override + public PuzzleState state() { + return state; + } + + @Override + public List traces() { + return List.copyOf(traces); + } + + @Override + public void accept(PuzzleAction action) { + if (state == PuzzleState.SOLVED || state == PuzzleState.FAILED) { + return; + } + state = PuzzleState.ACTIVE; + if (!"select".equals(action.type()) || index >= expected.size() || !expected.get(index).equals(action.value())) { + if (puzzle.failable()) { + state = PuzzleState.FAILED; + traces.add(PuzzleTrace.of(state, action.value())); + } + return; + } + index++; + traces.add(PuzzleTrace.of(state, action.value())); + if (index >= expected.size()) { + state = PuzzleState.SOLVED; + traces.add(PuzzleTrace.of(state, puzzle.displayName())); + } + } + + @Override + public void reset() { + index = 0; + state = PuzzleState.RESET; + traces.add(PuzzleTrace.of(state, "Architect's First Draft")); + } +} diff --git a/dungeons/src/main/java/net/swofty/dungeons/catacombs/puzzle/PuzzleAction.java b/dungeons/src/main/java/net/swofty/dungeons/catacombs/puzzle/PuzzleAction.java new file mode 100644 index 000000000..1eb6ba1bb --- /dev/null +++ b/dungeons/src/main/java/net/swofty/dungeons/catacombs/puzzle/PuzzleAction.java @@ -0,0 +1,7 @@ +package net.swofty.dungeons.catacombs.puzzle; + +public record PuzzleAction(String type, String value) { + public static PuzzleAction of(String type, String value) { + return new PuzzleAction(type, value); + } +} diff --git a/dungeons/src/main/java/net/swofty/dungeons/catacombs/puzzle/PuzzleController.java b/dungeons/src/main/java/net/swofty/dungeons/catacombs/puzzle/PuzzleController.java new file mode 100644 index 000000000..b7d0967e9 --- /dev/null +++ b/dungeons/src/main/java/net/swofty/dungeons/catacombs/puzzle/PuzzleController.java @@ -0,0 +1,15 @@ +package net.swofty.dungeons.catacombs.puzzle; + +import java.util.List; + +public interface PuzzleController { + CatacombsPuzzle puzzle(); + + PuzzleState state(); + + List traces(); + + void accept(PuzzleAction action); + + void reset(); +} diff --git a/dungeons/src/main/java/net/swofty/dungeons/catacombs/puzzle/PuzzleState.java b/dungeons/src/main/java/net/swofty/dungeons/catacombs/puzzle/PuzzleState.java new file mode 100644 index 000000000..2646dd8e2 --- /dev/null +++ b/dungeons/src/main/java/net/swofty/dungeons/catacombs/puzzle/PuzzleState.java @@ -0,0 +1,9 @@ +package net.swofty.dungeons.catacombs.puzzle; + +public enum PuzzleState { + READY, + ACTIVE, + SOLVED, + FAILED, + RESET +} diff --git a/dungeons/src/main/java/net/swofty/dungeons/catacombs/puzzle/PuzzleTrace.java b/dungeons/src/main/java/net/swofty/dungeons/catacombs/puzzle/PuzzleTrace.java new file mode 100644 index 000000000..e68f0b7c6 --- /dev/null +++ b/dungeons/src/main/java/net/swofty/dungeons/catacombs/puzzle/PuzzleTrace.java @@ -0,0 +1,9 @@ +package net.swofty.dungeons.catacombs.puzzle; + +import java.time.Instant; + +public record PuzzleTrace(PuzzleState state, Instant happenedAt, String detail) { + public static PuzzleTrace of(PuzzleState state, String detail) { + return new PuzzleTrace(state, Instant.now(), detail); + } +}