diff --git a/api/src/main/java/net/momirealms/customfishing/api/BukkitCustomFishingPlugin.java b/api/src/main/java/net/momirealms/customfishing/api/BukkitCustomFishingPlugin.java index abc141c5..30101fc6 100644 --- a/api/src/main/java/net/momirealms/customfishing/api/BukkitCustomFishingPlugin.java +++ b/api/src/main/java/net/momirealms/customfishing/api/BukkitCustomFishingPlugin.java @@ -35,10 +35,12 @@ import net.momirealms.customfishing.api.mechanic.misc.placeholder.PlaceholderMan import net.momirealms.customfishing.api.mechanic.requirement.RequirementManager; import net.momirealms.customfishing.api.mechanic.statistic.StatisticsManager; import net.momirealms.customfishing.api.storage.StorageManager; +import net.momirealms.customfishing.common.dependency.DependencyManager; +import net.momirealms.customfishing.common.locale.TranslationManager; import net.momirealms.customfishing.common.plugin.CustomFishingPlugin; +import net.momirealms.customfishing.common.plugin.feature.Reloadable; import net.momirealms.customfishing.common.plugin.scheduler.AbstractJavaScheduler; import net.momirealms.customfishing.common.sender.SenderFactory; -import org.bukkit.Bukkit; import org.bukkit.Location; import org.bukkit.command.CommandSender; import org.bukkit.entity.Player; @@ -46,12 +48,10 @@ import org.bukkit.plugin.Plugin; import java.io.File; -import static java.util.Objects.requireNonNull; - -public abstract class BukkitCustomFishingPlugin implements CustomFishingPlugin { +public abstract class BukkitCustomFishingPlugin implements CustomFishingPlugin, Reloadable { private static BukkitCustomFishingPlugin instance; - private final Plugin boostrap = requireNonNull(Bukkit.getPluginManager().getPlugin("CustomFishing")); + private final Plugin boostrap; protected EventManager eventManager; protected ConfigManager configManager; @@ -73,13 +73,20 @@ public abstract class BukkitCustomFishingPlugin implements CustomFishingPlugin { protected EffectManager effectManager; protected HookManager hookManager; protected BagManager bagManager; + protected DependencyManager dependencyManager; + protected TranslationManager translationManager; + protected boolean initialized = false; - public BukkitCustomFishingPlugin() { + public BukkitCustomFishingPlugin(Plugin boostrap) { + if (!boostrap.getName().equals("CustomFishing")) { + throw new IllegalArgumentException("CustomFishing plugin requires custom fishing plugin"); + } + this.boostrap = boostrap; instance = this; } public static BukkitCustomFishingPlugin getInstance() { - if (instance == null) { + if (instance == null || !instance.initialized) { throw new IllegalArgumentException("Plugin not initialized"); } return instance; @@ -175,7 +182,15 @@ public abstract class BukkitCustomFishingPlugin implements CustomFishingPlugin { return boostrap; } - public void reload() { - + @Override + public DependencyManager getDependencyManager() { + return dependencyManager; } + + @Override + public TranslationManager getTranslationManager() { + return translationManager; + } + + public abstract void enable(); } diff --git a/api/src/main/java/net/momirealms/customfishing/api/event/RodCastEvent.java b/api/src/main/java/net/momirealms/customfishing/api/event/RodCastEvent.java index 7d496973..a5d7cc8d 100644 --- a/api/src/main/java/net/momirealms/customfishing/api/event/RodCastEvent.java +++ b/api/src/main/java/net/momirealms/customfishing/api/event/RodCastEvent.java @@ -17,8 +17,8 @@ package net.momirealms.customfishing.api.event; -import net.momirealms.customfishing.api.mechanic.condition.FishingPreparation; import net.momirealms.customfishing.api.mechanic.effect.Effect; +import net.momirealms.customfishing.api.mechanic.fishing.FishingPreparation; import org.bukkit.event.Cancellable; import org.bukkit.event.HandlerList; import org.bukkit.event.player.PlayerEvent; diff --git a/api/src/main/java/net/momirealms/customfishing/api/integration/IntegrationManager.java b/api/src/main/java/net/momirealms/customfishing/api/integration/IntegrationManager.java index fa1ec030..6468d47b 100644 --- a/api/src/main/java/net/momirealms/customfishing/api/integration/IntegrationManager.java +++ b/api/src/main/java/net/momirealms/customfishing/api/integration/IntegrationManager.java @@ -17,6 +17,7 @@ package net.momirealms.customfishing.api.integration; +import net.momirealms.customfishing.common.plugin.feature.Reloadable; import net.momirealms.customfishing.common.util.Pair; import org.bukkit.inventory.ItemStack; import org.jetbrains.annotations.NotNull; @@ -29,7 +30,7 @@ import java.util.List; * This allows for the registration and retrieval of various types of providers * such as Leveler, Enchantment, and Season providers. */ -public interface IntegrationManager { +public interface IntegrationManager extends Reloadable { /** * Registers a LevelerProvider. diff --git a/api/src/main/java/net/momirealms/customfishing/api/mechanic/action/ActionManager.java b/api/src/main/java/net/momirealms/customfishing/api/mechanic/action/ActionManager.java index ce72e41a..140df1c1 100644 --- a/api/src/main/java/net/momirealms/customfishing/api/mechanic/action/ActionManager.java +++ b/api/src/main/java/net/momirealms/customfishing/api/mechanic/action/ActionManager.java @@ -19,6 +19,7 @@ package net.momirealms.customfishing.api.mechanic.action; import dev.dejvokep.boostedyaml.block.implementation.Section; import net.momirealms.customfishing.api.mechanic.context.Context; +import net.momirealms.customfishing.common.plugin.feature.Reloadable; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; @@ -29,7 +30,7 @@ import java.util.*; * * @param the type of the context in which the actions are triggered. */ -public interface ActionManager { +public interface ActionManager extends Reloadable { /** * Registers a custom action type with its corresponding factory. diff --git a/api/src/main/java/net/momirealms/customfishing/api/mechanic/competition/CompetitionGoal.java b/api/src/main/java/net/momirealms/customfishing/api/mechanic/competition/CompetitionGoal.java index 8f24fc16..2938292d 100644 --- a/api/src/main/java/net/momirealms/customfishing/api/mechanic/competition/CompetitionGoal.java +++ b/api/src/main/java/net/momirealms/customfishing/api/mechanic/competition/CompetitionGoal.java @@ -18,7 +18,9 @@ package net.momirealms.customfishing.api.mechanic.competition; import net.kyori.adventure.util.Index; +import net.momirealms.customfishing.common.locale.StandardLocales; import net.momirealms.customfishing.common.util.RandomUtils; +import org.apache.logging.log4j.util.Supplier; import org.apache.logging.log4j.util.TriConsumer; import org.bukkit.entity.Player; @@ -26,11 +28,13 @@ public final class CompetitionGoal { public static final CompetitionGoal CATCH_AMOUNT = new CompetitionGoal( "catch_amount", - ((rankingProvider, player, score) -> rankingProvider.refreshData(player, 1)) + ((rankingProvider, player, score) -> rankingProvider.refreshData(player, 1)), + () -> StandardLocales.GOAL_CATCH_AMOUNT ); public static final CompetitionGoal TOTAL_SCORE = new CompetitionGoal( "total_score", - (RankingProvider::refreshData) + (RankingProvider::refreshData), + () -> StandardLocales.GOAL_TOTAL_SCORE ); public static final CompetitionGoal MAX_SIZE = new CompetitionGoal( "max_size", @@ -38,15 +42,18 @@ public final class CompetitionGoal { if (rankingProvider.getPlayerScore(player) < score) { rankingProvider.setData(player, score); } - }) + }), + () -> StandardLocales.GOAL_MAX_SIZE ); public static final CompetitionGoal TOTAL_SIZE = new CompetitionGoal( "total_size", - (RankingProvider::refreshData) + (RankingProvider::refreshData), + () -> StandardLocales.GOAL_TOTAL_SIZE ); public static final CompetitionGoal RANDOM = new CompetitionGoal( "random", - (rankingProvider, player, score) -> {} + (rankingProvider, player, score) -> {}, + () -> "random" ); private static final CompetitionGoal[] values = new CompetitionGoal[] { @@ -84,10 +91,12 @@ public final class CompetitionGoal { private final String key; private final TriConsumer scoreConsumer; + private final Supplier nameSupplier; - private CompetitionGoal(String key, TriConsumer scoreConsumer) { + private CompetitionGoal(String key, TriConsumer scoreConsumer, Supplier nameSupplier) { this.key = key; this.scoreConsumer = scoreConsumer; + this.nameSupplier = nameSupplier; } /** @@ -105,6 +114,6 @@ public final class CompetitionGoal { @Override public String toString() { - return super.toString(); + return nameSupplier.get(); } } diff --git a/api/src/main/java/net/momirealms/customfishing/api/mechanic/competition/CompetitionManager.java b/api/src/main/java/net/momirealms/customfishing/api/mechanic/competition/CompetitionManager.java index 23705891..ba735dcd 100644 --- a/api/src/main/java/net/momirealms/customfishing/api/mechanic/competition/CompetitionManager.java +++ b/api/src/main/java/net/momirealms/customfishing/api/mechanic/competition/CompetitionManager.java @@ -17,9 +17,10 @@ package net.momirealms.customfishing.api.mechanic.competition; +import net.momirealms.customfishing.common.plugin.feature.Reloadable; import org.jetbrains.annotations.Nullable; -public interface CompetitionManager { +public interface CompetitionManager extends Reloadable { boolean startCompetition(String competition, boolean force, @Nullable String serverGroup); diff --git a/api/src/main/java/net/momirealms/customfishing/api/mechanic/config/ConfigManager.java b/api/src/main/java/net/momirealms/customfishing/api/mechanic/config/ConfigManager.java index 74872e6d..23dac5c2 100644 --- a/api/src/main/java/net/momirealms/customfishing/api/mechanic/config/ConfigManager.java +++ b/api/src/main/java/net/momirealms/customfishing/api/mechanic/config/ConfigManager.java @@ -89,6 +89,15 @@ public abstract class ConfigManager implements ConfigLoader, Reloadable { } public static String bagTitle() { + return null; + } + + public static boolean metrics() { + return true; + } + + public static boolean checkUpdate() { + return true; } public void registerLootParser(Function> function, String... nodes) { diff --git a/api/src/main/java/net/momirealms/customfishing/api/mechanic/entity/EntityConfig.java b/api/src/main/java/net/momirealms/customfishing/api/mechanic/entity/EntityConfig.java index a3ae8da9..0afc2328 100644 --- a/api/src/main/java/net/momirealms/customfishing/api/mechanic/entity/EntityConfig.java +++ b/api/src/main/java/net/momirealms/customfishing/api/mechanic/entity/EntityConfig.java @@ -42,14 +42,14 @@ public interface EntityConfig { * * @return the horizontal vector value as a double */ - MathValue getHorizontalVector(); + MathValue horizontalVector(); /** * Retrieves the vertical vector value for the entity. * * @return the vertical vector value as a double */ - MathValue getVerticalVector(); + MathValue verticalVector(); /** * Retrieves the unique identifier for the entity. @@ -57,7 +57,7 @@ public interface EntityConfig { * @return the entity ID as a non-null String */ @NotNull - String getEntityID(); + String entityID(); /** * Retrieves a map of properties associated with the entity. @@ -65,7 +65,7 @@ public interface EntityConfig { * @return a non-null map where keys are property names and values are property values */ @NotNull - Map getPropertyMap(); + Map propertyMap(); /** * Creates a new Builder instance for constructing an EntityConfig. diff --git a/api/src/main/java/net/momirealms/customfishing/api/mechanic/entity/EntityConfigImpl.java b/api/src/main/java/net/momirealms/customfishing/api/mechanic/entity/EntityConfigImpl.java index 5a89aa54..d327c601 100644 --- a/api/src/main/java/net/momirealms/customfishing/api/mechanic/entity/EntityConfigImpl.java +++ b/api/src/main/java/net/momirealms/customfishing/api/mechanic/entity/EntityConfigImpl.java @@ -45,24 +45,24 @@ public class EntityConfigImpl implements EntityConfig { } @Override - public MathValue getHorizontalVector() { + public MathValue horizontalVector() { return horizontalVector; } @Override - public MathValue getVerticalVector() { + public MathValue verticalVector() { return verticalVector; } @NotNull @Override - public String getEntityID() { + public String entityID() { return entityID; } @NotNull @Override - public Map getPropertyMap() { + public Map propertyMap() { return propertyMap; } diff --git a/api/src/main/java/net/momirealms/customfishing/api/mechanic/fishing/FishingPreparation.java b/api/src/main/java/net/momirealms/customfishing/api/mechanic/fishing/FishingPreparation.java new file mode 100644 index 00000000..4a13e565 --- /dev/null +++ b/api/src/main/java/net/momirealms/customfishing/api/mechanic/fishing/FishingPreparation.java @@ -0,0 +1,4 @@ +package net.momirealms.customfishing.api.mechanic.fishing; + +public class FishingPreparation { +} diff --git a/api/src/main/java/net/momirealms/customfishing/api/mechanic/game/AbstractGamingPlayer.java b/api/src/main/java/net/momirealms/customfishing/api/mechanic/game/AbstractGamingPlayer.java index fdf35b43..46e94f02 100644 --- a/api/src/main/java/net/momirealms/customfishing/api/mechanic/game/AbstractGamingPlayer.java +++ b/api/src/main/java/net/momirealms/customfishing/api/mechanic/game/AbstractGamingPlayer.java @@ -30,7 +30,7 @@ import java.util.concurrent.TimeUnit; public abstract class AbstractGamingPlayer implements GamingPlayer, Runnable { - private final FishingManager manager; +// private final FishingManager manager; protected long deadline; protected boolean success; protected SchedulerTask task; @@ -43,7 +43,7 @@ public abstract class AbstractGamingPlayer implements GamingPlayer, Runnable { this.player = player; this.fishHook = hook; this.settings = settings; - this.manager = BukkitCustomFishingPlugin.getFishingManager(); +// this.manager = BukkitCustomFishingPlugin.getInstance().get(); this.deadline = (long) (System.currentTimeMillis() + settings.time() * 1000L); this.arrangeTask(); } @@ -119,7 +119,7 @@ public abstract class AbstractGamingPlayer implements GamingPlayer, Runnable { } protected void endGame() { - this.manager.processGameResult(this); +// this.manager.processGameResult(this); } protected void setGameResult(boolean success) { diff --git a/api/src/main/java/net/momirealms/customfishing/api/mechanic/hook/HookManager.java b/api/src/main/java/net/momirealms/customfishing/api/mechanic/hook/HookManager.java index 6d0450cd..07330045 100644 --- a/api/src/main/java/net/momirealms/customfishing/api/mechanic/hook/HookManager.java +++ b/api/src/main/java/net/momirealms/customfishing/api/mechanic/hook/HookManager.java @@ -17,11 +17,12 @@ package net.momirealms.customfishing.api.mechanic.hook; +import net.momirealms.customfishing.common.plugin.feature.Reloadable; import org.jetbrains.annotations.NotNull; import java.util.Optional; -public interface HookManager { +public interface HookManager extends Reloadable { boolean registerHook(HookConfig hook); diff --git a/api/src/main/java/net/momirealms/customfishing/api/mechanic/loot/LootManager.java b/api/src/main/java/net/momirealms/customfishing/api/mechanic/loot/LootManager.java index d669dcd2..e6215095 100644 --- a/api/src/main/java/net/momirealms/customfishing/api/mechanic/loot/LootManager.java +++ b/api/src/main/java/net/momirealms/customfishing/api/mechanic/loot/LootManager.java @@ -19,6 +19,7 @@ package net.momirealms.customfishing.api.mechanic.loot; import net.momirealms.customfishing.api.mechanic.context.Context; import net.momirealms.customfishing.api.mechanic.effect.Effect; +import net.momirealms.customfishing.common.plugin.feature.Reloadable; import org.bukkit.entity.Player; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; @@ -27,7 +28,7 @@ import java.util.List; import java.util.Map; import java.util.Optional; -public interface LootManager { +public interface LootManager extends Reloadable { void registerLoot(@NotNull Loot loot); diff --git a/api/src/main/java/net/momirealms/customfishing/api/mechanic/misc/cooldown/CoolDownManager.java b/api/src/main/java/net/momirealms/customfishing/api/mechanic/misc/cooldown/CoolDownManager.java index 9c10de5d..024ab4e7 100644 --- a/api/src/main/java/net/momirealms/customfishing/api/mechanic/misc/cooldown/CoolDownManager.java +++ b/api/src/main/java/net/momirealms/customfishing/api/mechanic/misc/cooldown/CoolDownManager.java @@ -18,6 +18,7 @@ package net.momirealms.customfishing.api.mechanic.misc.cooldown; import net.momirealms.customfishing.api.BukkitCustomFishingPlugin; +import net.momirealms.customfishing.common.plugin.feature.Reloadable; import org.bukkit.Bukkit; import org.bukkit.event.EventHandler; import org.bukkit.event.HandlerList; @@ -34,7 +35,7 @@ import java.util.concurrent.ConcurrentHashMap; * Manages cooldowns for various actions or events. * Keeps track of cooldown times for different keys associated with player UUIDs. */ -public class CoolDownManager implements Listener { +public class CoolDownManager implements Listener, Reloadable { private final ConcurrentHashMap dataMap; private final BukkitCustomFishingPlugin plugin; @@ -57,14 +58,17 @@ public class CoolDownManager implements Listener { return data.isCoolDown(key, time); } + @Override public void load() { Bukkit.getPluginManager().registerEvents(this, plugin.getBoostrap()); } + @Override public void unload() { HandlerList.unregisterAll(this); } + @Override public void disable() { unload(); this.dataMap.clear(); diff --git a/api/src/main/java/net/momirealms/customfishing/api/mechanic/misc/placeholder/BukkitPlaceholderManager.java b/api/src/main/java/net/momirealms/customfishing/api/mechanic/misc/placeholder/BukkitPlaceholderManager.java index bcbcb63c..66043318 100644 --- a/api/src/main/java/net/momirealms/customfishing/api/mechanic/misc/placeholder/BukkitPlaceholderManager.java +++ b/api/src/main/java/net/momirealms/customfishing/api/mechanic/misc/placeholder/BukkitPlaceholderManager.java @@ -32,17 +32,21 @@ import java.util.stream.Collectors; public class BukkitPlaceholderManager implements PlaceholderManager { private final BukkitCustomFishingPlugin plugin; - private final boolean hasPapi; + private boolean hasPapi; private final HashMap customPlaceholderMap; private static BukkitPlaceholderManager instance; public BukkitPlaceholderManager(BukkitCustomFishingPlugin plugin) { this.plugin = plugin; - this.hasPapi = Bukkit.getPluginManager().isPluginEnabled("PlaceholderAPI"); this.customPlaceholderMap = new HashMap<>(); instance = this; } + @Override + public void reload() { + this.hasPapi = Bukkit.getPluginManager().isPluginEnabled("PlaceholderAPI"); + } + public static BukkitPlaceholderManager getInstance() { return instance; } diff --git a/api/src/main/java/net/momirealms/customfishing/api/mechanic/misc/placeholder/PlaceholderManager.java b/api/src/main/java/net/momirealms/customfishing/api/mechanic/misc/placeholder/PlaceholderManager.java index cb834a50..94cda0bd 100644 --- a/api/src/main/java/net/momirealms/customfishing/api/mechanic/misc/placeholder/PlaceholderManager.java +++ b/api/src/main/java/net/momirealms/customfishing/api/mechanic/misc/placeholder/PlaceholderManager.java @@ -17,6 +17,7 @@ package net.momirealms.customfishing.api.mechanic.misc.placeholder; +import net.momirealms.customfishing.common.plugin.feature.Reloadable; import org.bukkit.OfflinePlayer; import org.jetbrains.annotations.Nullable; @@ -24,7 +25,7 @@ import java.util.List; import java.util.Map; import java.util.regex.Pattern; -public interface PlaceholderManager { +public interface PlaceholderManager extends Reloadable { Pattern PATTERN = Pattern.compile("\\{[^{}]+}"); diff --git a/api/src/main/java/net/momirealms/customfishing/api/mechanic/requirement/RequirementManager.java b/api/src/main/java/net/momirealms/customfishing/api/mechanic/requirement/RequirementManager.java index fbfcf2d7..0fd1ded8 100644 --- a/api/src/main/java/net/momirealms/customfishing/api/mechanic/requirement/RequirementManager.java +++ b/api/src/main/java/net/momirealms/customfishing/api/mechanic/requirement/RequirementManager.java @@ -19,6 +19,7 @@ package net.momirealms.customfishing.api.mechanic.requirement; import dev.dejvokep.boostedyaml.block.implementation.Section; import net.momirealms.customfishing.api.mechanic.context.Context; +import net.momirealms.customfishing.common.plugin.feature.Reloadable; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; @@ -29,7 +30,7 @@ import java.util.List; * * @param the type of the context in which the requirements are evaluated. */ -public interface RequirementManager { +public interface RequirementManager extends Reloadable { /** * Registers a custom requirement type with its corresponding factory. diff --git a/api/src/main/java/net/momirealms/customfishing/api/mechanic/totem/TotemConfig.java b/api/src/main/java/net/momirealms/customfishing/api/mechanic/totem/TotemConfig.java new file mode 100644 index 00000000..e24d34ac --- /dev/null +++ b/api/src/main/java/net/momirealms/customfishing/api/mechanic/totem/TotemConfig.java @@ -0,0 +1,33 @@ +package net.momirealms.customfishing.api.mechanic.totem; + +import net.momirealms.customfishing.api.mechanic.requirement.Requirement; +import net.momirealms.customfishing.api.mechanic.totem.block.TotemBlock; +import org.bukkit.Location; +import org.bukkit.entity.Player; + +public interface TotemConfig +{ + TotemModel[] totemModels(); + + Requirement[] activateRequirements(); + + String id(); + + boolean isRightPattern(Location location); + + TotemParticle[] particleSettings(); + + double radius(); + + int duration(); + + TotemBlock[] totemCore(); + + static Builder builder() { + return new TotemConfigImpl.BuilderImpl(); + } + + interface Builder { + + } +} diff --git a/api/src/main/java/net/momirealms/customfishing/api/mechanic/totem/TotemConfigImpl.java b/api/src/main/java/net/momirealms/customfishing/api/mechanic/totem/TotemConfigImpl.java new file mode 100644 index 00000000..af82dcee --- /dev/null +++ b/api/src/main/java/net/momirealms/customfishing/api/mechanic/totem/TotemConfigImpl.java @@ -0,0 +1,125 @@ +/* + * Copyright (C) <2022> + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +package net.momirealms.customfishing.api.mechanic.totem; + +import net.momirealms.customfishing.api.mechanic.requirement.Requirement; +import net.momirealms.customfishing.api.mechanic.totem.block.TotemBlock; +import org.bukkit.Location; +import org.bukkit.entity.Player; + +import static java.util.Objects.requireNonNull; + +public class TotemConfigImpl implements TotemConfig { + + private String id; + private TotemModel[] totemModels; + private TotemParticle[] particleSettings; + private Requirement[] activateRequirements; + private double radius; + private int duration; + + public TotemConfigImpl(String id, TotemModel[] totemModels, TotemParticle[] particleSettings, Requirement[] activateRequirements, double radius, int duration) { + this.id = id; + this.totemModels = totemModels; + this.particleSettings = particleSettings; + this.activateRequirements = activateRequirements; + this.radius = radius; + this.duration = duration; + } + + @Override + public TotemModel[] totemModels() { + return totemModels; + } + + @Override + public Requirement[] activateRequirements() { + return activateRequirements; + } + + @Override + public String id() { + return id; + } + + @Override + public boolean isRightPattern(Location location) { + for (TotemModel totemModel : totemModels) { + if (totemModel.isPatternSatisfied(location)) { + return true; + } + } + return false; + } + + @Override + public TotemParticle[] particleSettings() { + return particleSettings; + } + + @Override + public double radius() { + return radius; + } + + @Override + public int duration() { + return duration; + } + + @Override + public TotemBlock[] totemCore() { + return totemModels[0].getTotemCore(); + } + + public static class BuilderImpl implements Builder { + private String id; + private TotemModel[] totemModels; + private TotemParticle[] particleSettings; + private Requirement[] activateRequirements; + private double radius; + private int duration; + public Builder id(String id) { + this.id = id; + return this; + } + public Builder totemModels(TotemModel[] totemModels) { + this.totemModels = totemModels; + return this; + } + public Builder particleSettings(TotemParticle[] particleSettings) { + this.particleSettings = particleSettings; + return this; + } + public Builder radius(double radius) { + this.radius = radius; + return this; + } + public Builder duration(int duration) { + this.duration = duration; + return this; + } + public Builder activateRequirements(Requirement[] activateRequirements) { + this.activateRequirements = activateRequirements; + return this; + } + public TotemConfig build() { + return new TotemConfigImpl(requireNonNull(id), requireNonNull(totemModels), particleSettings, activateRequirements, radius, duration); + } + } +} diff --git a/api/src/main/java/net/momirealms/customfishing/api/mechanic/totem/TotemManager.java b/api/src/main/java/net/momirealms/customfishing/api/mechanic/totem/TotemManager.java new file mode 100644 index 00000000..9116fc49 --- /dev/null +++ b/api/src/main/java/net/momirealms/customfishing/api/mechanic/totem/TotemManager.java @@ -0,0 +1,6 @@ +package net.momirealms.customfishing.api.mechanic.totem; + +import net.momirealms.customfishing.common.plugin.feature.Reloadable; + +public interface TotemManager extends Reloadable { +} diff --git a/api/src/main/java/net/momirealms/customfishing/api/mechanic/totem/TotemModel.java b/api/src/main/java/net/momirealms/customfishing/api/mechanic/totem/TotemModel.java new file mode 100644 index 00000000..c52c6c02 --- /dev/null +++ b/api/src/main/java/net/momirealms/customfishing/api/mechanic/totem/TotemModel.java @@ -0,0 +1,277 @@ +/* + * Copyright (C) <2022> + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +package net.momirealms.customfishing.api.mechanic.totem; + +import net.momirealms.customfishing.api.mechanic.totem.block.TotemBlock; +import org.apache.commons.lang3.SerializationUtils; +import org.bukkit.Axis; +import org.bukkit.Location; + +import java.io.Serializable; +import java.util.StringJoiner; + +/** + * This class represents a totem model used to define the pattern of a totem. + */ +public class TotemModel implements Serializable { + + private int coreX; + private final int coreY; + private int coreZ; + // [Y][Z][X][alternative totem blocks] + private TotemBlock[][][][] model; + + /** + * Constructs a TotemModel with the specified parameters. + * + * @param coreX X-coordinate of the totem's core within the model. + * @param coreY Y-coordinate of the totem's core within the model. + * @param coreZ Z-coordinate of the totem's core within the model. + * @param model 3D array representing the totem model's structure. + */ + public TotemModel(int coreX, int coreY, int coreZ, TotemBlock[][][][] model) { + this.coreX = coreX; + this.coreY = coreY; + this.coreZ = coreZ; + this.model = model; + } + + /** + * Get the totem core as an array of TotemBlock objects. + * + * @return An array of TotemBlock objects representing the totem's core. + */ + public TotemBlock[] getTotemCore() { + return model[coreY][coreZ][coreX]; + } + + /** + * Get the X-coordinate of the totem's core within the model. + * + * @return The X-coordinate as an integer. + */ + public int getCoreX() { + return coreX; + } + + /** + * Get the Y-coordinate of the totem's core within the model. + * + * @return The Y-coordinate as an integer. + */ + public int getCoreY() { + return coreY; + } + + /** + * Get the Z-coordinate of the totem's core within the model. + * + * @return The Z-coordinate as an integer. + */ + public int getCoreZ() { + return coreZ; + } + + /** + * Get the 3D array representing the totem model's structure. + * + * @return The 3D array of TotemBlock objects. + */ + public TotemBlock[][][][] getModel() { + return model; + } + + @Override + public String toString() { + StringBuilder stringBuilder = new StringBuilder(); + for (int h = 0; h < model.length; h++) { + stringBuilder.append("layer: ").append(h + 1).append("\n"); + TotemBlock[][][] totemBlocks1 = model[h]; + for (TotemBlock[][] totemBlocks2 : totemBlocks1) { + for (TotemBlock[] totemBlocks3 : totemBlocks2) { + StringJoiner stringJoiner = new StringJoiner("||"); + for (TotemBlock totemBlock : totemBlocks3) { + stringJoiner.add(totemBlock.toString()); + } + stringBuilder.append(stringJoiner).append("\t"); + } + stringBuilder.append("\n"); + } + } + return stringBuilder.toString(); + } + + public TotemModel deepClone() { + return SerializationUtils.clone(this); + } + + /** + * Rotate the totem model 90 degrees clockwise. + * + * @return The rotated TotemModel. + */ + public TotemModel rotate90() { + int tempX = this.coreX; + this.coreX = this.coreZ; + this.coreZ = this.model[0][0].length - 1 - tempX; + this.model = rotate90(model); + for (TotemBlock[][][] totemBlocks1 : model) { + for (TotemBlock[][] totemBlocks2 : totemBlocks1) { + for (TotemBlock[] totemBlocks3 : totemBlocks2) { + for (TotemBlock totemBlock : totemBlocks3) { + totemBlock.rotate90(); + } + } + } + } + return this; + } + + /** + * Mirror the totem model horizontally. + * + * @return The mirrored TotemModel. + */ + public TotemModel mirrorHorizontally() { + mirrorHorizontally(model); + this.coreZ = model[0].length - this.coreZ - 1; + for (TotemBlock[][][] totemBlocks1 : model) { + for (TotemBlock[][] totemBlocks2 : totemBlocks1) { + for (TotemBlock[] totemBlocks3 : totemBlocks2) { + for (TotemBlock totemBlock : totemBlocks3) { + totemBlock.mirror(Axis.X); + } + } + } + } + return this; + } + + /** + * Mirror the totem model vertically. + * + * @return The mirrored TotemModel. + */ + public TotemModel mirrorVertically() { + mirrorVertically(model); + this.coreX = model[0][0].length - this.coreX - 1; + + for (TotemBlock[][][] totemBlocks1 : model) { + for (TotemBlock[][] totemBlocks2 : totemBlocks1) { + for (TotemBlock[] totemBlocks3 : totemBlocks2) { + for (TotemBlock totemBlock : totemBlocks3) { + totemBlock.mirror(Axis.Z); + } + } + } + } + return this; + } + + /** + * Check if the provided location satisfies the pattern defined by the totem model. + * + * @param location The location to check. + * @return True if the location satisfies the pattern, false otherwise. + */ + public boolean isPatternSatisfied(Location location) { + Location startLoc = location.clone().subtract(0, coreY, 0); + + int height = model.length; + int width = model[0].length; + int length = model[0][0].length; + + for (int y = 0; y < height; y++) { + Location loc = startLoc.clone().add(-coreX, y, -coreZ); + for (int z = 0; z < width; z++) { + outer: + for (int x = 0; x < length; x++) { + for (TotemBlock totemBlock : model[y][z][x]) { + if (totemBlock.isRightBlock(loc.clone().add(x, 0, z).getBlock())) { + continue outer; + } + } + return false; + } + } + } + return true; + } + + /** + * Rotate a 3D totem model 90 degrees clockwise. + * + * @param matrix The 3D totem model to rotate. + * @return The rotated 3D totem model. + */ + private static TotemBlock[][][][] rotate90(TotemBlock[][][][] matrix) { + int height = matrix.length; + int rows = matrix[0].length; + int cols = matrix[0][0].length; + TotemBlock[][][][] rotated = new TotemBlock[height][cols][rows][]; + for (int h = 0; h < height; h++) { + for (int r = 0; r < rows; r++) { + for (int c = 0; c < cols; c++) { + rotated[h][c][rows - 1 - r] = matrix[h][r][c]; + } + } + } + return rotated; + } + + /** + * Mirror a 3D totem model horizontally. + * + * @param matrix The 3D totem model to mirror. + */ + private static void mirrorHorizontally(TotemBlock[][][][] matrix) { + int height = matrix.length; + int rows = matrix[0].length; + int cols = matrix[0][0].length; + + for (int h = 0; h < height; h++) { + for (int i = 0; i < rows / 2; i++) { + for (int j = 0; j < cols; j++) { + TotemBlock[] temp = matrix[h][i][j]; + matrix[h][i][j] = matrix[h][rows - i - 1][j]; + matrix[h][rows - i - 1][j] = temp; + } + } + } + } + + /** + * Mirror a 3D totem model vertically. + * + * @param matrix The 3D totem model to mirror. + */ + private static void mirrorVertically(TotemBlock[][][][] matrix) { + int height = matrix.length; + int rows = matrix[0].length; + int cols = matrix[0][0].length; + for (int h = 0; h < height; h++) { + for (int i = 0; i < rows; i++) { + for (int j = 0; j < cols / 2; j++) { + TotemBlock[] temp = matrix[h][i][j]; + matrix[h][i][j] = matrix[h][i][cols - j - 1]; + matrix[h][i][cols - j - 1] = temp; + } + } + } + } +} diff --git a/api/src/main/java/net/momirealms/customfishing/api/mechanic/totem/TotemParticle.java b/api/src/main/java/net/momirealms/customfishing/api/mechanic/totem/TotemParticle.java new file mode 100644 index 00000000..e8354a6e --- /dev/null +++ b/api/src/main/java/net/momirealms/customfishing/api/mechanic/totem/TotemParticle.java @@ -0,0 +1,16 @@ +package net.momirealms.customfishing.api.mechanic.totem; + +import net.momirealms.customfishing.common.plugin.scheduler.SchedulerTask; +import org.bukkit.Location; + +public interface TotemParticle { + + /** + * Start the particle task at specified location + * + * @param location location + * @param radius totem radius + * @return cancellable task + */ + SchedulerTask start(Location location, double radius); +} diff --git a/api/src/main/java/net/momirealms/customfishing/api/mechanic/totem/block/TotemBlock.java b/api/src/main/java/net/momirealms/customfishing/api/mechanic/totem/block/TotemBlock.java new file mode 100644 index 00000000..6d69648c --- /dev/null +++ b/api/src/main/java/net/momirealms/customfishing/api/mechanic/totem/block/TotemBlock.java @@ -0,0 +1,118 @@ +/* + * Copyright (C) <2022> + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +package net.momirealms.customfishing.api.mechanic.totem.block; + +import net.momirealms.customfishing.api.mechanic.totem.block.property.TotemBlockProperty; +import net.momirealms.customfishing.api.mechanic.totem.block.type.TypeCondition; +import org.bukkit.Axis; +import org.bukkit.block.Block; + +import java.io.Serializable; +import java.util.StringJoiner; + +/** + * Represents a TotemBlock that defines conditions and properties for a specific block type in a totem structure. + */ +public class TotemBlock implements Serializable { + + private final TypeCondition typeCondition; + private final TotemBlockProperty[] properties; + + /** + * Initializes a TotemBlock with the specified TypeCondition and properties. + * + * @param typeCondition The TypeCondition that specifies the block type. + * @param properties An array of TotemBlockProperty objects representing additional block properties. + */ + public TotemBlock(TypeCondition typeCondition, TotemBlockProperty[] properties) { + this.typeCondition = typeCondition; + this.properties = properties; + } + + /** + * Gets the TypeCondition associated with this TotemBlock. + * + * @return The TypeCondition defining the block type. + */ + public TypeCondition getTypeCondition() { + return typeCondition; + } + + /** + * Gets an array of properties associated with this TotemBlock. + * + * @return An array of TotemBlockProperty objects representing block properties. + */ + public TotemBlockProperty[] getProperties() { + return properties; + } + + /** + * Checks if a given Block satisfies the TypeCondition and properties of this TotemBlock. + * + * @param block The Block to be checked against the conditions and properties. + * @return `true` if the block satisfies all conditions and properties, otherwise `false`. + */ + public boolean isRightBlock(Block block) { + if (!typeCondition.isMet(block)) { + return false; + } + for (TotemBlockProperty property : properties) { + if (!property.isPropertyMet(block)) { + return false; + } + } + return true; + } + + /** + * Rotates the properties of this TotemBlock by 90 degrees. + * This method should be called when the totem structure is rotated. + */ + public void rotate90() { + for (TotemBlockProperty property : properties) { + property.rotate90(); + } + } + + /** + * Mirrors the properties of this TotemBlock horizontally or vertically. + * This method should be called when the totem structure is mirrored. + * + * @param axis The Axis along which to mirror the properties (X or Z). + */ + public void mirror(Axis axis) { + for (TotemBlockProperty property : properties) { + property.mirror(axis); + } + } + + /** + * Returns the raw text representation of this TotemBlock, including its TypeCondition and properties. + * + * @return The raw text representation of this TotemBlock. + */ + @Override + public String toString() { + StringJoiner stringJoiner = new StringJoiner(";"); + for (TotemBlockProperty property : properties) { + stringJoiner.add(property.getRawText()); + } + return typeCondition.getRawText() + "{" + stringJoiner + "}"; + } +} diff --git a/api/src/main/java/net/momirealms/customfishing/api/mechanic/totem/block/property/AxisImpl.java b/api/src/main/java/net/momirealms/customfishing/api/mechanic/totem/block/property/AxisImpl.java new file mode 100644 index 00000000..7fd160e0 --- /dev/null +++ b/api/src/main/java/net/momirealms/customfishing/api/mechanic/totem/block/property/AxisImpl.java @@ -0,0 +1,71 @@ +/* + * Copyright (C) <2022> + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +package net.momirealms.customfishing.api.mechanic.totem.block.property; + +import org.bukkit.Axis; +import org.bukkit.block.Block; +import org.bukkit.block.data.Orientable; + +import java.io.Serializable; +import java.util.Locale; + +public class AxisImpl implements TotemBlockProperty, Serializable { + + private Axis axis; + + public AxisImpl(Axis axis) { + this.axis = axis; + } + + @Override + public TotemBlockProperty mirror(Axis axis) { + return this; + } + + /** + * Rotates the block axis 90 degrees. (X -> Z, Z -> X) + * @return The rotated block axis. + */ + @Override + public TotemBlockProperty rotate90() { + if (this.axis == Axis.X) { + axis = Axis.Z; + } else if (this.axis == Axis.Z) { + axis = Axis.X; + } + return this; + } + + /** + * Checks if the block has the property. + * @param block The block to check. + * @return True if the block has the property. + */ + @Override + public boolean isPropertyMet(Block block) { + if (block.getBlockData() instanceof Orientable orientable) { + return orientable.getAxis().equals(this.axis); + } + return false; + } + + @Override + public String getRawText() { + return "axis=" + axis.name().toLowerCase(Locale.ENGLISH); + } +} diff --git a/api/src/main/java/net/momirealms/customfishing/api/mechanic/totem/block/property/FaceImpl.java b/api/src/main/java/net/momirealms/customfishing/api/mechanic/totem/block/property/FaceImpl.java new file mode 100644 index 00000000..8519fad3 --- /dev/null +++ b/api/src/main/java/net/momirealms/customfishing/api/mechanic/totem/block/property/FaceImpl.java @@ -0,0 +1,86 @@ +/* + * Copyright (C) <2022> + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +package net.momirealms.customfishing.api.mechanic.totem.block.property; + +import org.bukkit.Axis; +import org.bukkit.block.Block; +import org.bukkit.block.BlockFace; +import org.bukkit.block.data.Directional; + +import java.io.Serializable; +import java.util.Locale; + +public class FaceImpl implements TotemBlockProperty, Serializable { + + private BlockFace blockFace; + + public FaceImpl(BlockFace blockFace) { + this.blockFace = blockFace; + } + + /** + * Mirrors the block face if the axis is X or Z. + * @param axis The axis to mirror. + * @return The mirrored block face. + */ + @Override + public TotemBlockProperty mirror(Axis axis) { + if (axis == Axis.X) { + if (blockFace == BlockFace.SOUTH || blockFace == BlockFace.NORTH) { + return new FaceImpl(blockFace.getOppositeFace()); + } else { + return this; + } + } else if (axis == Axis.Z) { + if (blockFace == BlockFace.EAST || blockFace == BlockFace.WEST) { + return new FaceImpl(blockFace.getOppositeFace()); + } else { + return this; + } + } + return this; + } + + @Override + public TotemBlockProperty rotate90() { + switch (blockFace) { + case UP, DOWN -> { + return this; + } + case EAST -> blockFace = BlockFace.SOUTH; + case SOUTH -> blockFace = BlockFace.WEST; + case WEST -> blockFace = BlockFace.NORTH; + case NORTH -> blockFace = BlockFace.EAST; + default -> throw new IllegalArgumentException("Unsupported block facing: " + blockFace); + } + return this; + } + + @Override + public boolean isPropertyMet(Block block) { + if (block.getBlockData() instanceof Directional directional) { + return directional.getFacing().equals(this.blockFace); + } + return false; + } + + @Override + public String getRawText() { + return "face=" + blockFace.name().toLowerCase(Locale.ENGLISH); + } +} diff --git a/api/src/main/java/net/momirealms/customfishing/api/mechanic/totem/block/property/HalfImpl.java b/api/src/main/java/net/momirealms/customfishing/api/mechanic/totem/block/property/HalfImpl.java new file mode 100644 index 00000000..e2a2e2fb --- /dev/null +++ b/api/src/main/java/net/momirealms/customfishing/api/mechanic/totem/block/property/HalfImpl.java @@ -0,0 +1,74 @@ +/* + * Copyright (C) <2022> + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +package net.momirealms.customfishing.api.mechanic.totem.block.property; + +import org.bukkit.Axis; +import org.bukkit.block.Block; +import org.bukkit.block.data.Bisected; + +import java.io.Serializable; +import java.util.Locale; + +public class HalfImpl implements TotemBlockProperty, Serializable { + private final Bisected.Half half; + + public HalfImpl(Bisected.Half half) { + this.half = half; + } + + /** + * half is not affected by mirroring. + * @param axis The axis to mirror. + * @return this + */ + @Override + public TotemBlockProperty mirror(Axis axis) { + return this; + } + + /** + * half is not affected by rotation. + * @return this + */ + @Override + public TotemBlockProperty rotate90() { + return this; + } + + /** + * Checks if the block's half is the same as the half of this property. + * @param block The block to check. + * @return true if the block's half is the same as the half of this property. + */ + @Override + public boolean isPropertyMet(Block block) { + if (block.getBlockData() instanceof Bisected bisected) { + return bisected.getHalf().equals(this.half); + } + return false; + } + + /** + * Returns the raw text of the half property. + * @return The raw text of the half property. + */ + @Override + public String getRawText() { + return "half=" + half.name().toLowerCase(Locale.ENGLISH); + } +} diff --git a/api/src/main/java/net/momirealms/customfishing/api/mechanic/totem/block/property/TotemBlockProperty.java b/api/src/main/java/net/momirealms/customfishing/api/mechanic/totem/block/property/TotemBlockProperty.java new file mode 100644 index 00000000..be238682 --- /dev/null +++ b/api/src/main/java/net/momirealms/customfishing/api/mechanic/totem/block/property/TotemBlockProperty.java @@ -0,0 +1,50 @@ +/* + * Copyright (C) <2022> + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +package net.momirealms.customfishing.api.mechanic.totem.block.property; + +import org.bukkit.Axis; +import org.bukkit.block.Block; + +public interface TotemBlockProperty { + + /** + * Mirrors the block face if the axis is X or Z. + * @param axis The axis to mirror. + * @return The mirrored block face. + */ + TotemBlockProperty mirror(Axis axis); + + /** + * Rotates the block face 90 degrees. + * @return The rotated block face. + */ + TotemBlockProperty rotate90(); + + /** + * Checks if the block has the property. + * @param block The block to check. + * @return True if the block has the property. + */ + boolean isPropertyMet(Block block); + + /** + * Gets the raw text of the property. + * @return The raw text of the property. + */ + String getRawText(); +} diff --git a/api/src/main/java/net/momirealms/customfishing/api/mechanic/totem/block/type/EndWithType.java b/api/src/main/java/net/momirealms/customfishing/api/mechanic/totem/block/type/EndWithType.java new file mode 100644 index 00000000..1d723c5f --- /dev/null +++ b/api/src/main/java/net/momirealms/customfishing/api/mechanic/totem/block/type/EndWithType.java @@ -0,0 +1,56 @@ +/* + * Copyright (C) <2022> + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +package net.momirealms.customfishing.api.mechanic.totem.block.type; + +import org.bukkit.block.Block; + +import java.io.Serializable; + +/** + * Represents a TypeCondition that checks if a Block's type name ends with a specified string. + */ +public class EndWithType implements TypeCondition, Serializable { + + private final String end; + + public EndWithType(String end) { + this.end = end; + } + + /** + * Checks if the specified Block's type name ends with the configured ending string. + * + * @param type The Block to check. + * @return `true` if the Block's type name ends with the specified string, otherwise `false`. + */ + @Override + public boolean isMet(Block type) { + return type.getType().name().endsWith(end); + } + + /** + * Gets the raw text representation of this TypeCondition. + * The raw text includes the asterisk (*) followed by the configured ending string. + * + * @return The raw text representation of this TypeCondition. + */ + @Override + public String getRawText() { + return "*" + end; + } +} diff --git a/api/src/main/java/net/momirealms/customfishing/api/mechanic/totem/block/type/EqualType.java b/api/src/main/java/net/momirealms/customfishing/api/mechanic/totem/block/type/EqualType.java new file mode 100644 index 00000000..dfed289b --- /dev/null +++ b/api/src/main/java/net/momirealms/customfishing/api/mechanic/totem/block/type/EqualType.java @@ -0,0 +1,56 @@ +/* + * Copyright (C) <2022> + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +package net.momirealms.customfishing.api.mechanic.totem.block.type; + +import net.momirealms.customfishing.api.BukkitCustomFishingPlugin; +import org.bukkit.block.Block; + +import java.io.Serializable; + +/** + * Represents a TypeCondition that checks if a Block's type matches a specified type string. + */ +public class EqualType implements TypeCondition, Serializable { + + private final String type; + + public EqualType(String type) { + this.type = type; + } + + /** + * Checks if the specified Block's type matches the configured type string. + * + * @param type The Block to check. + * @return `true` if the Block's type matches the specified type string, otherwise `false`. + */ + @Override + public boolean isMet(Block type) { + return this.type.equals(BukkitCustomFishingPlugin.getInstance().getBlockManager().getBlockID(type)); + } + + /** + * Gets the raw text representation of this TypeCondition, which is the configured type string. + * + * @return The raw text representation of this TypeCondition. + */ + @Override + public String getRawText() { + return type; + } +} diff --git a/api/src/main/java/net/momirealms/customfishing/api/mechanic/totem/block/type/StartWithType.java b/api/src/main/java/net/momirealms/customfishing/api/mechanic/totem/block/type/StartWithType.java new file mode 100644 index 00000000..7fab7ba1 --- /dev/null +++ b/api/src/main/java/net/momirealms/customfishing/api/mechanic/totem/block/type/StartWithType.java @@ -0,0 +1,55 @@ +/* + * Copyright (C) <2022> + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +package net.momirealms.customfishing.api.mechanic.totem.block.type; + +import org.bukkit.block.Block; + +import java.io.Serializable; + +/** + * Represents a TypeCondition that checks if a Block's type starts with a specified prefix. + */ +public class StartWithType implements TypeCondition, Serializable { + + private final String start; + + public StartWithType(String start) { + this.start = start; + } + + /** + * Checks if the specified Block's type starts with the configured prefix. + * + * @param type The Block to check. + * @return `true` if the Block's type starts with the specified prefix, otherwise `false`. + */ + @Override + public boolean isMet(Block type) { + return type.getType().name().startsWith(start); + } + + /** + * Gets the raw text representation of this TypeCondition, which is the configured prefix followed by '*'. + * + * @return The raw text representation of this TypeCondition. + */ + @Override + public String getRawText() { + return start + "*"; + } +} diff --git a/api/src/main/java/net/momirealms/customfishing/api/mechanic/totem/block/type/TypeCondition.java b/api/src/main/java/net/momirealms/customfishing/api/mechanic/totem/block/type/TypeCondition.java new file mode 100644 index 00000000..4f5422b2 --- /dev/null +++ b/api/src/main/java/net/momirealms/customfishing/api/mechanic/totem/block/type/TypeCondition.java @@ -0,0 +1,57 @@ +/* + * Copyright (C) <2022> + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +package net.momirealms.customfishing.api.mechanic.totem.block.type; + +import org.bukkit.block.Block; + +/** + * Represents a condition used to check the type of a Block. + */ +public interface TypeCondition { + + /** + * Checks if the specified Block meets the condition. + * + * @param block The Block to check. + * @return `true` if the condition is met, otherwise `false`. + */ + boolean isMet(Block block); + + /** + * Gets the raw text representation of this TypeCondition. + * + * @return The raw text representation of this TypeCondition. + */ + String getRawText(); + + /** + * Gets a TypeCondition based on its raw text representation. + * + * @param raw The raw text representation of the TypeCondition. + * @return A TypeCondition instance corresponding to the raw text. + */ + static TypeCondition getTypeCondition(String raw) { + if (raw.startsWith("*")) { + return new EndWithType(raw.substring(1)); + } else if (raw.endsWith("*")) { + return new StartWithType(raw.substring(0, raw.length() -1)); + } else { + return new EqualType(raw); + } + } +} diff --git a/api/src/main/java/net/momirealms/customfishing/api/storage/StorageManager.java b/api/src/main/java/net/momirealms/customfishing/api/storage/StorageManager.java index 0d98e047..bb4f72e6 100644 --- a/api/src/main/java/net/momirealms/customfishing/api/storage/StorageManager.java +++ b/api/src/main/java/net/momirealms/customfishing/api/storage/StorageManager.java @@ -19,6 +19,7 @@ package net.momirealms.customfishing.api.storage; import net.momirealms.customfishing.api.storage.data.PlayerData; import net.momirealms.customfishing.api.storage.user.UserData; +import net.momirealms.customfishing.common.plugin.feature.Reloadable; import org.jetbrains.annotations.NotNull; import java.util.Collection; @@ -26,7 +27,7 @@ import java.util.Optional; import java.util.UUID; import java.util.concurrent.CompletableFuture; -public interface StorageManager { +public interface StorageManager extends Reloadable { @NotNull String getServerID(); @@ -52,7 +53,7 @@ public interface StorageManager { * @param data The PlayerData to be converted. * @return The byte array representation of PlayerData. */ - byte @NotNull [] toBytes(@NotNull PlayerData data); + byte[] toBytes(@NotNull PlayerData data); /** * Converts PlayerData to JSON format. diff --git a/bukkit-loader/build.gradle.kts b/bukkit-loader/build.gradle.kts index e69de29b..39f7b021 100644 --- a/bukkit-loader/build.gradle.kts +++ b/bukkit-loader/build.gradle.kts @@ -0,0 +1,12 @@ +repositories { + maven("https://oss.sonatype.org/content/repositories/snapshots") + maven("https://hub.spigotmc.org/nexus/content/repositories/snapshots/") +} + +dependencies { + implementation(project(":core")) + implementation(project(":common")) + implementation(project(":compatibility")) + implementation(project(":api")) + compileOnly("org.spigotmc:spigot-api:${rootProject.properties["paper_version"]}-R0.1-SNAPSHOT") +} diff --git a/bukkit-loader/src/main/java/net/momirealms/Main.java b/bukkit-loader/src/main/java/net/momirealms/Main.java deleted file mode 100644 index 6a66b517..00000000 --- a/bukkit-loader/src/main/java/net/momirealms/Main.java +++ /dev/null @@ -1,7 +0,0 @@ -package net.momirealms; - -public class Main { - public static void main(String[] args) { - System.out.println("Hello world!"); - } -} \ No newline at end of file diff --git a/bukkit-loader/src/main/java/net/momirealms/customfishing/bukkit/BukkitBootstrap.java b/bukkit-loader/src/main/java/net/momirealms/customfishing/bukkit/BukkitBootstrap.java new file mode 100644 index 00000000..2f04ece7 --- /dev/null +++ b/bukkit-loader/src/main/java/net/momirealms/customfishing/bukkit/BukkitBootstrap.java @@ -0,0 +1,25 @@ +package net.momirealms.customfishing.bukkit; + +import net.momirealms.customfishing.api.BukkitCustomFishingPlugin; +import org.bukkit.plugin.java.JavaPlugin; + +public class BukkitBootstrap extends JavaPlugin { + + private BukkitCustomFishingPlugin plugin; + + @Override + public void onLoad() { + this.plugin = new BukkitCustomFishingPluginImpl(this); + this.plugin.load(); + } + + @Override + public void onEnable() { + this.plugin.enable(); + } + + @Override + public void onDisable() { + this.plugin.disable(); + } +} diff --git a/core/src/main/resources/plugin.yml b/bukkit-loader/src/main/resources/plugin.yml similarity index 83% rename from core/src/main/resources/plugin.yml rename to bukkit-loader/src/main/resources/plugin.yml index 7df57363..62a1e5b3 100644 --- a/core/src/main/resources/plugin.yml +++ b/bukkit-loader/src/main/resources/plugin.yml @@ -1,11 +1,9 @@ name: CustomFishing -version: '${version}' -main: net.momirealms.customfishing.CustomFishingPluginImpl +version: '${project_version}' +main: net.momirealms.customfishing.bukkit.BukkitBootstrap api-version: 1.17 authors: [ XiaoMoMi ] folia-supported: true -depend: - - ProtocolLib softdepend: - Vault - PlaceholderAPI diff --git a/common/src/main/java/net/momirealms/customfishing/common/config/ConfigLoader.java b/common/src/main/java/net/momirealms/customfishing/common/config/ConfigLoader.java index ef0fec43..8cdb4bd8 100644 --- a/common/src/main/java/net/momirealms/customfishing/common/config/ConfigLoader.java +++ b/common/src/main/java/net/momirealms/customfishing/common/config/ConfigLoader.java @@ -13,4 +13,6 @@ public interface ConfigLoader { YamlDocument loadData(File file); YamlDocument loadData(File file, char routeSeparator); + + void saveResource(String filePath); } diff --git a/common/src/main/java/net/momirealms/customfishing/common/dependency/Dependency.java b/common/src/main/java/net/momirealms/customfishing/common/dependency/Dependency.java index e79edcdc..fed83925 100644 --- a/common/src/main/java/net/momirealms/customfishing/common/dependency/Dependency.java +++ b/common/src/main/java/net/momirealms/customfishing/common/dependency/Dependency.java @@ -236,13 +236,6 @@ public enum Dependency { "caffeine", Relocation.of("caffeine", "com{}github{}benmanes{}caffeine") ), - LETTUCE( - "io{}lettuce", - "lettuce-core", - "maven", - "lettuce-core", - Relocation.of("lettuce", "io{}lettuce") - ), JEDIS( "redis{}clients", "jedis", diff --git a/common/src/main/java/net/momirealms/customfishing/common/helper/VersionHelper.java b/common/src/main/java/net/momirealms/customfishing/common/helper/VersionHelper.java index 1ca6c826..fdf8365f 100644 --- a/common/src/main/java/net/momirealms/customfishing/common/helper/VersionHelper.java +++ b/common/src/main/java/net/momirealms/customfishing/common/helper/VersionHelper.java @@ -17,126 +17,25 @@ package net.momirealms.customfishing.common.helper; +import net.momirealms.customfishing.common.plugin.CustomFishingPlugin; + import java.io.BufferedReader; import java.io.InputStream; import java.io.InputStreamReader; import java.net.URL; import java.net.URLConnection; import java.util.concurrent.CompletableFuture; +import java.util.function.Function; /** * This class implements the VersionManager interface and is responsible for managing version-related information. */ public class VersionHelper { - private final boolean isNewerThan1_19_3; - private final boolean isNewerThan1_19_4; - private final boolean isNewerThan1_20; - private final boolean isNewerThan1_20_5; - private final boolean isNewerThan1_19; - private final String serverVersion; - private final boolean isSpigot; - private boolean hasRegionScheduler; - private boolean isMojmap; - private final String pluginVersion; - - public VersionHelper(String serverVersion) { - this.serverVersion = serverVersion; - String[] split = serverVersion.split("\\."); - int main_ver = Integer.parseInt(split[0]); - // Determine if the server version is newer than 1_19_R2 and 1_20_R1 - if (main_ver >= 20) { - isNewerThan1_20_5 = Integer.parseInt(split[1]) >= 5; - isNewerThan1_19_3 = isNewerThan1_19_4 = true; - isNewerThan1_20 = true; - isNewerThan1_19 = true; - } else if (main_ver == 19) { - isNewerThan1_20 = isNewerThan1_20_5 = false; - isNewerThan1_19_3 = Integer.parseInt(split[1]) >= 3; - isNewerThan1_19_4 = Integer.parseInt(split[1]) >= 4; - isNewerThan1_19 = true; - } else { - isNewerThan1_20 = isNewerThan1_20_5 = isNewerThan1_19 = isNewerThan1_19_3 = isNewerThan1_19_4 = false; - } - // Check if the server is Spigot - String server_name = plugin.getServer().getName(); - this.isSpigot = server_name.equals("CraftBukkit"); - - // Check if the server is Folia - try { - Class.forName("io.papermc.paper.threadedregions.scheduler.AsyncScheduler"); - this.hasRegionScheduler = true; - } catch (ClassNotFoundException ignored) { - - } - - // Check if the server is Mojmap - try { - Class.forName("net.minecraft.network.protocol.game.ClientboundBossEventPacket"); - this.isMojmap = true; - } catch (ClassNotFoundException ignored) { - - } - - // Get the plugin version - this.pluginVersion = plugin.getDescription().getVersion(); - } - - @Override - public boolean isVersionNewerThan1_19() { - return isNewerThan1_19; - } - - @Override - public boolean isVersionNewerThan1_19_4() { - return isNewerThan1_19_4; - } - - @Override - public boolean isVersionNewerThan1_19_3() { - return isNewerThan1_19_3; - } - - @Override - public boolean isVersionNewerThan1_20() { - return isNewerThan1_20; - } - - @Override - public boolean isNewerThan1_20_5() { - return isNewerThan1_20_5; - } - - @Override - public boolean isSpigot() { - return isSpigot; - } - - @Override - public String getPluginVersion() { - return pluginVersion; - } - - @Override - public boolean hasRegionScheduler() { - return hasRegionScheduler; - } - - @Override - public boolean isMojmap() { - return isMojmap; - } - - @Override - public String getServerVersion() { - return serverVersion; - } - // Method to asynchronously check for plugin updates - @Override - public CompletableFuture checkUpdate() { + public static final Function> UPDATE_CHECKER = (plugin) -> { CompletableFuture updateFuture = new CompletableFuture<>(); - plugin.getScheduler().async(() -> { + plugin.getScheduler().async().execute(() -> { try { URL url = new URL("https://api.polymart.org/v1/getResourceInfoSimple/?resource_id=2723&key=version"); URLConnection conn = url.openConnection(); @@ -144,7 +43,7 @@ public class VersionHelper { conn.setReadTimeout(60000); InputStream inputStream = conn.getInputStream(); String newest = new BufferedReader(new InputStreamReader(inputStream)).readLine(); - String current = plugin.getVersionManager().getPluginVersion(); + String current = plugin.getPluginVersion(); inputStream.close(); if (!compareVer(newest, current)) { updateFuture.complete(false); @@ -152,15 +51,71 @@ public class VersionHelper { } updateFuture.complete(true); } catch (Exception exception) { - LogUtils.warn("Error occurred when checking update.", exception); + plugin.getPluginLogger().warn("Error occurred when checking update.", exception); updateFuture.complete(false); } }); return updateFuture; + }; + + private static float version; + private static boolean mojmap; + private static boolean folia; + + public static void init(String serverVersion) { + String[] split = serverVersion.split("\\."); + version = Float.parseFloat(split[1] + "." + split[2]); + checkMojMap(); + checkFolia(); + } + + private static void checkMojMap() { + // Check if the server is Mojmap + try { + Class.forName("net.minecraft.network.protocol.game.ClientboundBossEventPacket"); + mojmap = true; + } catch (ClassNotFoundException ignored) { + } + } + + private static void checkFolia() { + try { + Class.forName("io.papermc.paper.threadedregions.RegionizedServer"); + folia = true; + } catch (ClassNotFoundException ignored) { + } + } + + public static boolean isVersionNewerThan1_19() { + return version >= 19; + } + + public static boolean isVersionNewerThan1_19_4() { + return version >= 19.4; + } + + public static boolean isVersionNewerThan1_19_3() { + return version >= 19.3; + } + + public static boolean isVersionNewerThan1_20() { + return version >= 20.0; + } + + public boolean isNewerThan1_20_5() { + return version >= 20.5; + } + + public static boolean isFolia() { + return folia; + } + + public static boolean isMojmap() { + return mojmap; } // Method to compare two version strings - private boolean compareVer(String newV, String currentV) { + private static boolean compareVer(String newV, String currentV) { if (newV == null || currentV == null || newV.isEmpty() || currentV.isEmpty()) { return false; } diff --git a/common/src/main/java/net/momirealms/customfishing/common/locale/MessageConstants.java b/common/src/main/java/net/momirealms/customfishing/common/locale/MessageConstants.java index 67bab813..f6c121a2 100644 --- a/common/src/main/java/net/momirealms/customfishing/common/locale/MessageConstants.java +++ b/common/src/main/java/net/momirealms/customfishing/common/locale/MessageConstants.java @@ -5,5 +5,112 @@ import net.kyori.adventure.text.TranslatableComponent; public interface MessageConstants { - TranslatableComponent.Builder COMMAND_RELOAD = Component.translatable().key("argument.entity.notfound.player"); + TranslatableComponent.Builder COMMAND_PREFIX = Component.translatable().key("command.prefix"); + TranslatableComponent.Builder COMMAND_RELOAD_SUCCESS = Component.translatable().key("command.reload.success"); + TranslatableComponent.Builder COMMAND_ITEM_FAILURE_NOT_EXIST = Component.translatable().key("command.item.failure.not_exist"); + TranslatableComponent.Builder COMMAND_ITEM_GIVE_SUCCESS = Component.translatable().key("command.item.give.success"); + TranslatableComponent.Builder COMMAND_ITEM_GET_SUCCESS = Component.translatable().key("command.item.get.success"); + TranslatableComponent.Builder COMMAND_FISH_FINDER_POSSIBLE_LOOTS = Component.translatable().key("command.fish_finder.possible_loots"); + TranslatableComponent.Builder COMMAND_FISH_FINDER_NO_LOOT = Component.translatable().key("command.fish_finder.no_loot"); + TranslatableComponent.Builder COMMAND_FISH_FINDER_SPLIT_CHAR = Component.translatable().key("command.fish_finder.split_char"); + TranslatableComponent.Builder COMMAND_COMPETITION_FAILURE_NOT_EXIST = Component.translatable().key("command.competition.failure.not_exist"); + TranslatableComponent.Builder COMMAND_COMPETITION_FAILURE_NO_COMPETITION = Component.translatable().key("command.competition.failure.no_competition"); + TranslatableComponent.Builder COMMAND_COMPETITION_FAILURE_STOP_SUCCESS = Component.translatable().key("command.competition.failure.stop.success"); + TranslatableComponent.Builder COMMAND_COMPETITION_FAILURE_END_SUCCESS = Component.translatable().key("command.competition.failure.end.success"); + TranslatableComponent.Builder COMMAND_BAG_EDIT_FAILURE_UNSAFE = Component.translatable().key("command.bag.edit.failure.unsafe"); + TranslatableComponent.Builder COMMAND_BAG_EDIT_FAILURE_NEVER_PLAYED = Component.translatable().key("command.bag.edit.failure.never_played"); + TranslatableComponent.Builder COMMAND_BAG_OPEN_SUCCESS = Component.translatable().key("command.bag.edit.open.success"); + TranslatableComponent.Builder COMMAND_DATA_FAILURE_NOT_LOAD = Component.translatable().key("command.data.failure.not_load"); + TranslatableComponent.Builder COMMAND_MARKET_OPEN_SUCCESS = Component.translatable().key("command.market.open.success"); + TranslatableComponent.Builder GUI_SELECT_FILE = Component.translatable().key("gui.select_file"); + TranslatableComponent.Builder GUI_SELECT_ITEM = Component.translatable().key("gui.select_item"); + TranslatableComponent.Builder GUI_INVALID_KEY = Component.translatable().key("gui.invalid_key"); + TranslatableComponent.Builder GUI_NEW_VALUE = Component.translatable().key("gui.new_value"); + TranslatableComponent.Builder GUI_TEMP_NEW_KEY = Component.translatable().key("gui.temp_new_key"); + TranslatableComponent.Builder GUI_SET_NEW_KEY = Component.translatable().key("gui.set_new_key"); + TranslatableComponent.Builder GUI_EDIT_KEY = Component.translatable().key("gui.edit_key"); + TranslatableComponent.Builder GUI_DELETE_PROPERTY = Component.translatable().key("gui.delete_property"); + TranslatableComponent.Builder GUI_CLICK_CONFIRM = Component.translatable().key("gui.click_confirm"); + TranslatableComponent.Builder GUI_INVALID_NUMBER = Component.translatable().key("gui.invalid_number"); + TranslatableComponent.Builder GUI_ILLEGAL_FORMAT = Component.translatable().key("gui.illegal_format"); + TranslatableComponent.Builder GUI_SCROLL_UP = Component.translatable().key("gui.scroll_up"); + TranslatableComponent.Builder GUI_SCROLL_DOWN = Component.translatable().key("gui.scroll_down"); + TranslatableComponent.Builder GUI_CANNOT_SCROLL_UP = Component.translatable().key("gui.cannot_scroll_up"); + TranslatableComponent.Builder GUI_CANNOT_SCROLL_DOWN = Component.translatable().key("gui.cannot_scroll_down"); + TranslatableComponent.Builder GUI_NEXT_PAGE = Component.translatable().key("gui.next_page"); + TranslatableComponent.Builder GUI_GOTO_NEXT_PAGE = Component.translatable().key("gui.goto_next_page"); + TranslatableComponent.Builder GUI_CANNOT_GOTO_NEXT_PAGE = Component.translatable().key("gui.cannot_goto_next_page"); + TranslatableComponent.Builder GUI_PREVIOUS_PAGE = Component.translatable().key("gui.previous_page"); + TranslatableComponent.Builder GUI_GOTO_PREVIOUS_PAGE = Component.translatable().key("gui.goto_previous_page"); + TranslatableComponent.Builder GUI_CANNOT_GOTO_PREVIOUS_PAGE = Component.translatable().key("gui.cannot_goto_previous_page"); + TranslatableComponent.Builder GUI_BACK_TO_PARENT_PAGE = Component.translatable().key("gui.back_to_parent_page"); + TranslatableComponent.Builder GUI_BACK_TO_PARENT_FOLDER = Component.translatable().key("gui.back_to_parent_folder"); + TranslatableComponent.Builder GUI_CURRENT_VALUE = Component.translatable().key("gui.current_value"); + TranslatableComponent.Builder GUI_CLICK_TO_TOGGLE = Component.translatable().key("gui.click_to_toggle"); + TranslatableComponent.Builder GUI_LEFT_CLICK_EDIT = Component.translatable().key("gui.left_click_edit"); + TranslatableComponent.Builder GUI_RIGHT_CLICK_RESET = Component.translatable().key("gui.right_click_reset"); + TranslatableComponent.Builder GUI_RIGHT_CLICK_DELETE = Component.translatable().key("gui.right_click_delete"); + TranslatableComponent.Builder GUI_RIGHT_CLICK_CANCEL = Component.translatable().key("gui.right_click_cancel"); + TranslatableComponent.Builder GUI_LOOT_SHOW_IN_FINDER = Component.translatable().key("gui.loot_show_in_finder"); + TranslatableComponent.Builder GUI_LOOT_SCORE = Component.translatable().key("gui.loot_score"); + TranslatableComponent.Builder GUI_LOOT_NICK = Component.translatable().key("gui.loot_nick"); + TranslatableComponent.Builder GUI_LOOT_INSTANT_GAME = Component.translatable().key("gui.loot_instant_game"); + TranslatableComponent.Builder GUI_LOOT_DISABLE_STATISTICS = Component.translatable().key("gui.loot_disable_statistics"); + TranslatableComponent.Builder GUI_LOOT_DISABLE_GAME = Component.translatable().key("gui.loot_disable_game"); + TranslatableComponent.Builder GUI_ITEM_AMOUNT = Component.translatable().key("gui.item_amount"); + TranslatableComponent.Builder GUI_ITEM_CUSTOM_MODEL_DATA = Component.translatable().key("gui.item_custom_model_data"); + TranslatableComponent.Builder GUI_ITEM_DISPLAY_NAME = Component.translatable().key("gui.item_display_name"); + TranslatableComponent.Builder GUI_ITEM_CUSTOM_DURABILITY = Component.translatable().key("gui.item_custom_durability"); + TranslatableComponent.Builder GUI_ITEM_ENCHANTMENT = Component.translatable().key("gui.item_enchantment"); + TranslatableComponent.Builder GUI_ITEM_HEAD64 = Component.translatable().key("gui.item_head64"); + TranslatableComponent.Builder GUI_ITEM_FLAG = Component.translatable().key("gui.item_item_flag"); + TranslatableComponent.Builder GUI_ITEM_LORE = Component.translatable().key("gui.item_lore"); + TranslatableComponent.Builder GUI_ITEM_MATERIAL = Component.translatable().key("gui.item_material"); + TranslatableComponent.Builder GUI_ITEM_NBT = Component.translatable().key("gui.item_nbt"); + TranslatableComponent.Builder GUI_ITEM_PREVENT_GRAB = Component.translatable().key("gui.item_prevent_grab"); + TranslatableComponent.Builder GUI_ITEM_PRICE = Component.translatable().key("gui.item_price"); + TranslatableComponent.Builder GUI_ITEM_PRICE_BASE = Component.translatable().key("gui.item_price_base"); + TranslatableComponent.Builder GUI_ITEM_PRICE_BONUS = Component.translatable().key("gui.item_price_bonus"); + TranslatableComponent.Builder GUI_ITEM_RANDOM_DURABILITY = Component.translatable().key("gui.item_random_durability"); + TranslatableComponent.Builder GUI_ITEM_SIZE = Component.translatable().key("gui.item_size"); + TranslatableComponent.Builder GUI_ITEM_STACKABLE = Component.translatable().key("gui.item_stackable"); + TranslatableComponent.Builder GUI_ITEM_STORED_ENCHANTMENT = Component.translatable().key("gui.item_stored_enchantment"); + TranslatableComponent.Builder GUI_ITEM_TAG = Component.translatable().key("gui.item_tag"); + TranslatableComponent.Builder GUI_ITEM_UNBREAKABLE = Component.translatable().key("gui.item_unbreakable"); + TranslatableComponent.Builder GUI_PAGE_AMOUNT_TITLE = Component.translatable().key("gui.page_amount_title"); + TranslatableComponent.Builder GUI_PAGE_MODEL_DATA_TITLE = Component.translatable().key("gui.page_model_data_title"); + TranslatableComponent.Builder GUI_PAGE_DISPLAY_NAME_TITLE = Component.translatable().key("gui.page_display_name_title"); + TranslatableComponent.Builder GUI_PAGE_NEW_DISPLAY_NAME = Component.translatable().key("gui.page_new_display_name"); + TranslatableComponent.Builder GUI_PAGE_CUSTOM_DURABILITY_TITLE = Component.translatable().key("gui.page_custom_durability_title"); + TranslatableComponent.Builder GUI_PAGE_STORED_ENCHANTMENT_TITLE = Component.translatable().key("gui.page_stored_enchantment_title"); + TranslatableComponent.Builder GUI_PAGE_ENCHANTMENT_TITLE = Component.translatable().key("gui.page_enchantment_title"); + TranslatableComponent.Builder GUI_PAGE_SELECT_ONE_ENCHANTMENT = Component.translatable().key("gui.page_select_one_enchantment"); + TranslatableComponent.Builder GUI_PAGE_ADD_NEW_ENCHANTMENT = Component.translatable().key("gui.page_add_new_enchantment"); + TranslatableComponent.Builder GUI_PAGE_ITEM_FLAG_TITLE = Component.translatable().key("gui.page_item_flag_title"); + TranslatableComponent.Builder GUI_PAGE_LORE_TITLE = Component.translatable().key("gui.page_lore_title"); + TranslatableComponent.Builder GUI_PAGE_ADD_NEW_LORE = Component.translatable().key("gui.page_add_new_lore"); + TranslatableComponent.Builder GUI_PAGE_SELECT_ONE_LORE = Component.translatable().key("gui.page_select_one_lore"); + TranslatableComponent.Builder GUI_PAGE_MATERIAL_TITLE = Component.translatable().key("gui.page_material_title"); + TranslatableComponent.Builder GUI_PAGE_NBT_COMPOUND_KEY_TITLE = Component.translatable().key("gui.page_nbt_compound_key_title"); + TranslatableComponent.Builder GUI_PAGE_NBT_LIST_KEY_TITLE = Component.translatable().key("gui.page_nbt_list_key_title"); + TranslatableComponent.Builder GUI_PAGE_NBT_KEY_TITLE = Component.translatable().key("gui.page_nbt_key_title"); + TranslatableComponent.Builder GUI_PAGE_NBT_INVALID_KEY = Component.translatable().key("gui.page_nbt_invalid_key"); + TranslatableComponent.Builder GUI_PAGE_NBT_ADD_NEW_COMPOUND= Component.translatable().key("gui.page_nbt_add_new_compound"); + TranslatableComponent.Builder GUI_PAGE_NBT_ADD_NEW_LIST = Component.translatable().key("gui.page_nbt_add_new_list"); + TranslatableComponent.Builder GUI_PAGE_NBT_ADD_NEW_VALUE = Component.translatable().key("gui.page_nbt_add_new_value"); + TranslatableComponent.Builder GUI_PAGE_ADD_NEW_KEY = Component.translatable().key("gui.page_add_new_key"); + TranslatableComponent.Builder GUI_PAGE_NBT_PREVIEW = Component.translatable().key("gui.page_nbt_preview"); + TranslatableComponent.Builder GUI_PAGE_NBT_BACK_TO_COMPOUND = Component.translatable().key("gui.page_nbt_back_to_compound"); + TranslatableComponent.Builder GUI_PAGE_NBT_SET_VALUE_TITLE = Component.translatable().key("gui.page_nbt_set_value_title"); + TranslatableComponent.Builder GUI_PAGE_NBT_EDIT_TITLE = Component.translatable().key("gui.page_nbt_edit_title"); + TranslatableComponent.Builder GUI_PAGE_NICK_TITLE = Component.translatable().key("gui.page_nick_title"); + TranslatableComponent.Builder GUI_PAGE_NEW_NICK = Component.translatable().key("gui.page_new_nick"); + TranslatableComponent.Builder GUI_PAGE_PRICE_TITLE = Component.translatable().key("gui.page_price_title"); + TranslatableComponent.Builder GUI_PAGE_BASE_PRICE = Component.translatable().key("gui.page_base_price"); + TranslatableComponent.Builder GUI_PAGE_BASE_BONUS = Component.translatable().key("gui.page_base_bonus"); + TranslatableComponent.Builder GUI_PAGE_SCORE_TITLE = Component.translatable().key("gui.page_score_title"); + TranslatableComponent.Builder GUI_PAGE_SIZE_TITLE = Component.translatable().key("gui.page_size_title"); + TranslatableComponent.Builder GUI_PAGE_SIZE_MIN = Component.translatable().key("gui.page_size_min"); + TranslatableComponent.Builder GUI_PAGE_SIZE_MAX = Component.translatable().key("gui.page_size_max"); + TranslatableComponent.Builder GUI_PAGE_SIZE_MAX_NO_LESS_MIN = Component.translatable().key("gui.page_size_max_no_less_min"); } diff --git a/common/src/main/java/net/momirealms/customfishing/common/locale/StandardLocales.java b/common/src/main/java/net/momirealms/customfishing/common/locale/StandardLocales.java index 034bd848..c88475a1 100644 --- a/common/src/main/java/net/momirealms/customfishing/common/locale/StandardLocales.java +++ b/common/src/main/java/net/momirealms/customfishing/common/locale/StandardLocales.java @@ -5,7 +5,123 @@ public class StandardLocales { public static String COMPETITION_NO_PLAYER = "No Player"; public static String COMPETITION_NO_SCORE = "No Score"; public static String COMPETITION_NO_RANK = "No Rank"; + + public static String GOAL_TOTAL_SIZE; + public static String GOAL_CATCH_AMOUNT; + public static String GOAL_TOTAL_SCORE; + public static String GOAL_MAX_SIZE; + public static String FORMAT_SECOND = "s"; public static String FORMAT_MINUTE = "m"; public static String FORMAT_HOUR = "h"; + + public static String COMMAND_PREFIX; + public static String COMMAND_RELOAD; + public static String COMMAND_COMPETITION_NOT_EXISTS; + public static String COMMAND_N0_COMPETITION_ONGOING; + public static String COMMAND_END_COMPETITION; + public static String COMMAND_STOP_COMPETITION; + public static String COMMAND_ITEM_NOT_EXISTS; + public static String COMMAND_GET_ITEM; + public static String COMMAND_GIVE_ITEM; + public static String COMMAND_NEVER_PLAYED; + public static String COMMAND_UNSAFE_MODIFICATION; + public static String COMMAND_DATA_NOT_LOAD; + public static String COMMAND_MARKET_OPEN; + public static String COMMAND_FISHING_BAG_OPEN; + public static String COMMAND_POSSIBLE_LOOTS_SPLIT_CHAR; + public static String COMMAND_POSSIBLE_LOOTS; + + public static String GUI_SCROLL_DOWN; + public static String GUI_SCROLL_UP; + public static String GUI_CANNOT_SCROLL_UP; + public static String GUI_CANNOT_SCROLL_DOWN; + public static String GUI_NEXT_PAGE; + public static String GUI_GOTO_NEXT_PAGE; + public static String GUI_CANNOT_GOTO_NEXT_PAGE; + public static String GUI_PREVIOUS_PAGE; + public static String GUI_GOTO_PREVIOUS_PAGE; + public static String GUI_CANNOT_GOTO_PREVIOUS_PAGE; + public static String GUI_BACK_TO_PARENT_PAGE; + public static String GUI_BACK_TO_PARENT_FOLDER; + public static String GUI_CURRENT_VALUE; + public static String GUI_CLICK_TO_TOGGLE; + public static String GUI_LEFT_CLICK_EDIT; + public static String GUI_RIGHT_CLICK_RESET; + public static String GUI_RIGHT_CLICK_DELETE; + public static String GUI_LOOT_SHOW_IN_FINDER; + public static String GUI_LOOT_SCORE; + public static String GUI_LOOT_NICK; + public static String GUI_LOOT_INSTANT_GAME; + public static String GUI_LOOT_DISABLE_STATS; + public static String GUI_LOOT_DISABLE_GAME; + public static String GUI_ITEM_AMOUNT; + public static String GUI_ITEM_MODEL_DATA; + public static String GUI_ITEM_DISPLAY_NAME; + public static String GUI_ITEM_DURABILITY; + public static String GUI_ITEM_ENCHANTMENT; + public static String GUI_ITEM_HEAD64; + public static String GUI_ITEM_FLAG; + public static String GUI_ITEM_LORE; + public static String GUI_ITEM_MATERIAL; + public static String GUI_ITEM_NBT; + public static String GUI_ITEM_PREVENT_GRAB; + public static String GUI_ITEM_PRICE; + public static String GUI_ITEM_PRICE_BASE; + public static String GUI_ITEM_PRICE_BONUS; + public static String GUI_ITEM_RANDOM_DURABILITY; + public static String GUI_ITEM_SIZE; + public static String GUI_ITEM_STACKABLE; + public static String GUI_ITEM_STORED_ENCHANTMENT; + public static String GUI_ITEM_TAG; + public static String GUI_ITEM_UNBREAKABLE; + public static String GUI_DELETE_PROPERTY; + public static String GUI_NEW_VALUE; + public static String GUI_CLICK_CONFIRM; + public static String GUI_INVALID_NUMBER; + public static String GUI_ILLEGAL_FORMAT; + public static String GUI_TITLE_AMOUNT; + public static String GUI_TITLE_MODEL_DATA; + public static String GUI_TITLE_DISPLAY_NAME; + public static String GUI_NEW_DISPLAY_NAME; + public static String GUI_TITLE_CUSTOM_DURABILITY; + public static String GUI_TITLE_ENCHANTMENT; + public static String GUI_TITLE_STORED_ENCHANTMENT; + public static String GUI_SELECT_ONE_ENCHANTMENT; + public static String GUI_ADD_NEW_ENCHANTMENT; + public static String GUI_TITLE_ITEM_FLAG; + public static String GUI_TITLE_LORE; + public static String GUI_ADD_NEW_LORE; + public static String GUI_SELECT_ONE_LORE; + public static String GUI_TITLE_MATERIAL; + public static String GUI_TITLE_NBT_COMPOUND; + public static String GUI_TITLE_NBT_LIST; + public static String GUI_TITLE_NBT_KEY; + public static String GUI_NBT_INVALID_KEY; + public static String GUI_RIGHT_CLICK_CANCEL; + public static String GUI_NBT_ADD_COMPOUND; + public static String GUI_NBT_ADD_LIST; + public static String GUI_NBT_ADD_VALUE; + public static String GUI_NBT_PREVIEW; + public static String GUI_NBT_BACK_TO_COMPOUND; + public static String GUI_NBT_SET_VALUE_TITLE; + public static String GUI_NBT_EDIT_TITLE; + public static String GUI_NICK_TITLE; + public static String GUI_NICK_NEW; + public static String GUI_PRICE_TITLE; + public static String GUI_PRICE_BASE; + public static String GUI_PRICE_BONUS; + public static String GUI_SCORE_TITLE; + public static String GUI_SIZE_TITLE; + public static String GUI_SIZE_MIN; + public static String GUI_SIZE_MAX; + public static String GUI_SIZE_MAX_NO_LESS; + public static String GUI_SELECT_FILE; + public static String GUI_SELECT_ITEM; + public static String GUI_ADD_NEW_KEY; + public static String GUI_DUPE_INVALID_KEY; + public static String GUI_SEARCH; + public static String GUI_TEMP_NEW_KEY; + public static String GUI_SET_NEW_KEY; + public static String GUI_EDIT_KEY; } diff --git a/common/src/main/java/net/momirealms/customfishing/common/locale/TranslationManager.java b/common/src/main/java/net/momirealms/customfishing/common/locale/TranslationManager.java index dd084ade..cec8c36f 100644 --- a/common/src/main/java/net/momirealms/customfishing/common/locale/TranslationManager.java +++ b/common/src/main/java/net/momirealms/customfishing/common/locale/TranslationManager.java @@ -20,7 +20,7 @@ import java.util.stream.Stream; public class TranslationManager { public static final Locale DEFAULT_LOCALE = Locale.ENGLISH; - private static final List locales = List.of("en"); + private static final List locales = List.of("en", "zh_cn"); private final CustomFishingPlugin plugin; private final Set installed = ConcurrentHashMap.newKeySet(); @@ -40,7 +40,7 @@ public class TranslationManager { } for (String lang : locales) { - this.plugin.getConfigManager().loadConfig("translations/" + lang + ".yml"); + this.plugin.getConfigManager().saveResource("translations/" + lang + ".yml"); } this.registry = MiniMessageTranslationRegistry.create(Key.key("customfishing", "main"), AdventureHelper.getMiniMessage()); diff --git a/compatibility/build.gradle.kts b/compatibility/build.gradle.kts index 86bfc239..e211e820 100644 --- a/compatibility/build.gradle.kts +++ b/compatibility/build.gradle.kts @@ -8,6 +8,7 @@ repositories { maven("https://repo.oraxen.com/releases/") // oraxen maven("https://repo.auxilor.io/repository/maven-public/") // eco maven("https://nexus.betonquest.org/repository/betonquest/") // betonquest + maven("https://repo.dmulloy2.net/repository/public/") // betonquest needs packet wrapper? } dependencies { @@ -48,7 +49,7 @@ dependencies { compileOnly("net.Indyuce:MMOItems-API:6.10-SNAPSHOT") compileOnly("io.lumine:MythicLib-dist:1.6.2-SNAPSHOT") compileOnly("pers.neige.neigeitems:NeigeItems:1.17.13") - compileOnly("io.th0rgal:oraxen:1.175.0") + compileOnly("io.th0rgal:oraxen:1.168.0") // entity compileOnly("io.lumine:Mythic-Dist:5.6.2") // eco diff --git a/compatibility/src/main/java/net/momirealms/customfishing/bukkit/integration/item/CustomFishingItemProvider.java b/compatibility/src/main/java/net/momirealms/customfishing/bukkit/integration/item/CustomFishingItemProvider.java index a5148f5c..b1421a76 100644 --- a/compatibility/src/main/java/net/momirealms/customfishing/bukkit/integration/item/CustomFishingItemProvider.java +++ b/compatibility/src/main/java/net/momirealms/customfishing/bukkit/integration/item/CustomFishingItemProvider.java @@ -17,10 +17,10 @@ package net.momirealms.customfishing.bukkit.integration.item; -import net.kyori.adventure.key.Key; import net.momirealms.customfishing.api.BukkitCustomFishingPlugin; import net.momirealms.customfishing.api.integration.ItemProvider; import net.momirealms.customfishing.api.mechanic.context.Context; +import net.momirealms.customfishing.common.util.Key; import org.bukkit.entity.Player; import org.bukkit.inventory.ItemStack; import org.jetbrains.annotations.NotNull; @@ -38,7 +38,13 @@ public class CustomFishingItemProvider implements ItemProvider { @Override public ItemStack buildItem(@NotNull Player player, @NotNull String id) { String[] split = id.split(":", 2); - ItemStack itemStack = BukkitCustomFishingPlugin.getInstance().getItemManager().buildInternal(Context.player(player), Key.key(split[0], split[1])); + String finalID; + if (split.length != 2) { + finalID = split[0]; + } else { + finalID = split[1]; + } + ItemStack itemStack = BukkitCustomFishingPlugin.getInstance().getItemManager().buildInternal(Context.player(player), finalID); return requireNonNull(itemStack); } diff --git a/compatibility/src/main/java/net/momirealms/customfishing/bukkit/integration/papi/CompetitionPapi.java b/compatibility/src/main/java/net/momirealms/customfishing/bukkit/integration/papi/CompetitionPapi.java index b7f2d615..6382605b 100644 --- a/compatibility/src/main/java/net/momirealms/customfishing/bukkit/integration/papi/CompetitionPapi.java +++ b/compatibility/src/main/java/net/momirealms/customfishing/bukkit/integration/papi/CompetitionPapi.java @@ -1,144 +1,144 @@ -/* - * Copyright (C) <2022> - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - -package net.momirealms.customfishing.bukkit.integration.papi; - -import me.clip.placeholderapi.expansion.PlaceholderExpansion; -import net.momirealms.customfishing.api.BukkitCustomFishingPlugin; -import net.momirealms.customfishing.api.mechanic.competition.FishingCompetition; -import org.bukkit.OfflinePlayer; -import org.jetbrains.annotations.NotNull; -import org.jetbrains.annotations.Nullable; - -import java.util.Optional; - -public class CompetitionPapi extends PlaceholderExpansion { - - private final BukkitCustomFishingPlugin plugin; - - public CompetitionPapi(BukkitCustomFishingPlugin plugin) { - this.plugin = plugin; - } - - public void load() { - super.register(); - } - - public void unload() { - super.unregister(); - } - - @Override - public @NotNull String getIdentifier() { - return "cfcompetition"; - } - - @Override - public @NotNull String getAuthor() { - return "XiaoMoMi"; - } - - @Override - public @NotNull String getVersion() { - return "2.0"; - } - - @Override - public boolean persist() { - return true; - } - - @Override - public @Nullable String onRequest(OfflinePlayer player, @NotNull String params) { - switch (params) { - case "goingon" -> { - return String.valueOf(plugin.getCompetitionManager().getOnGoingCompetition() != null); - } - case "nextseconds" -> { - return String.valueOf(plugin.getCompetitionManager().getNextCompetitionInSeconds()); - } - case "nextsecond" -> { - return plugin.getCompetitionManager().getNextCompetitionInSeconds() % 60 + CFLocale.FORMAT_Second; - } - case "nextminute" -> { - int sec = plugin.getCompetitionManager().getNextCompetitionInSeconds(); - int min = (sec % 3600) / 60; - return sec < 60 ? "" : min + CFLocale.FORMAT_Minute; - } - case "nexthour" -> { - int sec = plugin.getCompetitionManager().getNextCompetitionInSeconds(); - int h = (sec % (3600 * 24)) / 3600; - return sec < 3600 ? "" : h + CFLocale.FORMAT_Hour; - } - case "nextday" -> { - int sec = plugin.getCompetitionManager().getNextCompetitionInSeconds(); - int day = sec / (3600 * 24); - return day == 0 ? "" : day + CFLocale.FORMAT_Day; - } - case "rank" -> { - FishingCompetition competition = plugin.getCompetitionManager().getOnGoingCompetition(); - if (competition == null) return ""; - else return String.valueOf(competition.getRanking().getPlayerRank(player.getName())); - } - case "goal" -> { - FishingCompetition competition = plugin.getCompetitionManager().getOnGoingCompetition(); - if (competition == null) return ""; - else return competition.getGoal().name(); - } - case "seconds" -> { - FishingCompetition competition = plugin.getCompetitionManager().getOnGoingCompetition(); - if (competition == null) return ""; - return competition.getCachedPlaceholder("{seconds}"); - } - case "second" -> { - FishingCompetition competition = plugin.getCompetitionManager().getOnGoingCompetition(); - if (competition == null) return ""; - return competition.getCachedPlaceholder("{second}"); - } - case "minute" -> { - FishingCompetition competition = plugin.getCompetitionManager().getOnGoingCompetition(); - if (competition == null) return ""; - return competition.getCachedPlaceholder("{minute}"); - } - case "hour" -> { - FishingCompetition competition = plugin.getCompetitionManager().getOnGoingCompetition(); - if (competition == null) return ""; - return competition.getCachedPlaceholder("{hour}"); - } - } - - String[] split = params.split("_", 2); - switch (split[0]) { - case "score" -> { - FishingCompetition competition = plugin.getCompetitionManager().getOnGoingCompetition(); - if (competition == null) return ""; - if (split.length == 1) { - return String.format("%.2f", competition.getRanking().getPlayerScore(player.getName())); - } else { - return String.format("%.2f", competition.getRanking().getScoreAt(Integer.parseInt(split[1]))); - } - } - case "player" -> { - FishingCompetition competition = plugin.getCompetitionManager().getOnGoingCompetition(); - if (competition == null) return ""; - if (split.length == 1) return "Invalid format"; - return Optional.ofNullable(competition.getRanking().getPlayerAt(Integer.parseInt(split[1]))).orElse(""); - } - } - return "null"; - } -} +///* +// * Copyright (C) <2022> +// * +// * This program is free software: you can redistribute it and/or modify +// * it under the terms of the GNU General Public License as published by +// * the Free Software Foundation, either version 3 of the License, or +// * any later version. +// * +// * This program is distributed in the hope that it will be useful, +// * but WITHOUT ANY WARRANTY; without even the implied warranty of +// * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// * GNU General Public License for more details. +// * +// * You should have received a copy of the GNU General Public License +// * along with this program. If not, see . +// */ +// +//package net.momirealms.customfishing.bukkit.integration.papi; +// +//import me.clip.placeholderapi.expansion.PlaceholderExpansion; +//import net.momirealms.customfishing.api.BukkitCustomFishingPlugin; +//import net.momirealms.customfishing.api.mechanic.competition.FishingCompetition; +//import org.bukkit.OfflinePlayer; +//import org.jetbrains.annotations.NotNull; +//import org.jetbrains.annotations.Nullable; +// +//import java.util.Optional; +// +//public class CompetitionPapi extends PlaceholderExpansion { +// +// private final BukkitCustomFishingPlugin plugin; +// +// public CompetitionPapi(BukkitCustomFishingPlugin plugin) { +// this.plugin = plugin; +// } +// +// public void load() { +// super.register(); +// } +// +// public void unload() { +// super.unregister(); +// } +// +// @Override +// public @NotNull String getIdentifier() { +// return "cfcompetition"; +// } +// +// @Override +// public @NotNull String getAuthor() { +// return "XiaoMoMi"; +// } +// +// @Override +// public @NotNull String getVersion() { +// return "2.0"; +// } +// +// @Override +// public boolean persist() { +// return true; +// } +// +// @Override +// public @Nullable String onRequest(OfflinePlayer player, @NotNull String params) { +// switch (params) { +// case "goingon" -> { +// return String.valueOf(plugin.getCompetitionManager().getOnGoingCompetition() != null); +// } +// case "nextseconds" -> { +// return String.valueOf(plugin.getCompetitionManager().getNextCompetitionInSeconds()); +// } +// case "nextsecond" -> { +// return plugin.getCompetitionManager().getNextCompetitionInSeconds() % 60 + CFLocale.FORMAT_Second; +// } +// case "nextminute" -> { +// int sec = plugin.getCompetitionManager().getNextCompetitionInSeconds(); +// int min = (sec % 3600) / 60; +// return sec < 60 ? "" : min + CFLocale.FORMAT_Minute; +// } +// case "nexthour" -> { +// int sec = plugin.getCompetitionManager().getNextCompetitionInSeconds(); +// int h = (sec % (3600 * 24)) / 3600; +// return sec < 3600 ? "" : h + CFLocale.FORMAT_Hour; +// } +// case "nextday" -> { +// int sec = plugin.getCompetitionManager().getNextCompetitionInSeconds(); +// int day = sec / (3600 * 24); +// return day == 0 ? "" : day + CFLocale.FORMAT_Day; +// } +// case "rank" -> { +// FishingCompetition competition = plugin.getCompetitionManager().getOnGoingCompetition(); +// if (competition == null) return ""; +// else return String.valueOf(competition.getRanking().getPlayerRank(player.getName())); +// } +// case "goal" -> { +// FishingCompetition competition = plugin.getCompetitionManager().getOnGoingCompetition(); +// if (competition == null) return ""; +// else return competition.getGoal().name(); +// } +// case "seconds" -> { +// FishingCompetition competition = plugin.getCompetitionManager().getOnGoingCompetition(); +// if (competition == null) return ""; +// return competition.getCachedPlaceholder("{seconds}"); +// } +// case "second" -> { +// FishingCompetition competition = plugin.getCompetitionManager().getOnGoingCompetition(); +// if (competition == null) return ""; +// return competition.getCachedPlaceholder("{second}"); +// } +// case "minute" -> { +// FishingCompetition competition = plugin.getCompetitionManager().getOnGoingCompetition(); +// if (competition == null) return ""; +// return competition.getCachedPlaceholder("{minute}"); +// } +// case "hour" -> { +// FishingCompetition competition = plugin.getCompetitionManager().getOnGoingCompetition(); +// if (competition == null) return ""; +// return competition.getCachedPlaceholder("{hour}"); +// } +// } +// +// String[] split = params.split("_", 2); +// switch (split[0]) { +// case "score" -> { +// FishingCompetition competition = plugin.getCompetitionManager().getOnGoingCompetition(); +// if (competition == null) return ""; +// if (split.length == 1) { +// return String.format("%.2f", competition.getRanking().getPlayerScore(player.getName())); +// } else { +// return String.format("%.2f", competition.getRanking().getScoreAt(Integer.parseInt(split[1]))); +// } +// } +// case "player" -> { +// FishingCompetition competition = plugin.getCompetitionManager().getOnGoingCompetition(); +// if (competition == null) return ""; +// if (split.length == 1) return "Invalid format"; +// return Optional.ofNullable(competition.getRanking().getPlayerAt(Integer.parseInt(split[1]))).orElse(""); +// } +// } +// return "null"; +// } +//} diff --git a/compatibility/src/main/java/net/momirealms/customfishing/bukkit/integration/papi/CustomFishingPapi.java b/compatibility/src/main/java/net/momirealms/customfishing/bukkit/integration/papi/CustomFishingPapi.java index 2d9297a5..74170889 100644 --- a/compatibility/src/main/java/net/momirealms/customfishing/bukkit/integration/papi/CustomFishingPapi.java +++ b/compatibility/src/main/java/net/momirealms/customfishing/bukkit/integration/papi/CustomFishingPapi.java @@ -1,126 +1,126 @@ -/* - * Copyright (C) <2022> - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - -package net.momirealms.customfishing.bukkit.integration.papi; - -import me.clip.placeholderapi.expansion.PlaceholderExpansion; -import net.momirealms.customfishing.api.BukkitCustomFishingPlugin; -import org.bukkit.Bukkit; -import org.bukkit.OfflinePlayer; -import org.bukkit.entity.Player; -import org.jetbrains.annotations.NotNull; -import org.jetbrains.annotations.Nullable; - -public class CustomFishingPapi extends PlaceholderExpansion { - - private final BukkitCustomFishingPlugin plugin; - - public CustomFishingPapi(BukkitCustomFishingPlugin plugin) { - this.plugin = plugin; - } - - public void load() { - super.register(); - } - - public void unload() { - super.unregister(); - } - - @Override - public @NotNull String getIdentifier() { - return "customfishing"; - } - - @Override - public @NotNull String getAuthor() { - return "XiaoMoMi"; - } - - @Override - public @NotNull String getVersion() { - return "2.0"; - } - - @Override - public boolean persist() { - return true; - } - - @Override - public @Nullable String onRequest(OfflinePlayer offlinePlayer, @NotNull String params) { - String[] split = params.split("_"); - - Player player = offlinePlayer.getPlayer(); - if (player == null) - return ""; - - switch (split[0]) { - case "market" -> { - if (split.length < 2) - return null; - switch (split[1]) { - case "limit" -> { - if (split.length < 3) { - return String.format("%.2f", plugin.getMarketManager().earningLimit(player)); - } else { - Player another = Bukkit.getPlayer(split[2]); - if (another == null) { - return ""; - } - return String.format("%.2f", plugin.getMarketManager().earningLimit(another)); - } - } - case "earnings" -> { - OnlineUserData user; - if (split.length < 3) { - user = plugin.getStorageManager().getOnlineUser(player.getUniqueId()); - } else { - Player another = Bukkit.getPlayer(split[2]); - if (another == null) { - return ""; - } - user = plugin.getStorageManager().getOnlineUser(another.getUniqueId()); - } - if (user == null) - return ""; - return String.format("%.2f", user.getEarningData().earnings); - } - case "canearn" -> { - if (split.length < 3) { - OnlineUserData user = plugin.getStorageManager().getOnlineUser(player.getUniqueId()); - if (user == null) - return ""; - return String.format("%.2f", plugin.getMarketManager().earningLimit(player) - user.getEarningData().earnings); - } else { - Player another = Bukkit.getPlayer(split[2]); - if (another == null) { - return ""; - } - - OnlineUserData user = plugin.getStorageManager().getOnlineUser(another.getUniqueId()); - if (user == null) - return ""; - return String.format("%.2f", plugin.getMarketManager().earningLimit(another) - user.getEarningData().earnings); - } - } - } - } - } - return null; - } -} +///* +// * Copyright (C) <2022> +// * +// * This program is free software: you can redistribute it and/or modify +// * it under the terms of the GNU General Public License as published by +// * the Free Software Foundation, either version 3 of the License, or +// * any later version. +// * +// * This program is distributed in the hope that it will be useful, +// * but WITHOUT ANY WARRANTY; without even the implied warranty of +// * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// * GNU General Public License for more details. +// * +// * You should have received a copy of the GNU General Public License +// * along with this program. If not, see . +// */ +// +//package net.momirealms.customfishing.bukkit.integration.papi; +// +//import me.clip.placeholderapi.expansion.PlaceholderExpansion; +//import net.momirealms.customfishing.api.BukkitCustomFishingPlugin; +//import org.bukkit.Bukkit; +//import org.bukkit.OfflinePlayer; +//import org.bukkit.entity.Player; +//import org.jetbrains.annotations.NotNull; +//import org.jetbrains.annotations.Nullable; +// +//public class CustomFishingPapi extends PlaceholderExpansion { +// +// private final BukkitCustomFishingPlugin plugin; +// +// public CustomFishingPapi(BukkitCustomFishingPlugin plugin) { +// this.plugin = plugin; +// } +// +// public void load() { +// super.register(); +// } +// +// public void unload() { +// super.unregister(); +// } +// +// @Override +// public @NotNull String getIdentifier() { +// return "customfishing"; +// } +// +// @Override +// public @NotNull String getAuthor() { +// return "XiaoMoMi"; +// } +// +// @Override +// public @NotNull String getVersion() { +// return "2.0"; +// } +// +// @Override +// public boolean persist() { +// return true; +// } +// +// @Override +// public @Nullable String onRequest(OfflinePlayer offlinePlayer, @NotNull String params) { +// String[] split = params.split("_"); +// +// Player player = offlinePlayer.getPlayer(); +// if (player == null) +// return ""; +// +// switch (split[0]) { +// case "market" -> { +// if (split.length < 2) +// return null; +// switch (split[1]) { +// case "limit" -> { +// if (split.length < 3) { +// return String.format("%.2f", plugin.getMarketManager().earningLimit(player)); +// } else { +// Player another = Bukkit.getPlayer(split[2]); +// if (another == null) { +// return ""; +// } +// return String.format("%.2f", plugin.getMarketManager().earningLimit(another)); +// } +// } +// case "earnings" -> { +// OnlineUserData user; +// if (split.length < 3) { +// user = plugin.getStorageManager().getOnlineUser(player.getUniqueId()); +// } else { +// Player another = Bukkit.getPlayer(split[2]); +// if (another == null) { +// return ""; +// } +// user = plugin.getStorageManager().getOnlineUser(another.getUniqueId()); +// } +// if (user == null) +// return ""; +// return String.format("%.2f", user.getEarningData().earnings); +// } +// case "canearn" -> { +// if (split.length < 3) { +// OnlineUserData user = plugin.getStorageManager().getOnlineUser(player.getUniqueId()); +// if (user == null) +// return ""; +// return String.format("%.2f", plugin.getMarketManager().earningLimit(player) - user.getEarningData().earnings); +// } else { +// Player another = Bukkit.getPlayer(split[2]); +// if (another == null) { +// return ""; +// } +// +// OnlineUserData user = plugin.getStorageManager().getOnlineUser(another.getUniqueId()); +// if (user == null) +// return ""; +// return String.format("%.2f", plugin.getMarketManager().earningLimit(another) - user.getEarningData().earnings); +// } +// } +// } +// } +// } +// return null; +// } +//} diff --git a/compatibility/src/main/java/net/momirealms/customfishing/bukkit/integration/papi/StatisticsPapi.java b/compatibility/src/main/java/net/momirealms/customfishing/bukkit/integration/papi/StatisticsPapi.java index ed6a1fec..051c288e 100644 --- a/compatibility/src/main/java/net/momirealms/customfishing/bukkit/integration/papi/StatisticsPapi.java +++ b/compatibility/src/main/java/net/momirealms/customfishing/bukkit/integration/papi/StatisticsPapi.java @@ -1,112 +1,112 @@ -/* - * Copyright (C) <2022> - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - -package net.momirealms.customfishing.bukkit.integration.papi; - -import me.clip.placeholderapi.expansion.PlaceholderExpansion; -import net.momirealms.customfishing.api.BukkitCustomFishingPlugin; -import org.bukkit.OfflinePlayer; -import org.jetbrains.annotations.NotNull; -import org.jetbrains.annotations.Nullable; - -import java.util.List; - -public class StatisticsPapi extends PlaceholderExpansion { - - private final BukkitCustomFishingPlugin plugin; - - public StatisticsPapi(BukkitCustomFishingPlugin plugin) { - this.plugin = plugin; - } - - public void load() { - super.register(); - } - - public void unload() { - super.unregister(); - } - - @Override - public @NotNull String getIdentifier() { - return "fishingstats"; - } - - @Override - public @NotNull String getAuthor() { - return "XiaoMoMi"; - } - - @Override - public @NotNull String getVersion() { - return "2.0"; - } - - @Override - public boolean persist() { - return true; - } - - @Override - public @Nullable String onRequest(OfflinePlayer player, @NotNull String params) { - OnlineUserData onlineUser = plugin.getStorageManager().getOnlineUser(player.getUniqueId()); - if (onlineUser == null) return "Data not loaded"; - Statistics statistics = onlineUser.getStatistics(); - String[] split = params.split("_", 2); - switch (split[0]) { - case "total" -> { - return String.valueOf(statistics.getTotalCatchAmount()); - } - case "hascaught" -> { - if (split.length == 1) return "Invalid format"; - return String.valueOf(statistics.getLootAmount(split[1]) != 0); - } - case "amount" -> { - if (split.length == 1) return "Invalid format"; - return String.valueOf(statistics.getLootAmount(split[1])); - } - case "size-record" -> { - return String.format("%.2f", statistics.getSizeRecord(split[1])); - } - case "category" -> { - if (split.length == 1) return "Invalid format"; - String[] categorySplit = split[1].split("_", 2); - if (categorySplit.length == 1) return "Invalid format"; - List category = plugin.getStatisticsManager().getCategory(categorySplit[1]); - if (category == null) return "Category Not Exists"; - if (categorySplit[0].equals("total")) { - int total = 0; - for (String loot : category) { - total += statistics.getLootAmount(loot); - } - return String.valueOf(total); - } else if (categorySplit[0].equals("progress")) { - int size = category.size(); - int unlocked = 0; - for (String loot : category) { - if (statistics.getLootAmount(loot) != 0) unlocked++; - } - double percent = ((double) unlocked * 100) / size; - String progress = String.format("%.1f", percent); - return progress.equals("100.0") ? "100" : progress; - } - } - } - - return "null"; - } -} +///* +// * Copyright (C) <2022> +// * +// * This program is free software: you can redistribute it and/or modify +// * it under the terms of the GNU General Public License as published by +// * the Free Software Foundation, either version 3 of the License, or +// * any later version. +// * +// * This program is distributed in the hope that it will be useful, +// * but WITHOUT ANY WARRANTY; without even the implied warranty of +// * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// * GNU General Public License for more details. +// * +// * You should have received a copy of the GNU General Public License +// * along with this program. If not, see . +// */ +// +//package net.momirealms.customfishing.bukkit.integration.papi; +// +//import me.clip.placeholderapi.expansion.PlaceholderExpansion; +//import net.momirealms.customfishing.api.BukkitCustomFishingPlugin; +//import org.bukkit.OfflinePlayer; +//import org.jetbrains.annotations.NotNull; +//import org.jetbrains.annotations.Nullable; +// +//import java.util.List; +// +//public class StatisticsPapi extends PlaceholderExpansion { +// +// private final BukkitCustomFishingPlugin plugin; +// +// public StatisticsPapi(BukkitCustomFishingPlugin plugin) { +// this.plugin = plugin; +// } +// +// public void load() { +// super.register(); +// } +// +// public void unload() { +// super.unregister(); +// } +// +// @Override +// public @NotNull String getIdentifier() { +// return "fishingstats"; +// } +// +// @Override +// public @NotNull String getAuthor() { +// return "XiaoMoMi"; +// } +// +// @Override +// public @NotNull String getVersion() { +// return "2.0"; +// } +// +// @Override +// public boolean persist() { +// return true; +// } +// +// @Override +// public @Nullable String onRequest(OfflinePlayer player, @NotNull String params) { +// OnlineUserData onlineUser = plugin.getStorageManager().getOnlineUser(player.getUniqueId()); +// if (onlineUser == null) return "Data not loaded"; +// Statistics statistics = onlineUser.getStatistics(); +// String[] split = params.split("_", 2); +// switch (split[0]) { +// case "total" -> { +// return String.valueOf(statistics.getTotalCatchAmount()); +// } +// case "hascaught" -> { +// if (split.length == 1) return "Invalid format"; +// return String.valueOf(statistics.getLootAmount(split[1]) != 0); +// } +// case "amount" -> { +// if (split.length == 1) return "Invalid format"; +// return String.valueOf(statistics.getLootAmount(split[1])); +// } +// case "size-record" -> { +// return String.format("%.2f", statistics.getSizeRecord(split[1])); +// } +// case "category" -> { +// if (split.length == 1) return "Invalid format"; +// String[] categorySplit = split[1].split("_", 2); +// if (categorySplit.length == 1) return "Invalid format"; +// List category = plugin.getStatisticsManager().getCategory(categorySplit[1]); +// if (category == null) return "Category Not Exists"; +// if (categorySplit[0].equals("total")) { +// int total = 0; +// for (String loot : category) { +// total += statistics.getLootAmount(loot); +// } +// return String.valueOf(total); +// } else if (categorySplit[0].equals("progress")) { +// int size = category.size(); +// int unlocked = 0; +// for (String loot : category) { +// if (statistics.getLootAmount(loot) != 0) unlocked++; +// } +// double percent = ((double) unlocked * 100) / size; +// String progress = String.format("%.1f", percent); +// return progress.equals("100.0") ? "100" : progress; +// } +// } +// } +// +// return "null"; +// } +//} diff --git a/core/build.gradle.kts b/core/build.gradle.kts index 3e577bdc..99fe8e4b 100644 --- a/core/build.gradle.kts +++ b/core/build.gradle.kts @@ -47,6 +47,8 @@ dependencies { compileOnly("org.incendo:cloud-core:${rootProject.properties["cloud_core_version"]}") compileOnly("org.incendo:cloud-minecraft-extras:${rootProject.properties["cloud_minecraft_extras_version"]}") compileOnly("org.incendo:cloud-paper:${rootProject.properties["cloud_paper_version"]}") + // expression + compileOnly("net.objecthunter:exp4j:${rootProject.properties["exp4j_version"]}") } tasks { diff --git a/core/src/main/java/net/momirealms/customfishing/bukkit/BukkitCustomFishingPluginImpl.java b/core/src/main/java/net/momirealms/customfishing/bukkit/BukkitCustomFishingPluginImpl.java new file mode 100644 index 00000000..3a7cbcf4 --- /dev/null +++ b/core/src/main/java/net/momirealms/customfishing/bukkit/BukkitCustomFishingPluginImpl.java @@ -0,0 +1,191 @@ +package net.momirealms.customfishing.bukkit; + +import net.momirealms.customfishing.api.BukkitCustomFishingPlugin; +import net.momirealms.customfishing.api.mechanic.config.ConfigManager; +import net.momirealms.customfishing.api.mechanic.misc.cooldown.CoolDownManager; +import net.momirealms.customfishing.api.mechanic.misc.placeholder.BukkitPlaceholderManager; +import net.momirealms.customfishing.bukkit.action.BukkitActionManager; +import net.momirealms.customfishing.bukkit.bag.BukkitBagManager; +import net.momirealms.customfishing.bukkit.block.BukkitBlockManager; +import net.momirealms.customfishing.bukkit.competition.BukkitCompetitionManager; +import net.momirealms.customfishing.bukkit.config.BukkitConfigManager; +import net.momirealms.customfishing.bukkit.effect.BukkitEffectManager; +import net.momirealms.customfishing.bukkit.entity.BukkitEntityManager; +import net.momirealms.customfishing.bukkit.event.BukkitEventManager; +import net.momirealms.customfishing.bukkit.hook.BukkitHookManager; +import net.momirealms.customfishing.bukkit.integration.BukkitIntegrationManager; +import net.momirealms.customfishing.bukkit.item.BukkitItemManager; +import net.momirealms.customfishing.bukkit.loot.BukkitLootManager; +import net.momirealms.customfishing.bukkit.market.BukkitMarketManager; +import net.momirealms.customfishing.bukkit.requirement.BukkitRequirementManager; +import net.momirealms.customfishing.bukkit.sender.BukkitSenderFactory; +import net.momirealms.customfishing.bukkit.statistic.BukkitStatisticsManager; +import net.momirealms.customfishing.bukkit.storage.BukkitStorageManager; +import net.momirealms.customfishing.common.dependency.Dependency; +import net.momirealms.customfishing.common.dependency.DependencyManagerImpl; +import net.momirealms.customfishing.common.helper.VersionHelper; +import net.momirealms.customfishing.common.locale.TranslationManager; +import net.momirealms.customfishing.common.plugin.classpath.ClassPathAppender; +import net.momirealms.customfishing.common.plugin.classpath.ReflectionClassPathAppender; +import net.momirealms.customfishing.common.plugin.logging.JavaPluginLogger; +import net.momirealms.customfishing.common.plugin.logging.PluginLogger; +import org.bstats.bukkit.Metrics; +import org.bukkit.Bukkit; +import org.bukkit.plugin.Plugin; +import org.bukkit.plugin.java.JavaPlugin; + +import java.io.InputStream; +import java.nio.file.Path; +import java.util.List; + +public class BukkitCustomFishingPluginImpl extends BukkitCustomFishingPlugin { + + private final ClassPathAppender classPathAppender; + private final PluginLogger logger; + + public BukkitCustomFishingPluginImpl(Plugin boostrap) { + super(boostrap); + VersionHelper.init(getServerVersion()); + this.classPathAppender = new ReflectionClassPathAppender(this); + this.logger = new JavaPluginLogger(getBoostrap().getLogger()); + this.eventManager = new BukkitEventManager(this); + this.configManager = new BukkitConfigManager(this); + this.requirementManager = new BukkitRequirementManager(this); + this.actionManager = new BukkitActionManager(this); + this.senderFactory = new BukkitSenderFactory(this); + this.placeholderManager = new BukkitPlaceholderManager(this); + this.itemManager = new BukkitItemManager(this); + this.integrationManager = new BukkitIntegrationManager(this); + this.competitionManager = new BukkitCompetitionManager(this); + this.marketManager = new BukkitMarketManager(this); + this.storageManager = new BukkitStorageManager(this); + this.lootManager = new BukkitLootManager(this); + this.coolDownManager = new CoolDownManager(this); + this.entityManager = new BukkitEntityManager(this); + this.blockManager = new BukkitBlockManager(this); + this.statisticsManager = new BukkitStatisticsManager(this); + this.effectManager = new BukkitEffectManager(this); + this.hookManager = new BukkitHookManager(this); + this.bagManager = new BukkitBagManager(this); + this.dependencyManager = new DependencyManagerImpl(this); + this.translationManager = new TranslationManager(this); + } + + @Override + public void load() { + this.dependencyManager.loadDependencies( + List.of(Dependency.BOOSTED_YAML, + Dependency.BSTATS_BASE, + Dependency.BSTATS_BUKKIT, + Dependency.CAFFEINE, + Dependency.CLOUD_CORE, + Dependency.CLOUD_SERVICES, + Dependency.CLOUD_BUKKIT, + Dependency.CLOUD_PAPER, + Dependency.CLOUD_BRIGADIER, + Dependency.CLOUD_MINECRAFT_EXTRAS, + Dependency.GSON, + Dependency.COMMONS_POOL_2, + Dependency.JEDIS, + Dependency.EXP4J, + Dependency.MYSQL_DRIVER, + Dependency.MARIADB_DRIVER, + Dependency.SQLITE_DRIVER, + Dependency.H2_DRIVER, + Dependency.MONGODB_DRIVER_CORE, + Dependency.MONGODB_DRIVER_SYNC, + Dependency.MONGODB_DRIVER_BSON, + Dependency.HIKARI_CP) + ); + } + + @Override + public void enable() { + this.reload(); + if (ConfigManager.metrics()) new Metrics((JavaPlugin) getBoostrap(), 16648); + if (ConfigManager.checkUpdate()) { + VersionHelper.UPDATE_CHECKER.apply(this).thenAccept(result -> { + if (!result) this.getPluginLogger().info("You are using the latest version."); + else this.getPluginLogger().warn("Update is available: https://polymart.org/resource/2723"); + }); + } + this.integrationManager.load(); + this.initialized = true; + } + + @Override + public void reload() { + this.eventManager.reload(); + this.configManager.reload(); + this.requirementManager.reload(); + this.actionManager.reload(); + this.placeholderManager.reload(); + this.itemManager.reload(); + this.competitionManager.reload(); + this.marketManager.reload(); + this.storageManager.reload(); + this.lootManager.reload(); + this.coolDownManager.reload(); + this.entityManager.reload(); + this.blockManager.reload(); + this.statisticsManager.reload(); + this.effectManager.reload(); + this.hookManager.reload(); + this.bagManager.reload(); + this.translationManager.reload(); + } + + @Override + public void disable() { + this.eventManager.disable(); + this.configManager.disable(); + this.requirementManager.disable(); + this.actionManager.disable(); + this.placeholderManager.disable(); + this.itemManager.disable(); + this.competitionManager.disable(); + this.marketManager.disable(); + this.storageManager.disable(); + this.lootManager.disable(); + this.coolDownManager.disable(); + this.entityManager.disable(); + this.blockManager.disable(); + this.statisticsManager.disable(); + this.effectManager.disable(); + this.hookManager.disable(); + this.bagManager.disable(); + this.integrationManager.disable(); + this.initialized = false; + } + + @Override + public InputStream getResourceStream(String filePath) { + return getBoostrap().getResource(filePath); + } + + @Override + public PluginLogger getPluginLogger() { + return logger; + } + + @Override + public ClassPathAppender getClassPathAppender() { + return classPathAppender; + } + + @Override + public Path getDataDirectory() { + return getBoostrap().getDataFolder().toPath().toAbsolutePath(); + } + + @Override + public String getServerVersion() { + return Bukkit.getServer().getBukkitVersion().split("-")[0]; + } + + @SuppressWarnings("deprecation") + @Override + public String getPluginVersion() { + return getBoostrap().getDescription().getVersion(); + } +} diff --git a/core/src/main/java/net/momirealms/customfishing/bukkit/action/BukkitActionManager.java b/core/src/main/java/net/momirealms/customfishing/bukkit/action/BukkitActionManager.java index eabf4049..cf88141e 100644 --- a/core/src/main/java/net/momirealms/customfishing/bukkit/action/BukkitActionManager.java +++ b/core/src/main/java/net/momirealms/customfishing/bukkit/action/BukkitActionManager.java @@ -13,7 +13,6 @@ import net.momirealms.customfishing.api.mechanic.misc.value.MathValue; import net.momirealms.customfishing.api.mechanic.misc.value.TextValue; import net.momirealms.customfishing.api.mechanic.requirement.Requirement; import net.momirealms.customfishing.bukkit.integration.VaultHook; -import net.momirealms.customfishing.bukkit.util.ItemUtils; import net.momirealms.customfishing.bukkit.util.LocationUtils; import net.momirealms.customfishing.bukkit.util.PlayerUtils; import net.momirealms.customfishing.common.helper.AdventureHelper; @@ -52,6 +51,16 @@ public class BukkitActionManager implements ActionManager { public BukkitActionManager(BukkitCustomFishingPlugin plugin) { this.plugin = plugin; this.registerBuiltInActions(); + + } + + @Override + public void disable() { + this.actionFactoryMap.clear(); + } + + @Override + public void reload() { this.loadExpansions(); } @@ -393,11 +402,11 @@ public class BukkitActionManager implements ActionManager { if (Math.random() > chance) return; Player player = context.getHolder(); ItemStack itemStack = player.getInventory().getItem(slot); - if (amount > 0) { - ItemUtils.increaseDurability(itemStack, amount, true); - } else { - ItemUtils.decreaseDurability(context.getHolder(), itemStack, -amount, true); - } +// if (amount > 0) { +// ItemUtils.increaseDurability(itemStack, amount, true); +// } else { +// ItemUtils.decreaseDurability(context.getHolder(), itemStack, -amount, true); +// } }; } else { plugin.getPluginLogger().warn("Invalid value type: " + args.getClass().getSimpleName() + " found at durability action which should be Section"); diff --git a/core/src/main/java/net/momirealms/customfishing/bukkit/block/BukkitBlockManager.java b/core/src/main/java/net/momirealms/customfishing/bukkit/block/BukkitBlockManager.java index 53384c06..11e05c59 100644 --- a/core/src/main/java/net/momirealms/customfishing/bukkit/block/BukkitBlockManager.java +++ b/core/src/main/java/net/momirealms/customfishing/bukkit/block/BukkitBlockManager.java @@ -65,7 +65,7 @@ public class BukkitBlockManager implements BlockManager, Listener { private final HashMap stateFactories = new HashMap<>(); private BlockProvider[] blockDetectArray; - public BukkitBlockManager(BukkitCustomFishingPluginImpl plugin) { + public BukkitBlockManager(BukkitCustomFishingPlugin plugin) { this.plugin = plugin; this.registerInbuiltProperties(); this.registerBlockProvider(new BlockProvider() { @@ -88,13 +88,6 @@ public class BukkitBlockManager implements BlockManager, Listener { }); } - @Override - public boolean registerBlock(@NotNull String id, @NotNull BlockConfig block) { - if (blocks.containsKey(id)) return false; - blocks.put(id, block); - return true; - } - @Override public void load() { Bukkit.getPluginManager().registerEvents(this, plugin.getBoostrap()); @@ -122,6 +115,13 @@ public class BukkitBlockManager implements BlockManager, Listener { this.blockDetectArray = list.toArray(new BlockProvider[0]); } + @Override + public boolean registerBlock(@NotNull BlockConfig block) { + if (blocks.containsKey(block.id())) return false; + blocks.put(block.id(), block); + return true; + } + /** * Event handler for the EntityChangeBlockEvent. * This method is triggered when an entity changes a block, typically when a block falls or lands. @@ -230,8 +230,8 @@ public class BukkitBlockManager implements BlockManager, Listener { PersistentDataType.STRING, id + ";" + context.getHolder().getName() ); - Vector vector = playerLocation.subtract(hookLocation).toVector().multiply((config.horizontalVector().evaluate(context)) - 1); - vector = vector.setY((vector.getY() + 0.2) * config.verticalVector().evaluate(context)); + Vector vector = playerLocation.subtract(hookLocation).toVector().multiply(1.2 - 1); + vector = vector.setY((vector.getY() + 0.2) * 1.2); fallingBlock.setVelocity(vector); return fallingBlock; } diff --git a/core/src/main/java/net/momirealms/customfishing/bukkit/command/feature/ReloadCommand.java b/core/src/main/java/net/momirealms/customfishing/bukkit/command/feature/ReloadCommand.java index fd1a1d54..412684f0 100644 --- a/core/src/main/java/net/momirealms/customfishing/bukkit/command/feature/ReloadCommand.java +++ b/core/src/main/java/net/momirealms/customfishing/bukkit/command/feature/ReloadCommand.java @@ -20,7 +20,7 @@ public class ReloadCommand extends BukkitCommandFeature { .flag(manager.flagBuilder("silent")) .handler(context -> { BukkitCustomFishingPlugin.getInstance().reload(); - handleFeedback(context.sender(), MessageConstants.COMMAND_RELOAD); + handleFeedback(context.sender(), MessageConstants.COMMAND_RELOAD_SUCCESS); }); } diff --git a/core/src/main/java/net/momirealms/customfishing/bukkit/config/BukkitConfigLoader.java b/core/src/main/java/net/momirealms/customfishing/bukkit/config/BukkitConfigManager.java similarity index 98% rename from core/src/main/java/net/momirealms/customfishing/bukkit/config/BukkitConfigLoader.java rename to core/src/main/java/net/momirealms/customfishing/bukkit/config/BukkitConfigManager.java index 9729ed4a..7a37a23b 100644 --- a/core/src/main/java/net/momirealms/customfishing/bukkit/config/BukkitConfigLoader.java +++ b/core/src/main/java/net/momirealms/customfishing/bukkit/config/BukkitConfigManager.java @@ -27,9 +27,9 @@ import java.util.*; import java.util.function.BiConsumer; import java.util.function.BiFunction; -public class BukkitConfigLoader extends ConfigManager { +public class BukkitConfigManager extends ConfigManager { - public BukkitConfigLoader(BukkitCustomFishingPlugin plugin) { + public BukkitConfigManager(BukkitCustomFishingPlugin plugin) { super(plugin); this.registerBuiltInItemProperties(); this.registerBuiltInBaseEffectParser(); @@ -438,4 +438,11 @@ public class BukkitConfigLoader extends ConfigManager { return builder -> builder.statisticsKeys(keys); }, "statistics"); } + + @Override + public void saveResource(String filePath) { + if (!new File(plugin.getDataFolder(), filePath).exists()) { + plugin.getBoostrap().saveResource(filePath, false); + } + } } diff --git a/core/src/main/java/net/momirealms/customfishing/bukkit/entity/BukkitEntityManager.java b/core/src/main/java/net/momirealms/customfishing/bukkit/entity/BukkitEntityManager.java index 332b5731..5eb78f45 100644 --- a/core/src/main/java/net/momirealms/customfishing/bukkit/entity/BukkitEntityManager.java +++ b/core/src/main/java/net/momirealms/customfishing/bukkit/entity/BukkitEntityManager.java @@ -76,9 +76,9 @@ public class BukkitEntityManager implements EntityManager { } @Override - public boolean registerEntity(String id, EntityConfig entity) { - if (entities.containsKey(id)) return false; - this.entities.put(id, entity); + public boolean registerEntity(EntityConfig entity) { + if (entities.containsKey(entity.id())) return false; + this.entities.put(entity.id(), entity); return true; } @@ -99,17 +99,17 @@ public class BukkitEntityManager implements EntityManager { EntityConfig config = requireNonNull(entities.get(id), "Entity " + id + " not found"); Location hookLocation = requireNonNull(context.arg(ContextKeys.HOOK_LOCATION)); Location playerLocation = requireNonNull(context.getHolder().getLocation()); - String entityID = config.getEntityID(); + String entityID = config.entityID(); Entity entity; if (entityID.contains(":")) { String[] split = entityID.split(":", 2); EntityProvider provider = requireNonNull(entityProviders.get(split[0]), "EntityProvider " + split[0] + " doesn't exist"); - entity = requireNonNull(provider.spawn(hookLocation, split[1], config.getPropertyMap()), "Entity " + entityID + " doesn't exist"); + entity = requireNonNull(provider.spawn(hookLocation, split[1], config.propertyMap()), "Entity " + entityID + " doesn't exist"); } else { - entity = entityProviders.get("vanilla").spawn(hookLocation, entityID, config.getPropertyMap()); + entity = entityProviders.get("vanilla").spawn(hookLocation, entityID, config.propertyMap()); } - Vector vector = playerLocation.subtract(hookLocation).toVector().multiply((config.getHorizontalVector()) - 1); - vector = vector.setY((vector.getY() + 0.2) * config.getVerticalVector()); + Vector vector = playerLocation.subtract(hookLocation).toVector().multiply(config.horizontalVector().evaluate(context) - 1); + vector = vector.setY((vector.getY() + 0.2) * config.verticalVector().evaluate(context)); entity.setVelocity(vector); return entity; } diff --git a/core/src/main/java/net/momirealms/customfishing/bukkit/gui/icon/BackToFolderItem.java b/core/src/main/java/net/momirealms/customfishing/bukkit/gui/icon/BackToFolderItem.java index 5b702f00..77d60480 100644 --- a/core/src/main/java/net/momirealms/customfishing/bukkit/gui/icon/BackToFolderItem.java +++ b/core/src/main/java/net/momirealms/customfishing/bukkit/gui/icon/BackToFolderItem.java @@ -20,6 +20,9 @@ package net.momirealms.customfishing.bukkit.gui.icon; import net.momirealms.customfishing.bukkit.adventure.ShadedAdventureComponentWrapper; import net.momirealms.customfishing.bukkit.gui.Icon; import net.momirealms.customfishing.bukkit.gui.page.file.FileSelector; +import net.momirealms.customfishing.common.helper.AdventureHelper; +import net.momirealms.customfishing.common.locale.MessageConstants; +import net.momirealms.customfishing.common.locale.TranslationManager; import org.bukkit.Material; import org.bukkit.entity.Player; import org.bukkit.event.inventory.ClickType; @@ -44,10 +47,8 @@ public class BackToFolderItem extends AbstractItem implements Icon { public ItemProvider getItemProvider() { if (file != null && (file.getPath().startsWith("plugins\\CustomFishing\\contents") || file.getPath().startsWith("plugins/CustomFishing/contents"))) { return new ItemBuilder(Material.ORANGE_STAINED_GLASS_PANE) - .setDisplayName(new ShadedAdventureComponentWrapper(AdventureHelper.getInstance().getComponentFromMiniMessage( - CFLocale.GUI_BACK_TO_PARENT_FOLDER - ))) - .setLore(List.of(new ShadedAdventureComponentWrapper(AdventureHelper.getInstance().getComponentFromMiniMessage( + .setDisplayName(new ShadedAdventureComponentWrapper(TranslationManager.render(MessageConstants.GUI_BACK_TO_PARENT_FOLDER.build()))) + .setLore(List.of(new ShadedAdventureComponentWrapper(AdventureHelper.miniMessage( "<#FFA500>-> " + file.getName() )))); } else { diff --git a/core/src/main/java/net/momirealms/customfishing/bukkit/gui/icon/BackToPageItem.java b/core/src/main/java/net/momirealms/customfishing/bukkit/gui/icon/BackToPageItem.java index 519c7a52..b0968aad 100644 --- a/core/src/main/java/net/momirealms/customfishing/bukkit/gui/icon/BackToPageItem.java +++ b/core/src/main/java/net/momirealms/customfishing/bukkit/gui/icon/BackToPageItem.java @@ -19,6 +19,8 @@ package net.momirealms.customfishing.bukkit.gui.icon; import net.momirealms.customfishing.bukkit.adventure.ShadedAdventureComponentWrapper; import net.momirealms.customfishing.bukkit.gui.ParentPage; +import net.momirealms.customfishing.common.locale.MessageConstants; +import net.momirealms.customfishing.common.locale.TranslationManager; import org.bukkit.Material; import org.bukkit.entity.Player; import org.bukkit.event.inventory.ClickType; @@ -39,9 +41,7 @@ public class BackToPageItem extends AbstractItem { @Override public ItemProvider getItemProvider() { return new ItemBuilder(Material.ORANGE_STAINED_GLASS_PANE) - .setDisplayName(new ShadedAdventureComponentWrapper(AdventureHelper.getInstance().getComponentFromMiniMessage( - CFLocale.GUI_BACK_TO_PARENT_PAGE - ))); + .setDisplayName(new ShadedAdventureComponentWrapper(TranslationManager.render(MessageConstants.GUI_BACK_TO_PARENT_PAGE.build()))); } @Override diff --git a/core/src/main/java/net/momirealms/customfishing/bukkit/gui/icon/NextPageItem.java b/core/src/main/java/net/momirealms/customfishing/bukkit/gui/icon/NextPageItem.java index 51d1cbc3..b92457b6 100644 --- a/core/src/main/java/net/momirealms/customfishing/bukkit/gui/icon/NextPageItem.java +++ b/core/src/main/java/net/momirealms/customfishing/bukkit/gui/icon/NextPageItem.java @@ -17,8 +17,11 @@ package net.momirealms.customfishing.bukkit.gui.icon; +import net.kyori.adventure.text.Component; import net.momirealms.customfishing.bukkit.adventure.ShadedAdventureComponentWrapper; import net.momirealms.customfishing.bukkit.gui.Icon; +import net.momirealms.customfishing.common.locale.MessageConstants; +import net.momirealms.customfishing.common.locale.TranslationManager; import org.bukkit.Material; import xyz.xenondevs.invui.gui.PagedGui; import xyz.xenondevs.invui.item.ItemProvider; @@ -34,15 +37,13 @@ public class NextPageItem extends PageItem implements Icon { @Override public ItemProvider getItemProvider(PagedGui gui) { ItemBuilder builder = new ItemBuilder(Material.GREEN_STAINED_GLASS_PANE); - builder.setDisplayName(new ShadedAdventureComponentWrapper(AdventureHelper.getInstance().getComponentFromMiniMessage( - CFLocale.GUI_NEXT_PAGE - ))) - .addLoreLines(new ShadedAdventureComponentWrapper(AdventureHelper.getInstance().getComponentFromMiniMessage( - gui.hasNextPage() - ? CFLocale.GUI_GOTO_NEXT_PAGE - .replace("{0}", String.valueOf(gui.getCurrentPage() + 2)) - .replace("{1}", String.valueOf(gui.getPageAmount())) - : CFLocale.GUI_CANNOT_GOTO_NEXT_PAGE + builder.setDisplayName(new ShadedAdventureComponentWrapper(TranslationManager.render(MessageConstants.GUI_NEXT_PAGE.build()))) + .addLoreLines(new ShadedAdventureComponentWrapper(TranslationManager.render( gui.hasNextPage() + ? MessageConstants.GUI_GOTO_NEXT_PAGE.arguments( + Component.text(gui.getCurrentPage() + 2), + Component.text(gui.getPageAmount()) + ).build() : + MessageConstants.GUI_CANNOT_GOTO_NEXT_PAGE.build() ))); return builder; } diff --git a/core/src/main/java/net/momirealms/customfishing/bukkit/gui/icon/PreviousPageItem.java b/core/src/main/java/net/momirealms/customfishing/bukkit/gui/icon/PreviousPageItem.java index a26925db..e5ea43cf 100644 --- a/core/src/main/java/net/momirealms/customfishing/bukkit/gui/icon/PreviousPageItem.java +++ b/core/src/main/java/net/momirealms/customfishing/bukkit/gui/icon/PreviousPageItem.java @@ -17,8 +17,11 @@ package net.momirealms.customfishing.bukkit.gui.icon; +import net.kyori.adventure.text.Component; import net.momirealms.customfishing.bukkit.adventure.ShadedAdventureComponentWrapper; import net.momirealms.customfishing.bukkit.gui.Icon; +import net.momirealms.customfishing.common.locale.MessageConstants; +import net.momirealms.customfishing.common.locale.TranslationManager; import org.bukkit.Material; import xyz.xenondevs.invui.gui.PagedGui; import xyz.xenondevs.invui.item.ItemProvider; @@ -34,16 +37,13 @@ public class PreviousPageItem extends PageItem implements Icon { @Override public ItemProvider getItemProvider(PagedGui gui) { ItemBuilder builder = new ItemBuilder(Material.RED_STAINED_GLASS_PANE); - builder.setDisplayName(new ShadedAdventureComponentWrapper(AdventureHelper.getInstance().getComponentFromMiniMessage( - CFLocale.GUI_PREVIOUS_PAGE - ))) - .addLoreLines(new ShadedAdventureComponentWrapper(AdventureHelper.getInstance().getComponentFromMiniMessage( - gui.hasPreviousPage() - ? CFLocale.GUI_GOTO_PREVIOUS_PAGE - .replace("{0}", String.valueOf(gui.getCurrentPage())) - .replace("{1}", String.valueOf(gui.getPageAmount())) - : CFLocale.GUI_CANNOT_GOTO_PREVIOUS_PAGE - ))); + builder.setDisplayName(new ShadedAdventureComponentWrapper(TranslationManager.render(MessageConstants.GUI_PREVIOUS_PAGE.build()))) + .addLoreLines(new ShadedAdventureComponentWrapper(TranslationManager.render( gui.hasPreviousPage() + ? MessageConstants.GUI_GOTO_PREVIOUS_PAGE.arguments( + Component.text(gui.getCurrentPage()), + Component.text(gui.getPageAmount()) + ).build() + : MessageConstants.GUI_CANNOT_GOTO_PREVIOUS_PAGE.build()))); return builder; } } diff --git a/core/src/main/java/net/momirealms/customfishing/bukkit/gui/icon/property/item/AmountItem.java b/core/src/main/java/net/momirealms/customfishing/bukkit/gui/icon/property/item/AmountItem.java index 83e09882..85464cdb 100644 --- a/core/src/main/java/net/momirealms/customfishing/bukkit/gui/icon/property/item/AmountItem.java +++ b/core/src/main/java/net/momirealms/customfishing/bukkit/gui/icon/property/item/AmountItem.java @@ -17,9 +17,12 @@ package net.momirealms.customfishing.bukkit.gui.icon.property.item; +import net.kyori.adventure.text.Component; import net.momirealms.customfishing.bukkit.adventure.ShadedAdventureComponentWrapper; import net.momirealms.customfishing.bukkit.gui.SectionPage; import net.momirealms.customfishing.bukkit.gui.page.property.AmountEditor; +import net.momirealms.customfishing.common.locale.MessageConstants; +import net.momirealms.customfishing.common.locale.TranslationManager; import org.bukkit.Material; import org.bukkit.entity.Player; import org.bukkit.event.inventory.ClickType; @@ -40,24 +43,19 @@ public class AmountItem extends AbstractItem { @Override public ItemProvider getItemProvider() { ItemBuilder itemBuilder = new ItemBuilder(Material.IRON_NUGGET) - .setDisplayName(new ShadedAdventureComponentWrapper(AdventureHelper.getComponentFromMiniMessage( - CFLocale.GUI_ITEM_AMOUNT - ))) + .setDisplayName(new ShadedAdventureComponentWrapper(TranslationManager.render(MessageConstants.GUI_ITEM_AMOUNT.build()))) .setAmount(itemPage.getSection().getInt("amount", 1)); if (itemPage.getSection().contains("amount")) { - itemBuilder.addLoreLines(new ShadedAdventureComponentWrapper(AdventureHelper.getInstance().getComponentFromMiniMessage( - CFLocale.GUI_CURRENT_VALUE + itemPage.getSection().getInt("amount") + itemBuilder.addLoreLines(new ShadedAdventureComponentWrapper(TranslationManager.render( + MessageConstants.GUI_CURRENT_VALUE.arguments( + Component.text(itemPage.getSection().getInt("amount")) + ).build() ))) .addLoreLines(""); - itemBuilder.addLoreLines(new ShadedAdventureComponentWrapper(AdventureHelper.getInstance().getComponentFromMiniMessage( - CFLocale.GUI_LEFT_CLICK_EDIT - ))).addLoreLines(new ShadedAdventureComponentWrapper(AdventureHelper.getInstance().getComponentFromMiniMessage( - CFLocale.GUI_RIGHT_CLICK_RESET - ))); + itemBuilder.addLoreLines(new ShadedAdventureComponentWrapper(TranslationManager.render(MessageConstants.GUI_LEFT_CLICK_EDIT.build()))) + .addLoreLines(new ShadedAdventureComponentWrapper(TranslationManager.render(MessageConstants.GUI_RIGHT_CLICK_RESET.build()))); } else { - itemBuilder.addLoreLines(new ShadedAdventureComponentWrapper(AdventureHelper.getInstance().getComponentFromMiniMessage( - CFLocale.GUI_LEFT_CLICK_EDIT - ))); + itemBuilder.addLoreLines(new ShadedAdventureComponentWrapper(TranslationManager.render(MessageConstants.GUI_LEFT_CLICK_EDIT.build()))); } return itemBuilder; } diff --git a/core/src/main/java/net/momirealms/customfishing/bukkit/gui/icon/property/item/CMDItem.java b/core/src/main/java/net/momirealms/customfishing/bukkit/gui/icon/property/item/CMDItem.java index d8018fff..57a135ba 100644 --- a/core/src/main/java/net/momirealms/customfishing/bukkit/gui/icon/property/item/CMDItem.java +++ b/core/src/main/java/net/momirealms/customfishing/bukkit/gui/icon/property/item/CMDItem.java @@ -17,9 +17,12 @@ package net.momirealms.customfishing.bukkit.gui.icon.property.item; +import net.kyori.adventure.text.Component; import net.momirealms.customfishing.bukkit.adventure.ShadedAdventureComponentWrapper; import net.momirealms.customfishing.bukkit.gui.SectionPage; import net.momirealms.customfishing.bukkit.gui.page.property.CustomModelDataEditor; +import net.momirealms.customfishing.common.locale.MessageConstants; +import net.momirealms.customfishing.common.locale.TranslationManager; import org.bukkit.Material; import org.bukkit.entity.Player; import org.bukkit.event.inventory.ClickType; @@ -40,23 +43,20 @@ public class CMDItem extends AbstractItem { @Override public ItemProvider getItemProvider() { ItemBuilder itemBuilder = new ItemBuilder(Material.GLOW_INK_SAC) - .setDisplayName(new ShadedAdventureComponentWrapper(AdventureHelper.getInstance().getComponentFromMiniMessage( - CFLocale.GUI_ITEM_MODEL_DATA + .setDisplayName(new ShadedAdventureComponentWrapper(TranslationManager.render( + MessageConstants.GUI_ITEM_CUSTOM_MODEL_DATA.build() ))); if (itemPage.getSection().contains("custom-model-data")) { - itemBuilder.addLoreLines(new ShadedAdventureComponentWrapper(AdventureHelper.getInstance().getComponentFromMiniMessage( - CFLocale.GUI_CURRENT_VALUE + itemPage.getSection().getInt("custom-model-data") + itemBuilder.addLoreLines(new ShadedAdventureComponentWrapper(TranslationManager.render( + MessageConstants.GUI_CURRENT_VALUE.arguments( + Component.text(itemPage.getSection().getInt("custom-model-data")) + ).build() ))) .addLoreLines(""); - itemBuilder.addLoreLines(new ShadedAdventureComponentWrapper(AdventureHelper.getInstance().getComponentFromMiniMessage( - CFLocale.GUI_LEFT_CLICK_EDIT - ))).addLoreLines(new ShadedAdventureComponentWrapper(AdventureHelper.getInstance().getComponentFromMiniMessage( - CFLocale.GUI_RIGHT_CLICK_RESET - ))); + itemBuilder.addLoreLines(new ShadedAdventureComponentWrapper(TranslationManager.render(MessageConstants.GUI_LEFT_CLICK_EDIT.build()))) + .addLoreLines(new ShadedAdventureComponentWrapper(TranslationManager.render(MessageConstants.GUI_RIGHT_CLICK_RESET.build()))); } else { - itemBuilder.addLoreLines(new ShadedAdventureComponentWrapper(AdventureHelper.getInstance().getComponentFromMiniMessage( - CFLocale.GUI_LEFT_CLICK_EDIT - ))); + itemBuilder.addLoreLines(new ShadedAdventureComponentWrapper(TranslationManager.render(MessageConstants.GUI_LEFT_CLICK_EDIT.build()))); } return itemBuilder; } diff --git a/core/src/main/java/net/momirealms/customfishing/bukkit/gui/icon/property/item/NBTItem.java b/core/src/main/java/net/momirealms/customfishing/bukkit/gui/icon/property/item/NBTItem.java index d128f30f..83b2161d 100644 --- a/core/src/main/java/net/momirealms/customfishing/bukkit/gui/icon/property/item/NBTItem.java +++ b/core/src/main/java/net/momirealms/customfishing/bukkit/gui/icon/property/item/NBTItem.java @@ -20,7 +20,6 @@ package net.momirealms.customfishing.bukkit.gui.icon.property.item; import net.momirealms.customfishing.bukkit.adventure.ShadedAdventureComponentWrapper; import net.momirealms.customfishing.bukkit.gui.SectionPage; import net.momirealms.customfishing.bukkit.gui.page.property.NBTEditor; -import net.momirealms.customfishing.bukkit.util.ConfigUtils; import org.bukkit.Material; import org.bukkit.entity.Player; import org.bukkit.event.inventory.ClickType; diff --git a/core/src/main/java/net/momirealms/customfishing/bukkit/gui/page/file/FileSelector.java b/core/src/main/java/net/momirealms/customfishing/bukkit/gui/page/file/FileSelector.java index 4f32ae5d..52aa140c 100644 --- a/core/src/main/java/net/momirealms/customfishing/bukkit/gui/page/file/FileSelector.java +++ b/core/src/main/java/net/momirealms/customfishing/bukkit/gui/page/file/FileSelector.java @@ -23,6 +23,8 @@ import net.momirealms.customfishing.bukkit.gui.icon.BackToFolderItem; import net.momirealms.customfishing.bukkit.gui.icon.ScrollDownItem; import net.momirealms.customfishing.bukkit.gui.icon.ScrollUpItem; import net.momirealms.customfishing.bukkit.gui.page.item.ItemSelector; +import net.momirealms.customfishing.common.locale.MessageConstants; +import net.momirealms.customfishing.common.locale.TranslationManager; import org.bukkit.Material; import org.bukkit.entity.Player; import org.bukkit.event.inventory.ClickType; @@ -79,19 +81,10 @@ public class FileSelector { Window window = Window.single() .setViewer(player) - .setTitle(new ShadedAdventureComponentWrapper(AdventureHelper.getInstance().getComponentFromMiniMessage( - CFLocale.GUI_SELECT_FILE - ))) + .setTitle(new ShadedAdventureComponentWrapper(TranslationManager.render(MessageConstants.GUI_SELECT_FILE.build()))) .setGui(gui) .build(); -// gui.playAnimation(new SequentialAnimation(1, true), slotElement -> { -// if (slotElement instanceof SlotElement.ItemSlotElement itemSlotElement) { -// return !(itemSlotElement.getItem() instanceof Icon); -// } -// return true; -// }); - window.open(); } diff --git a/core/src/main/java/net/momirealms/customfishing/bukkit/gui/page/property/NBTEditor.java b/core/src/main/java/net/momirealms/customfishing/bukkit/gui/page/property/NBTEditor.java index 9bb6aa40..a9e22821 100644 --- a/core/src/main/java/net/momirealms/customfishing/bukkit/gui/page/property/NBTEditor.java +++ b/core/src/main/java/net/momirealms/customfishing/bukkit/gui/page/property/NBTEditor.java @@ -20,7 +20,6 @@ package net.momirealms.customfishing.bukkit.gui.page.property; import net.momirealms.customfishing.bukkit.adventure.ShadedAdventureComponentWrapper; import net.momirealms.customfishing.bukkit.gui.SectionPage; import net.momirealms.customfishing.bukkit.gui.icon.BackGroundItem; -import net.momirealms.customfishing.bukkit.util.ConfigUtils; import org.bukkit.Material; import org.bukkit.configuration.ConfigurationSection; import org.bukkit.entity.Player; diff --git a/core/src/main/java/net/momirealms/customfishing/bukkit/hook/BukkitHookManager.java b/core/src/main/java/net/momirealms/customfishing/bukkit/hook/BukkitHookManager.java new file mode 100644 index 00000000..264d66eb --- /dev/null +++ b/core/src/main/java/net/momirealms/customfishing/bukkit/hook/BukkitHookManager.java @@ -0,0 +1,28 @@ +package net.momirealms.customfishing.bukkit.hook; + +import net.momirealms.customfishing.api.BukkitCustomFishingPlugin; +import net.momirealms.customfishing.api.mechanic.hook.HookConfig; +import net.momirealms.customfishing.api.mechanic.hook.HookManager; +import org.jetbrains.annotations.NotNull; + +import java.util.Optional; + +public class BukkitHookManager implements HookManager { + + private BukkitCustomFishingPlugin plugin; + + public BukkitHookManager(BukkitCustomFishingPlugin plugin) { + this.plugin = plugin; + } + + @Override + public boolean registerHook(HookConfig hook) { + return false; + } + + @NotNull + @Override + public Optional getHook(String id) { + return Optional.empty(); + } +} diff --git a/core/src/main/java/net/momirealms/customfishing/bukkit/item/BukkitItemManager.java b/core/src/main/java/net/momirealms/customfishing/bukkit/item/BukkitItemManager.java index b0d5ec3b..1bd5cdbb 100644 --- a/core/src/main/java/net/momirealms/customfishing/bukkit/item/BukkitItemManager.java +++ b/core/src/main/java/net/momirealms/customfishing/bukkit/item/BukkitItemManager.java @@ -9,7 +9,6 @@ import net.momirealms.customfishing.api.mechanic.context.Context; import net.momirealms.customfishing.api.mechanic.context.ContextKeys; import net.momirealms.customfishing.api.mechanic.item.CustomFishingItem; import net.momirealms.customfishing.api.mechanic.item.ItemManager; -import net.momirealms.customfishing.bukkit.util.ItemUtils; import net.momirealms.customfishing.bukkit.util.LocationUtils; import net.momirealms.customfishing.common.item.Item; import org.bukkit.Bukkit; diff --git a/core/src/main/java/net/momirealms/customfishing/bukkit/requirement/BukkitRequirementManager.java b/core/src/main/java/net/momirealms/customfishing/bukkit/requirement/BukkitRequirementManager.java index 1447090d..33ca11ed 100644 --- a/core/src/main/java/net/momirealms/customfishing/bukkit/requirement/BukkitRequirementManager.java +++ b/core/src/main/java/net/momirealms/customfishing/bukkit/requirement/BukkitRequirementManager.java @@ -47,9 +47,18 @@ public class BukkitRequirementManager implements RequirementManager { public BukkitRequirementManager(BukkitCustomFishingPlugin plugin) { this.plugin = plugin; this.registerBuiltInRequirements(); + } + + @Override + public void reload() { this.loadExpansions(); } + @Override + public void disable() { + this.requirementFactoryMap.clear(); + } + @Override public boolean registerRequirement(@NotNull String type, @NotNull RequirementFactory requirementFactory) { if (this.requirementFactoryMap.containsKey(type)) return false; diff --git a/core/src/main/java/net/momirealms/customfishing/bukkit/requirement/ConditionalElement.java b/core/src/main/java/net/momirealms/customfishing/bukkit/requirement/ConditionalElement.java index 89f4691d..d27eacaa 100644 --- a/core/src/main/java/net/momirealms/customfishing/bukkit/requirement/ConditionalElement.java +++ b/core/src/main/java/net/momirealms/customfishing/bukkit/requirement/ConditionalElement.java @@ -1,63 +1,62 @@ -/* - * Copyright (C) <2022> - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - -package net.momirealms.customfishing.bukkit.requirement; - -import net.momirealms.customfishing.api.common.Pair; -import net.momirealms.customfishing.api.mechanic.requirement.Requirement; -import org.bukkit.entity.Player; - -import java.util.HashMap; -import java.util.List; - -public class ConditionalElement { - - private final List> modifierList; - private final HashMap subLoots; - private final Requirement[] requirements; - - public ConditionalElement( - Requirement[] requirements, - List> modifierList, - HashMap subElements - ) { - this.modifierList = modifierList; - this.requirements = requirements; - this.subLoots = subElements; - } - - /** - * Combines the weight modifiers for this element. - * - * @param player The player for whom the modifiers are applied. - * @param weightMap The map of weight modifiers. - */ - synchronized public void combine(Player player, HashMap weightMap) { - for (Pair modifierPair : this.modifierList) { - double previous = weightMap.getOrDefault(modifierPair.left(), 0d); - weightMap.put(modifierPair.left(), modifierPair.right().modify(player, previous)); - } - } - - public Requirement[] getRequirements() { - return requirements; - } - - public HashMap getSubElements() { - return subLoots; - } -} +///* +// * Copyright (C) <2022> +// * +// * This program is free software: you can redistribute it and/or modify +// * it under the terms of the GNU General Public License as published by +// * the Free Software Foundation, either version 3 of the License, or +// * any later version. +// * +// * This program is distributed in the hope that it will be useful, +// * but WITHOUT ANY WARRANTY; without even the implied warranty of +// * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// * GNU General Public License for more details. +// * +// * You should have received a copy of the GNU General Public License +// * along with this program. If not, see . +// */ +// +//package net.momirealms.customfishing.bukkit.requirement; +// +//import net.momirealms.customfishing.api.mechanic.requirement.Requirement; +//import org.bukkit.entity.Player; +// +//import java.util.HashMap; +//import java.util.List; +// +//public class ConditionalElement { +// +// private final List> modifierList; +// private final HashMap subLoots; +// private final Requirement[] requirements; +// +// public ConditionalElement( +// Requirement[] requirements, +// List> modifierList, +// HashMap subElements +// ) { +// this.modifierList = modifierList; +// this.requirements = requirements; +// this.subLoots = subElements; +// } +// +// /** +// * Combines the weight modifiers for this element. +// * +// * @param player The player for whom the modifiers are applied. +// * @param weightMap The map of weight modifiers. +// */ +// synchronized public void combine(Player player, HashMap weightMap) { +// for (Pair modifierPair : this.modifierList) { +// double previous = weightMap.getOrDefault(modifierPair.left(), 0d); +// weightMap.put(modifierPair.left(), modifierPair.right().modify(player, previous)); +// } +// } +// +// public Requirement[] getRequirements() { +// return requirements; +// } +// +// public HashMap getSubElements() { +// return subLoots; +// } +//} diff --git a/core/src/main/java/net/momirealms/customfishing/bukkit/storage/BukkitStorageManager.java b/core/src/main/java/net/momirealms/customfishing/bukkit/storage/BukkitStorageManager.java index 08aa8c57..380c5635 100644 --- a/core/src/main/java/net/momirealms/customfishing/bukkit/storage/BukkitStorageManager.java +++ b/core/src/main/java/net/momirealms/customfishing/bukkit/storage/BukkitStorageManager.java @@ -74,6 +74,7 @@ public class BukkitStorageManager implements StorageManager, Listener { Bukkit.getPluginManager().registerEvents(this, plugin.getBoostrap()); } + @Override public void reload() { YamlDocument config = plugin.getConfigManager().loadConfig("database.yml"); this.serverID = config.getString("unique-server-id", "default"); @@ -132,6 +133,7 @@ public class BukkitStorageManager implements StorageManager, Listener { /** * Disables the storage manager and cleans up resources. */ + @Override public void disable() { HandlerList.unregisterAll(this); this.dataSource.updateManyPlayersData(onlineUserMap.values(), true); diff --git a/core/src/main/java/net/momirealms/customfishing/bukkit/totem/ActivatedTotem.java b/core/src/main/java/net/momirealms/customfishing/bukkit/totem/ActivatedTotem.java index 8e10c550..c452cf88 100644 --- a/core/src/main/java/net/momirealms/customfishing/bukkit/totem/ActivatedTotem.java +++ b/core/src/main/java/net/momirealms/customfishing/bukkit/totem/ActivatedTotem.java @@ -1,86 +1,86 @@ -/* - * Copyright (C) <2022> - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - -package net.momirealms.customfishing.bukkit.totem; - -import net.momirealms.customfishing.api.BukkitCustomFishingPlugin; -import net.momirealms.customfishing.api.mechanic.action.Action; -import net.momirealms.customfishing.api.mechanic.action.ActionTrigger; -import net.momirealms.customfishing.api.mechanic.totem.TotemConfig; -import net.momirealms.customfishing.api.mechanic.totem.TotemParticle; -import net.momirealms.customfishing.api.scheduler.CancellableTask; -import org.bukkit.Location; - -import java.util.ArrayList; -import java.util.HashMap; -import java.util.List; - -public class ActivatedTotem { - - private final List subTasks; - private final Location coreLocation; - private final TotemConfig totemConfig; - private final long expireTime; - private final EffectCarrier effectCarrier; - - public ActivatedTotem(Location coreLocation, TotemConfig config) { - this.subTasks = new ArrayList<>(); - this.expireTime = System.currentTimeMillis() + config.getDuration() * 1000L; - this.coreLocation = coreLocation.clone().add(0.5,0,0.5); - this.totemConfig = config; - this.effectCarrier = BukkitCustomFishingPlugin.get().getEffectManager().getEffectCarrier("totem", config.getKey()); - for (TotemParticle particleSetting : config.getParticleSettings()) { - this.subTasks.add(particleSetting.start(coreLocation, config.getRadius())); - } - } - - public TotemConfig getTotemConfig() { - return totemConfig; - } - - public Location getCoreLocation() { - return coreLocation; - } - - public void cancel() { - for (CancellableTask task : subTasks) { - task.cancel(); - } - } - - public long getExpireTime() { - return expireTime; - } - - public void doTimerAction() { - HashMap args = new HashMap<>(); - args.put("{time_left}", String.valueOf((expireTime - System.currentTimeMillis())/1000)); - PlayerContext playerContext = new PlayerContext(coreLocation, null, args); - if (effectCarrier != null) { - Action[] actions = effectCarrier.getActions(ActionTrigger.TIMER); - if (actions != null) { - for (Action action : actions) { - action.trigger(playerContext); - } - } - } - } - - public EffectCarrier getEffectCarrier() { - return effectCarrier; - } -} +///* +// * Copyright (C) <2022> +// * +// * This program is free software: you can redistribute it and/or modify +// * it under the terms of the GNU General Public License as published by +// * the Free Software Foundation, either version 3 of the License, or +// * any later version. +// * +// * This program is distributed in the hope that it will be useful, +// * but WITHOUT ANY WARRANTY; without even the implied warranty of +// * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// * GNU General Public License for more details. +// * +// * You should have received a copy of the GNU General Public License +// * along with this program. If not, see . +// */ +// +//package net.momirealms.customfishing.bukkit.totem; +// +//import net.momirealms.customfishing.api.BukkitCustomFishingPlugin; +//import net.momirealms.customfishing.api.mechanic.action.Action; +//import net.momirealms.customfishing.api.mechanic.action.ActionTrigger; +//import net.momirealms.customfishing.api.mechanic.totem.TotemConfig; +//import net.momirealms.customfishing.api.mechanic.totem.TotemParticle; +//import net.momirealms.customfishing.common.plugin.scheduler.SchedulerTask; +//import org.bukkit.Location; +// +//import java.util.ArrayList; +//import java.util.HashMap; +//import java.util.List; +// +//public class ActivatedTotem { +// +// private final List subTasks; +// private final Location coreLocation; +// private final TotemConfig totemConfig; +// private final long expireTime; +// private final EffectCarrier effectCarrier; +// +// public ActivatedTotem(Location coreLocation, TotemConfig config) { +// this.subTasks = new ArrayList<>(); +// this.expireTime = System.currentTimeMillis() + config.getDuration() * 1000L; +// this.coreLocation = coreLocation.clone().add(0.5,0,0.5); +// this.totemConfig = config; +// this.effectCarrier = BukkitCustomFishingPlugin.get().getEffectManager().getEffectCarrier("totem", config.getKey()); +// for (TotemParticle particleSetting : config.getParticleSettings()) { +// this.subTasks.add(particleSetting.start(coreLocation, config.getRadius())); +// } +// } +// +// public TotemConfig getTotemConfig() { +// return totemConfig; +// } +// +// public Location getCoreLocation() { +// return coreLocation; +// } +// +// public void cancel() { +// for (CancellableTask task : subTasks) { +// task.cancel(); +// } +// } +// +// public long getExpireTime() { +// return expireTime; +// } +// +// public void doTimerAction() { +// HashMap args = new HashMap<>(); +// args.put("{time_left}", String.valueOf((expireTime - System.currentTimeMillis())/1000)); +// PlayerContext playerContext = new PlayerContext(coreLocation, null, args); +// if (effectCarrier != null) { +// Action[] actions = effectCarrier.getActions(ActionTrigger.TIMER); +// if (actions != null) { +// for (Action action : actions) { +// action.trigger(playerContext); +// } +// } +// } +// } +// +// public EffectCarrier getEffectCarrier() { +// return effectCarrier; +// } +//} diff --git a/core/src/main/java/net/momirealms/customfishing/bukkit/totem/BukkitTotemManager.java b/core/src/main/java/net/momirealms/customfishing/bukkit/totem/BukkitTotemManager.java index 54f9e503..4dd86d5f 100644 --- a/core/src/main/java/net/momirealms/customfishing/bukkit/totem/BukkitTotemManager.java +++ b/core/src/main/java/net/momirealms/customfishing/bukkit/totem/BukkitTotemManager.java @@ -18,11 +18,6 @@ package net.momirealms.customfishing.bukkit.totem; import net.momirealms.customfishing.api.BukkitCustomFishingPlugin; -import net.momirealms.customfishing.api.common.Pair; -import net.momirealms.customfishing.api.common.SimpleLocation; -import net.momirealms.customfishing.api.event.TotemActivateEvent; -import net.momirealms.customfishing.api.mechanic.action.Action; -import net.momirealms.customfishing.api.mechanic.action.ActionTrigger; import net.momirealms.customfishing.api.mechanic.totem.TotemConfig; import net.momirealms.customfishing.api.mechanic.totem.TotemManager; import net.momirealms.customfishing.api.mechanic.totem.TotemModel; @@ -32,16 +27,16 @@ import net.momirealms.customfishing.api.mechanic.totem.block.property.FaceImpl; import net.momirealms.customfishing.api.mechanic.totem.block.property.HalfImpl; import net.momirealms.customfishing.api.mechanic.totem.block.property.TotemBlockProperty; import net.momirealms.customfishing.api.mechanic.totem.block.type.TypeCondition; -import net.momirealms.customfishing.api.scheduler.CancellableTask; +import net.momirealms.customfishing.api.util.SimpleLocation; import net.momirealms.customfishing.bukkit.totem.particle.DustParticleSetting; import net.momirealms.customfishing.bukkit.totem.particle.ParticleSetting; -import net.momirealms.customfishing.bukkit.util.LocationUtils; +import net.momirealms.customfishing.common.plugin.scheduler.SchedulerTask; +import net.momirealms.customfishing.common.util.Pair; import org.bukkit.*; import org.bukkit.block.Block; import org.bukkit.block.BlockFace; import org.bukkit.block.data.Bisected; import org.bukkit.configuration.ConfigurationSection; -import org.bukkit.configuration.file.YamlConfiguration; import org.bukkit.event.Event; import org.bukkit.event.EventHandler; import org.bukkit.event.HandlerList; @@ -49,7 +44,6 @@ import org.bukkit.event.Listener; import org.bukkit.event.block.BlockBreakEvent; import org.bukkit.event.player.PlayerInteractEvent; import org.bukkit.inventory.EquipmentSlot; -import org.jetbrains.annotations.Nullable; import java.io.File; import java.util.*; @@ -58,382 +52,352 @@ import java.util.concurrent.TimeUnit; public class BukkitTotemManager implements TotemManager, Listener { - private final BukkitCustomFishingPlugin plugin; - private final HashMap> totemConfigMap; - private final List allMaterials; - private final ConcurrentHashMap activatedTotems; - private CancellableTask timerCheckTask; - - public BukkitTotemManager(BukkitCustomFishingPlugin plugin) { - this.plugin = plugin; - this.totemConfigMap = new HashMap<>(); - this.allMaterials = Arrays.stream(Material.values()).map(Enum::name).toList(); - this.activatedTotems = new ConcurrentHashMap<>(); - } - - public void load() { - this.loadConfig(); - Bukkit.getPluginManager().registerEvents(this, plugin); - this.timerCheckTask = plugin.getScheduler().runTaskAsyncTimer(() -> { - long time = System.currentTimeMillis(); - ArrayList removed = new ArrayList<>(); - for (Map.Entry entry : activatedTotems.entrySet()) { - if (time > entry.getValue().getExpireTime()) { - removed.add(entry.getKey()); - entry.getValue().cancel(); - } else { - entry.getValue().doTimerAction(); - } - } - for (SimpleLocation simpleLocation : removed) { - activatedTotems.remove(simpleLocation); - } - }, 1, 1, TimeUnit.SECONDS); - } - - public void unload() { - this.totemConfigMap.clear(); - for (ActivatedTotem activatedTotem : activatedTotems.values()) { - activatedTotem.cancel(); - } - activatedTotems.clear(); - HandlerList.unregisterAll(this); - if (this.timerCheckTask != null && !this.timerCheckTask.isCancelled()) - this.timerCheckTask.cancel(); - } - - public void disable() { - unload(); - } - - /** - * Get the EffectCarrier associated with an activated totem located near the specified location. - * - * @param location The location to search for activated totems. - * @return The EffectCarrier associated with the nearest activated totem or null if none are found. - */ - @Override - @Nullable - public EffectCarrier getTotemEffect(Location location) { - for (ActivatedTotem activatedTotem : activatedTotems.values()) { - if (LocationUtils.getDistance(activatedTotem.getCoreLocation(), location) < activatedTotem.getTotemConfig().getRadius()) { - return activatedTotem.getEffectCarrier(); - } - } - return null; - } - - @EventHandler - public void onBreakTotemCore(BlockBreakEvent event) { - if (event.isCancelled()) - return; - Location location = event.getBlock().getLocation(); - SimpleLocation simpleLocation = SimpleLocation.getByBukkitLocation(location); - ActivatedTotem activatedTotem = activatedTotems.remove(simpleLocation); - if (activatedTotem != null) - activatedTotem.cancel(); - } - - @EventHandler - public void onInteractBlock(PlayerInteractEvent event) { - if (event.isBlockInHand()) - return; - if (event.useItemInHand() == Event.Result.DENY) - return; - if (event.getAction() != org.bukkit.event.block.Action.RIGHT_CLICK_BLOCK) - return; - if (event.getHand() != EquipmentSlot.HAND) - return; - Block block = event.getClickedBlock(); - assert block != null; - String id = plugin.getBlockManager().getAnyPluginBlockID(block); - List configs = totemConfigMap.get(id); - if (configs == null) - return; - TotemConfig config = null; - for (TotemConfig temp : configs) { - if (temp.isRightPattern(block.getLocation())) { - config = temp; - break; - } - } - if (config == null) - return; - String totemKey = config.getKey(); - EffectCarrier carrier = plugin.getEffectManager().getEffectCarrier("totem", totemKey); - if (carrier == null) - return; - PlayerContext playerContext = new PlayerContext(block.getLocation(), event.getPlayer(), new HashMap<>()); - if (!carrier.isConditionMet(playerContext)) - return; - - TotemActivateEvent totemActivateEvent = new TotemActivateEvent(event.getPlayer(), block.getLocation(), config); - Bukkit.getPluginManager().callEvent(totemActivateEvent); - if (totemActivateEvent.isCancelled()) { - return; - } - - Action[] actions = carrier.getActionMap().get(ActionTrigger.ACTIVATE); - if (actions != null) - for (Action action : actions) { - action.trigger(playerContext); - } - Location location = block.getLocation(); - ActivatedTotem activatedTotem = new ActivatedTotem(location, config); - SimpleLocation simpleLocation = SimpleLocation.getByBukkitLocation(location); - - ActivatedTotem previous = this.activatedTotems.put(simpleLocation, activatedTotem); - if (previous != null) { - previous.cancel(); - } - } - - @SuppressWarnings("DuplicatedCode") - private void loadConfig() { - Deque fileDeque = new ArrayDeque<>(); - for (String type : List.of("totem")) { - File typeFolder = new File(plugin.getDataFolder() + File.separator + "contents" + File.separator + type); - if (!typeFolder.exists()) { - if (!typeFolder.mkdirs()) return; - plugin.saveResource("contents" + File.separator + type + File.separator + "default.yml", false); - } - fileDeque.push(typeFolder); - while (!fileDeque.isEmpty()) { - File file = fileDeque.pop(); - File[] files = file.listFiles(); - if (files == null) continue; - for (File subFile : files) { - if (subFile.isDirectory()) { - fileDeque.push(subFile); - } else if (subFile.isFile() && subFile.getName().endsWith(".yml")) { - this.loadSingleFile(subFile); - } - } - } - } - } - - private void loadSingleFile(File file) { - YamlConfiguration config = YamlConfiguration.loadConfiguration(file); - for (Map.Entry entry : config.getValues(false).entrySet()) { - if (entry.getValue() instanceof ConfigurationSection section) { - TotemConfig totemConfig = new TotemConfig.Builder(entry.getKey()) - .setTotemModels(getTotemModels(section.getConfigurationSection("pattern"))) - .setParticleSettings(getParticleSettings(section.getConfigurationSection("particles"))) - .setRequirements(plugin.getRequirementManager().parseRequirements(section.getConfigurationSection("requirements"), true)) - .setRadius(section.getDouble("radius", 8)) - .setDuration(section.getInt("duration", 300)) - .build(); - - HashSet coreMaterials = new HashSet<>(); - for (TotemBlock totemBlock : totemConfig.getTotemCore()) { - String text = totemBlock.getTypeCondition().getRawText(); - if (text.startsWith("*")) { - String sub = text.substring(1); - coreMaterials.addAll(allMaterials.stream().filter(it -> it.endsWith(sub)).toList()); - } else if (text.endsWith("*")) { - String sub = text.substring(0, text.length() - 1); - coreMaterials.addAll(allMaterials.stream().filter(it -> it.startsWith(sub)).toList()); - } else { - coreMaterials.add(text); - } - } - for (String material : coreMaterials) { - putTotemConfigToMap(material, totemConfig); - } - } - } - } - - private void putTotemConfigToMap(String material, TotemConfig totemConfig) { - List configs = this.totemConfigMap.getOrDefault(material, new ArrayList<>()); - configs.add(totemConfig); - this.totemConfigMap.put(material, configs); - } - - public ParticleSetting[] getParticleSettings(ConfigurationSection section) { - List particleSettings = new ArrayList<>(); - if (section != null) - for (Map.Entry entry : section.getValues(false).entrySet()) { - if (entry.getValue() instanceof ConfigurationSection innerSection) { - particleSettings.add(getParticleSetting(innerSection)); - } - } - return particleSettings.toArray(new ParticleSetting[0]); - } - - public ParticleSetting getParticleSetting(ConfigurationSection section) { - Particle particle = Particle.valueOf(section.getString("type","REDSTONE")); - String formulaHorizontal = section.getString("polar-coordinates-formula.horizontal"); - String formulaVertical = section.getString("polar-coordinates-formula.vertical"); - List> ranges = section.getStringList("theta.range") - .stream().map(it -> { - String[] split = it.split("~"); - return Pair.of(Double.parseDouble(split[0]) * Math.PI / 180, Double.parseDouble(split[1]) * Math.PI / 180); - }).toList(); - - double interval = section.getDouble("theta.draw-interval", 3d); - int delay = section.getInt("task.delay", 0); - int period = section.getInt("task.period", 0); - if (particle == Particle.REDSTONE) { - String color = section.getString("options.color","0,0,0"); - String[] colorSplit = color.split(","); - return new DustParticleSetting( - formulaHorizontal, - formulaVertical, - particle, - interval, - ranges, - delay, - period, - new Particle.DustOptions( - Color.fromRGB( - Integer.parseInt(colorSplit[0]), - Integer.parseInt(colorSplit[1]), - Integer.parseInt(colorSplit[2]) - ), - (float) section.getDouble("options.scale", 1) - ) - ); - } else if (particle == Particle.DUST_COLOR_TRANSITION) { - String color = section.getString("options.from","0,0,0"); - String[] colorSplit = color.split(","); - String toColor = section.getString("options.to","255,255,255"); - String[] toColorSplit = toColor.split(","); - return new DustParticleSetting( - formulaHorizontal, - formulaVertical, - particle, - interval, - ranges, - delay, - period, - new Particle.DustTransition( - Color.fromRGB( - Integer.parseInt(colorSplit[0]), - Integer.parseInt(colorSplit[1]), - Integer.parseInt(colorSplit[2]) - ), - Color.fromRGB( - Integer.parseInt(toColorSplit[0]), - Integer.parseInt(toColorSplit[1]), - Integer.parseInt(toColorSplit[2]) - ), - (float) section.getDouble("options.scale", 1) - ) - ); - } else { - return new ParticleSetting( - formulaHorizontal, - formulaVertical, - particle, - interval, - ranges, - delay, - period - ); - } - } - - public TotemModel[] getTotemModels(ConfigurationSection section) { - TotemModel originalModel = parseModel(section); - List modelList = new ArrayList<>(); - for (int i = 0; i < 4; i++) { - originalModel = originalModel.deepClone().rotate90(); - modelList.add(originalModel); - if (i % 2 == 0) { - modelList.add(originalModel.mirrorVertically()); - } else { - modelList.add(originalModel.mirrorHorizontally()); - } - } - return modelList.toArray(new TotemModel[0]); - } - - @SuppressWarnings("unchecked") - public TotemModel parseModel(ConfigurationSection section) { - ConfigurationSection layerSection = section.getConfigurationSection("layer"); - List totemBlocksList = new ArrayList<>(); - if (layerSection != null) { - var set = layerSection.getValues(false).entrySet(); - TotemBlock[][][][] totemBlocks = new TotemBlock[set.size()][][][]; - for (Map.Entry entry : set) { - if (entry.getValue() instanceof List list) { - totemBlocks[Integer.parseInt(entry.getKey())-1] = parseLayer((List) list); - } - } - totemBlocksList.addAll(List.of(totemBlocks)); - } - - String[] core = section.getString("core","1,1,1").split(","); - int x = Integer.parseInt(core[2]) - 1; - int z = Integer.parseInt(core[1]) - 1; - int y = Integer.parseInt(core[0]) - 1; - return new TotemModel( - x,y,z, - totemBlocksList.toArray(new TotemBlock[0][][][]) - ); - } - - public TotemBlock[][][] parseLayer(List lines) { - List totemBlocksList = new ArrayList<>(); - for (String line : lines) { - totemBlocksList.add(parseSingleLine(line)); - } - return totemBlocksList.toArray(new TotemBlock[0][][]); - } - - public TotemBlock[][] parseSingleLine(String line) { - List totemBlocksList = new ArrayList<>(); - String[] splits = line.split("\\s+"); - for (String split : splits) { - totemBlocksList.add(parseSingleElement(split)); - } - return totemBlocksList.toArray(new TotemBlock[0][]); - } - - public TotemBlock[] parseSingleElement(String element) { - String[] orBlocks = element.split("\\|\\|"); - List totemBlockList = new ArrayList<>(); - for (String block : orBlocks) { - int index = block.indexOf("{"); - List propertyList = new ArrayList<>(); - if (index == -1) { - index = block.length(); - } else { - String propertyStr = block.substring(index+1, block.length()-1); - String[] properties = propertyStr.split(";"); - for (String property : properties) { - String[] split = property.split("="); - if (split.length < 2) continue; - String key = split[0]; - String value = split[1]; - switch (key) { - // Block face - case "face" -> { - BlockFace blockFace = BlockFace.valueOf(value.toUpperCase(Locale.ENGLISH)); - propertyList.add(new FaceImpl(blockFace)); - } - // Block axis - case "axis" -> { - Axis axis = Axis.valueOf(value.toUpperCase(Locale.ENGLISH)); - propertyList.add(new AxisImpl(axis)); - } - // Slab, Stair half - case "half" -> { - Bisected.Half half = Bisected.Half.valueOf(value.toUpperCase(Locale.ENGLISH)); - propertyList.add(new HalfImpl(half)); - } - } - } - } - String type = block.substring(0, index); - TotemBlock totemBlock = new TotemBlock( - TypeCondition.getTypeCondition(type), - propertyList.toArray(new TotemBlockProperty[0]) - ); - totemBlockList.add(totemBlock); - } - return totemBlockList.toArray(new TotemBlock[0]); - } +// private final BukkitCustomFishingPlugin plugin; +// private final HashMap> totemConfigMap; +// private final List allMaterials; +// private final ConcurrentHashMap activatedTotems; +// private SchedulerTask timerCheckTask; +// +// public BukkitTotemManager(BukkitCustomFishingPlugin plugin) { +// this.plugin = plugin; +// this.totemConfigMap = new HashMap<>(); +// this.allMaterials = Arrays.stream(Material.values()).map(Enum::name).toList(); +// this.activatedTotems = new ConcurrentHashMap<>(); +// } +// +// @Override +// public void load() { +// this.loadConfig(); +// Bukkit.getPluginManager().registerEvents(this, plugin.getBoostrap()); +// this.timerCheckTask = plugin.getScheduler().asyncRepeating(() -> { +// long time = System.currentTimeMillis(); +// ArrayList removed = new ArrayList<>(); +// for (Map.Entry entry : activatedTotems.entrySet()) { +// if (time > entry.getValue().getExpireTime()) { +// removed.add(entry.getKey()); +// entry.getValue().cancel(); +// } else { +// entry.getValue().doTimerAction(); +// } +// } +// for (SimpleLocation simpleLocation : removed) { +// activatedTotems.remove(simpleLocation); +// } +// }, 1, 1, TimeUnit.SECONDS); +// } +// +// @Override +// public void unload() { +// HandlerList.unregisterAll(this); +// for (ActivatedTotem activatedTotem : this.activatedTotems.values()) +// activatedTotem.cancel(); +// this.activatedTotems.clear(); +// if (this.timerCheckTask != null) +// this.timerCheckTask.cancel(); +// this.totemConfigMap.clear(); +// } +// +//// /** +//// * Get the EffectCarrier associated with an activated totem located near the specified location. +//// * +//// * @param location The location to search for activated totems. +//// * @return The EffectCarrier associated with the nearest activated totem or null if none are found. +//// */ +//// @Override +//// @Nullable +//// public EffectCarrier getTotemEffect(Location location) { +//// for (ActivatedTotem activatedTotem : activatedTotems.values()) { +//// if (LocationUtils.getDistance(activatedTotem.getCoreLocation(), location) < activatedTotem.getTotemConfig().radius()) { +//// return activatedTotem.getEffectCarrier(); +//// } +//// } +//// return null; +//// } +// +// @EventHandler +// public void onBreakTotemCore(BlockBreakEvent event) { +// if (event.isCancelled()) +// return; +// Location location = event.getBlock().getLocation(); +// SimpleLocation simpleLocation = SimpleLocation.of(location); +// ActivatedTotem activatedTotem = activatedTotems.remove(simpleLocation); +// if (activatedTotem != null) +// activatedTotem.cancel(); +// } +// +// @EventHandler +// public void onInteractBlock(PlayerInteractEvent event) { +// if (event.isBlockInHand()) +// return; +// if (event.useItemInHand() == Event.Result.DENY) +// return; +// if (event.getAction() != org.bukkit.event.block.Action.RIGHT_CLICK_BLOCK) +// return; +// if (event.getHand() != EquipmentSlot.HAND) +// return; +// Block block = event.getClickedBlock(); +// assert block != null; +// String id = plugin.getBlockManager().getBlockID(block); +// List configs = totemConfigMap.get(id); +// if (configs == null) +// return; +// TotemConfig config = null; +// for (TotemConfig temp : configs) { +// if (temp.isRightPattern(block.getLocation())) { +// config = temp; +// break; +// } +// } +// if (config == null) +// return; +// } +// +// @SuppressWarnings("DuplicatedCode") +// private void loadConfig() { +// Deque fileDeque = new ArrayDeque<>(); +// for (String type : List.of("totem")) { +// File typeFolder = new File(plugin.getDataFolder() + File.separator + "contents" + File.separator + type); +// if (!typeFolder.exists()) { +// if (!typeFolder.mkdirs()) return; +// plugin.getBoostrap().saveResource("contents" + File.separator + type + File.separator + "default.yml", false); +// } +// fileDeque.push(typeFolder); +// while (!fileDeque.isEmpty()) { +// File file = fileDeque.pop(); +// File[] files = file.listFiles(); +// if (files == null) continue; +// for (File subFile : files) { +// if (subFile.isDirectory()) { +// fileDeque.push(subFile); +// } else if (subFile.isFile() && subFile.getName().endsWith(".yml")) { +// this.loadSingleFile(subFile); +// } +// } +// } +// } +// } +// +// private void loadSingleFile(File file) { +//// YamlConfiguration config = YamlConfiguration.loadConfiguration(file); +//// for (Map.Entry entry : config.getValues(false).entrySet()) { +//// if (entry.getValue() instanceof ConfigurationSection section) { +//// TotemConfig totemConfig = new TotemConfig.Builder(entry.getKey()) +//// .setTotemModels(getTotemModels(section.getConfigurationSection("pattern"))) +//// .setParticleSettings(getParticleSettings(section.getConfigurationSection("particles"))) +//// .setRequirements(plugin.getRequirementManager().parseRequirements(section.getConfigurationSection("requirements"), true)) +//// .setRadius(section.getDouble("radius", 8)) +//// .setDuration(section.getInt("duration", 300)) +//// .build(); +//// +//// HashSet coreMaterials = new HashSet<>(); +//// for (TotemBlock totemBlock : totemConfig.getTotemCore()) { +//// String text = totemBlock.getTypeCondition().getRawText(); +//// if (text.startsWith("*")) { +//// String sub = text.substring(1); +//// coreMaterials.addAll(allMaterials.stream().filter(it -> it.endsWith(sub)).toList()); +//// } else if (text.endsWith("*")) { +//// String sub = text.substring(0, text.length() - 1); +//// coreMaterials.addAll(allMaterials.stream().filter(it -> it.startsWith(sub)).toList()); +//// } else { +//// coreMaterials.add(text); +//// } +//// } +//// for (String material : coreMaterials) { +//// putTotemConfigToMap(material, totemConfig); +//// } +//// } +//// } +// } +// +// private void putTotemConfigToMap(String material, TotemConfig totemConfig) { +// List configs = this.totemConfigMap.getOrDefault(material, new ArrayList<>()); +// configs.add(totemConfig); +// this.totemConfigMap.put(material, configs); +// } +// +//// public ParticleSetting[] getParticleSettings(ConfigurationSection section) { +//// List particleSettings = new ArrayList<>(); +//// if (section != null) +//// for (Map.Entry entry : section.getValues(false).entrySet()) { +//// if (entry.getValue() instanceof ConfigurationSection innerSection) { +//// particleSettings.add(getParticleSetting(innerSection)); +//// } +//// } +//// return particleSettings.toArray(new ParticleSetting[0]); +//// } +// +//// public ParticleSetting getParticleSetting(ConfigurationSection section) { +//// Particle particle = Particle.valueOf(section.getString("type","REDSTONE")); +//// String formulaHorizontal = section.getString("polar-coordinates-formula.horizontal"); +//// String formulaVertical = section.getString("polar-coordinates-formula.vertical"); +//// List> ranges = section.getStringList("theta.range") +//// .stream().map(it -> { +//// String[] split = it.split("~"); +//// return Pair.of(Double.parseDouble(split[0]) * Math.PI / 180, Double.parseDouble(split[1]) * Math.PI / 180); +//// }).toList(); +//// +//// double interval = section.getDouble("theta.draw-interval", 3d); +//// int delay = section.getInt("task.delay", 0); +//// int period = section.getInt("task.period", 0); +//// if (particle == Particle.REDSTONE) { +//// String color = section.getString("options.color","0,0,0"); +//// String[] colorSplit = color.split(","); +//// return new DustParticleSetting( +//// formulaHorizontal, +//// formulaVertical, +//// particle, +//// interval, +//// ranges, +//// delay, +//// period, +//// new Particle.DustOptions( +//// Color.fromRGB( +//// Integer.parseInt(colorSplit[0]), +//// Integer.parseInt(colorSplit[1]), +//// Integer.parseInt(colorSplit[2]) +//// ), +//// (float) section.getDouble("options.scale", 1) +//// ) +//// ); +//// } else if (particle == Particle.DUST_COLOR_TRANSITION) { +//// String color = section.getString("options.from","0,0,0"); +//// String[] colorSplit = color.split(","); +//// String toColor = section.getString("options.to","255,255,255"); +//// String[] toColorSplit = toColor.split(","); +//// return new DustParticleSetting( +//// formulaHorizontal, +//// formulaVertical, +//// particle, +//// interval, +//// ranges, +//// delay, +//// period, +//// new Particle.DustTransition( +//// Color.fromRGB( +//// Integer.parseInt(colorSplit[0]), +//// Integer.parseInt(colorSplit[1]), +//// Integer.parseInt(colorSplit[2]) +//// ), +//// Color.fromRGB( +//// Integer.parseInt(toColorSplit[0]), +//// Integer.parseInt(toColorSplit[1]), +//// Integer.parseInt(toColorSplit[2]) +//// ), +//// (float) section.getDouble("options.scale", 1) +//// ) +//// ); +//// } else { +//// return new ParticleSetting( +//// formulaHorizontal, +//// formulaVertical, +//// particle, +//// interval, +//// ranges, +//// delay, +//// period +//// ); +//// } +//// } +// +// public TotemModel[] getTotemModels(ConfigurationSection section) { +// TotemModel originalModel = parseModel(section); +// List modelList = new ArrayList<>(); +// for (int i = 0; i < 4; i++) { +// originalModel = originalModel.deepClone().rotate90(); +// modelList.add(originalModel); +// if (i % 2 == 0) { +// modelList.add(originalModel.mirrorVertically()); +// } else { +// modelList.add(originalModel.mirrorHorizontally()); +// } +// } +// return modelList.toArray(new TotemModel[0]); +// } +// +// @SuppressWarnings("unchecked") +// public TotemModel parseModel(ConfigurationSection section) { +// ConfigurationSection layerSection = section.getConfigurationSection("layer"); +// List totemBlocksList = new ArrayList<>(); +// if (layerSection != null) { +// var set = layerSection.getValues(false).entrySet(); +// TotemBlock[][][][] totemBlocks = new TotemBlock[set.size()][][][]; +// for (Map.Entry entry : set) { +// if (entry.getValue() instanceof List list) { +// totemBlocks[Integer.parseInt(entry.getKey())-1] = parseLayer((List) list); +// } +// } +// totemBlocksList.addAll(List.of(totemBlocks)); +// } +// +// String[] core = section.getString("core","1,1,1").split(","); +// int x = Integer.parseInt(core[2]) - 1; +// int z = Integer.parseInt(core[1]) - 1; +// int y = Integer.parseInt(core[0]) - 1; +// return new TotemModel( +// x,y,z, +// totemBlocksList.toArray(new TotemBlock[0][][][]) +// ); +// } +// +// public TotemBlock[][][] parseLayer(List lines) { +// List totemBlocksList = new ArrayList<>(); +// for (String line : lines) { +// totemBlocksList.add(parseSingleLine(line)); +// } +// return totemBlocksList.toArray(new TotemBlock[0][][]); +// } +// +// public TotemBlock[][] parseSingleLine(String line) { +// List totemBlocksList = new ArrayList<>(); +// String[] splits = line.split("\\s+"); +// for (String split : splits) { +// totemBlocksList.add(parseSingleElement(split)); +// } +// return totemBlocksList.toArray(new TotemBlock[0][]); +// } +// +// public TotemBlock[] parseSingleElement(String element) { +// String[] orBlocks = element.split("\\|\\|"); +// List totemBlockList = new ArrayList<>(); +// for (String block : orBlocks) { +// int index = block.indexOf("{"); +// List propertyList = new ArrayList<>(); +// if (index == -1) { +// index = block.length(); +// } else { +// String propertyStr = block.substring(index+1, block.length()-1); +// String[] properties = propertyStr.split(";"); +// for (String property : properties) { +// String[] split = property.split("="); +// if (split.length < 2) continue; +// String key = split[0]; +// String value = split[1]; +// switch (key) { +// // Block face +// case "face" -> { +// BlockFace blockFace = BlockFace.valueOf(value.toUpperCase(Locale.ENGLISH)); +// propertyList.add(new FaceImpl(blockFace)); +// } +// // Block axis +// case "axis" -> { +// Axis axis = Axis.valueOf(value.toUpperCase(Locale.ENGLISH)); +// propertyList.add(new AxisImpl(axis)); +// } +// // Slab, Stair half +// case "half" -> { +// Bisected.Half half = Bisected.Half.valueOf(value.toUpperCase(Locale.ENGLISH)); +// propertyList.add(new HalfImpl(half)); +// } +// } +// } +// } +// String type = block.substring(0, index); +// TotemBlock totemBlock = new TotemBlock( +// TypeCondition.getTypeCondition(type), +// propertyList.toArray(new TotemBlockProperty[0]) +// ); +// totemBlockList.add(totemBlock); +// } +// return totemBlockList.toArray(new TotemBlock[0]); +// } } diff --git a/core/src/main/java/net/momirealms/customfishing/bukkit/totem/particle/DustParticleSetting.java b/core/src/main/java/net/momirealms/customfishing/bukkit/totem/particle/DustParticleSetting.java index d2e751f1..09e16fb4 100644 --- a/core/src/main/java/net/momirealms/customfishing/bukkit/totem/particle/DustParticleSetting.java +++ b/core/src/main/java/net/momirealms/customfishing/bukkit/totem/particle/DustParticleSetting.java @@ -18,8 +18,8 @@ package net.momirealms.customfishing.bukkit.totem.particle; import net.momirealms.customfishing.api.BukkitCustomFishingPlugin; -import net.momirealms.customfishing.api.common.Pair; -import net.momirealms.customfishing.api.scheduler.CancellableTask; +import net.momirealms.customfishing.common.plugin.scheduler.SchedulerTask; +import net.momirealms.customfishing.common.util.Pair; import org.bukkit.Location; import org.bukkit.Particle; import org.bukkit.World; @@ -46,7 +46,7 @@ public class DustParticleSetting extends ParticleSetting { } @SuppressWarnings("DuplicatedCode") - public CancellableTask start(Location location, double radius) { + public SchedulerTask start(Location location, double radius) { World world = location.getWorld(); return BukkitCustomFishingPlugin.get().getScheduler().runTaskAsyncTimer(() -> { for (Pair range : ranges) { diff --git a/core/src/main/java/net/momirealms/customfishing/bukkit/totem/particle/ParticleSetting.java b/core/src/main/java/net/momirealms/customfishing/bukkit/totem/particle/ParticleSetting.java index 1b1e21b3..c29239a4 100644 --- a/core/src/main/java/net/momirealms/customfishing/bukkit/totem/particle/ParticleSetting.java +++ b/core/src/main/java/net/momirealms/customfishing/bukkit/totem/particle/ParticleSetting.java @@ -18,9 +18,9 @@ package net.momirealms.customfishing.bukkit.totem.particle; import net.momirealms.customfishing.api.BukkitCustomFishingPlugin; -import net.momirealms.customfishing.api.common.Pair; import net.momirealms.customfishing.api.mechanic.totem.TotemParticle; -import net.momirealms.customfishing.api.scheduler.CancellableTask; +import net.momirealms.customfishing.common.plugin.scheduler.SchedulerTask; +import net.momirealms.customfishing.common.util.Pair; import net.objecthunter.exp4j.Expression; import net.objecthunter.exp4j.ExpressionBuilder; import org.bukkit.Location; @@ -63,9 +63,9 @@ public class ParticleSetting implements TotemParticle { } @SuppressWarnings("DuplicatedCode") - public CancellableTask start(Location location, double radius) { + public SchedulerTask start(Location location, double radius) { World world = location.getWorld(); - return BukkitCustomFishingPlugin.get().getScheduler().runTaskAsyncTimer(() -> { + return BukkitCustomFishingPlugin.getInstance().getScheduler().asyncRepeating(() -> { for (Pair range : ranges) { for (double theta = range.left(); theta <= range.right(); theta += interval) { double r = expressionHorizontal.setVariable("theta", theta).setVariable("radius", radius).evaluate(); diff --git a/core/src/main/java/net/momirealms/customfishing/bukkit/util/ArmorStandUtils.java b/core/src/main/java/net/momirealms/customfishing/bukkit/util/ArmorStandUtils.java deleted file mode 100644 index 80534a2b..00000000 --- a/core/src/main/java/net/momirealms/customfishing/bukkit/util/ArmorStandUtils.java +++ /dev/null @@ -1,221 +0,0 @@ -/* - * Copyright (C) <2022> - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - -package net.momirealms.customfishing.bukkit.util; - -import com.comphenix.protocol.PacketType; -import com.comphenix.protocol.events.PacketContainer; -import com.comphenix.protocol.wrappers.*; -import com.google.common.collect.Lists; -import net.kyori.adventure.text.Component; -import net.kyori.adventure.text.serializer.gson.GsonComponentSerializer; -import net.momirealms.customfishing.api.BukkitCustomFishingPlugin; -import org.bukkit.Location; -import org.bukkit.entity.EntityType; -import org.bukkit.entity.Player; -import org.bukkit.inventory.ItemStack; - -import java.util.*; -import java.util.concurrent.TimeUnit; - -/** - * Utility class for managing armor stands and sending related packets. - */ -public class ArmorStandUtils { - - private ArmorStandUtils() {} - - /** - * Creates a destroy packet for removing an armor stand entity. - * - * @param id The ID of the armor stand entity to destroy - * @return The PacketContainer representing the destroy packet - */ - public static PacketContainer getDestroyPacket(int id) { - PacketContainer destroyPacket = new PacketContainer(PacketType.Play.Server.ENTITY_DESTROY); - destroyPacket.getIntLists().write(0, List.of(id)); - return destroyPacket; - } - - /** - * Creates a spawn packet for an armor stand entity at the specified location. - * - * @param id The ID of the armor stand entity to spawn - * @param location The location where the armor stand entity should be spawned - * @return The PacketContainer representing the spawn packet - */ - public static PacketContainer getSpawnPacket(int id, Location location) { - PacketContainer entityPacket = new PacketContainer(PacketType.Play.Server.SPAWN_ENTITY); - try { - entityPacket.getModifier().write(0, id); - entityPacket.getModifier().write(1, UUID.randomUUID()); - entityPacket.getEntityTypeModifier().write(0, EntityType.ARMOR_STAND); - entityPacket.getDoubles().write(0, location.getX()); - entityPacket.getDoubles().write(1, location.getY()); - entityPacket.getDoubles().write(2, location.getZ()); - if (BukkitCustomFishingPlugin.get().getVersionManager().isVersionNewerThan1_19()) { - entityPacket.getBytes().write(0, (byte) ((location.getYaw() % 360) * 128 / 180)); - } else { - entityPacket.getIntegers().write(5, (int) ((location.getYaw() % 360) * 128 / 180)); - } - } catch (Exception e) { - e.printStackTrace(); - } - return entityPacket; - } - - /** - * Creates a metadata packet for updating the metadata of an armor stand entity. - * - * @param id The ID of the armor stand entity - * @return The PacketContainer representing the metadata packet - */ - public static PacketContainer getMetaPacket(int id) { - PacketContainer metaPacket = new PacketContainer(PacketType.Play.Server.ENTITY_METADATA); - metaPacket.getIntegers().write(0, id); - if (BukkitCustomFishingPlugin.get().getVersionManager().isVersionNewerThan1_19_3()) { - WrappedDataWatcher wrappedDataWatcher = createDataWatcher(); - setValueList(metaPacket, wrappedDataWatcher); - } else { - metaPacket.getWatchableCollectionModifier().write(0, createDataWatcher().getWatchableObjects()); - } - return metaPacket; - } - - /** - * Sets the value list in a PacketContainer's DataWatcher from a WrappedDataWatcher. - * - * @param metaPacket The PacketContainer representing the metadata packet - * @param wrappedDataWatcher The WrappedDataWatcher containing the value list - */ - @SuppressWarnings("DuplicatedCode") - private static void setValueList(PacketContainer metaPacket, WrappedDataWatcher wrappedDataWatcher) { - List wrappedDataValueList = Lists.newArrayList(); - wrappedDataWatcher.getWatchableObjects().stream().filter(Objects::nonNull).forEach(entry -> { - final WrappedDataWatcher.WrappedDataWatcherObject dataWatcherObject = entry.getWatcherObject(); - wrappedDataValueList.add(new WrappedDataValue(dataWatcherObject.getIndex(), dataWatcherObject.getSerializer(), entry.getRawValue())); - }); - metaPacket.getDataValueCollectionModifier().write(0, wrappedDataValueList); - } - - /** - * Creates a metadata packet for updating the metadata of an armor stand entity with a custom Component. - * - * @param id The ID of the armor stand entity - * @param component The Component to set as metadata - * @return The PacketContainer representing the metadata packet - */ - public static PacketContainer getMetaPacket(int id, Component component) { - PacketContainer metaPacket = new PacketContainer(PacketType.Play.Server.ENTITY_METADATA); - metaPacket.getIntegers().write(0, id); - if (BukkitCustomFishingPlugin.get().getVersionManager().isVersionNewerThan1_19_3()) { - WrappedDataWatcher wrappedDataWatcher = createDataWatcher(component); - setValueList(metaPacket, wrappedDataWatcher); - } else { - metaPacket.getWatchableCollectionModifier().write(0, createDataWatcher(component).getWatchableObjects()); - } - return metaPacket; - } - - /** - * Creates a DataWatcher for an invisible armor stand entity. - * - * @return The created DataWatcher - */ - public static WrappedDataWatcher createDataWatcher() { - WrappedDataWatcher wrappedDataWatcher = new WrappedDataWatcher(); - WrappedDataWatcher.Serializer serializer1 = WrappedDataWatcher.Registry.get(Boolean.class); - WrappedDataWatcher.Serializer serializer2 = WrappedDataWatcher.Registry.get(Byte.class); - wrappedDataWatcher.setObject(new WrappedDataWatcher.WrappedDataWatcherObject(3, serializer1), false); - byte flag = 0x20; - wrappedDataWatcher.setObject(new WrappedDataWatcher.WrappedDataWatcherObject(0, serializer2), flag); - return wrappedDataWatcher; - } - - /** - * Creates a DataWatcher for an invisible armor stand entity with a custom Component. - * - * @param component The Component to set in the DataWatcher - * @return The created DataWatcher - */ - public static WrappedDataWatcher createDataWatcher(Component component) { - WrappedDataWatcher wrappedDataWatcher = new WrappedDataWatcher(); - WrappedDataWatcher.Serializer serializer1 = WrappedDataWatcher.Registry.get(Boolean.class); - WrappedDataWatcher.Serializer serializer2 = WrappedDataWatcher.Registry.get(Byte.class); - wrappedDataWatcher.setObject(new WrappedDataWatcher.WrappedDataWatcherObject(2, WrappedDataWatcher.Registry.getChatComponentSerializer(true)), Optional.of(WrappedChatComponent.fromJson(GsonComponentSerializer.gson().serialize(component)).getHandle())); - wrappedDataWatcher.setObject(new WrappedDataWatcher.WrappedDataWatcherObject(3, serializer1), true); - wrappedDataWatcher.setObject(new WrappedDataWatcher.WrappedDataWatcherObject(15, serializer2), (byte) 0x01); - byte flag = 0x20; - wrappedDataWatcher.setObject(new WrappedDataWatcher.WrappedDataWatcherObject(0, serializer2), flag); - return wrappedDataWatcher; - } - - /** - * Creates an equipment packet for equipping an armor stand with an ItemStack. - * - * @param id The ID of the armor stand entity - * @param itemStack The ItemStack to equip - * @return The PacketContainer representing the equipment packet - */ - public static PacketContainer getEquipPacket(int id, ItemStack itemStack) { - PacketContainer equipPacket = new PacketContainer(PacketType.Play.Server.ENTITY_EQUIPMENT); - equipPacket.getIntegers().write(0, id); - List> pairs = new ArrayList<>(); - pairs.add(new Pair<>(EnumWrappers.ItemSlot.HEAD, itemStack)); - equipPacket.getSlotStackPairLists().write(0, pairs); - return equipPacket; - } - - /** - * Sends a fake armor stand entity with item on head to a player at the specified location. - * - * @param player The player to send the entity to - * @param location The location where the entity should appear - * @param itemStack The ItemStack to represent the entity - * @param seconds The duration (in seconds) the entity should be displayed - */ - public static void sendFakeItem(Player player, Location location, ItemStack itemStack, int seconds) { - int id = new Random().nextInt(Integer.MAX_VALUE); - if (BukkitCustomFishingPlugin.get().getVersionManager().isVersionNewerThan1_19_4()) { - BukkitCustomFishingPluginImpl.sendPackets(player, getSpawnPacket(id, location.clone().subtract(0,1,0)), getMetaPacket(id), getEquipPacket(id, itemStack)); - } else { - BukkitCustomFishingPluginImpl.sendPacket(player, getSpawnPacket(id, location.clone().subtract(0,1,0))); - BukkitCustomFishingPluginImpl.sendPacket(player, getMetaPacket(id)); - BukkitCustomFishingPluginImpl.sendPacket(player, getEquipPacket(id, itemStack)); - } - BukkitCustomFishingPlugin.get().getScheduler().runTaskAsyncLater(() -> BukkitCustomFishingPluginImpl.getProtocolManager().sendServerPacket(player, getDestroyPacket(id)), seconds * 50L, TimeUnit.MILLISECONDS); - } - - /** - * Sends a hologram (armor stand with custom text) to a player at the specified location. - * - * @param player The player to send the hologram to - * @param location The location where the hologram should appear - * @param component The Component representing the hologram's text - * @param seconds The duration (in seconds) the hologram should be displayed - */ - public static void sendHologram(Player player, Location location, Component component, int seconds) { - int id = new Random().nextInt(Integer.MAX_VALUE); - if (BukkitCustomFishingPlugin.get().getVersionManager().isVersionNewerThan1_19_4()) { - BukkitCustomFishingPluginImpl.sendPackets(player, getSpawnPacket(id, location.clone().subtract(0,1,0)), getMetaPacket(id, component)); - } else { - BukkitCustomFishingPluginImpl.sendPacket(player, getSpawnPacket(id, location.clone().subtract(0,1,0))); - BukkitCustomFishingPluginImpl.sendPacket(player, getMetaPacket(id, component)); - } - BukkitCustomFishingPlugin.get().getScheduler().runTaskAsyncLater(() -> BukkitCustomFishingPluginImpl.getProtocolManager().sendServerPacket(player, getDestroyPacket(id)), seconds * 50L, TimeUnit.MILLISECONDS); - } -} \ No newline at end of file diff --git a/core/src/main/java/net/momirealms/customfishing/bukkit/util/ConfigUtils.java b/core/src/main/java/net/momirealms/customfishing/bukkit/util/ConfigUtils.java deleted file mode 100644 index 5c236536..00000000 --- a/core/src/main/java/net/momirealms/customfishing/bukkit/util/ConfigUtils.java +++ /dev/null @@ -1,256 +0,0 @@ -/* - * Copyright (C) <2022> - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - -package net.momirealms.customfishing.bukkit.util; - -import net.momirealms.customfishing.api.mechanic.misc.placeholder.BukkitPlaceholderManager; -import net.momirealms.customfishing.api.mechanic.misc.value.MathValue; -import org.bukkit.configuration.ConfigurationSection; -import org.bukkit.configuration.file.YamlConfiguration; -import org.bukkit.entity.Player; -import org.jetbrains.annotations.NotNull; - -import java.io.File; -import java.io.IOException; -import java.util.ArrayList; -import java.util.List; -import java.util.Map; - -/** - * Utility class for configuration-related operations. - */ -public class ConfigUtils { - - private ConfigUtils() {} - - - /** - * Splits a string into a pair of integers using the "~" delimiter. - * - * @param value The input string - * @return A Pair of integers - */ - public static Pair splitStringIntegerArgs(String value, String regex) { - String[] split = value.split(regex); - return Pair.of(Integer.parseInt(split[0]), Integer.parseInt(split[1])); - } - - /** - * Converts a list of strings in the format "key:value" into a list of Pairs with keys and doubles. - * - * @param list The input list of strings - * @return A list of Pairs containing keys and doubles - */ - public static List> getWeights(List list) { - List> result = new ArrayList<>(list.size()); - for (String member : list) { - String[] split = member.split(":",2); - String key = split[0]; - result.add(Pair.of(key, Double.parseDouble(split[1]))); - } - return result; - } - - - - /** - * Retrieves a list of enchantment pairs from a configuration section. - * - * @param section The configuration section to extract enchantment data from. - * @return A list of enchantment pairs. - */ - @NotNull - public static List> getEnchantmentPair(ConfigurationSection section) { - List> list = new ArrayList<>(); - if (section == null) return list; - for (Map.Entry entry : section.getValues(false).entrySet()) { - if (entry.getValue() instanceof Integer integer) { - list.add(Pair.of(entry.getKey(), Short.parseShort(String.valueOf(Math.max(1, Math.min(Short.MAX_VALUE, integer)))))); - } - } - return list; - } - - public static List> getEnchantAmountPair(ConfigurationSection section) { - List> list = new ArrayList<>(); - if (section == null) return list; - for (Map.Entry entry : section.getValues(false).entrySet()) { - list.add(Pair.of(Integer.parseInt(entry.getKey()), getValue(entry.getValue()))); - } - return list; - } - - public static List, MathValue>> getEnchantPoolPair(ConfigurationSection section) { - List, MathValue>> list = new ArrayList<>(); - if (section == null) return list; - for (Map.Entry entry : section.getValues(false).entrySet()) { - list.add(Pair.of(getEnchantmentPair(entry.getKey()), getValue(entry.getValue()))); - } - return list; - } - - public static Pair getEnchantmentPair(String value) { - int last = value.lastIndexOf(":"); - if (last == -1 || last == 0 || last == value.length() - 1) { - throw new IllegalArgumentException("Invalid format of the input enchantment"); - } - return Pair.of(value.substring(0, last), Short.parseShort(value.substring(last + 1))); - } - - /** - * Retrieves a list of enchantment tuples from a configuration section. - * - * @param section The configuration section to extract enchantment data from. - * @return A list of enchantment tuples. - */ - @NotNull - public static List> getEnchantmentTuple(ConfigurationSection section) { - List> list = new ArrayList<>(); - if (section == null) return list; - for (Map.Entry entry : section.getValues(false).entrySet()) { - if (entry.getValue() instanceof ConfigurationSection inner) { - Tuple tuple = Tuple.of( - inner.getDouble("chance"), - inner.getString("enchant"), - Short.valueOf(String.valueOf(inner.getInt("level"))) - ); - list.add(tuple); - } - } - return list; - } - - public static String getString(Object o) { - if (o instanceof String s) { - return s; - } else if (o instanceof Integer i) { - return String.valueOf(i); - } else if (o instanceof Double d) { - return String.valueOf(d); - } - throw new IllegalArgumentException("Illegal string format: " + o); - } - - /** - * Reads data from a YAML configuration file and creates it if it doesn't exist. - * - * @param file The file path - * @return The YamlConfiguration - */ - @SuppressWarnings("ResultOfMethodCallIgnored") - public static YamlConfiguration readData(File file) { - if (!file.exists()) { - try { - file.getParentFile().mkdirs(); - file.createNewFile(); - } catch (IOException e) { - e.printStackTrace(); - LogUtils.warn("Failed to generate data files!"); - } - } - return YamlConfiguration.loadConfiguration(file); - } - - /** - * Parses a WeightModifier from a string representation. - * - * @param text The input string - * @return A WeightModifier based on the provided text - * @throws IllegalArgumentException if the weight format is invalid - */ - public static WeightModifier getModifier(String text) { - if (text.length() == 0) { - throw new IllegalArgumentException("Weight format is invalid."); - } - switch (text.charAt(0)) { - case '/' -> { - double arg = Double.parseDouble(text.substring(1)); - return (player, weight) -> weight / arg; - } - case '*' -> { - double arg = Double.parseDouble(text.substring(1)); - return (player, weight) -> weight * arg; - } - case '-' -> { - double arg = Double.parseDouble(text.substring(1)); - return (player, weight) -> weight - arg; - } - case '%' -> { - double arg = Double.parseDouble(text.substring(1)); - return (player, weight) -> weight % arg; - } - case '+' -> { - double arg = Double.parseDouble(text.substring(1)); - return (player, weight) -> weight + arg; - } - case '=' -> { - String formula = text.substring(1); - return (player, weight) -> getExpressionValue(player, formula, Map.of("{0}", String.valueOf(weight))); - } - default -> throw new IllegalArgumentException("Invalid weight: " + text); - } - } - - public static double getExpressionValue(Player player, String formula, Map vars) { - formula = BukkitPlaceholderManager.getInstance().parse(player, formula, vars); - return new ExpressionBuilder(formula).build().evaluate(); - } - - public static ArrayList getReadableSection(Map map) { - ArrayList list = new ArrayList<>(); - mapToReadableStringList(map, list, 0, false); - return list; - } - - @SuppressWarnings("unchecked") - public static void mapToReadableStringList(Map map, List readableList, int loop_times, boolean isMapList) { - boolean first = true; - for (Map.Entry entry : map.entrySet()) { - Object nbt = entry.getValue(); - if (nbt instanceof List list) { - if (isMapList && first) { - first = false; - readableList.add(" ".repeat(loop_times - 1) + "- " + entry.getKey() + ":"); - } else { - readableList.add(" ".repeat(loop_times) + "" + entry.getKey() + ":"); - } - for (Object value : list) { - if (value instanceof Map nbtMap) { - mapToReadableStringList((Map) nbtMap, readableList, loop_times + 2, true); - } else { - readableList.add(" ".repeat(loop_times + 1) + "- " + value); - } - } - } else if (nbt instanceof Map innerMap) { - if (isMapList && first) { - first = false; - readableList.add(" ".repeat(loop_times - 1) + "- " + entry.getKey() + ":"); - } else { - readableList.add(" ".repeat(loop_times) + "" + entry.getKey() + ":"); - } - mapToReadableStringList((Map) innerMap, readableList, loop_times + 1, false); - } else { - if (isMapList && first) { - first = false; - readableList.add(" ".repeat(loop_times - 1) + "- " + entry.getKey() + ": " + nbt.toString()); - } else { - readableList.add(" ".repeat(loop_times) + "" + entry.getKey() + ": " + nbt.toString()); - } - } - } - } -} diff --git a/core/src/main/java/net/momirealms/customfishing/bukkit/util/FakeItemUtils.java b/core/src/main/java/net/momirealms/customfishing/bukkit/util/FakeItemUtils.java deleted file mode 100644 index c6520867..00000000 --- a/core/src/main/java/net/momirealms/customfishing/bukkit/util/FakeItemUtils.java +++ /dev/null @@ -1,151 +0,0 @@ -/* - * Copyright (C) <2022> - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - -package net.momirealms.customfishing.bukkit.util; - -import com.comphenix.protocol.PacketType; -import com.comphenix.protocol.events.PacketContainer; -import com.comphenix.protocol.wrappers.WrappedDataValue; -import com.comphenix.protocol.wrappers.WrappedDataWatcher; -import com.google.common.collect.Lists; -import net.momirealms.customfishing.api.BukkitCustomFishingPlugin; -import org.bukkit.Location; -import org.bukkit.entity.EntityType; -import org.bukkit.inventory.ItemStack; -import org.bukkit.util.Vector; - -import java.util.List; -import java.util.Objects; -import java.util.UUID; - -/** - * Utility class for managing fake item entities using PacketContainers. - */ -public class FakeItemUtils { - - private FakeItemUtils() {} - - /** - * Creates a destroy packet for removing a fake item entity. - * - * @param id The ID of the fake item entity to destroy - * @return The PacketContainer representing the destroy packet - */ - public static PacketContainer getDestroyPacket(int id) { - PacketContainer destroyPacket = new PacketContainer(PacketType.Play.Server.ENTITY_DESTROY); - destroyPacket.getIntLists().write(0, List.of(id)); - return destroyPacket; - } - - /** - * Creates a spawn packet for a fake item entity at the specified location. - * - * @param id The ID of the fake item entity to spawn - * @param location The location where the fake item entity should be spawned - * @return The PacketContainer representing the spawn packet - */ - public static PacketContainer getSpawnPacket(int id, Location location) { - PacketContainer entityPacket = new PacketContainer(PacketType.Play.Server.SPAWN_ENTITY); - entityPacket.getModifier().write(0, id); - entityPacket.getModifier().write(1, UUID.randomUUID()); - entityPacket.getEntityTypeModifier().write(0, EntityType.DROPPED_ITEM); - entityPacket.getDoubles().write(0, location.getX()); - entityPacket.getDoubles().write(1, location.getY() - 0.5); - entityPacket.getDoubles().write(2, location.getZ()); - return entityPacket; - } - - /** - * Creates a metadata packet for updating the metadata of a fake item entity. - * - * @param id The ID of the fake item entity - * @param itemStack The ItemStack to update the metadata with - * @return The PacketContainer representing the metadata packet - */ - public static PacketContainer getMetaPacket(int id, ItemStack itemStack) { - PacketContainer metaPacket = new PacketContainer(PacketType.Play.Server.ENTITY_METADATA); - metaPacket.getIntegers().write(0, id); - if (BukkitCustomFishingPlugin.getInstance().getVersionManager().isVersionNewerThan1_19_3()) { - WrappedDataWatcher wrappedDataWatcher = createDataWatcher(itemStack); - setValueList(metaPacket, wrappedDataWatcher); - } else { - metaPacket.getWatchableCollectionModifier().write(0, createDataWatcher(itemStack).getWatchableObjects()); - } - return metaPacket; - } - - /** - * Creates a teleport packet for moving a fake item entity to the specified location. - * - * @param id The ID of the fake item entity to teleport - * @param location The location to teleport the fake item entity to - * @return The PacketContainer representing the teleport packet - */ - public static PacketContainer getTpPacket(int id, Location location) { - PacketContainer tpPacket = new PacketContainer(PacketType.Play.Server.ENTITY_TELEPORT); - tpPacket.getModifier().write(0, id); - tpPacket.getDoubles().write(0, location.getX()); - tpPacket.getDoubles().write(1, location.getY() - 0.5); - tpPacket.getDoubles().write(2, location.getZ()); - return tpPacket; - } - - /** - * Creates a velocity packet for applying velocity to a fake item entity. - * - * @param id The ID of the fake item entity - * @param vector The velocity vector to apply - * @return The PacketContainer representing the velocity packet - */ - public static PacketContainer getVelocityPacket(int id, Vector vector) { - PacketContainer entityPacket = new PacketContainer(PacketType.Play.Server.ENTITY_VELOCITY); - entityPacket.getModifier().write(0, id); - entityPacket.getIntegers().write(1, (int) (vector.getX() * 8000)); - entityPacket.getIntegers().write(2, (int) (vector.getY() * 8000)); - entityPacket.getIntegers().write(3, (int) (vector.getZ() * 8000)); - return entityPacket; - } - - /** - * Creates a DataWatcher for a given ItemStack. - * - * @param itemStack The ItemStack to create the DataWatcher for - * @return The created DataWatcher - */ - public static WrappedDataWatcher createDataWatcher(ItemStack itemStack) { - WrappedDataWatcher wrappedDataWatcher = new WrappedDataWatcher(); - wrappedDataWatcher.setObject(new WrappedDataWatcher.WrappedDataWatcherObject(8, WrappedDataWatcher.Registry.getItemStackSerializer(false)), itemStack); - wrappedDataWatcher.setObject(new WrappedDataWatcher.WrappedDataWatcherObject(5, WrappedDataWatcher.Registry.get(Boolean.class)), true); - return wrappedDataWatcher; - } - - /** - * Sets the value list in a PacketContainer's DataWatcher from a WrappedDataWatcher. - * - * @param metaPacket The PacketContainer representing the metadata packet - * @param wrappedDataWatcher The WrappedDataWatcher containing the value list - */ - @SuppressWarnings("DuplicatedCode") - private static void setValueList(PacketContainer metaPacket, WrappedDataWatcher wrappedDataWatcher) { - List wrappedDataValueList = Lists.newArrayList(); - wrappedDataWatcher.getWatchableObjects().stream().filter(Objects::nonNull).forEach(entry -> { - final WrappedDataWatcher.WrappedDataWatcherObject dataWatcherObject = entry.getWatcherObject(); - wrappedDataValueList.add(new WrappedDataValue(dataWatcherObject.getIndex(), dataWatcherObject.getSerializer(), entry.getRawValue())); - }); - metaPacket.getDataValueCollectionModifier().write(0, wrappedDataValueList); - } -} diff --git a/core/src/main/java/net/momirealms/customfishing/bukkit/util/ItemUtils.java b/core/src/main/java/net/momirealms/customfishing/bukkit/util/ItemUtils.java deleted file mode 100644 index 140216f0..00000000 --- a/core/src/main/java/net/momirealms/customfishing/bukkit/util/ItemUtils.java +++ /dev/null @@ -1,502 +0,0 @@ -/* - * Copyright (C) <2022> - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - -package net.momirealms.customfishing.bukkit.util; - -import de.tr7zw.changeme.nbtapi.NBTCompound; -import de.tr7zw.changeme.nbtapi.NBTItem; -import de.tr7zw.changeme.nbtapi.NBTList; -import net.kyori.adventure.text.Component; -import net.kyori.adventure.text.ScoreComponent; -import net.kyori.adventure.text.serializer.gson.GsonComponentSerializer; -import net.momirealms.customfishing.api.BukkitCustomFishingPlugin; -import net.momirealms.customfishing.api.common.Pair; -import net.momirealms.customfishing.api.mechanic.hook.HookConfigImpl; -import org.bukkit.Bukkit; -import org.bukkit.Material; -import org.bukkit.enchantments.Enchantment; -import org.bukkit.entity.Player; -import org.bukkit.event.player.PlayerItemDamageEvent; -import org.bukkit.inventory.Inventory; -import org.bukkit.inventory.ItemStack; -import org.bukkit.inventory.PlayerInventory; -import org.bukkit.inventory.meta.Damageable; -import org.bukkit.inventory.meta.ItemMeta; -import org.bukkit.util.io.BukkitObjectInputStream; -import org.bukkit.util.io.BukkitObjectOutputStream; -import org.yaml.snakeyaml.external.biz.base64Coder.Base64Coder; - -import java.io.ByteArrayInputStream; -import java.io.ByteArrayOutputStream; -import java.io.IOException; - -/** - * Utility class for various item-related operations. - */ -public class ItemUtils { - - private ItemUtils() {} - - /** - * Updates the lore of an NBTItem based on its custom NBT tags. - * - * @param nbtItem The NBTItem to update - * @return The updated NBTItem - */ - public static NBTItem updateNBTItemLore(NBTItem nbtItem) { - NBTCompound cfCompound = nbtItem.getCompound("CustomFishing"); - if (cfCompound == null) - return nbtItem; - - NBTCompound displayCompound = nbtItem.getOrCreateCompound("display"); - NBTList lore = displayCompound.getStringList("Lore"); - lore.removeIf(it -> GsonComponentSerializer.gson().deserialize(it) instanceof ScoreComponent scoreComponent && scoreComponent.name().equals("cf")); - - if (cfCompound.hasTag("hook_id")) { - String hookID = cfCompound.getString("hook_id"); - HookConfigImpl setting = BukkitCustomFishingPlugin.get().getHookManager().getHookSetting(hookID); - if (setting == null) { - cfCompound.removeKey("hook_id"); - cfCompound.removeKey("hook_item"); - cfCompound.removeKey("hook_dur"); - } else { - for (String newLore : setting.lore()) { - ScoreComponent.Builder builder = Component.score().name("cf").objective("hook"); - builder.append(AdventureHelper.getInstance().getComponentFromMiniMessage( - newLore.replace("{dur}", String.valueOf(cfCompound.getInteger("hook_dur"))) - .replace("{max}", String.valueOf(setting.maxDurability())) - )); - lore.add(GsonComponentSerializer.gson().serialize(builder.build())); - } - } - } - - if (cfCompound.hasTag("max_dur")) { - int max = cfCompound.getInteger("max_dur"); - int current = cfCompound.getInteger("cur_dur"); - for (String newLore : CFConfig.durabilityLore) { - ScoreComponent.Builder builder = Component.score().name("cf").objective("durability"); - builder.append(AdventureHelper.getInstance().getComponentFromMiniMessage( - newLore.replace("{dur}", String.valueOf(current)) - .replace("{max}", String.valueOf(max)) - )); - lore.add(GsonComponentSerializer.gson().serialize(builder.build())); - } - } - return nbtItem; - } - - /** - * Updates the lore of an ItemStack based on its custom NBT tags. - * - * @param itemStack The ItemStack to update - */ - public static void updateItemLore(ItemStack itemStack) { - if (itemStack == null || itemStack.getType() == Material.AIR) - return; - NBTItem nbtItem = updateNBTItemLore(new NBTItem(itemStack)); - itemStack.setItemMeta(nbtItem.getItem().getItemMeta()); - } - - /** - * Reduces the durability of a fishing hook item. - * - * @param rod The fishing rod ItemStack - * @param updateLore Whether to update the lore after reducing durability - */ - public static void decreaseHookDurability(ItemStack rod, int amount, boolean updateLore) { - if (rod == null || rod.getType() != Material.FISHING_ROD) - return; - NBTItem nbtItem = new NBTItem(rod); - NBTCompound cfCompound = nbtItem.getCompound("CustomFishing"); - if (cfCompound != null && cfCompound.hasTag("hook_dur")) { - int hookDur = cfCompound.getInteger("hook_dur"); - if (hookDur != -1) { - hookDur = Math.max(0, hookDur - amount); - if (hookDur > 0) { - cfCompound.setInteger("hook_dur", hookDur); - } else { - cfCompound.removeKey("hook_id"); - cfCompound.removeKey("hook_dur"); - cfCompound.removeKey("hook_item"); - } - } - } - if (updateLore) updateNBTItemLore(nbtItem); - rod.setItemMeta(nbtItem.getItem().getItemMeta()); - } - - /** - * Increases the durability of a fishing hook by a specified amount and optionally updates its lore. - * - * @param rod The fishing rod ItemStack to modify. - * @param amount The amount by which to increase the durability. - * @param updateLore Whether to update the lore of the fishing rod. - */ - public static void increaseHookDurability(ItemStack rod, int amount, boolean updateLore) { - if (rod == null || rod.getType() != Material.FISHING_ROD) - return; - NBTItem nbtItem = new NBTItem(rod); - NBTCompound cfCompound = nbtItem.getCompound("CustomFishing"); - if (cfCompound != null && cfCompound.hasTag("hook_dur")) { - int hookDur = cfCompound.getInteger("hook_dur"); - if (hookDur != -1) { - String id = cfCompound.getString("hook_id"); - HookConfigImpl setting = BukkitCustomFishingPlugin.get().getHookManager().getHookSetting(id); - if (setting == null) { - cfCompound.removeKey("hook_id"); - cfCompound.removeKey("hook_dur"); - cfCompound.removeKey("hook_item"); - } else { - hookDur = Math.min(setting.maxDurability(), hookDur + amount); - cfCompound.setInteger("hook_dur", hookDur); - } - } - } - if (updateLore) updateNBTItemLore(nbtItem); - rod.setItemMeta(nbtItem.getItem().getItemMeta()); - } - - /** - * Sets the durability of a fishing hook to a specific amount and optionally updates its lore. - * - * @param rod The fishing rod ItemStack to modify. - * @param amount The new durability value to set. - * @param updateLore Whether to update the lore of the fishing rod. - */ - public static void setHookDurability(ItemStack rod, int amount, boolean updateLore) { - if (rod == null || rod.getType() != Material.FISHING_ROD) - return; - NBTItem nbtItem = new NBTItem(rod); - NBTCompound cfCompound = nbtItem.getCompound("CustomFishing"); - if (cfCompound != null && cfCompound.hasTag("hook_dur")) { - int hookDur = cfCompound.getInteger("hook_dur"); - if (hookDur != -1) { - String id = cfCompound.getString("hook_id"); - HookConfigImpl setting = BukkitCustomFishingPlugin.get().getHookManager().getHookSetting(id); - if (setting == null) { - cfCompound.removeKey("hook_id"); - cfCompound.removeKey("hook_dur"); - cfCompound.removeKey("hook_item"); - } else { - hookDur = Math.min(setting.maxDurability(), amount); - cfCompound.setInteger("hook_dur", hookDur); - } - } - } - if (updateLore) updateNBTItemLore(nbtItem); - rod.setItemMeta(nbtItem.getItem().getItemMeta()); - } - - /** - * Decreases the durability of an item and updates its lore. - * - * @param itemStack The ItemStack to reduce durability for - * @param amount The amount by which to reduce durability - * @param updateLore Whether to update the lore after reducing durability - */ - public static void decreaseDurability(Player player, ItemStack itemStack, int amount, boolean updateLore) { - if (itemStack == null || itemStack.getType() == Material.AIR) - return; - NBTItem nbtItem = new NBTItem(itemStack); - NBTCompound cfCompound = nbtItem.getCompound("CustomFishing"); - if (cfCompound != null && cfCompound.hasTag("max_dur")) { - int unBreakingLevel = itemStack.getEnchantmentLevel(Enchantment.DURABILITY); - if (Math.random() > (double) 1 / (unBreakingLevel + 1)) { - return; - } - if (nbtItem.getByte("Unbreakable") == 1) { - return; - } - int max = cfCompound.getInteger("max_dur"); - int current = cfCompound.getInteger("cur_dur") - amount; - cfCompound.setInteger("cur_dur", current); - int damage = (int) (itemStack.getType().getMaxDurability() * (1 - ((double) current / max))); - nbtItem.setInteger("Damage", damage); - if (current > 0) { - if (updateLore) updateNBTItemLore(nbtItem); - itemStack.setItemMeta(nbtItem.getItem().getItemMeta()); - } else { - itemStack.setAmount(0); - } - } else { - ItemMeta previousMeta = itemStack.getItemMeta().clone(); - PlayerItemDamageEvent itemDamageEvent = new PlayerItemDamageEvent(player, itemStack, amount, amount); - Bukkit.getPluginManager().callEvent(itemDamageEvent); - if (!itemStack.getItemMeta().equals(previousMeta) || itemDamageEvent.isCancelled()) { - return; - } - int unBreakingLevel = itemStack.getEnchantmentLevel(Enchantment.DURABILITY); - if (Math.random() > (double) 1 / (unBreakingLevel + 1)) { - return; - } - if (nbtItem.getByte("Unbreakable") == 1) { - return; - } - int damage = nbtItem.getInteger("Damage") + amount; - if (damage > itemStack.getType().getMaxDurability()) { - itemStack.setAmount(0); - } else { - nbtItem.setInteger("Damage", damage); - if (updateLore) updateNBTItemLore(nbtItem); - itemStack.setItemMeta(nbtItem.getItem().getItemMeta()); - } - } - } - - /** - * Increases the durability of an item and updates its lore. - * - * @param itemStack The ItemStack to increase durability for - * @param amount The amount by which to increase durability - * @param updateLore Whether to update the lore after increasing durability - */ - public static void increaseDurability(ItemStack itemStack, int amount, boolean updateLore) { - if (itemStack == null || itemStack.getType() == Material.AIR) - return; - NBTItem nbtItem = new NBTItem(itemStack); - if (nbtItem.getByte("Unbreakable") == 1) { - return; - } - NBTCompound cfCompound = nbtItem.getCompound("CustomFishing"); - if (cfCompound != null && cfCompound.hasTag("max_dur")) { - int max = cfCompound.getInteger("max_dur"); - int current = Math.min(max, cfCompound.getInteger("cur_dur") + amount); - cfCompound.setInteger("cur_dur", current); - int damage = (int) (itemStack.getType().getMaxDurability() * (1 - ((double) current / max))); - nbtItem.setInteger("Damage", damage); - if (updateLore) updateNBTItemLore(nbtItem); - } else { - int damage = Math.max(nbtItem.getInteger("Damage") - amount, 0); - nbtItem.setInteger("Damage", damage); - } - itemStack.setItemMeta(nbtItem.getItem().getItemMeta()); - } - - /** - * Sets the durability of an item and updates its lore. - * - * @param itemStack The ItemStack to set durability for - * @param amount The new durability value - * @param updateLore Whether to update the lore after setting durability - */ - public static void setDurability(ItemStack itemStack, int amount, boolean updateLore) { - if (itemStack == null || itemStack.getType() == Material.AIR) - return; - if (amount <= 0) { - itemStack.setAmount(0); - return; - } - NBTItem nbtItem = new NBTItem(itemStack); - if (nbtItem.getByte("Unbreakable") == 1) { - return; - } - NBTCompound cfCompound = nbtItem.getCompound("CustomFishing"); - if (cfCompound != null && cfCompound.hasTag("max_dur")) { - int max = cfCompound.getInteger("max_dur"); - amount = Math.min(amount, max); - cfCompound.setInteger("cur_dur", amount); - int damage = (int) (itemStack.getType().getMaxDurability() * (1 - ((double) amount / max))); - nbtItem.setInteger("Damage", damage); - if (updateLore) updateNBTItemLore(nbtItem); - } else { - nbtItem.setInteger("Damage", itemStack.getType().getMaxDurability() - amount); - } - itemStack.setItemMeta(nbtItem.getItem().getItemMeta()); - } - - /** - * Retrieves the current durability of an item. - * - * @param itemStack The ItemStack to get durability from - * @return The current durability value - */ - public static Pair getCustomDurability(ItemStack itemStack) { - if (itemStack == null || itemStack.getType() == Material.AIR) - return Pair.of(0, 0); - if (itemStack.getItemMeta() instanceof Damageable damageable && damageable.isUnbreakable()) - return Pair.of(-1, -1); - NBTItem nbtItem = new NBTItem(itemStack); - NBTCompound cfCompound = nbtItem.getCompound("CustomFishing"); - if (cfCompound != null && cfCompound.hasTag("max_dur")) { - return Pair.of(cfCompound.getInteger("max_dur"), cfCompound.getInteger("cur_dur")); - } else { - return Pair.of(0, 0); - } - } - - /** - * Gives a certain amount of an item to a player, handling stacking and item drops. - * - * @param player The player to give the item to - * @param itemStack The ItemStack to give - * @param amount The amount of items to give - * @return The actual amount of items given - */ - public static int giveItem(Player player, ItemStack itemStack, int amount) { - PlayerInventory inventory = player.getInventory(); - ItemMeta meta = itemStack.getItemMeta(); - int maxStackSize = itemStack.getMaxStackSize(); - - if (amount > maxStackSize * 100) { - LogUtils.warn("Detected too many items spawning. Lowering the amount to " + (maxStackSize * 100)); - amount = maxStackSize * 100; - } - - int actualAmount = amount; - - for (ItemStack other : inventory.getStorageContents()) { - if (other != null) { - if (other.getType() == itemStack.getType() && other.getItemMeta().equals(meta)) { - if (other.getAmount() < maxStackSize) { - int delta = maxStackSize - other.getAmount(); - if (amount > delta) { - other.setAmount(maxStackSize); - amount -= delta; - } else { - other.setAmount(amount + other.getAmount()); - return actualAmount; - } - } - } - } - } - - if (amount > 0) { - for (ItemStack other : inventory.getStorageContents()) { - if (other == null) { - if (amount > maxStackSize) { - amount -= maxStackSize; - ItemStack cloned = itemStack.clone(); - cloned.setAmount(maxStackSize); - inventory.addItem(cloned); - } else { - ItemStack cloned = itemStack.clone(); - cloned.setAmount(amount); - inventory.addItem(cloned); - return actualAmount; - } - } - } - } - - if (amount > 0) { - for (int i = 0; i < amount / maxStackSize; i++) { - ItemStack cloned = itemStack.clone(); - cloned.setAmount(maxStackSize); - player.getWorld().dropItem(player.getLocation(), cloned); - } - int left = amount % maxStackSize; - if (left != 0) { - ItemStack cloned = itemStack.clone(); - cloned.setAmount(left); - player.getWorld().dropItem(player.getLocation(), cloned); - } - } - - return actualAmount; - } - - public static String toBase64(ItemStack itemStack) { - if (itemStack == null || itemStack.getType() == Material.AIR) - return ""; - ByteArrayOutputStream outputStream = new ByteArrayOutputStream(); - try (BukkitObjectOutputStream dataOutput = new BukkitObjectOutputStream(outputStream)) { - dataOutput.writeObject(itemStack); - byte[] byteArr = outputStream.toByteArray(); - dataOutput.close(); - outputStream.close(); - return Base64Coder.encodeLines(byteArr); - } catch (IOException e) { - e.printStackTrace(); - return ""; - } - } - - public static ItemStack fromBase64(String base64) { - if (base64 == null || base64.equals("")) - return new ItemStack(Material.AIR); - ByteArrayInputStream inputStream; - try { - inputStream = new ByteArrayInputStream(Base64Coder.decodeLines(base64)); - } catch (IllegalArgumentException e) { - return new ItemStack(Material.AIR); - } - ItemStack stack = null; - try (BukkitObjectInputStream dataInput = new BukkitObjectInputStream(inputStream)) { - stack = (ItemStack) dataInput.readObject(); - } catch (IOException | ClassNotFoundException e) { - e.printStackTrace(); - } - return stack; - } - - public static ItemStack removeOwner(ItemStack itemStack) { - if (itemStack == null || itemStack.getType() == Material.AIR) return itemStack; - NBTItem nbtItem = new NBTItem(itemStack); - if (nbtItem.hasTag("owner")) { - nbtItem.removeKey("owner"); - return nbtItem.getItem(); - } - return itemStack; - } - - /** - * @return the amount of items that can't be put in the inventory - */ - public static int putLootsToBag(Inventory inventory, ItemStack itemStack, int amount) { - itemStack = removeOwner(itemStack.clone()); - ItemMeta meta = itemStack.getItemMeta(); - int maxStackSize = itemStack.getMaxStackSize(); - for (ItemStack other : inventory.getStorageContents()) { - if (other != null) { - if (other.getType() == itemStack.getType() && other.getItemMeta().equals(meta)) { - if (other.getAmount() < maxStackSize) { - int delta = maxStackSize - other.getAmount(); - if (amount > delta) { - other.setAmount(maxStackSize); - amount -= delta; - } else { - other.setAmount(amount + other.getAmount()); - return 0; - } - } - } - } - } - - if (amount > 0) { - for (ItemStack other : inventory.getStorageContents()) { - if (other == null) { - if (amount > maxStackSize) { - amount -= maxStackSize; - ItemStack cloned = itemStack.clone(); - cloned.setAmount(maxStackSize); - inventory.addItem(cloned); - } else { - ItemStack cloned = itemStack.clone(); - cloned.setAmount(amount); - inventory.addItem(cloned); - return 0; - } - } - } - } - - return amount; - } -} diff --git a/core/src/main/resources/config.yml b/core/src/main/resources/config.yml index 580fcb50..932ee29c 100644 --- a/core/src/main/resources/config.yml +++ b/core/src/main/resources/config.yml @@ -1,6 +1,4 @@ -# Developer: @Xiao-MoMi -# Wiki: https://mo-mi.gitbook.io/xiaomomi-plugins/ -config-version: '32' +config-version: '${config_version}' # Debug debug: false diff --git a/core/src/main/resources/database.yml b/core/src/main/resources/database.yml index af8f3715..1c133b46 100644 --- a/core/src/main/resources/database.yml +++ b/core/src/main/resources/database.yml @@ -1,3 +1,5 @@ +config-version: '${config_version}' + # file: # JSON # YAML diff --git a/core/src/main/resources/market.yml b/core/src/main/resources/market.yml index e53f5380..f7987c76 100644 --- a/core/src/main/resources/market.yml +++ b/core/src/main/resources/market.yml @@ -1,3 +1,5 @@ +config-version: '${config_version}' + enable: true # Container title diff --git a/core/src/main/resources/messages/en.yml b/core/src/main/resources/messages/en.yml deleted file mode 100644 index 82ef3fa2..00000000 --- a/core/src/main/resources/messages/en.yml +++ /dev/null @@ -1,125 +0,0 @@ -# Don't change this -config-version: '31' - -messages: - prefix: '[CustomFishing] ' - reload: 'Reloaded. Took {time}ms.' - item-not-exist: 'Item not found.' - give-item: 'Successfully given player {player} {amount}x {item}.' - get-item: 'Successfully got {amount}x {item}.' - possible-loots: 'Possible loots here: ' - split-char: ', ' - competition-not-exist: 'Competition {id} does not exist.' - no-competition-ongoing: "There's no competition ongoing." - stop-competition: 'Stopped the current competition.' - end-competition: 'Ended the current competition.' - no-score: 'No Score' - no-player: 'No Player' - no-rank: 'No Rank' - goal-catch-amount: 'Fish count caught' - goal-max-size: 'Largest fish caught' - goal-total-size: 'Total length of fish caught' - goal-total-score: 'Cumulative score of fish caught' - unsafe-modification: "Cannot modify a player's fishing bag if they're active on another linked server." - never-played: "The player hasn't joined the server before. Can't modify a nonexistent player's fishing bag." - data-not-loaded: "Data hasn't loaded. Please re-enter the server. If issues persist, reach out to the server admin." - open-market-gui: "Successfully opened the market gui for {player}" - open-fishing-bag: "Successfully opened the fishing bag for {player}" - format-day: 'd' - format-hour: 'h' - format-minute: 'm' - format-second: 's' - -gui: - search: "Search" - select-file: 'Select file' - select-item: "Select item" - dupe-invalid-key: "● Duplicated or invalid key" - new-value: "New value: " - temp-new-key: 'New key' - set-new-key: "Set new key" - edit-key: 'Edit {0}' - delete-property: "<#00CED1>● Delete property" - click-confirm: "<#00FF7F> -> Click to confirm" - invalid-number: "● Invalid number" - illegal-format: "● Illegal format" - scroll-up: '● Scroll up' - scroll-down: '● Scroll down' - cannot-scroll-up: "You've reached the top" - cannot-scroll-down: "You can't scroll further down" - next-page: '● Next Page' - goto-next-page: 'Go to page {0} / {1}' - cannot-goto-next-page: 'There are no more pages' - previous-page: '● Previous page' - goto-previous-page: 'Go to page {0} / {1}' - cannot-goto-previous-page: "You can't go further back" - back-to-parent-page: "<#FF8C00>Back to parent page" - back-to-parent-folder: "<#FF8C00>Back to parent folder" - current-value: "Current value: " - click-to-toggle: "<#00FF7F> -> Click to toggle" - left-click-edit: "<#00FF7F> -> Left click to edit" - right-click-reset: "<#FF6347> -> Right click to reset" - right-click-delete: "<#FF6347> -> Right click to delete" - right-click-cancel: "<#00CED1> -> Right click to cancel" - loot-show-in-finder: "<#5F9EA0>● Show In Fish Finder" - loot-score: "<#FF1493>● Score" - loot-nick: "<#00FF00>● Nick" - loot-instant-game: "<#7B68EE>● Instant Game" - loot-disable-statistics: "<#CD853F>● Disable Statistics" - loot-disable-game: "<#8B4513>● Disable Game" - item-amount: "<#1E90FF>● Amount" - item-custom-model-data: "<#FFC0CB>● Custom Model Data" - item-display-name: "<#FAFAD2>● Display Name" - item-custom-durability: "<#1E90FF>● Custom Durability" - item-enchantment: "<#8A2BE2>● Enchantment" - item-head64: "<#2E8B57>● Head64" - item-item-flag: "<#E6E6FA>● Item Flag" - item-lore: "<#FA8072>● Lore" - item-material: "<#FF00FF>● Material" - item-nbt: "<#FA8072>● NBT" - item-prevent-grab: "<#FF4500>● Prevent Grabbing" - item-price: "<#FFD700>● Price" - item-price-base: " - base: " - item-price-bonus: " - bonus: " - item-random-durability: "<#FFFF00>● Random Durability" - item-size: "<#FFF0F5>● Size" - item-stackable: "<#9370DB>● Stackable" - item-stored-enchantment: "<#9370DB>● Stored Enchantment" - item-tag: "<#2E8B57>● Tag" - item-unbreakable: "<#C0C0C0>● Unbreakable" - page-amount-title: "Edit Amount" - page-model-data-title: "Edit CustomModelData" - page-display-name-title: "Edit display name" - page-new-display-name: "New name" - page-custom-durability-title: "Edit custom durability" - page-stored-enchantment-title: "Edit stored enchantment" - page-enchantment-title: "Edit enchantment" - page-select-one-enchantment: "Select one enchantment" - page-add-new-enchantment: "[+] Add a new enchantment" - page-item-flag-title: "Edit item flag" - page-lore-title: "Edit lore" - page-add-new-lore: "[+] Add a new line" - page-select-one-lore: "Select one line" - page-material-title: "Edit Material" - page-nbt-compound-key-title: "Edit compound key" - page-nbt-list-key-title: "Edit list key" - page-nbt-key-title: "Edit key" - page-nbt-invalid-key: "Invaild key" - page-nbt-add-new-compound: "[+] Add a new compound" - page-nbt-add-new-list: "[+] Add a new list" - page-nbt-add-new-value: "[+] Add a new value" - page-add-new-key: "[+] Add a new key" - page-nbt-preview: "● NBT Preview" - page-nbt-back-to-compound: "Back to parent compound" - page-nbt-set-value-title: "Set value" - page-nbt-edit-title: "Edit NBT" - page-nick-title: "Edit nick" - page-new-nick: "New nick" - page-price-title: "Edit price" - page-base-price: "Base" - page-base-bonus: "Bonus" - page-score-title: "Edit score" - page-size-title: "Edit size" - page-size-min: "Minimum" - page-size-max: "Maximum" - page-size-max-no-less-min: "● Max must be no less than min" diff --git a/core/src/main/resources/messages/es.yml b/core/src/main/resources/messages/es.yml deleted file mode 100644 index 11405083..00000000 --- a/core/src/main/resources/messages/es.yml +++ /dev/null @@ -1,125 +0,0 @@ -# Don't change this -config-version: '31' - -messages: - prefix: '[CustomFishing] ' - reload: 'Recargado! Tardó {time}ms.' - item-not-exist: 'Item no encontrado.' - give-item: 'Se ha entregado {amount}x {item} al jugador {player}.' - get-item: 'Se ha recibido {amount}x {item}.' - possible-loots: 'Posibles recompensas: ' - split-char: ', ' - competition-not-exist: 'La Competición {id} no existe.' - no-competition-ongoing: "No hay una competencia activa." - stop-competition: 'Se ha detenido la competición.' - end-competition: 'Ha finalizado la competición.' - no-score: 'Sin puntaje' - no-player: 'Sin jugador' - no-rank: 'Sin rango' - goal-catch-amount: 'Peces atrapados' - goal-max-size: 'Pez más grande capturado' - goal-total-size: 'Longitud total de peces capturados' - goal-total-score: 'Puntaje acumulado por peces capturados' - unsafe-modification: "No se puede modificar la bolsa de pesca de un jugador si sigue activo en otro servidor vinculado." - never-played: "Este jugador nunca se ha unido al servidor. No puedes modificar la bolsa de pesca de un jugador inexistente." - data-not-loaded: "No se pudo cargar la información. Por favor, vuelve a ingresar al servidor. Si el problema persiste, contacta a un administrador." - open-market-gui: "Se ha abierto la interfaz para {player}" - open-fishing-bag: "Se ha abierto la bolsa de pesca de {player}" - format-day: 'd' - format-hour: 'h' - format-minute: 'm' - format-second: 's' - -gui: - search: "Buscar" - select-file: 'Seleccionar archivo' - select-item: "Seleccionar item" - dupe-invalid-key: "● ID inválida o duplicada" - new-value: "Nuevo valor: " - temp-new-key: 'Nueva ID' - set-new-key: "Definir nueva ID" - edit-key: 'Editar {0}' - delete-property: "<#00CED1>● Eliminar propiedad" - click-confirm: "<#00FF7F> -> Click para confirmar" - invalid-number: "● Número inválido" - illegal-format: "● Formato inválido" - scroll-up: '● Arriba' - scroll-down: '● Abajo' - cannot-scroll-up: "Estás en el límite superior" - cannot-scroll-down: "Estás en el límite inferior" - next-page: '● Siguiente Página' - goto-next-page: 'Ir a la página {0} / {1}' - cannot-goto-next-page: 'No hay más páginas' - previous-page: '● Página anterior' - goto-previous-page: 'Ir a la página {0} / {1}' - cannot-goto-previous-page: "No hay más páginas atrás" - back-to-parent-page: "<#FF8C00>Volver al menú anterior" - back-to-parent-folder: "<#FF8C00>Volver a la carpeta anterior" - current-value: "Valor actual: " - click-to-toggle: "<#00FF7F> -> Click para cambiar" - left-click-edit: "<#00FF7F> -> Click izquierdo para editar" - right-click-reset: "<#FF6347> -> Click derecho para restablecer" - right-click-delete: "<#FF6347> -> Click derecho para eliminar" - right-click-cancel: "<#00CED1> -> Click derecho para cancelar" - loot-show-in-finder: "<#5F9EA0>● Mostar en el rastreador de peces" - loot-score: "<#FF1493>● Puntaje" - loot-nick: "<#00FF00>● Apodo" - loot-instant-game: "<#7B68EE>● Juego Instantáneo" - loot-disable-statistics: "<#CD853F>● Deshabilitar Estadísticas" - loot-disable-game: "<#8B4513>● Deshabilitar Juego" - item-amount: "<#1E90FF>● Cantidad" - item-custom-model-data: "<#FFC0CB>● Custom Model Data" - item-display-name: "<#FAFAD2>● Nombre a mostrar" - item-custom-durability: "<#1E90FF>● Durabilidad" - item-enchantment: "<#8A2BE2>● Encantamiento" - item-head64: "<#2E8B57>● Head64" - item-item-flag: "<#E6E6FA>● Item Flag" - item-lore: "<#FA8072>● Descripción" - item-material: "<#FF00FF>● Material" - item-nbt: "<#FA8072>● NBT" - item-prevent-grab: "<#FF4500>● Evitar recoger item" - item-price: "<#FFD700>● Precio" - item-price-base: " - base: " - item-price-bonus: " - bonus: " - item-random-durability: "<#FFFF00>● Durabilidad Aleatoria" - item-size: "<#FFF0F5>● Tamaño" - item-stackable: "<#9370DB>● Acumulable" - item-stored-enchantment: "<#9370DB>● Encantamiento Almacenado" - item-tag: "<#2E8B57>● Etiqueta" - item-unbreakable: "<#C0C0C0>● Irrompible" - page-amount-title: "Editar Cantidad" - page-model-data-title: "Editar CustomModelData" - page-display-name-title: "Editar nombre a mostrar" - page-new-display-name: "Nuevo nombre" - page-custom-durability-title: "Edit durabilidad" - page-stored-enchantment-title: "Edit encantamiento almacenado" - page-enchantment-title: "Editar enchantmentamiento" - page-select-one-enchantment: "Seleccionar un encantamiento" - page-add-new-enchantment: "[+] Añadir un encantamiento" - page-item-flag-title: "Editar item flag" - page-lore-title: "Editar descripción" - page-add-new-lore: "[+] Añadir nueva línea" - page-select-one-lore: "Seleccionar una línea" - page-material-title: "Editar Material" - page-nbt-compound-key-title: "Editar ID de NBT compuesta" - page-nbt-list-key-title: "Editar lista de IDs" - page-nbt-key-title: "Editar ID" - page-nbt-invalid-key: "ID inválida" - page-nbt-add-new-compound: "[+] Añadir nueva NBT compuesta" - page-nbt-add-new-list: "[+] Añadir nueva lista" - page-nbt-add-new-value: "[+] Añadir nuevo valor" - page-add-new-key: "[+] Añadir nueva ID" - page-nbt-preview: "● Vista previa de NBT" - page-nbt-back-to-compound: "Volver al compuesto padre" - page-nbt-set-value-title: "Definir nuevo valor" - page-nbt-edit-title: "Editar NBT" - page-nick-title: "Editar apodo" - page-new-nick: "Nuevo apodo" - page-price-title: "Editar precio" - page-base-price: "Base" - page-base-bonus: "Bonus" - page-score-title: "Editar puntuación" - page-size-title: "Editar tamaño" - page-size-min: "Mínimo" - page-size-max: "Máximo" - page-size-max-no-less-min: "● El valor máximo no puede ser inferior al mínimo" diff --git a/core/src/main/resources/messages/fr.yml b/core/src/main/resources/messages/fr.yml deleted file mode 100644 index abf04c67..00000000 --- a/core/src/main/resources/messages/fr.yml +++ /dev/null @@ -1,125 +0,0 @@ -# Don't change this -config-version: '30' - -messages: - prefix: '[CustomFishing] ' - reload: 'Rechargé. A pris {time}ms.' - item-not-exist: 'Objet non trouvé.' - give-item: 'Joueur {player} a reçu avec succès {amount}x {item}.' - get-item: 'A obtenu avec succès {amount}x {item}.' - possible-loots: 'Butins possibles ici : ' - split-char: ', ' - competition-not-exist: "La compétition {id} n'existe pas." - no-competition-ongoing: 'Aucune compétition en cours.' - stop-competition: 'Compétition actuelle arrêtée.' - end-competition: 'Compétition actuelle terminée.' - no-score: 'Pas de score' - no-player: 'Pas de joueur' - no-rank: 'Pas de classement' - goal-catch-amount: 'Nombre de poissons attrapés' - goal-max-size: 'Plus gros poisson attrapé' - goal-total-size: 'Longueur totale des poissons attrapés' - goal-total-score: 'Score cumulatif des poissons attrapés' - unsafe-modification: "Impossible de modifier le sac de pêche d'un joueur s'il est actif sur un autre serveur lié." - never-played: "Le joueur n'a jamais rejoint le serveur auparavant. Impossible de modifier le sac de pêche d'un joueur inexistant." - data-not-loaded: "Les données n'ont pas été chargées. Veuillez réessayer de rejoindre le serveur. Si les problèmes persistent, contactez l'administrateur du serveur." - open-market-gui: "L'interface du marché a été ouverte avec succès pour {player}." - open-fishing-bag: "Le sac de pêche de {player} a été ouvert avec succès." - format-day: 'j' - format-hour: 'h' - format-minute: 'm' - format-second: 's' - -gui: - search: "Rechercher" - select-file: "Sélectionner un fichier" - select-item: "Sélectionner un élément" - dupe-invalid-key: "● Clé en double ou invalide" - new-value: "Nouvelle valeur : " - temp-new-key: "Nouvelle clé" - set-new-key: "Définir une nouvelle clé" - edit-key: "Modifier {0}" - delete-property: "<#00CED1>● Supprimer la propriété" - click-confirm: "<#00FF7F> -> Cliquez pour confirmer" - invalid-number: "● Nombre invalide" - illegal-format: "● Format illégal" - scroll-up: "● Faire défiler vers le haut" - scroll-down: "● Faire défiler vers le bas" - cannot-scroll-up: "Vous avez atteint le haut" - cannot-scroll-down: "Vous ne pouvez pas faire défiler plus bas" - next-page: "● Page suivante" - goto-next-page: "Aller à la page {0} / {1}" - cannot-goto-next-page: "Il n'y a plus de pages" - previous-page: "● Page précédente" - goto-previous-page: "Aller à la page {0} / {1}" - cannot-goto-previous-page: "Vous ne pouvez pas revenir en arrière" - back-to-parent-page: "<#FF8C00>Retour à la page parente" - back-to-parent-folder: "<#FF8C00>Retour au dossier parent" - current-value: "Valeur actuelle : " - click-to-toggle: "<#00FF7F> -> Cliquez pour basculer" - left-click-edit: "<#00FF7F> -> Cliquez gauche pour modifier" - right-click-reset: "<#FF6347> -> Cliquez droit pour réinitialiser" - right-click-delete: "<#FF6347> -> Cliquez droit pour supprimer" - right-click-cancel: "<#00CED1> -> Cliquez droit pour annuler" - loot-show-in-finder: "<#5F9EA0>● Afficher dans le repère de poisson" - loot-score: "<#FF1493>● Score" - loot-nick: "<#00FF00>● Surnom" - loot-instant-game: "<#7B68EE>● Jeu instantané" - loot-disable-statistics: "<#CD853F>● Désactiver les statistiques" - loot-disable-game: "<#8B4513>● Désactiver le jeu" - item-amount: "<#1E90FF>● Quantité" - item-custom-model-data: "<#FFC0CB>● Données de modèle personnalisées" - item-display-name: "<#FAFAD2>● Nom affiché" - item-custom-durability: "<#1E90FF>● Durabilité personnalisée" - item-enchantment: "<#8A2BE2>● Enchantement" - item-head64: "<#2E8B57>● Tête64" - item-item-flag: "<#E6E6FA>● Drapeau d'élément" - item-lore: "<#FA8072>● Légende" - item-material: "<#FF00FF>● Matériau" - item-nbt: "<#FA8072>● NBT" - item-prevent-grab: "<#FF4500>● Empêcher la saisie" - item-price: "<#FFD700>● Prix" - item-price-base: " - de base : " - item-price-bonus: " - bonus : " - item-random-durability: "<#FFFF00>● Durabilité aléatoire" - item-size: "<#FFF0F5>● Taille" - item-stackable: "<#9370DB>● Empilable" - item-stored-enchantment: "<#9370DB>● Enchantement stocké" - item-tag: "<#2E8B57>● Étiquette" - item-unbreakable: "<#C0C0C0>● Incassable" - page-amount-title: "Modifier la quantité" - page-model-data-title: "Modifier CustomModelData" - page-display-name-title: "Modifier le nom affiché" - page-new-display-name: "Nouveau nom" - page-custom-durability-title: "Modifier la durabilité personnalisée" - page-stored-enchantment-title: "Modifier l'enchantement stocké" - page-enchantment-title: "Modifier l'enchantement" - page-select-one-enchantment: "Sélectionner un enchantement" - page-add-new-enchantment: "[+] Ajouter un nouvel enchantement" - page-item-flag-title: "Modifier le drapeau d'élément" - page-lore-title: "Modifier la légende" - page-add-new-lore: "[+] Ajouter une nouvelle ligne" - page-select-one-lore: "Sélectionner une ligne" - page-material-title: "Modifier le matériau" - page-nbt-compound-key-title: "Modifier la clé composée" - page-nbt-list-key-title: "Modifier la clé de liste" - page-nbt-key-title: "Modifier la clé" - page-nbt-invalid-key: "Clé invalide" - page-nbt-add-new-compound: "[+] Ajouter une nouvelle composante" - page-nbt-add-new-list: "[+] Ajouter une nouvelle liste" - page-nbt-add-new-value: "[+] Ajouter une nouvelle valeur" - page-add-new-key: "[+] Ajouter une nouvelle clé" - page-nbt-preview: "● Aperçu NBT" - page-nbt-back-to-compound: "Retour à la composante parente" - page-nbt-set-value-title: "Définir la valeur" - page-nbt-edit-title: "Modifier NBT" - page-nick-title: "Modifier le surnom" - page-new-nick: "Nouveau surnom" - page-price-title: "Modifier le prix" - page-base-price: "De base" - page-base-bonus: "Bonus" - page-score-title: "Modifier le score" - page-size-title: "Modifier la taille" - page-size-min: "Minimum" - page-size-max: "Maximum" - page-size-max-no-less-min: "Le maximum ne doit pas être inférieur au minimum" diff --git a/core/src/main/resources/messages/hu.yml b/core/src/main/resources/messages/hu.yml deleted file mode 100644 index 49ac3b02..00000000 --- a/core/src/main/resources/messages/hu.yml +++ /dev/null @@ -1,126 +0,0 @@ -# Don't change this -config-version: '30' - -messages: - prefix: '[CustomFishing] ' - reload: 'Újratöltve. Időtartam: {time}ms.' - item-not-exist: 'Tétel nem található.' - give-item: 'Sikeresen adva {player} játékosnak {amount}x {item}.' - get-item: 'Sikeresen megszerezve {amount}x {item}.' - possible-loots: 'Lehetséges kapások itt: ' - split-char: ', ' - competition-not-exist: 'A(z) {id} verseny nem létezik.' - no-competition-ongoing: "Nincs folyamatban lévő verseny." - stop-competition: 'Leállítottad a jelenlegi versenyt.' - end-competition: 'Befejezted a jelenlegi versenyt.' - no-score: 'Nincs pontszám' - no-player: 'Nincs játékos' - no-rank: 'Nincs rang' - goal-catch-amount: 'Kifogott halak száma' - goal-max-size: 'Legnagyobb kifogott hal' - goal-total-size: 'Összes kifogott hal hossza' - goal-total-score: 'Kifogott halak összpontszáma' - unsafe-modification: "Nem lehet módosítani egy játékos horgász táskáját, ha aktív egy másik szerveren." - never-played: "A játékos még nem csatlakozott a szerverhez. Nem lehet módosítani egy nem létező játékos horgász táskáját." - data-not-loaded: "Az adatok nem lettek betöltve. Kérjük, csatlakozz újra a szerverhez. Ha a probléma továbbra is fennáll, fordulj a szerveradminisztrátorhoz." - open-market-gui: "A piac menü sikeresen meg lett nyitva {player} részére" - open-fishing-bag: "A horgász táska sikeresen meg lett nyitva {player} részére" - format-day: 'n' - format-hour: 'ó' - format-minute: 'p' - format-second: 'mp' - -# We're looking for a translator :D -gui: - search: "Search" - select-file: 'Select file' - select-item: "Select item" - dupe-invalid-key: "● Duplicated or invalid key" - new-value: "New value: " - temp-new-key: 'New key' - set-new-key: "Set new key" - edit-key: 'Edit {0}' - delete-property: "<#00CED1>● Delete property" - click-confirm: "<#00FF7F> -> Click to confirm" - invalid-number: "● Invalid number" - illegal-format: "● Illegal format" - scroll-up: '● Scroll up' - scroll-down: '● Scroll down' - cannot-scroll-up: "You've reached the top" - cannot-scroll-down: "You can't scroll further down" - next-page: '● Next Page' - goto-next-page: 'Go to page {0} / {1}' - cannot-goto-next-page: 'There are no more pages' - previous-page: '● Previous page' - goto-previous-page: 'Go to page {0} / {1}' - cannot-goto-previous-page: "You can't go further back" - back-to-parent-page: "<#FF8C00>Back to parent page" - back-to-parent-folder: "<#FF8C00>Back to parent folder" - current-value: "Current value: " - click-to-toggle: "<#00FF7F> -> Click to toggle" - left-click-edit: "<#00FF7F> -> Left click to edit" - right-click-reset: "<#FF6347> -> Right click to reset" - right-click-delete: "<#FF6347> -> Right click to delete" - right-click-cancel: "<#00CED1> -> Right click to cancel" - loot-show-in-finder: "<#5F9EA0>● Show In Fish Finder" - loot-score: "<#FF1493>● Score" - loot-nick: "<#00FF00>● Nick" - loot-instant-game: "<#7B68EE>● Instant Game" - loot-disable-statistics: "<#CD853F>● Disable Statistics" - loot-disable-game: "<#8B4513>● Disable Game" - item-amount: "<#1E90FF>● Amount" - item-custom-model-data: "<#FFC0CB>● Custom Model Data" - item-display-name: "<#FAFAD2>● Display Name" - item-custom-durability: "<#1E90FF>● Custom Durability" - item-enchantment: "<#8A2BE2>● Enchantment" - item-head64: "<#2E8B57>● Head64" - item-item-flag: "<#E6E6FA>● Item Flag" - item-lore: "<#FA8072>● Lore" - item-material: "<#FF00FF>● Material" - item-nbt: "<#FA8072>● NBT" - item-prevent-grab: "<#FF4500>● Prevent Grabbing" - item-price: "<#FFD700>● Price" - item-price-base: " - base: " - item-price-bonus: " - bonus: " - item-random-durability: "<#FFFF00>● Random Durability" - item-size: "<#FFF0F5>● Size" - item-stackable: "<#9370DB>● Stackable" - item-stored-enchantment: "<#9370DB>● Stored Enchantment" - item-tag: "<#2E8B57>● Tag" - item-unbreakable: "<#C0C0C0>● Unbreakable" - page-amount-title: "Edit Amount" - page-model-data-title: "Edit CustomModelData" - page-display-name-title: "Edit display name" - page-new-display-name: "New name" - page-custom-durability-title: "Edit custom durability" - page-stored-enchantment-title: "Edit stored enchantment" - page-enchantment-title: "Edit enchantment" - page-select-one-enchantment: "Select one enchantment" - page-add-new-enchantment: "[+] Add a new enchantment" - page-item-flag-title: "Edit item flag" - page-lore-title: "Edit lore" - page-add-new-lore: "[+] Add a new line" - page-select-one-lore: "Select one line" - page-material-title: "Edit Material" - page-nbt-compound-key-title: "Edit compound key" - page-nbt-list-key-title: "Edit list key" - page-nbt-key-title: "Edit key" - page-nbt-invalid-key: "Invaild key" - page-nbt-add-new-compound: "[+] Add a new compound" - page-nbt-add-new-list: "[+] Add a new list" - page-nbt-add-new-value: "[+] Add a new value" - page-add-new-key: "[+] Add a new key" - page-nbt-preview: "● NBT Preview" - page-nbt-back-to-compound: "Back to parent compound" - page-nbt-set-value-title: "Set value" - page-nbt-edit-title: "Edit NBT" - page-nick-title: "Edit nick" - page-new-nick: "New nick" - page-price-title: "Edit price" - page-base-price: "Base" - page-base-bonus: "Bonus" - page-score-title: "Edit score" - page-size-title: "Edit size" - page-size-min: "Minimum" - page-size-max: "Maximum" - page-size-max-no-less-min: "● Max must be no less than min" diff --git a/core/src/main/resources/messages/zh_cn.yml b/core/src/main/resources/messages/zh_cn.yml deleted file mode 100644 index 9f8a39ba..00000000 --- a/core/src/main/resources/messages/zh_cn.yml +++ /dev/null @@ -1,125 +0,0 @@ -# Don't change this -config-version: '31' - -messages: - prefix: '[CustomFishing] ' - reload: '重载完成. 耗时 {time}ms.' - item-not-exist: '物品不存在.' - give-item: '给予玩家 {player} {amount}x {item}.' - get-item: '获得 {amount}x {item}.' - possible-loots: '可能的战利品: ' - split-char: ', ' - competition-not-exist: '比赛 {id} 不存在.' - no-competition-ongoing: "没有正在进行的比赛." - stop-competition: '停止了当前的比赛.' - end-competition: '结束了当前的比赛.' - no-score: '无比分' - no-player: '无选手' - no-rank: '无排名' - goal-catch-amount: '捕鱼总数' - goal-max-size: '最大尺寸' - goal-total-size: '捕鱼总尺寸' - goal-total-score: '捕鱼总分' - unsafe-modification: "你不能修改一个正在其他子服游玩的玩家钓鱼背包." - never-played: "此玩家从未玩过服务器." - data-not-loaded: "数据未能正常加载. 请尝试切换子服或重进. 如果问题依然存在请联系服务器管理员." - open-market-gui: "为玩家 {player} 打开了市场" - open-fishing-bag: "为玩家 {player} 打开了钓鱼背包" - format-day: '天' - format-hour: '小时' - format-minute: '分' - format-second: '秒' - -gui: - search: 搜索 - select-file: 选择文件 - select-item-to-edit: 选择要编辑的物品 - dupe-invalid-key: ● 重复或无效的键 - new-value: '新值: ' - temp-new-key: '新键' - set-new-key: '设置新键' - edit-key: '修改 {0}' - delete-property: <#00CED1>● 删除属性 - click-confirm: <#00FF7F> -> 点击确认 - invalid-number: ● 无效的数字 - illegal-format: ● 非法的格式 - scroll-up: ● 向上翻 - scroll-down: ● 向下翻 - cannot-scroll-up: 你已经到顶了 - cannot-scroll-down: 你不能再往下了 - next-page: ● 下一页 - goto-next-page: 前往 {0} / {1} - cannot-goto-next-page: 没有更多页了 - previous-page: ● 上一页 - goto-previous-page: 前往 {0} / {1} - cannot-goto-previous-page: 已经到达第一页了 - back-to-parent-page: <#FF8C00>返回上一界面 - back-to-parent-folder: <#FF8C00>返回父文件夹 - current-value: '当前值: ' - click-to-toggle: <#00FF7F> -> 点击切换 - left-click-edit: <#00FF7F> -> 左键编辑 - right-click-reset: <#FF6347> -> 右键重置 - right-click-delete: <#FF6347> -> 右键删除 - right-click-cancel: <#00CED1> -> 右键取消 - loot-show-in-finder: <#5F9EA0>● 在找鱼器中可见 - loot-score: <#FF1493>● 比赛分数 - loot-nick: <#00FF00>● 昵称 - loot-instant-game: <#7B68EE>● 咬钩立即游戏 - loot-disable-statistics: <#CD853F>● 禁用统计数据 - loot-disable-game: <#8B4513>● 禁用游戏 - item-amount: <#1E90FF>● 数量 - item-custom-model-data: <#FFC0CB>● 自定义模型值 - item-display-name: <#FAFAD2>● 名称 - item-custom-durability: <#1E90FF>● 自定义耐久度 - item-enchantment: <#8A2BE2>● 附魔 - item-head64: <#2E8B57>● 头颅base64 - item-item-flag: <#E6E6FA>● 物品标签 - item-lore: <#FA8072>● 描述 - item-material: <#FF00FF>● 材质 - item-nbt: <#FA8072>● NBT - item-prevent-grab: <#FF4500>● 防止抢夺 - item-price: <#FFD700>● 价格 - item-price-base: ' - 基础: ' - item-price-bonus: ' - 尺寸增益: ' - item-random-durability: <#FFFF00>● 随机耐久 - item-size: <#FFF0F5>● 尺寸 - item-stackable: <#9370DB>● 是否可以堆叠 - item-stored-enchantment: <#9370DB>● 存储附魔 - item-tag: <#2E8B57>● 启用CustomFishing标签 - item-unbreakable: <#C0C0C0>● 不可破坏 - page-amount-title: 修改数量 - page-model-data-title: 修改自定义模型值 - page-display-name-title: 修改名称 - page-new-display-name: 新名称 - page-custom-durability-title: 修改自定义耐久度 - page-stored-enchantment-title: 修改存储附魔 - page-enchantment-title: 修改附魔 - page-select-one-enchantment: 选择一个附魔 - page-add-new-enchantment: [+] 新增一个附魔 - page-item-flag-title: 修改物品标签 - page-lore-title: 修改描述 - page-add-new-lore: [+] 新增一行描述 - page-select-one-lore: 选择一行描述 - page-material-title: 修改材质 - page-nbt-compound-key-title: 修改复合键名 - page-nbt-list-key-title: 修改列表名 - page-nbt-key-title: 修改键 - page-nbt-invalid-key: 无效的键 - page-nbt-add-new-compound: [+] 新增一个复合NBT - page-nbt-add-new-list: [+] 新增一个列表 - page-nbt-add-new-value: [+] 新增一个值 - page-add-new-key: [+] 新增一个键 - page-nbt-preview: ● NBT 预览 - page-nbt-back-to-compound: 返回父复合NBT - page-nbt-set-value-title: 设置值 - page-nbt-edit-title: 修改NBT - page-nick-title: 修改昵称 - page-new-nick: 新昵称 - page-price-title: 修改价格 - page-base-price: 基础 - page-base-bonus: 尺寸增益 - page-score-title: 修改分数 - page-size-title: 修改尺寸 - page-size-min: 最小值 - page-size-max: 最大值 - page-size-max-no-less-min: ● 最大值必须大于最小值 diff --git a/core/src/main/resources/translations/en.yml b/core/src/main/resources/translations/en.yml new file mode 100644 index 00000000..d71dd9fd --- /dev/null +++ b/core/src/main/resources/translations/en.yml @@ -0,0 +1,123 @@ +# Don"t change this +config-version: "31" + +command.prefix: "[CustomFishing] " +command.reload.success: "Reloaded. Took ms." +command.item.failure.not_exist: "Item not exists" +command.item.give.success: "Successfully given player x ." +command.item.get.success: "Successfully got x ." +command.fish_finder.possible_loots: "Possible loots here: " +command.fish_finder.no_loot: "No loot available" +command.fish_finder.split_char: ", " +command.competition.failure.not_exist: "Competition does not exist." +command.competition.failure.no_competition: "There's no competition ongoing." +command.competition.stop.success: "Stopped the current competition." +command.competition.end.success: "Ended the current competition." +command.bag.edit.failure.unsafe: "Cannot edit a player's fishing bag if they"re active on another linked server." +command.bag.edit.failure.never_played: 'The player hasn\'t joined the server before. Can't modify a nonexistent player"s fishing bag." +command.bag.open.success: "Successfully opened the fishing bag for " +command.data.failure.not_load: 'Data hasn't loaded. Please re-enter the server. If issues persist, reach out to the server admin." +command.market.open.success: "Successfully opened the market gui for " +competition.no_score: "No Score" +competition.no_player: "No Player" +competition.no_rank: "No Rank" +competition.goal.catch_amount: "Fish count caught" +competition.goal.max_size: "Largest fish caught" +competition.goal.total_score: "Cumulative score of fish caught" +competition.goal.total_size: "Total length of fish caught" +format.day: "d" +format.hour: "h" +format.minute: "m" +format.second: "s" +gui.search: "Search" +gui.select_file: "Select file" +gui.select_item: "Select item" +gui.invalid_key: "● Duplicated or invalid key" +gui.new_value: "New value: " +gui.temp_new_key: "New key" +gui.set_new_key: "Set new key" +gui.edit_key: "Edit " +gui.delete_property: "<#00CED1>● Delete property" +gui.click_confirm: "<#00FF7F> -> Click to confirm" +gui.invalid_number: "● Invalid number" +gui.illegal_format: "● Illegal format" +gui.scroll_up: "● Scroll up" +gui.scroll_down: "● Scroll down" +gui.cannot_scroll_up: "You"ve reached the top" +gui.cannot_scroll_down: "You can"t scroll further down" +gui.next_page: "● Next Page" +gui.goto_next_page: "Go to page / " +gui.cannot_goto_next_page: "There are no more pages" +gui.previous_page: "● Previous page" +gui.goto_previous_page: "Go to page / " +gui.cannot_goto_previous_page: "You can"t go further back" +gui.back_to_parent_page: "<#FF8C00>Back to parent page" +gui.back_to_parent_folder: "<#FF8C00>Back to parent folder" +gui.current_value: "Current value: " +gui.click_to_toggle: "<#00FF7F> -> Click to toggle" +gui.left_click_edit: "<#00FF7F> -> Left click to edit" +gui.right_click_reset: "<#FF6347> -> Right click to reset" +gui.right_click_delete: "<#FF6347> -> Right click to delete" +gui.right_click_cancel: "<#00CED1> -> Right click to cancel" +gui.loot_show_in_finder: "<#5F9EA0>● Show In Fish Finder" +gui.loot_score: "<#FF1493>● Score" +gui.loot_nick: "<#00FF00>● Nick" +gui.loot_instant_game: "<#7B68EE>● Instant Game" +gui.loot_disable_statistics: "<#CD853F>● Disable Statistics" +gui.loot_disable_game: "<#8B4513>● Disable Game" +gui.item_amount: "<#1E90FF>● Amount" +gui.item_custom_model_data: "<#FFC0CB>● Custom Model Data" +gui.item_display_name: "<#FAFAD2>● Display Name" +gui.item_custom_durability: "<#1E90FF>● Custom Durability" +gui.item_enchantment: "<#8A2BE2>● Enchantment" +gui.item_head64: "<#2E8B57>● Head64" +gui.item_item_flag: "<#E6E6FA>● Item Flag" +gui.item_lore: "<#FA8072>● Lore" +gui.item_material: "<#FF00FF>● Material" +gui.item_nbt: "<#FA8072>● NBT" +gui.item_prevent_grab: "<#FF4500>● Prevent Grabbing" +gui.item_price: "<#FFD700>● Price" +gui.item_price_base: " - base: " +gui.item_price_bonus: " - bonus: " +gui.item_random_durability: "<#FFFF00>● Random Durability" +gui.item_size: "<#FFF0F5>● Size" +gui.item_stackable: "<#9370DB>● Stackable" +gui.item_stored_enchantment: "<#9370DB>● Stored Enchantment" +gui.item_tag: "<#2E8B57>● Tag" +gui.item_unbreakable: "<#C0C0C0>● Unbreakable" +gui.page_amount_title: "Edit Amount" +gui.page_model_data_title: "Edit CustomModelData" +gui.page_display_name_title: "Edit display name" +gui.page_new_display_name: "New name" +gui.page_custom_durability_title: "Edit custom durability" +gui.page_stored_enchantment_title: "Edit stored enchantment" +gui.page_enchantment_title: "Edit enchantment" +gui.page_select_one_enchantment: "Select one enchantment" +gui.page_add_new_enchantment: "[+] Add a new enchantment" +gui.page_item_flag_title: "Edit item flag" +gui.page_lore_title: "Edit lore" +gui.page_add_new_lore: "[+] Add a new line" +gui.page_select_one_lore: "Select one line" +gui.page_material_title: "Edit Material" +gui.page_nbt_compound_key_title: "Edit compound key" +gui.page_nbt_list_key_title: "Edit list key" +gui.page_nbt_key_title: "Edit key" +gui.page_nbt_invalid_key: "Invaild key" +gui.page_nbt_add_new_compound: "[+] Add a new compound" +gui.page_nbt_add_new_list: "[+] Add a new list" +gui.page_nbt_add_new_value: "[+] Add a new value" +gui.page_add_new_key: "[+] Add a new key" +gui.page_nbt_preview: "● NBT Preview" +gui.page_nbt_back_to_compound: "Back to parent compound" +gui.page_nbt_set_value_title: "Set value" +gui.page_nbt_edit_title: "Edit NBT" +gui.page_nick_title: "Edit nick" +gui.page_new_nick: "New nick" +gui.page_price_title: "Edit price" +gui.page_base_price: "Base" +gui.page_base_bonus: "Bonus" +gui.page_score_title: "Edit score" +gui.page_size_title: "Edit size" +gui.page_size_min: "Minimum" +gui.page_size_max: "Maximum" +gui.page_size_max_no_less_min: "● Max must be no less than min" \ No newline at end of file diff --git a/gradle.properties b/gradle.properties index 52f63977..70bebe14 100644 --- a/gradle.properties +++ b/gradle.properties @@ -1,7 +1,7 @@ # Project settings # Rule: [major update].[feature update].[bug fix] -project_version=1.7.1 -config_version=2 +project_version=2.2.0 +config_version=32 project_group=net.momirealms # Dependency settings