9
0
mirror of https://github.com/Xiao-MoMi/Custom-Fishing.git synced 2026-01-04 15:41:35 +00:00

Add more annotations

This commit is contained in:
XiaoMoMi
2024-07-11 23:45:29 +08:00
parent a2503f0213
commit c5e6f75f64
93 changed files with 2040 additions and 197 deletions

View File

@@ -1,5 +1,6 @@
plugins {
id("io.github.goooler.shadow") version "8.1.7"
id("maven-publish")
}
repositories {
@@ -45,4 +46,15 @@ tasks {
relocate("dev.dejvokep", "net.momirealms.customfishing.libraries")
relocate ("com.saicone.rtag", "net.momirealms.customfishing.libraries.rtag")
}
}
}
publishing {
publications {
create<MavenPublication>("mavenJava") {
groupId = "net.momirealms"
artifactId = "CustomFishing"
version = rootProject.version.toString()
artifact(tasks.shadowJar)
}
}
}

View File

@@ -41,7 +41,6 @@ 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.Location;
@@ -51,7 +50,11 @@ import org.bukkit.plugin.Plugin;
import java.io.File;
public abstract class BukkitCustomFishingPlugin implements CustomFishingPlugin, Reloadable {
/**
* Abstract class representing the main CustomFishing plugin.
* This class provides access to various managers and functionalities within the plugin.
*/
public abstract class BukkitCustomFishingPlugin implements CustomFishingPlugin {
private static BukkitCustomFishingPlugin instance;
private final Plugin boostrap;
@@ -82,6 +85,11 @@ public abstract class BukkitCustomFishingPlugin implements CustomFishingPlugin,
protected FishingManager fishingManager;
protected GameManager gameManager;
/**
* Constructs a new BukkitCustomFishingPlugin instance.
*
* @param boostrap the plugin instance used to initialize this class
*/
public BukkitCustomFishingPlugin(Plugin boostrap) {
if (!boostrap.getName().equals("CustomFishing")) {
throw new IllegalArgumentException("CustomFishing plugin requires custom fishing plugin");
@@ -90,6 +98,12 @@ public abstract class BukkitCustomFishingPlugin implements CustomFishingPlugin,
instance = this;
}
/**
* Retrieves the singleton instance of BukkitCustomFishingPlugin.
*
* @return the singleton instance
* @throws IllegalArgumentException if the plugin is not initialized
*/
public static BukkitCustomFishingPlugin getInstance() {
if (instance == null) {
throw new IllegalArgumentException("Plugin not initialized");
@@ -97,119 +111,257 @@ public abstract class BukkitCustomFishingPlugin implements CustomFishingPlugin,
return instance;
}
/**
* Retrieves the EventManager.
*
* @return the {@link EventManager}
*/
public EventManager getEventManager() {
return eventManager;
}
/**
* Retrieves the ConfigManager.
*
* @return the {@link ConfigManager}
*/
@Override
public ConfigManager getConfigManager() {
return configManager;
}
/**
* Retrieves the RequirementManager.
*
* @return the {@link RequirementManager} for {@link Player}
*/
public RequirementManager<Player> getRequirementManager() {
return requirementManager;
}
/**
* Retrieves the ActionManager.
*
* @return the {@link ActionManager} for {@link Player}
*/
public ActionManager<Player> getActionManager() {
return actionManager;
}
/**
* Retrieves the SenderFactory.
*
* @return the {@link SenderFactory} for {@link BukkitCustomFishingPlugin} and {@link CommandSender}
*/
public SenderFactory<BukkitCustomFishingPlugin, CommandSender> getSenderFactory() {
return senderFactory;
}
/**
* Retrieves the data folder of the plugin.
*
* @return the data folder as a {@link File}
*/
public File getDataFolder() {
return boostrap.getDataFolder();
}
/**
* Retrieves the PlaceholderManager.
*
* @return the {@link PlaceholderManager}
*/
public PlaceholderManager getPlaceholderManager() {
return placeholderManager;
}
/**
* Retrieves the ItemManager.
*
* @return the {@link ItemManager}
*/
public ItemManager getItemManager() {
return itemManager;
}
/**
* Retrieves the IntegrationManager.
*
* @return the {@link IntegrationManager}
*/
public IntegrationManager getIntegrationManager() {
return integrationManager;
}
/**
* Retrieves the Scheduler.
*
* @return the {@link AbstractJavaScheduler} for {@link Location}
*/
@Override
public AbstractJavaScheduler<Location> getScheduler() {
return scheduler;
}
/**
* Retrieves the CompetitionManager.
*
* @return the {@link CompetitionManager}
*/
public CompetitionManager getCompetitionManager() {
return competitionManager;
}
/**
* Retrieves the MarketManager.
*
* @return the {@link MarketManager}
*/
public MarketManager getMarketManager() {
return marketManager;
}
/**
* Retrieves the StorageManager.
*
* @return the {@link StorageManager}
*/
public StorageManager getStorageManager() {
return storageManager;
}
/**
* Retrieves the LootManager.
*
* @return the {@link LootManager}
*/
public LootManager getLootManager() {
return lootManager;
}
/**
* Retrieves the EntityManager.
*
* @return the {@link EntityManager}
*/
public EntityManager getEntityManager() {
return entityManager;
}
/**
* Retrieves the HookManager.
*
* @return the {@link HookManager}
*/
public HookManager getHookManager() {
return hookManager;
}
/**
* Retrieves the BlockManager.
*
* @return the {@link BlockManager}
*/
public BlockManager getBlockManager() {
return blockManager;
}
/**
* Retrieves the CoolDownManager.
*
* @return the {@link CoolDownManager}
*/
public CoolDownManager getCoolDownManager() {
return coolDownManager;
}
/**
* Retrieves the StatisticsManager.
*
* @return the {@link StatisticsManager}
*/
public StatisticsManager getStatisticsManager() {
return statisticsManager;
}
/**
* Retrieves the EffectManager.
*
* @return the {@link EffectManager}
*/
public EffectManager getEffectManager() {
return effectManager;
}
/**
* Retrieves the BagManager.
*
* @return the {@link BagManager}
*/
public BagManager getBagManager() {
return bagManager;
}
/**
* Retrieves the TotemManager.
*
* @return the {@link TotemManager}
*/
public TotemManager getTotemManager() {
return totemManager;
}
/**
* Retrieves the FishingManager.
*
* @return the {@link FishingManager}
*/
public FishingManager getFishingManager() {
return fishingManager;
}
/**
* Retrieves the GameManager.
*
* @return the {@link GameManager}
*/
public GameManager getGameManager() {
return gameManager;
}
/**
* Retrieves the plugin instance used to initialize this class.
*
* @return the {@link Plugin} instance
*/
public Plugin getBoostrap() {
return boostrap;
}
/**
* Retrieves the DependencyManager.
*
* @return the {@link DependencyManager}
*/
@Override
public DependencyManager getDependencyManager() {
return dependencyManager;
}
/**
* Retrieves the TranslationManager.
*
* @return the {@link TranslationManager}
*/
@Override
public TranslationManager getTranslationManager() {
return translationManager;
}
public abstract void enable();
/**
* Logs a debug message.
*
* @param message the message to log
*/
public abstract void debug(Object message);
}

View File

@@ -18,7 +18,6 @@
package net.momirealms.customfishing.api.event;
import net.momirealms.customfishing.api.mechanic.competition.FishingCompetition;
import net.momirealms.customfishing.api.mechanic.totem.TotemConfig;
import org.bukkit.event.Event;
import org.bukkit.event.HandlerList;
import org.jetbrains.annotations.NotNull;

View File

@@ -18,7 +18,6 @@
package net.momirealms.customfishing.api.event;
import net.momirealms.customfishing.api.BukkitCustomFishingPlugin;
import net.momirealms.customfishing.api.mechanic.totem.TotemConfig;
import org.bukkit.event.Event;
import org.bukkit.event.HandlerList;
import org.jetbrains.annotations.NotNull;

View File

@@ -17,7 +17,6 @@
package net.momirealms.customfishing.api.event;
import net.momirealms.customfishing.api.mechanic.totem.TotemConfig;
import org.bukkit.entity.Player;
import org.bukkit.event.Cancellable;
import org.bukkit.event.HandlerList;

View File

@@ -17,7 +17,6 @@
package net.momirealms.customfishing.api.event;
import net.momirealms.customfishing.api.mechanic.totem.TotemConfig;
import org.bukkit.entity.FishHook;
import org.bukkit.entity.Player;
import org.bukkit.event.HandlerList;

View File

@@ -19,7 +19,6 @@ package net.momirealms.customfishing.api.event;
import net.momirealms.customfishing.api.mechanic.context.Context;
import net.momirealms.customfishing.api.mechanic.loot.Loot;
import net.momirealms.customfishing.api.mechanic.totem.TotemConfig;
import org.bukkit.Location;
import org.bukkit.entity.Entity;
import org.bukkit.entity.Player;

View File

@@ -19,7 +19,6 @@ package net.momirealms.customfishing.api.event;
import net.momirealms.customfishing.api.mechanic.context.Context;
import net.momirealms.customfishing.api.mechanic.context.ContextKeys;
import net.momirealms.customfishing.api.mechanic.fishing.FishingGears;
import net.momirealms.customfishing.api.mechanic.loot.Loot;
import org.bukkit.entity.FishHook;
import org.bukkit.entity.Player;

View File

@@ -18,7 +18,6 @@
package net.momirealms.customfishing.api.event;
import net.momirealms.customfishing.api.mechanic.fishing.FishingGears;
import org.bukkit.entity.FishHook;
import org.bukkit.event.Cancellable;
import org.bukkit.event.HandlerList;
import org.bukkit.event.player.PlayerEvent;

View File

@@ -23,7 +23,6 @@ import org.bukkit.entity.Player;
import org.bukkit.event.Cancellable;
import org.bukkit.event.HandlerList;
import org.bukkit.event.player.PlayerEvent;
import org.bukkit.event.player.PlayerFishEvent;
import org.jetbrains.annotations.NotNull;
/**

View File

@@ -28,8 +28,7 @@ import org.jetbrains.annotations.Nullable;
import java.util.List;
/**
* Interface for providing custom block data and retrieving block IDs within the CustomFishing plugin.
* Extends the ExternalProvider interface.
* Interface for providing custom block data and retrieving block IDs.
*/
public interface BlockProvider extends ExternalProvider {

View File

@@ -18,10 +18,7 @@
package net.momirealms.customfishing.api.integration;
/**
* The ExternalProvider interface serves as a base interface for various external
* providers in the CustomFishing plugin. It defines a method to retrieve the
* identification string of the provider, which can be used to distinguish between
* different providers.
* The ExternalProvider interface serves as a base interface for various external providers
*/
public interface ExternalProvider {

View File

@@ -26,7 +26,7 @@ import org.jetbrains.annotations.Nullable;
import java.util.List;
/**
* Interface for managing integration providers in the custom fishing API.
* Interface for managing integration providers.
* This allows for the registration and retrieval of various types of providers
* such as Leveler, Enchantment, and Season providers.
*/

View File

@@ -23,7 +23,7 @@ import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
/**
* Interface representing a provider for custom items in the Custom Fishing plugin.
* Interface representing a provider for custom items.
* This interface allows for building items for players and retrieving item IDs from item stacks.
*/
public interface ItemProvider extends ExternalProvider {

View File

@@ -26,6 +26,10 @@ import java.util.HashMap;
import java.util.List;
import java.util.Objects;
/**
* Represents a type of mechanic.
* This class provides predefined mechanic types and methods for managing and retrieving mechanic types by ID.
*/
public class MechanicType {
private static final HashMap<String, List<MechanicType>> types = new HashMap<>();
@@ -42,40 +46,83 @@ public class MechanicType {
private final String type;
/**
* Constructs a new MechanicType.
*
* @param type the type identifier as a String
*/
public MechanicType(String type) {
this.type = type;
}
/**
* Retrieves the type identifier.
*
* @return the type identifier as a String
*/
public String getType() {
return type;
}
/**
* Creates a new MechanicType with the specified type identifier.
*
* @param type the type identifier as a String
* @return a new {@link MechanicType} instance
*/
private static MechanicType of(String type) {
return new MechanicType(type);
}
private static final MechanicType[] VALUES = new MechanicType[]{LOOT, ROD, UTIL, BAIT, HOOK, TOTEM, ENCHANT, ENTITY, BLOCK};
/**
* Retrieves an array of all predefined mechanic types.
*
* @return an array of {@link MechanicType} instances
*/
public static MechanicType[] values() {
return new MechanicType[]{LOOT, ROD, UTIL, BAIT, HOOK, TOTEM, ENCHANT, ENTITY, BLOCK};
return VALUES;
}
private static final Index<String, MechanicType> INDEX = Index.create(MechanicType::getType, values());
/**
* Retrieves the index of mechanic types by their type identifier.
*
* @return an {@link Index} of mechanic types
*/
public static Index<String, MechanicType> index() {
return INDEX;
}
/**
* Registers a new mechanic type with the specified ID.
*
* @param id the identifier for the mechanic type
* @param type the {@link MechanicType} to be registered
*/
@ApiStatus.Internal
public static void register(String id, MechanicType type) {
List<MechanicType> previous = types.computeIfAbsent(id, k -> new ArrayList<>());
previous.add(type);
}
/**
* Retrieves a list of mechanic types by their ID.
*
* @param id the identifier for the mechanic types
* @return a list of {@link MechanicType} instances, or null if none are found
*/
@Nullable
@ApiStatus.Internal
public static List<MechanicType> getTypeByID(String id) {
return types.get(id);
}
/**
* Clears all registered mechanic types.
*/
@ApiStatus.Internal
public static void reset() {
types.clear();

View File

@@ -18,7 +18,7 @@
package net.momirealms.customfishing.api.mechanic.action;
/**
* Abstract class representing an expansion of an action in the custom fishing API.
* Abstract class representing an expansion of an action.
* This class should be extended to provide specific implementations of actions.
*
* @param <T> the type parameter for the action factory

View File

@@ -25,7 +25,7 @@ import java.util.UUID;
import java.util.concurrent.CompletableFuture;
/**
* The BagManager interface defines methods for managing fishing bags in the CustomFishing plugin.
* The BagManager interface defines methods for managing fishing bags.
*/
public interface BagManager extends Reloadable {

View File

@@ -20,8 +20,7 @@ package net.momirealms.customfishing.api.mechanic.block;
import java.util.List;
/**
* Interface representing the configuration for a custom block in the CustomFishing plugin.
* Provides methods to access various block properties and modifiers.
* Interface representing the configuration for a block loot.
*/
public interface BlockConfig {

View File

@@ -63,16 +63,16 @@ public interface ActionBarConfig {
boolean enabled();
/**
* Creates a new builder instance for constructing {@code ActionBarConfig} objects.
* Creates a new builder instance for constructing {@link ActionBarConfig} objects.
*
* @return A new {@code Builder} instance.
* @return A new {@link Builder} instance.
*/
static Builder builder() {
return new ActionBarConfigImpl.BuilderImpl();
}
/**
* Builder interface for constructing {@code ActionBarConfig} objects.
* Builder interface for constructing {@link ActionBarConfig} objects.
*/
interface Builder {
@@ -80,7 +80,7 @@ public interface ActionBarConfig {
* Sets whether the competition information should be shown to all players.
*
* @param showToAll True to show information to all players, false to show only to participants.
* @return The current {@code Builder} instance.
* @return The current {@link Builder} instance.
*/
Builder showToAll(boolean showToAll);
@@ -88,7 +88,7 @@ public interface ActionBarConfig {
* Sets the refresh rate for updating the competition information.
*
* @param rate The refresh rate in ticks.
* @return The current {@code Builder} instance.
* @return The current {@link Builder} instance.
*/
Builder refreshRate(int rate);
@@ -96,7 +96,7 @@ public interface ActionBarConfig {
* Sets the interval for switching between different competition texts.
*
* @param interval The switch interval in ticks.
* @return The current {@code Builder} instance.
* @return The current {@link Builder} instance.
*/
Builder switchInterval(int interval);
@@ -104,7 +104,7 @@ public interface ActionBarConfig {
* Sets the texts to be displayed on the action bar during the competition.
*
* @param texts An array of competition information texts.
* @return The current {@code Builder} instance.
* @return The current {@link Builder} instance.
*/
Builder text(String[] texts);
@@ -112,14 +112,14 @@ public interface ActionBarConfig {
* Sets whether the actionbar is enabled
*
* @param enable enable or not
* @return The current {@code Builder} instance.
* @return The current {@link Builder} instance.
*/
Builder enable(boolean enable);
/**
* Builds the {@code ActionBarConfig} object with the configured settings.
* Builds the {@link ActionBarConfig} object with the configured settings.
*
* @return The constructed {@code ActionBarConfig} object.
* @return The constructed {@link ActionBarConfig} object.
*/
ActionBarConfig build();
}

View File

@@ -81,16 +81,16 @@ public interface BossBarConfig {
boolean enabled();
/**
* Creates a new builder instance for constructing {@code BossBarConfig} objects.
* Creates a new builder instance for constructing {@link BossBarConfig} objects.
*
* @return A new {@code Builder} instance.
* @return A new {@link Builder} instance.
*/
static Builder builder() {
return new BossBarConfigImpl.BuilderImpl();
}
/**
* Builder interface for constructing {@code BossBarConfig} objects.
* Builder interface for constructing {@link BossBarConfig} objects.
*/
interface Builder {
@@ -98,7 +98,7 @@ public interface BossBarConfig {
* Sets whether the competition information should be shown to all players.
*
* @param showToAll True to show information to all players, false to show only to participants.
* @return The current {@code Builder} instance.
* @return The current {@link Builder} instance.
*/
Builder showToAll(boolean showToAll);
@@ -106,7 +106,7 @@ public interface BossBarConfig {
* Sets the refresh rate for updating the competition information.
*
* @param rate The refresh rate in ticks.
* @return The current {@code Builder} instance.
* @return The current {@link Builder} instance.
*/
Builder refreshRate(int rate);
@@ -114,7 +114,7 @@ public interface BossBarConfig {
* Sets the interval for switching between different competition texts.
*
* @param interval The switch interval in ticks.
* @return The current {@code Builder} instance.
* @return The current {@link Builder} instance.
*/
Builder switchInterval(int interval);
@@ -122,7 +122,7 @@ public interface BossBarConfig {
* Sets the texts to be displayed on the boss bar during the competition.
*
* @param texts An array of competition information texts.
* @return The current {@code Builder} instance.
* @return The current {@link Builder} instance.
*/
Builder text(String[] texts);
@@ -130,7 +130,7 @@ public interface BossBarConfig {
* Sets the color of the boss bar.
*
* @param color The color of the boss bar.
* @return The current {@code Builder} instance.
* @return The current {@link Builder} instance.
*/
Builder color(BossBar.Color color);
@@ -138,7 +138,7 @@ public interface BossBarConfig {
* Sets the overlay style of the boss bar.
*
* @param overlay The overlay style of the boss bar.
* @return The current {@code Builder} instance.
* @return The current {@link Builder} instance.
*/
Builder overlay(BossBar.Overlay overlay);
@@ -146,14 +146,14 @@ public interface BossBarConfig {
* Sets whether the bossbar is enabled
*
* @param enable enable or not
* @return The current {@code Builder} instance.
* @return The current {@link Builder} instance.
*/
Builder enable(boolean enable);
/**
* Builds the {@code BossBarConfig} object with the configured settings.
* Builds the {@link BossBarConfig} object with the configured settings.
*
* @return The constructed {@code BossBarConfig} object.
* @return The constructed {@link BossBarConfig} object.
*/
BossBarConfig build();
}

View File

@@ -27,7 +27,7 @@ import net.momirealms.customfishing.common.util.TriConsumer;
import java.util.Map;
/**
* Configuration types for various mechanics in the CustomFishing plugin.
* Configuration types for various mechanics.
*/
public class ConfigType {

View File

@@ -28,7 +28,7 @@ import java.util.concurrent.ConcurrentHashMap;
/**
* The PlayerContextImpl class implements the Context interface specifically
* for the Player type. It allows for storing and retrieving arguments related
* to a player in the custom fishing mechanics.
* to a player.
*/
public final class PlayerContextImpl implements Context<Player> {

View File

@@ -26,7 +26,7 @@ import java.util.Map;
import java.util.function.BiFunction;
/**
* Represents an effect applied in the custom fishing mechanic.
* Represents an effect applied in the fishing.
*/
public interface Effect {

View File

@@ -23,7 +23,7 @@ import net.momirealms.customfishing.common.plugin.feature.Reloadable;
import java.util.Optional;
/**
* Interface for managing effect modifiers in the custom fishing plugin.
* Interface for managing effect modifiers.
*/
public interface EffectManager extends Reloadable {

View File

@@ -9,7 +9,7 @@ import org.bukkit.entity.Player;
import java.util.List;
/**
* EffectModifier interface for modifying effects in the CustomFishing plugin.
* EffectModifier interface for modifying effects.
* This interface allows defining conditions and modifications for effects applied to players.
*/
public interface EffectModifier {

View File

@@ -20,7 +20,7 @@ package net.momirealms.customfishing.api.mechanic.effect;
import java.util.Objects;
/**
* Represents properties for effects in the custom fishing plugin.
* Represents properties for effects.
*
* @param <T> the type of the property value.
*/

View File

@@ -22,7 +22,7 @@ import net.momirealms.customfishing.api.mechanic.misc.value.MathValue;
import org.bukkit.entity.Player;
/**
* Represents the base effect applied to loot in the custom fishing mechanic.
* Represents the base effect applied to loot.
*/
public interface LootBaseEffect {

View File

@@ -24,7 +24,7 @@ import org.jetbrains.annotations.NotNull;
import java.util.Map;
/**
* The EntityConfig interface defines the configuration for an entity used in custom fishing mechanics.
* The EntityConfig interface defines the configuration for an entity.
* It includes methods to retrieve various properties of the entity such as vectors and an ID, as well
* as a nested Builder interface for constructing instances of EntityConfig.
*/

View File

@@ -27,7 +27,7 @@ import java.util.HashMap;
import java.util.TreeMap;
/**
* The EventCarrier interface represents an object that carries events in the custom fishing system.
* The EventCarrier interface represents an object that carries events.
* It defines methods to trigger actions based on specific triggers and contexts.
*/
public interface EventCarrier {

View File

@@ -14,7 +14,7 @@ import java.util.Optional;
import java.util.TreeMap;
/**
* EventManager interface for managing events and their associated actions within the custom fishing plugin.
* EventManager interface for managing events and their associated actions.
* It provides methods to register, retrieve, and trigger events based on different conditions.
*/
public interface EventManager extends Reloadable {

View File

@@ -258,11 +258,11 @@ public class FishingGears {
((context, itemStack) -> {}),
((context, itemStack) -> {
if (context.getHolder().getGameMode() != GameMode.CREATIVE)
BukkitCustomFishingPlugin.getInstance().getItemManager().decreaseDurability(context.getHolder(), itemStack, 1, false);
BukkitCustomFishingPlugin.getInstance().getItemManager().increaseDamage(context.getHolder(), itemStack, 1, false);
}),
((context, itemStack) -> {
if (context.getHolder().getGameMode() != GameMode.CREATIVE)
BukkitCustomFishingPlugin.getInstance().getItemManager().decreaseDurability(context.getHolder(), itemStack, 1, false);
BukkitCustomFishingPlugin.getInstance().getItemManager().increaseDamage(context.getHolder(), itemStack, 1, false);
}),
((context, itemStack) -> {}),
((context, itemStack) -> {}),

View File

@@ -25,7 +25,7 @@ import java.util.Optional;
import java.util.UUID;
/**
* Interface for managing fishing hooks in the custom fishing plugin.
* Interface for managing fishing.
*/
public interface FishingManager extends Reloadable {

View File

@@ -20,7 +20,7 @@ package net.momirealms.customfishing.api.mechanic.fishing.hook;
import net.momirealms.customfishing.api.mechanic.effect.Effect;
/**
* Interface for managing the mechanics of a fishing hook in the custom fishing plugin.
* Interface for managing the mechanics of a fishing hook.
*/
public interface HookMechanic {

View File

@@ -23,8 +23,7 @@ import net.momirealms.customfishing.api.mechanic.fishing.CustomFishingHook;
import java.util.function.BiFunction;
/**
* Represents an abstract game in the custom fishing plugin.
* Provides the basic structure and functionalities for a game.
* Represents an abstract game which provides the basic structure and functionalities for a game.
*/
public abstract class AbstractGame implements Game {

View File

@@ -26,6 +26,10 @@ import org.jetbrains.annotations.ApiStatus;
import java.util.concurrent.TimeUnit;
/**
* Represents an abstract gaming player.
* Provides the basic structure and functionalities for a gaming player.
*/
public abstract class AbstractGamingPlayer implements GamingPlayer, Runnable {
protected long deadline;
@@ -37,6 +41,12 @@ public abstract class AbstractGamingPlayer implements GamingPlayer, Runnable {
private boolean valid = true;
private boolean firstFlag = true;
/**
* Constructs an AbstractGamingPlayer instance.
*
* @param hook the custom fishing hook.
* @param settings the game settings.
*/
public AbstractGamingPlayer(CustomFishingHook hook, GameSetting settings) {
this.hook = hook;
this.settings = settings;
@@ -44,37 +54,62 @@ public abstract class AbstractGamingPlayer implements GamingPlayer, Runnable {
this.arrangeTask();
}
/**
* Arranges the task for the gaming player.
*/
public void arrangeTask() {
this.task = BukkitCustomFishingPlugin.getInstance().getScheduler().asyncRepeating(this, 50, 50, TimeUnit.MILLISECONDS);
}
/**
* Destroys the gaming player, canceling any ongoing tasks.
*/
@Override
public void destroy() {
if (task != null) task.cancel();
valid = false;
}
/**
* Cancels the gaming player, it defaults to {@link AbstractGamingPlayer#destroy()}
*/
@Override
public void cancel() {
destroy();
}
/**
* Checks if the gaming player has successfully completed the game.
*
* @return true if successful, false otherwise.
*/
@Override
public boolean isSuccessful() {
return success;
}
/**
* Handles internal right-click actions.
*/
@ApiStatus.Internal
public void internalRightClick() {
firstFlag = true;
handleRightClick();
}
/**
* Handles right-click actions.
*/
@Override
public void handleRightClick() {
endGame();
}
/**
* Handles internal left-click actions.
*
* @return true if cancel the event, false otherwise.
*/
@ApiStatus.Internal
public boolean internalLeftClick() {
if (firstFlag) {
@@ -84,35 +119,67 @@ public abstract class AbstractGamingPlayer implements GamingPlayer, Runnable {
return handleLeftClick();
}
/**
* Handles left-click actions.
*
* @return true if cancel the event, false otherwise.
*/
@Override
public boolean handleLeftClick() {
return false;
}
/**
* Handles chat input during the game.
*
* @param message the chat message.
* @return true if cancel the event, false otherwise.
*/
@Override
public boolean handleChat(String message) {
return false;
}
/**
* Handles the swap hand action during the game.
*/
@Override
public void handleSwapHand() {
}
/**
* Handles the jump action during the game.
*
* @return true if cancel the event, false otherwise.
*/
@Override
public boolean handleJump() {
return false;
}
/**
* Handles the sneak action during the game.
*
* @return true if cancel the event, false otherwise.
*/
@Override
public boolean handleSneak() {
return false;
}
/**
* Gets the player associated with the gaming player.
*
* @return the player.
*/
@Override
public Player getPlayer() {
return hook.getContext().getHolder();
}
/**
* Runs the gaming player's task.
*/
@Override
public void run() {
if (timeOutCheck()) {
@@ -121,13 +188,24 @@ public abstract class AbstractGamingPlayer implements GamingPlayer, Runnable {
tick();
}
/**
* Checks if the game is valid.
*
* @return true if valid, false otherwise.
*/
@Override
public boolean isValid() {
return valid;
}
/**
* Defines the tick behavior for the gaming player.
*/
protected abstract void tick();
/**
* Ends the game for the gaming player.
*/
protected void endGame() {
destroy();
boolean success = isSuccessful();
@@ -141,10 +219,20 @@ public abstract class AbstractGamingPlayer implements GamingPlayer, Runnable {
}, hook.getHookEntity().getLocation());
}
/**
* Sets the game result.
*
* @param success true if the game was successful, false otherwise.
*/
protected void setGameResult(boolean success) {
this.success = success;
}
/**
* Checks if the game has timed out.
*
* @return true if the game has timed out, false otherwise.
*/
protected boolean timeOutCheck() {
long delta = deadline - System.currentTimeMillis();
if (delta <= 0) {

View File

@@ -20,9 +20,24 @@ package net.momirealms.customfishing.api.mechanic.game;
import net.momirealms.customfishing.api.mechanic.effect.Effect;
import net.momirealms.customfishing.api.mechanic.fishing.CustomFishingHook;
/**
* Represents a mini-game
*/
public interface Game {
/**
* Gets the identifier of the game.
*
* @return the identifier of the game.
*/
String id();
/**
* Starts the game with the provided fishing hook and effect.
*
* @param hook the custom fishing hook.
* @param effect the effect to apply.
* @return the gaming player instance.
*/
GamingPlayer start(CustomFishingHook hook, Effect effect);
}

View File

@@ -1,35 +1,120 @@
/*
* Copyright (C) <2022> <XiaoMoMi>
*
* 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 <https://www.gnu.org/licenses/>.
*/
package net.momirealms.customfishing.api.mechanic.game;
import net.momirealms.customfishing.api.mechanic.effect.Effect;
import org.jetbrains.annotations.NotNull;
/**
* Represents the basic settings for a game.
*/
public interface GameBasics {
/**
* Gets the minimum time for the game.
*
* @return the minimum time in seconds.
*/
int minTime();
/**
* Gets the maximum time for the game.
*
* @return the maximum time in seconds.
*/
int maxTime();
/**
* Gets the minimum difficulty for the game.
*
* @return the minimum difficulty level.
*/
int minDifficulty();
/**
* Gets the maximum difficulty for the game.
*
* @return the maximum difficulty level.
*/
int maxDifficulty();
/**
* Creates a new builder for constructing {@link GameBasics} instances.
*
* @return a new {@link Builder} instance.
*/
static GameBasics.Builder builder() {
return new GameBasicsImpl.BuilderImpl();
}
/**
* Converts the game basics to a {@link GameSetting} instance based on the provided effect.
*
* @param effect the effect to apply.
* @return the generated {@link GameSetting} instance.
*/
@NotNull
GameSetting toGameSetting(Effect effect);
/**
* Builder interface for constructing {@link GameBasics} instances.
*/
interface Builder {
/**
* Sets the difficulty for the game.
*
* @param value the difficulty level.
* @return the current {@link Builder} instance.
*/
Builder difficulty(int value);
/**
* Sets the difficulty range for the game.
*
* @param min the minimum difficulty level.
* @param max the maximum difficulty level.
* @return the current {@link Builder} instance.
*/
Builder difficulty(int min, int max);
/**
* Sets the time for the game.
*
* @param value the time in seconds.
* @return the current {@link Builder} instance.
*/
Builder time(int value);
/**
* Sets the time range for the game.
*
* @param min the minimum time in seconds.
* @param max the maximum time in seconds.
* @return the current {@link Builder} instance.
*/
Builder time(int min, int max);
/**
* Builds and returns the {@link GameBasics} instance.
*
* @return the constructed {@link GameBasics} instance.
*/
GameBasics build();
}
}

View File

@@ -17,13 +17,36 @@
package net.momirealms.customfishing.api.mechanic.game;
/**
* Represents an expansion for a mini-game.
*/
public abstract class GameExpansion {
/**
* Gets the version of the game expansion.
*
* @return the version of the game expansion.
*/
public abstract String getVersion();
/**
* Gets the author of the game expansion.
*
* @return the author of the game expansion.
*/
public abstract String getAuthor();
/**
* Gets the type of the game expansion.
*
* @return the type of the game expansion.
*/
public abstract String getGameType();
/**
* Gets the game factory for creating instances of the game.
*
* @return the game factory.
*/
public abstract GameFactory getGameFactory();
}

View File

@@ -19,7 +19,17 @@ package net.momirealms.customfishing.api.mechanic.game;
import dev.dejvokep.boostedyaml.block.implementation.Section;
/**
* Factory interface for creating game instances.
*/
public interface GameFactory {
/**
* Creates a new game instance with the specified identifier and configuration section.
*
* @param id the identifier of the game.
* @param section the configuration section for the game.
* @return the created game instance.
*/
Game create(String id, Section section);
}

View File

@@ -25,6 +25,9 @@ import org.jetbrains.annotations.Nullable;
import java.util.Optional;
/**
* Interface for managing games.
*/
public interface GameManager extends Reloadable {
/**
@@ -48,15 +51,34 @@ public interface GameManager extends Reloadable {
* Retrieves the game factory associated with the specified game type.
*
* @param type The type identifier of the game.
* @return The {@code GameFactory} for the specified game type, or {@code null} if not found.
* @return The {@link GameFactory} for the specified game type, or {@code null} if not found.
*/
@Nullable
GameFactory getGameFactory(String type);
/**
* Retrieves a game instance by its identifier.
*
* @param id The identifier of the game.
* @return An {@link Optional} containing the game if found, or an empty {@link Optional} if not found.
*/
Optional<Game> getGame(String id);
/**
* Registers a game instance.
*
* @param game The game instance to register.
* @return {@code true} if the game was successfully registered, {@code false} otherwise.
*/
boolean registerGame(Game game);
/**
* Retrieves the next game to be played based on the specified effect and context.
*
* @param effect The effect influencing the game selection.
* @param context The context of the player.
* @return The next game to be played, or {@code null} if no suitable game is found.
*/
@Nullable
Game getNextGame(Effect effect, Context<Player> context);
}

View File

@@ -17,5 +17,11 @@
package net.momirealms.customfishing.api.mechanic.game;
/**
* Represents the settings for a game.
*
* @param time The time allocated for the game, in seconds.
* @param difficulty The difficulty level of the game. (1~100)
*/
public record GameSetting(double time, int difficulty) {
}

View File

@@ -19,27 +19,78 @@ package net.momirealms.customfishing.api.mechanic.game;
import org.bukkit.entity.Player;
/**
* Represents a gaming player.
*/
public interface GamingPlayer {
/**
* Checks if the gaming player is valid.
*
* @return {@code true} if the gaming player is valid, {@code false} otherwise
*/
boolean isValid();
/**
* Destroys the gaming player, performing any necessary cleanup
*/
void destroy();
/**
* Cancels the game
*/
void cancel();
/**
* Checks if the gaming player has successfully completed the game.
*
* @return true if successful, false otherwise.
*/
boolean isSuccessful();
void handleRightClick();
void handleSwapHand();
/**
* Handles left-click actions.
*
* @return true if cancel the event, false otherwise.
*/
boolean handleLeftClick();
/**
* Handles right-click actions.
*/
void handleRightClick();
/**
* Handles the swap hand action during the game.
*/
void handleSwapHand();
/**
* Handles chat input during the game.
*
* @param message the chat message.
* @return true if cancel the event, false otherwise.
*/
boolean handleChat(String message);
/**
* Handles the jump action during the game.
*
* @return true if cancel the event, false otherwise.
*/
boolean handleJump();
/**
* Handles the sneak action during the game.
*
* @return true if cancel the event, false otherwise.
*/
boolean handleSneak();
/**
* Gets the player associated with the gaming player.
*
* @return the player.
*/
Player getPlayer();
}

View File

@@ -19,22 +19,60 @@ package net.momirealms.customfishing.api.mechanic.hook;
import java.util.List;
/**
* Represents the configuration for a fishing hook.
*/
public interface HookConfig {
/**
* Gets the identifier of the hook.
*
* @return the identifier of the hook.
*/
String id();
/**
* Gets the additional lore of the hook.
*
* @return a list of additional lore strings for the hook.
*/
List<String> lore();
/**
* Creates a new builder for constructing {@link HookConfig} instances.
*
* @return a new {@link Builder} instance.
*/
static Builder builder() {
return new HookConfigImpl.BuilderImpl();
}
/**
* Builder interface for constructing {@link HookConfig} instances.
*/
interface Builder {
/**
* Sets the identifier for the hook configuration.
*
* @param id the identifier of the hook.
* @return the current {@link Builder} instance.
*/
Builder id(String id);
/**
* Sets the lore for the hook configuration.
*
* @param lore a list of lore strings for the hook.
* @return the current {@link Builder} instance.
*/
Builder lore(List<String> lore);
/**
* Builds and returns the {@link HookConfig} instance.
*
* @return the constructed {@link HookConfig} instance.
*/
HookConfig build();
}
}

View File

@@ -23,12 +23,33 @@ import org.jetbrains.annotations.NotNull;
import java.util.Optional;
/**
* Interface for managing hooks.
*/
public interface HookManager extends Reloadable {
/**
* Registers a new hook configuration.
*
* @param hook the {@link HookConfig} to be registered
* @return true if the hook was successfully registered, false otherwise
*/
boolean registerHook(HookConfig hook);
/**
* Retrieves a hook configuration by its ID.
*
* @param id the ID of the hook
* @return an {@link Optional} containing the {@link HookConfig} if found, or an empty {@link Optional} if not
*/
@NotNull
Optional<HookConfig> getHook(String id);
/**
* Retrieves the hook ID associated with a given fishing rod.
*
* @param rod the {@link ItemStack} representing the fishing rod
* @return an {@link Optional} containing the hook ID if found, or an empty {@link Optional} if not
*/
Optional<String> getHookID(ItemStack rod);
}

View File

@@ -27,6 +27,9 @@ import org.bukkit.inventory.ItemStack;
import java.util.List;
import java.util.function.BiConsumer;
/**
* Interface representing a custom fishing item
*/
public interface CustomFishingItem {
String DEFAULT_MATERIAL = "PAPER";
@@ -38,56 +41,74 @@ public interface CustomFishingItem {
*/
String material();
/**
* Returns the unique identifier of the custom fishing item.
*
* @return the unique identifier as a String.
*/
String id();
/**
* Returns a list of tag consumers which are functions that take an item and context as parameters
* and perform some operation on them.
* Returns a list of tag consumers. Tag consumers are functions that take an {@link Item} and a {@link Context}
* as parameters and perform some operation on them.
*
* @return a list of BiConsumer instances.
* @return a list of {@link BiConsumer} instances.
*/
List<BiConsumer<Item<ItemStack>, Context<Player>>> tagConsumers();
/**
* Builds the custom fishing item using the given context.
*
* @param context the {@link Context} in which the item is built.
* @return the built {@link ItemStack}.
*/
default ItemStack build(Context<Player> context) {
return BukkitCustomFishingPlugin.getInstance().getItemManager().build(context, this);
}
/**
* Creates a new Builder instance to construct a CustomFishingItem.
* Creates a new {@link Builder} instance to construct a {@link CustomFishingItem}.
*
* @return a new Builder instance.
* @return a new {@link Builder} instance.
*/
static Builder builder() {
return new CustomFishingItemImpl.BuilderImpl();
}
/**
* Builder interface for constructing instances of CustomFishingItem.
* Builder interface for constructing instances of {@link CustomFishingItem}.
*/
interface Builder {
/**
* Sets the unique identifier for the {@link CustomFishingItem} being built.
*
* @param id the unique identifier as a String.
* @return the {@link Builder} instance for method chaining.
*/
Builder id(String id);
/**
* Sets the material type for the CustomFishingItem being built.
* Sets the material type for the {@link CustomFishingItem} being built.
*
* @param material the material type as a String.
* @return the Builder instance for method chaining.
* @return the {@link Builder} instance for method chaining.
*/
Builder material(String material);
/**
* Sets the list of tag consumers for the CustomFishingItem being built.
* Sets the list of tag consumers for the {@link CustomFishingItem} being built.
* Tag consumers are functions that take an {@link Item} and a {@link Context} as parameters and perform some operation on them.
*
* @param tagConsumers a list of BiConsumer instances.
* @return the Builder instance for method chaining.
* @param tagConsumers a list of {@link PriorityFunction} instances wrapping {@link BiConsumer} functions.
* @return the {@link Builder} instance for method chaining.
*/
Builder tagConsumers(List<PriorityFunction<BiConsumer<Item<ItemStack>, Context<Player>>>> tagConsumers);
/**
* Builds and returns a new CustomFishingItem instance.
* Builds and returns a new {@link CustomFishingItem} instance.
*
* @return a new CustomFishingItem instance.
* @return a new {@link CustomFishingItem} instance.
*/
CustomFishingItem build();
}

View File

@@ -20,9 +20,21 @@ package net.momirealms.customfishing.api.mechanic.item;
import com.saicone.rtag.RtagItem;
import net.momirealms.customfishing.api.mechanic.context.Context;
import org.bukkit.entity.Player;
import org.jetbrains.annotations.ApiStatus;
/**
* Functional interface representing an editor for custom fishing items.
* Implementations of this interface apply modifications to an {@link RtagItem} using the provided context.
*/
@ApiStatus.Internal
@FunctionalInterface
public interface ItemEditor {
/**
* Applies modifications to the given {@link RtagItem} using the provided context.
*
* @param item the {@link RtagItem} to be modified
* @param context the {@link Context} in which the modifications are applied
*/
void apply(RtagItem item, Context<Player> context);
}

View File

@@ -32,40 +32,150 @@ import org.jetbrains.annotations.Nullable;
import java.util.Collection;
/**
* Interface for managing custom fishing items
*/
public interface ItemManager extends Reloadable {
/**
* Registers a new custom fishing item.
*
* @param item the {@link CustomFishingItem} to be registered
* @return true if the item was successfully registered, false otherwise
*/
boolean registerItem(@NotNull CustomFishingItem item);
/**
* Builds an internal representation of an item using the given context and item ID.
*
* @param context the {@link Context} in which the item is built
* @param id the ID of the item to be built
* @return the built {@link ItemStack}
* @throws NullPointerException if the item ID is not found
*/
@Nullable
ItemStack buildInternal(@NotNull Context<Player> context, @NotNull String id) throws NullPointerException;
/**
* Builds a custom fishing item using the given context and item definition.
*
* @param context the {@link Context} in which the item is built
* @param item the {@link CustomFishingItem} definition
* @return the built {@link ItemStack}
*/
ItemStack build(@NotNull Context<Player> context, @NotNull CustomFishingItem item);
/**
* Builds any item using the given context and item ID. Example: {@code CustomFishing:ID} / {@code Oraxen:ID} / {@code ItemsAdder:namespace:id}
*
* @param context the {@link Context} in which the item is built
* @param id the ID of the item to be built
* @return the built {@link ItemStack}, or null if the item ID is not found
*/
@Nullable
ItemStack buildAny(@NotNull Context<Player> context, @NotNull String id);
/**
* Retrieves the item ID of the given item stack. If it's a vanilla item, the returned value would be capitalized for instance {@code PAPER}. If it's a CustomFishing
* item, the returned value would be the ID for instance {@code beginner_rod}. If it's an item from other plugins, the returned value would be the
* id from that plugin for instance {@code itemsadder_namespace:id} / {@code oraxen_item_id}
*
* @param itemStack the {@link ItemStack} to be checked
* @return the custom fishing item ID, or null if the item stack is not a custom fishing item
*/
@NotNull
String getItemID(@NotNull ItemStack itemStack);
/**
* Retrieves the custom fishing item ID if the given item stack is a custom fishing item.
*
* @param itemStack the {@link ItemStack} to be checked
* @return the custom fishing item ID, or null if the item stack is not a custom fishing item
*/
@Nullable
String getCustomFishingItemID(@NotNull ItemStack itemStack);
/**
* Drops a custom fishing item as loot.
*
* @param context the {@link Context} in which the item is dropped
* @param rod the fishing rod {@link ItemStack}
* @param hook the {@link FishHook} entity
* @return the dropped {@link Item} entity
*/
@Nullable
Item dropItemLoot(@NotNull Context<Player> context, ItemStack rod, FishHook hook);
boolean hasCustomDurability(ItemStack itemStack);
/**
* Checks if the given item stack has custom durability.
*
* @param itemStack the {@link ItemStack} to be checked
* @return true if the item stack has custom durability, false otherwise
*/
boolean hasCustomMaxDamage(ItemStack itemStack);
void increaseDurability(Player player, ItemStack itemStack, int amount);
/**
* Gets the maximum damage value for the given item stack.
*
* @param itemStack the {@link ItemStack} to be checked
* @return the maximum damage value
*/
int getMaxDamage(ItemStack itemStack);
void decreaseDurability(Player player, ItemStack itemStack, int amount, boolean incorrectUsage);
/**
* Decreases the damage of the given item stack.
*
* @param player the {@link Player} holding the item
* @param itemStack the {@link ItemStack} to be modified
* @param amount the amount to decrease the damage by
*/
void decreaseDamage(Player player, ItemStack itemStack, int amount);
void setDurability(Player player, ItemStack itemStack, int damage);
/**
* Increases the damage of the given item stack.
*
* @param player the {@link Player} holding the item
* @param itemStack the {@link ItemStack} to be modified
* @param amount the amount to increase the damage by
* @param incorrectUsage true if the damage increase is due to incorrect usage, false otherwise
*/
void increaseDamage(Player player, ItemStack itemStack, int amount, boolean incorrectUsage);
/**
* Sets the damage of the given item stack.
*
* @param player the {@link Player} holding the item
* @param itemStack the {@link ItemStack} to be modified
* @param damage the new damage value
*/
void setDamage(Player player, ItemStack itemStack, int damage);
/**
* Returns the item factory used to create custom fishing items.
*
* @return the {@link ItemFactory} instance
*/
ItemFactory<CustomFishingPlugin, RtagItem, ItemStack> getFactory();
/**
* Returns an array of item providers used to manage custom fishing items.
*
* @return an array of {@link ItemProvider} instances
*/
ItemProvider[] getItemProviders();
/**
* Returns a collection of all registered item IDs.
*
* @return a collection of item ID strings
*/
Collection<String> getItemIDs();
/**
* Wraps the given item stack in a custom fishing item wrapper.
*
* @param itemStack the {@link ItemStack} to be wrapped
* @return the wrapped {@link net.momirealms.customfishing.common.item.Item} instance
*/
net.momirealms.customfishing.common.item.Item<ItemStack> wrap(ItemStack itemStack);
}

View File

@@ -19,9 +19,11 @@ package net.momirealms.customfishing.api.mechanic.item.tag;
import net.momirealms.customfishing.api.mechanic.context.Context;
import org.bukkit.entity.Player;
import org.jetbrains.annotations.ApiStatus;
import java.util.Map;
@ApiStatus.Internal
public interface TagMap {
Map<String, Object> apply(Context<Player> context);

View File

@@ -17,6 +17,9 @@
package net.momirealms.customfishing.api.mechanic.item.tag;
import org.jetbrains.annotations.ApiStatus;
@ApiStatus.Internal
public enum TagValueType {
BYTE,
INT,

View File

@@ -63,6 +63,11 @@ public interface Loot {
*/
boolean showInFinder();
/**
* Check if players can't grab the loot
*
* @return True if players can't grab the loot, false otherwise.
*/
boolean preventGrabbing();
/**
@@ -153,6 +158,12 @@ public interface Loot {
*/
Builder disableGame(boolean disableGame);
/**
* Specify whether players are prevented from grabbing the loot
*
* @param preventGrabbing True if grabbing should be prevented.
* @return The builder instance.
*/
Builder preventGrabbing(boolean preventGrabbing);
/**

View File

@@ -28,18 +28,53 @@ import java.util.List;
import java.util.Map;
import java.util.Optional;
/**
* Interface for managing loot
*/
public interface LootManager extends Reloadable {
/**
* Registers a new loot item.
*
* @param loot the {@link Loot} to be registered
* @return true if the loot was successfully registered, false otherwise
*/
boolean registerLoot(@NotNull Loot loot);
/**
* Retrieves the members of a loot group identified by the given key.
*
* @param key the key identifying the loot group
* @return a list of member identifiers as strings
*/
@NotNull
List<String> getGroupMembers(String key);
/**
* Retrieves a loot item by its key.
*
* @param key the key identifying the loot item
* @return an {@link Optional} containing the {@link Loot} if found, or an empty {@link Optional} if not
*/
@NotNull
Optional<Loot> getLoot(String key);
/**
* Retrieves a map of weighted loots based on the given effect and context.
*
* @param effect the {@link Effect} influencing the loot selection
* @param context the {@link Context} in which the loot selection occurs
* @return a map of loot keys to their respective weights
*/
Map<String, Double> getWeightedLoots(Effect effect, Context<Player> context);
/**
* Retrieves the next loot item based on the given effect and context.
*
* @param effect the {@link Effect} influencing the loot selection
* @param context the {@link Context} in which the loot selection occurs
* @return the next {@link Loot} item, or null if no suitable loot is found
*/
@Nullable
Loot getNextLoot(Effect effect, Context<Player> context);
}

View File

@@ -22,13 +22,40 @@ import net.momirealms.customfishing.common.plugin.feature.Reloadable;
import org.bukkit.entity.Player;
import org.bukkit.inventory.ItemStack;
/**
* Interface for managing the market
*/
public interface MarketManager extends Reloadable {
/**
* Opens the market GUI for the specified player.
*
* @param player the {@link Player} for whom the market GUI will be opened
* @return true if the market GUI was successfully opened, false otherwise
*/
boolean openMarketGUI(Player player);
/**
* Retrieves the price of the specified item within the given context.
*
* @param context the {@link Context} in which the price is calculated
* @param itemStack the {@link ItemStack} representing the item
* @return the price of the item as a double
*/
double getItemPrice(Context<Player> context, ItemStack itemStack);
/**
* Retrieves the formula used for calculating item prices.
*
* @return the pricing formula as a String
*/
String getFormula();
/**
* Retrieves the earning limit within the given context.
*
* @param context the {@link Context} in which the earning limit is checked
* @return the earning limit as a double
*/
double earningLimit(Context<Player> context);
}

View File

@@ -28,6 +28,10 @@ import java.util.function.Function;
import java.util.regex.Matcher;
import java.util.stream.Collectors;
/**
* This class handles the registration and parsing of custom placeholders,
* and integrates with PlaceholderAPI if available.
*/
public class BukkitPlaceholderManager implements PlaceholderManager {
private final BukkitCustomFishingPlugin plugin;
@@ -35,23 +39,40 @@ public class BukkitPlaceholderManager implements PlaceholderManager {
private final HashMap<String, Function<OfflinePlayer, String>> customPlaceholderMap;
private static BukkitPlaceholderManager instance;
/**
* Constructs a new BukkitPlaceholderManager instance.
*
* @param plugin the instance of {@link BukkitCustomFishingPlugin}
*/
public BukkitPlaceholderManager(BukkitCustomFishingPlugin plugin) {
this.plugin = plugin;
this.customPlaceholderMap = new HashMap<>();
instance = this;
}
/**
* Loads the placeholder manager, checking for PlaceholderAPI and registering default placeholders.
*/
@Override
public void load() {
this.hasPapi = Bukkit.getPluginManager().isPluginEnabled("PlaceholderAPI");
this.customPlaceholderMap.put("{random}", (p) -> String.valueOf(RandomUtils.generateRandomDouble(0, 1)));
}
/**
* Unloads the placeholder manager, clearing all registered placeholders.
*/
@Override
public void unload() {
this.hasPapi = false;
this.customPlaceholderMap.clear();
}
/**
* Gets the singleton instance of BukkitPlaceholderManager.
*
* @return the singleton instance
*/
public static BukkitPlaceholderManager getInstance() {
return instance;
}
@@ -63,6 +84,13 @@ public class BukkitPlaceholderManager implements PlaceholderManager {
return true;
}
@Override
public boolean registerCustomPlaceholder(String placeholder, Function<OfflinePlayer, String> provider) {
if (this.customPlaceholderMap.containsKey(placeholder)) return false;
this.customPlaceholderMap.put(placeholder, provider);
return true;
}
@Override
public List<String> resolvePlaceholders(String text) {
List<String> placeholders = new ArrayList<>();

View File

@@ -23,6 +23,7 @@ import org.jetbrains.annotations.Nullable;
import java.util.List;
import java.util.Map;
import java.util.function.Function;
import java.util.regex.Pattern;
public interface PlaceholderManager extends Reloadable {
@@ -30,14 +31,23 @@ public interface PlaceholderManager extends Reloadable {
Pattern PATTERN = Pattern.compile("\\{[^{}]+}");
/**
* Registers a custom placeholder with its corresponding original string.
* Registers a custom placeholder.
*
* @param placeholder the placeholder to register.
* @param original the original string corresponding to the placeholder.
* @return true if the placeholder was successfully registered, false if it already exists.
* @param placeholder the placeholder to be registered
* @param original the original placeholder string for instance {@code %test_placeholder%}
* @return true if the placeholder was successfully registered, false otherwise
*/
boolean registerCustomPlaceholder(String placeholder, String original);
/**
* Registers a custom placeholder.
*
* @param placeholder the placeholder to be registered
* @param provider the value provider
* @return true if the placeholder was successfully registered, false otherwise
*/
boolean registerCustomPlaceholder(String placeholder, Function<OfflinePlayer, String> provider);
/**
* Resolves all placeholders within a given text.
*
@@ -47,32 +57,32 @@ public interface PlaceholderManager extends Reloadable {
List<String> resolvePlaceholders(String text);
/**
* Parses a single placeholder for a specified player, optionally using a map of replacements.
* Parses a single placeholder for the specified player, using the provided replacements.
*
* @param player the player for whom the placeholder should be parsed.
* @param placeholder the placeholder to parse.
* @param replacements a map of replacement strings for placeholders.
* @return the parsed placeholder string.
* @param player the player for whom the placeholder is being parsed
* @param placeholder the placeholder to be parsed
* @param replacements a map of replacements to be used
* @return the parsed placeholder value
*/
String parseSingle(@Nullable OfflinePlayer player, String placeholder, Map<String, String> replacements);
/**
* Parses all placeholders in the given text for a specified player, optionally using a map of replacements.
* Parses placeholders in the given text for the specified player, using the provided replacements.
*
* @param player the player for whom the placeholders should be parsed.
* @param text the text containing placeholders.
* @param replacements a map of replacement strings for placeholders.
* @return the text with parsed placeholders.
* @param player the player for whom placeholders are being parsed
* @param text the text containing placeholders
* @param replacements a map of replacements to be used
* @return the text with placeholders replaced
*/
String parse(@Nullable OfflinePlayer player, String text, Map<String, String> replacements);
/**
* Parses all placeholders in a list of strings for a specified player, optionally using a map of replacements.
* Parses placeholders in the given list of texts for the specified player, using the provided replacements.
*
* @param player the player for whom the placeholders should be parsed.
* @param list the list of strings containing placeholders.
* @param replacements a map of replacement strings for placeholders.
* @return the list of strings with parsed placeholders.
* @param player the player for whom placeholders are being parsed
* @param list the list of texts containing placeholders
* @param replacements a map of replacements to be used
* @return the list of texts with placeholders replaced
*/
List<String> parse(@Nullable OfflinePlayer player, List<String> list, Map<String, String> replacements);
}

View File

@@ -58,6 +58,13 @@ public interface MathValue<T> {
return new PlainMathValueImpl<>(value);
}
/**
* Creates a MathValue based on a range of values.
*
* @param value the ranged value to represent
* @param <T> the type of the holder object for the context
* @return a MathValue instance representing the given ranged value
*/
static <T> MathValue<T> ranged(String value) {
return new RangedMathValueImpl<>(value);
}

View File

@@ -19,26 +19,54 @@ package net.momirealms.customfishing.api.mechanic.requirement;
import java.util.Map;
/**
* Represents a conditional element that can hold an element, its sub-elements, and associated requirements.
*
* @param <E> the type of the main element
* @param <T> the type of the requirement parameter
*/
public class ConditionalElement<E, T> {
private final E element;
private final Map<String, ConditionalElement<E, T>> subElements;
private final Requirement<T>[] requirements;
/**
* Constructs a new ConditionalElement.
*
* @param element the main element of this conditional element
* @param subElements a map of sub-elements identified by a string key
* @param requirements an array of requirements associated with this element
*/
public ConditionalElement(E element, Map<String, ConditionalElement<E, T>> subElements, Requirement<T>[] requirements) {
this.element = element;
this.subElements = subElements;
this.requirements = requirements;
}
/**
* Retrieves the main element.
*
* @return the main element of type {@link E}
*/
public E getElement() {
return element;
}
/**
* Retrieves the requirements associated with this element.
*
* @return an array of {@link Requirement} of type {@link T}
*/
public Requirement<T>[] getRequirements() {
return requirements;
}
/**
* Retrieves the sub-elements associated with this element.
*
* @return a map of sub-elements identified by a string key
*/
public Map<String, ConditionalElement<E, T>> getSubElements() {
return subElements;
}

View File

@@ -20,7 +20,7 @@ package net.momirealms.customfishing.api.mechanic.requirement;
import net.momirealms.customfishing.api.mechanic.context.Context;
/**
* Interface representing a requirement that must be met in the custom fishing API.
* Interface representing a requirement that must be met.
* This can be used to define conditions that need to be satisfied within a given context.
*
* @param <T> the type parameter for the context

View File

@@ -114,6 +114,13 @@ public interface RequirementManager<T> extends Reloadable {
return true;
}
/**
* Checks if all requirements in the provided array are satisfied within the given context.
*
* @param context The context in which the requirements are evaluated.
* @param requirements A list of requirements to check.
* @return True if all requirements are satisfied, otherwise false.
*/
static <T> boolean isSatisfied(Context<T> context, @Nullable List<Requirement<T>> requirements) {
if (requirements == null) return true;
for (Requirement<T> requirement : requirements) {

View File

@@ -22,8 +22,17 @@ import org.jetbrains.annotations.NotNull;
import java.util.List;
/**
* Interface for managing statistics
*/
public interface StatisticsManager extends Reloadable {
/**
* Retrieves the members of a statistics category identified by the given key.
*
* @param key the key identifying the statistics category
* @return a list of category member identifiers as strings
*/
@NotNull
List<String> getCategoryMembers(String key);
}

View File

@@ -22,38 +22,122 @@ import net.momirealms.customfishing.api.mechanic.totem.block.TotemBlock;
import org.bukkit.Location;
import org.bukkit.entity.Player;
/**
* Interface representing the configuration for a totem.
* This interface provides methods for retrieving totem models, particle settings,
* and other configuration details, as well as a builder for creating instances.
*/
public interface TotemConfig {
/**
* Retrieves the models for the totem.
*
* @return an array of {@link TotemModel} instances
*/
TotemModel[] totemModels();
/**
* Retrieves the unique identifier for the totem configuration.
*
* @return the unique identifier as a String
*/
String id();
/**
* Checks if the location matches the correct pattern for the totem.
*
* @param location the {@link Location} to be checked
* @return true if the location matches the pattern, false otherwise
*/
boolean isRightPattern(Location location);
/**
* Retrieves the particle settings for the totem.
*
* @return an array of {@link TotemParticle} instances
*/
TotemParticle[] particleSettings();
/**
* Retrieves the radius of the totem's effect.
*
* @return the radius as a {@link MathValue} for {@link Player}
*/
MathValue<Player> radius();
/**
* Retrieves the duration of the totem's effect.
*
* @return the duration as a {@link MathValue} for {@link Player}
*/
MathValue<Player> duration();
/**
* Retrieves the core blocks of the totem.
*
* @return an array of {@link TotemBlock} instances
*/
TotemBlock[] totemCore();
/**
* Creates a new {@link Builder} instance to construct a {@link TotemConfig}.
*
* @return a new {@link Builder} instance
*/
static Builder builder() {
return new TotemConfigImpl.BuilderImpl();
}
/**
* Builder interface for constructing instances of {@link TotemConfig}.
*/
interface Builder {
/**
* Sets the unique identifier for the {@link TotemConfig} being built.
*
* @param id the unique identifier as a String
* @return the {@link Builder} instance for method chaining
*/
Builder id(String id);
/**
* Sets the totem models for the {@link TotemConfig} being built.
*
* @param totemModels an array of {@link TotemModel} instances
* @return the {@link Builder} instance for method chaining
*/
Builder totemModels(TotemModel[] totemModels);
/**
* Sets the particle settings for the {@link TotemConfig} being built.
*
* @param particleSettings an array of {@link TotemParticle} instances
* @return the {@link Builder} instance for method chaining
*/
Builder particleSettings(TotemParticle[] particleSettings);
/**
* Sets the radius of the totem's effect for the {@link TotemConfig} being built.
*
* @param radius the radius as a {@link MathValue} for {@link Player}
* @return the {@link Builder} instance for method chaining
*/
Builder radius(MathValue<Player> radius);
/**
* Sets the duration of the totem's effect for the {@link TotemConfig} being built.
*
* @param duration the duration as a {@link MathValue} for {@link Player}
* @return the {@link Builder} instance for method chaining
*/
Builder duration(MathValue<Player> duration);
/**
* Builds and returns a new {@link TotemConfig} instance.
*
* @return a new {@link TotemConfig} instance
*/
TotemConfig build();
}
}

View File

@@ -24,12 +24,33 @@ import org.jetbrains.annotations.NotNull;
import java.util.Collection;
import java.util.Optional;
/**
* Interface for managing totems.
*/
public interface TotemManager extends Reloadable {
/**
* Retrieves a collection of activated totems at the specified location.
*
* @param location the {@link Location} to check for activated totems
* @return a collection of activated totem identifiers as strings
*/
Collection<String> getActivatedTotems(Location location);
/**
* Registers a new totem configuration.
*
* @param totem the {@link TotemConfig} to be registered
* @return true if the totem was successfully registered, false otherwise
*/
boolean registerTotem(TotemConfig totem);
/**
* Retrieves a totem configuration by its unique identifier.
*
* @param id the unique identifier of the totem
* @return an {@link Optional} containing the {@link TotemConfig} if found, or an empty {@link Optional} if not
*/
@NotNull
Optional<TotemConfig> getTotem(String id);
}

View File

@@ -20,6 +20,9 @@ package net.momirealms.customfishing.api.mechanic.totem;
import net.momirealms.customfishing.common.plugin.scheduler.SchedulerTask;
import org.bukkit.Location;
/**
* Interface representing the particle effect for a totem.
*/
public interface TotemParticle {
/**

View File

@@ -27,23 +27,79 @@ import java.util.Set;
import java.util.UUID;
import java.util.concurrent.CompletableFuture;
/**
* Interface representing a provider for data storage.
*/
public interface DataStorageProvider {
/**
* Initializes the data storage provider with the given configuration.
*
* @param config the {@link YamlDocument} configuration for the storage provider
*/
void initialize(YamlDocument config);
/**
* Disables the data storage provider, performing any necessary cleanup.
*/
void disable();
/**
* Retrieves the type of storage used by this provider.
*
* @return the {@link StorageType} of this provider
*/
StorageType getStorageType();
/**
* Retrieves the player data for the specified UUID.
*
* @param uuid the UUID of the player
* @param lock whether to lock the player data for exclusive access
* @return a {@link CompletableFuture} containing an {@link Optional} with the player data, or empty if not found
*/
CompletableFuture<Optional<PlayerData>> getPlayerData(UUID uuid, boolean lock);
/**
* Updates the player data for the specified UUID.
*
* @param uuid the UUID of the player
* @param playerData the {@link PlayerData} to be updated
* @param unlock whether to unlock the player data after updating
* @return a {@link CompletableFuture} containing a boolean indicating success or failure
*/
CompletableFuture<Boolean> updatePlayerData(UUID uuid, PlayerData playerData, boolean unlock);
/**
* Updates or inserts the player data for the specified UUID.
*
* @param uuid the UUID of the player
* @param playerData the {@link PlayerData} to be updated or inserted
* @param unlock whether to unlock the player data after updating or inserting
* @return a {@link CompletableFuture} containing a boolean indicating success or failure
*/
CompletableFuture<Boolean> updateOrInsertPlayerData(UUID uuid, PlayerData playerData, boolean unlock);
/**
* Updates the data for multiple players.
*
* @param users a collection of {@link UserData} to be updated
* @param unlock whether to unlock the player data after updating
*/
void updateManyPlayersData(Collection<? extends UserData> users, boolean unlock);
/**
* Locks or unlocks the player data for the specified UUID.
*
* @param uuid the UUID of the player
* @param lock whether to lock (true) or unlock (false) the player data
*/
void lockOrUnlockPlayerData(UUID uuid, boolean lock);
/**
* Retrieves the set of unique user UUIDs.
*
* @return a set of unique user UUIDs
*/
Set<UUID> getUniqueUsers();
}

View File

@@ -27,55 +27,98 @@ import java.util.Optional;
import java.util.UUID;
import java.util.concurrent.CompletableFuture;
/**
* Interface for managing storage.
*/
public interface StorageManager extends Reloadable {
/**
* Retrieves the server ID.
*
* @return the server ID as a String
*/
@NotNull
String getServerID();
/**
* Retrieves the user data for an online user by their UUID.
*
* @param uuid the UUID of the user
* @return an {@link Optional} containing the {@link UserData} if the user is online, or empty if not
*/
@NotNull
Optional<UserData> getOnlineUser(UUID uuid);
/**
* Retrieves a collection of all online users.
*
* @return a collection of {@link UserData} for all online users
*/
@NotNull
Collection<UserData> getOnlineUsers();
/**
* Retrieves the user data for an offline user by their UUID.
*
* @param uuid the UUID of the user
* @param lock whether to lock the user data for exclusive access
* @return a {@link CompletableFuture} containing an {@link Optional} with the user data, or empty if not found
*/
CompletableFuture<Optional<UserData>> getOfflineUserData(UUID uuid, boolean lock);
/**
* Saves the user data.
*
* @param userData the {@link UserData} to be saved
* @param unlock whether to unlock the user data after saving
* @return a {@link CompletableFuture} containing a boolean indicating success or failure
*/
CompletableFuture<Boolean> saveUserData(UserData userData, boolean unlock);
/**
* Retrieves the data storage provider.
*
* @return the {@link DataStorageProvider} instance
*/
@NotNull
DataStorageProvider getDataSource();
/**
* Checks if Redis is enabled for data storage.
*
* @return true if Redis is enabled, false otherwise
*/
boolean isRedisEnabled();
/**
* Converts PlayerData to bytes.
* Converts {@link PlayerData} to a byte array.
*
* @param data The PlayerData to be converted.
* @return The byte array representation of PlayerData.
* @param data the {@link PlayerData} to be converted
* @return the byte array representation of {@link PlayerData}
*/
byte[] toBytes(@NotNull PlayerData data);
/**
* Converts PlayerData to JSON format.
* Converts {@link PlayerData} to JSON format.
*
* @param data The PlayerData to be converted.
* @return The JSON string representation of PlayerData.
* @param data the {@link PlayerData} to be converted
* @return the JSON string representation of {@link PlayerData}
*/
@NotNull String toJson(@NotNull PlayerData data);
/**
* Converts JSON string to PlayerData.
* Converts a JSON string to {@link PlayerData}.
*
* @param json The JSON string to be converted.
* @return The PlayerData object.
* @param json the JSON string to be converted
* @return the {@link PlayerData} object
*/
@NotNull PlayerData fromJson(String json);
/**
* Converts bytes to PlayerData.
* Converts a byte array to {@link PlayerData}.
*
* @param data The byte array to be converted.
* @return The PlayerData object.
* @param data the byte array to be converted
* @return the {@link PlayerData} object
*/
@NotNull PlayerData fromBytes(byte[] data);
}

View File

@@ -27,132 +27,156 @@ import org.jetbrains.annotations.Nullable;
import java.util.UUID;
/**
* Interface representing user data.
* This interface provides methods for accessing and managing user-related information.
*/
public interface UserData {
/**
* Get the username
* Retrieves the username.
*
* @return user name
* @return the username as a {@link String}
*/
@NotNull
String name();
/**
* Get the user's uuid
* Retrieves the user's UUID.
*
* @return uuid
* @return the UUID as a {@link UUID}
*/
@NotNull
UUID uuid();
/**
* Get the player instance if that player is online
* Retrieves the {@link Player} instance if the player is online.
*
* @return player
* @return the {@link Player} instance, or null if the player is offline
*/
@Nullable
Player player();
/**
* Get the fishing bag holder
* Retrieves the fishing bag holder.
*
* @return fishing bag holder
* @return the {@link FishingBagHolder}
*/
@NotNull
FishingBagHolder holder();
/**
* Get the player's earning data
* Retrieves the player's earning data.
*
* @return earning data
* @return the {@link EarningData}
*/
@NotNull
EarningData earningData();
/**
* Get the player's statistics
* Retrieves the player's fishing statistics.
*
* @return statistics
* @return the {@link FishingStatistics}
*/
@NotNull
FishingStatistics statistics();
/**
* If the user is online on current server
* Checks if the user is online on the current server.
*
* @return online or not
* @return true if the user is online, false otherwise
*/
boolean isOnline();
/**
* If the data is locked
* Checks if the data is locked.
*
* @return locked or not
* @return true if the data is locked, false otherwise
*/
boolean isLocked();
/**
* Get the data in another minimized format that can be saved
* Converts the user data to a minimized format that can be saved.
*
* @return player data
* @return the {@link PlayerData}
*/
@NotNull
PlayerData toPlayerData();
/**
* Creates a new {@link Builder} instance to construct {@link UserData}.
*
* @return a new {@link Builder} instance
*/
static Builder builder() {
return new UserDataImpl.BuilderImpl();
}
/**
* Builder interface for constructing instances of {@link UserData}.
*/
interface Builder {
/**
* Set the username for the UserData being built.
* Sets the username for the {@link UserData} being built.
*
* @param name the username to set.
* @return the current Builder instance.
* @param name the username to set
* @return the current {@link Builder} instance for method chaining
*/
Builder name(String name);
/**
* Set the UUID for the UserData being built.
* Sets the UUID for the {@link UserData} being built.
*
* @param uuid the UUID to set.
* @return the current Builder instance.
* @param uuid the UUID to set
* @return the current {@link Builder} instance for method chaining
*/
Builder uuid(UUID uuid);
/**
* Set the FishingBagHolder for the UserData being built.
* Sets the fishing bag holder for the {@link UserData} being built.
*
* @param holder the FishingBagHolder to set.
* @return the current Builder instance.
* @param holder the {@link FishingBagHolder} to set
* @return the current {@link Builder} instance for method chaining
*/
Builder holder(FishingBagHolder holder);
/**
* Set the EarningData for the UserData being built.
* Sets the earning data for the {@link UserData} being built.
*
* @param earningData the EarningData to set.
* @return the current Builder instance.
* @param earningData the {@link EarningData} to set
* @return the current {@link Builder} instance for method chaining
*/
Builder earningData(EarningData earningData);
/**
* Set the FishingStatistics for the UserData being built.
* Sets the fishing statistics for the {@link UserData} being built.
*
* @param statistics the FishingStatistics to set.
* @return the current Builder instance.
* @param statistics the {@link FishingStatistics} to set
* @return the current {@link Builder} instance for method chaining
*/
Builder statistics(FishingStatistics statistics);
/**
* Sets whether the data is locked for the {@link UserData} being built.
*
* @param isLocked true if the data should be locked, false otherwise
* @return the current {@link Builder} instance for method chaining
*/
Builder locked(boolean isLocked);
/**
* Sets the player data for the {@link UserData} being built.
*
* @param playerData the {@link PlayerData} to set
* @return the current {@link Builder} instance for method chaining
*/
Builder data(PlayerData playerData);
/**
* Build and return the UserData instance based on the current state of the Builder.
* Builds and returns the {@link UserData} instance based on the current state of the {@link Builder}.
*
* @return the constructed UserData instance.
* @return the constructed {@link UserData} instance
*/
UserData build();
}

View File

@@ -21,12 +21,28 @@ import org.bukkit.Bukkit;
import org.bukkit.event.Cancellable;
import org.bukkit.event.Event;
/**
* Utility class for handling events.
*/
public class EventUtils {
/**
* Fires an event and does not wait for any result.
*
* @param event the {@link Event} to be fired
*/
public static void fireAndForget(Event event) {
Bukkit.getPluginManager().callEvent(event);
}
/**
* Fires an event and checks if it is cancelled.
* This method only accepts events that implement {@link Cancellable}.
*
* @param event the {@link Event} to be fired
* @return true if the event is cancelled, false otherwise
* @throws IllegalArgumentException if the event is not cancellable
*/
public static boolean fireAndCheckCancel(Event event) {
if (!(event instanceof Cancellable cancellable))
throw new IllegalArgumentException("Only cancellable events are allowed here");

View File

@@ -24,6 +24,7 @@ import org.jetbrains.annotations.ApiStatus;
/**
* Utility class for generating offset characters based on a font configuration.
*/
@ApiStatus.Internal
@SuppressWarnings("DuplicatedCode")
public class OffsetUtils {

View File

@@ -21,6 +21,9 @@ import org.bukkit.Location;
import java.util.Objects;
/**
* A simple representation of a location in a Minecraft world, identified by its world name and coordinates.
*/
public record SimpleLocation(String worldName, int x, int y, int z) {
@Override
@@ -57,6 +60,12 @@ public record SimpleLocation(String worldName, int x, int y, int z) {
return hash;
}
/**
* Creates a {@link SimpleLocation} from a {@link Location} object.
*
* @param location the {@link Location} object
* @return a new {@link SimpleLocation} representing the same location
*/
public static SimpleLocation of(Location location) {
return new SimpleLocation(location.getWorld().getName(), location.getBlockX(), location.getBlockY(), location.getBlockZ());
}

View File

@@ -1,12 +1,42 @@
/*
* Copyright (C) <2022> <XiaoMoMi>
*
* 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 <https://www.gnu.org/licenses/>.
*/
package net.momirealms.customfishing.api.util;
import net.momirealms.customfishing.api.mechanic.item.tag.TagValueType;
import net.momirealms.customfishing.common.util.Pair;
import org.jetbrains.annotations.ApiStatus;
import java.util.Locale;
/**
* Utility class for handling tag values.
*/
@ApiStatus.Internal
public class TagUtils {
/**
* Parses a string into a pair containing a {@link TagValueType} and its associated data.
* The input string should be in the format "&lt;type&gt; data".
*
* @param str the string to be parsed
* @return a {@link Pair} containing the {@link TagValueType} and its associated data
* @throws IllegalArgumentException if the input string is in an invalid format
*/
public static Pair<TagValueType, String> toTypeAndData(String str) {
String[] parts = str.split("\\s+", 2);
if (parts.length == 1) {

View File

@@ -21,15 +21,49 @@ import dev.dejvokep.boostedyaml.YamlDocument;
import java.io.File;
/**
* Interface for loading and managing configuration files.
*/
public interface ConfigLoader {
/**
* Loads a YAML configuration file from the specified file path.
*
* @param filePath the path to the configuration file
* @return the loaded {@link YamlDocument}
*/
YamlDocument loadConfig(String filePath);
/**
* Loads a YAML configuration file from the specified file path with a custom route separator.
*
* @param filePath the path to the configuration file
* @param routeSeparator the custom route separator character
* @return the loaded {@link YamlDocument}
*/
YamlDocument loadConfig(String filePath, char routeSeparator);
/**
* Loads a YAML data file.
*
* @param file the {@link File} object representing the data file
* @return the loaded {@link YamlDocument}
*/
YamlDocument loadData(File file);
/**
* Loads a YAML data file with a custom route separator.
*
* @param file the {@link File} object representing the data file
* @param routeSeparator the custom route separator character
* @return the loaded {@link YamlDocument}
*/
YamlDocument loadData(File file, char routeSeparator);
/**
* Saves a resource file from the plugin's jar to the specified file path.
*
* @param filePath the path where the resource file will be saved
*/
void saveResource(String filePath);
}

View File

@@ -30,6 +30,9 @@ import net.kyori.adventure.title.Title;
import java.time.Duration;
import java.util.concurrent.TimeUnit;
/**
* Helper class for handling Adventure components and related functionalities.
*/
public class AdventureHelper {
private final MiniMessage miniMessage;
@@ -48,10 +51,21 @@ public class AdventureHelper {
private static final AdventureHelper INSTANCE = new AdventureHelper();
}
/**
* Retrieves the singleton instance of AdventureHelper.
*
* @return the singleton instance
*/
public static AdventureHelper getInstance() {
return SingletonHolder.INSTANCE;
}
/**
* Converts a MiniMessage string to a Component.
*
* @param text the MiniMessage string
* @return the resulting Component
*/
public static Component miniMessage(String text) {
if (legacySupport) {
return getMiniMessage().deserialize(legacyToMiniMessage(text));
@@ -60,56 +74,153 @@ public class AdventureHelper {
}
}
/**
* Retrieves the MiniMessage instance.
*
* @return the MiniMessage instance
*/
public static MiniMessage getMiniMessage() {
return getInstance().miniMessage;
}
/**
* Retrieves the GsonComponentSerializer instance.
*
* @return the GsonComponentSerializer instance
*/
public static GsonComponentSerializer getGson() {
return getInstance().gsonComponentSerializer;
}
/**
* Converts a MiniMessage string to a JSON string.
*
* @param miniMessage the MiniMessage string
* @return the JSON string representation
*/
public static String miniMessageToJson(String miniMessage) {
AdventureHelper instance = getInstance();
return instance.miniMessageToJsonCache.get(miniMessage, (text) -> instance.gsonComponentSerializer.serialize(miniMessage(text)));
}
/**
* Sends a title to an audience.
*
* @param audience the audience to send the title to
* @param title the title component
* @param subtitle the subtitle component
* @param fadeIn the fade-in duration in ticks
* @param stay the stay duration in ticks
* @param fadeOut the fade-out duration in ticks
*/
public static void sendTitle(Audience audience, Component title, Component subtitle, int fadeIn, int stay, int fadeOut) {
audience.showTitle(Title.title(title, subtitle, Title.Times.times(Duration.ofMillis(fadeIn * 50L), Duration.ofMillis(stay * 50L), Duration.ofMillis(fadeOut * 50L))));
}
/**
* Sends an action bar message to an audience.
*
* @param audience the audience to send the action bar message to
* @param actionBar the action bar component
*/
public static void sendActionBar(Audience audience, Component actionBar) {
audience.sendActionBar(actionBar);
}
/**
* Sends a message to an audience.
*
* @param audience the audience to send the message to
* @param message the message component
*/
public static void sendMessage(Audience audience, Component message) {
audience.sendMessage(message);
}
/**
* Plays a sound for an audience.
*
* @param audience the audience to play the sound for
* @param sound the sound to play
*/
public static void playSound(Audience audience, Sound sound) {
audience.playSound(sound);
}
/**
* Surrounds text with a MiniMessage font tag.
*
* @param text the text to surround
* @param font the font as a {@link Key}
* @return the text surrounded by the MiniMessage font tag
*/
public static String surroundWithMiniMessageFont(String text, Key font) {
return "<font:" + font.asString() + ">" + text + "</font>";
}
/**
* Surrounds text with a MiniMessage font tag.
*
* @param text the text to surround
* @param font the font as a {@link String}
* @return the text surrounded by the MiniMessage font tag
*/
public static String surroundWithMiniMessageFont(String text, String font) {
return "<font:" + font + ">" + text + "</font>";
}
/**
* Converts a JSON string to a MiniMessage string.
*
* @param json the JSON string
* @return the MiniMessage string representation
*/
public static String jsonToMiniMessage(String json) {
return getInstance().miniMessageStrict.serialize(getInstance().gsonComponentSerializer.deserialize(json));
}
/**
* Converts a JSON string to a Component.
*
* @param json the JSON string
* @return the resulting Component
*/
public static Component jsonToComponent(String json) {
return getInstance().gsonComponentSerializer.deserialize(json);
}
/**
* Converts a Component to a JSON string.
*
* @param component the Component to convert
* @return the JSON string representation
*/
public static String componentToJson(Component component) {
return getGson().serialize(component);
}
/**
* Checks if a character is a legacy color code.
*
* @param c the character to check
* @return true if the character is a color code, false otherwise
*/
@SuppressWarnings("BooleanMethodIsAlwaysInverted")
public static boolean isLegacyColorCode(char c) {
return c == '§' || c == '&';
}
/**
* Converts a legacy color code string to a MiniMessage string.
*
* @param legacy the legacy color code string
* @return the MiniMessage string representation
*/
public static String legacyToMiniMessage(String legacy) {
StringBuilder stringBuilder = new StringBuilder();
char[] chars = legacy.toCharArray();
for (int i = 0; i < chars.length; i++) {
if (!isColorCode(chars[i])) {
if (!isLegacyColorCode(chars[i])) {
stringBuilder.append(chars[i]);
continue;
}
@@ -142,12 +253,12 @@ public class AdventureHelper {
case 'k' -> stringBuilder.append("<obf>");
case 'x' -> {
if (i + 13 >= chars.length
|| !isColorCode(chars[i+2])
|| !isColorCode(chars[i+4])
|| !isColorCode(chars[i+6])
|| !isColorCode(chars[i+8])
|| !isColorCode(chars[i+10])
|| !isColorCode(chars[i+12])) {
|| !isLegacyColorCode(chars[i+2])
|| !isLegacyColorCode(chars[i+4])
|| !isLegacyColorCode(chars[i+6])
|| !isLegacyColorCode(chars[i+8])
|| !isLegacyColorCode(chars[i+10])
|| !isLegacyColorCode(chars[i+12])) {
stringBuilder.append(chars[i]);
continue;
}
@@ -171,13 +282,4 @@ public class AdventureHelper {
}
return stringBuilder.toString();
}
public static String componentToJson(Component component) {
return getGson().serialize(component);
}
@SuppressWarnings("BooleanMethodIsAlwaysInverted")
public static boolean isColorCode(char c) {
return c == '§' || c == '&';
}
}

View File

@@ -19,8 +19,17 @@ package net.momirealms.customfishing.common.helper;
import net.objecthunter.exp4j.ExpressionBuilder;
/**
* Helper class for evaluating mathematical expressions.
*/
public class ExpressionHelper {
/**
* Evaluates a mathematical expression provided as a string.
*
* @param expression the mathematical expression to evaluate
* @return the result of the evaluation as a double
*/
public static double evaluate(String expression) {
return new ExpressionBuilder(expression).build().evaluate();
}

View File

@@ -20,6 +20,9 @@ package net.momirealms.customfishing.common.helper;
import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
/**
* Helper class for managing Gson instances.
*/
public class GsonHelper {
private final Gson gson;
@@ -29,14 +32,27 @@ public class GsonHelper {
.create();
}
/**
* Retrieves the Gson instance.
*
* @return the Gson instance
*/
public Gson getGson() {
return gson;
}
/**
* Retrieves the singleton Gson instance from GsonHelper.
*
* @return the singleton Gson instance
*/
public static Gson get() {
return SingletonHolder.INSTANCE.getGson();
}
/**
* Static inner class for holding the singleton instance of GsonHelper.
*/
private static class SingletonHolder {
private static final GsonHelper INSTANCE = new GsonHelper();
}

View File

@@ -23,57 +23,211 @@ import java.util.List;
import java.util.Map;
import java.util.Optional;
/**
* Interface representing an item.
* This interface provides methods for managing item properties such as custom model data,
* damage, display name, lore, enchantments, and tags.
*
* @param <I> the type of the item implementation
*/
public interface Item<I> {
/**
* Sets the custom model data for the item.
*
* @param data the custom model data to set
* @return the current {@link Item} instance for method chaining
*/
Item<I> customModelData(Integer data);
/**
* Retrieves the custom model data of the item.
*
* @return an {@link Optional} containing the custom model data, or empty if not set
*/
Optional<Integer> customModelData();
/**
* Sets the damage value for the item.
*
* @param data the damage value to set
* @return the current {@link Item} instance for method chaining
*/
Item<I> damage(Integer data);
/**
* Retrieves the damage value of the item.
*
* @return an {@link Optional} containing the damage value, or empty if not set
*/
Optional<Integer> damage();
/**
* Sets the maximum damage value for the item.
*
* @param data the maximum damage value to set
* @return the current {@link Item} instance for method chaining
*/
Item<I> maxDamage(Integer data);
/**
* Retrieves the maximum damage value of the item.
*
* @return an {@link Optional} containing the maximum damage value, or empty if not set
*/
Optional<Integer> maxDamage();
/**
* Sets the display name for the item.
*
* @param displayName the display name to set
* @return the current {@link Item} instance for method chaining
*/
Item<I> displayName(String displayName);
/**
* Retrieves the display name of the item.
*
* @return an {@link Optional} containing the display name, or empty if not set
*/
Optional<String> displayName();
/**
* Sets the lore for the item.
*
* @param lore the lore to set
* @return the current {@link Item} instance for method chaining
*/
Item<I> lore(List<String> lore);
/**
* Retrieves the lore of the item.
*
* @return an {@link Optional} containing the lore, or empty if not set
*/
Optional<List<String>> lore();
/**
* Sets whether the item is unbreakable.
*
* @param unbreakable true if the item should be unbreakable, false otherwise
* @return the current {@link Item} instance for method chaining
*/
Item<I> unbreakable(boolean unbreakable);
/**
* Checks if the item is unbreakable.
*
* @return true if the item is unbreakable, false otherwise
*/
boolean unbreakable();
/**
* Sets the skull data for the item.
*
* @param data the skull data to set
* @return the current {@link Item} instance for method chaining
*/
Item<I> skull(String data);
/**
* Sets the enchantments for the item.
*
* @param enchantments a map of enchantments to set
* @return the current {@link Item} instance for method chaining
*/
Item<I> enchantments(Map<Key, Short> enchantments);
/**
* Adds an enchantment to the item.
*
* @param enchantment the enchantment to add
* @param level the level of the enchantment
* @return the current {@link Item} instance for method chaining
*/
Item<I> addEnchantment(Key enchantment, int level);
/**
* Sets the stored enchantments for the item.
*
* @param enchantments a map of stored enchantments to set
* @return the current {@link Item} instance for method chaining
*/
Item<I> storedEnchantments(Map<Key, Short> enchantments);
/**
* Adds a stored enchantment to the item.
*
* @param enchantment the stored enchantment to add
* @param level the level of the stored enchantment
* @return the current {@link Item} instance for method chaining
*/
Item<I> addStoredEnchantment(Key enchantment, int level);
/**
* Sets the item flags for the item.
*
* @param flags a list of item flags to set
* @return the current {@link Item} instance for method chaining
*/
Item<I> itemFlags(List<String> flags);
/**
* Retrieves the tag value at the specified path.
*
* @param path the path to the tag value
* @return an {@link Optional} containing the tag value, or empty if not found
*/
Optional<Object> getTag(Object... path);
/**
* Sets the tag value at the specified path.
*
* @param value the value to set
* @param path the path to the tag value
* @return the current {@link Item} instance for method chaining
*/
Item<I> setTag(Object value, Object... path);
/**
* Checks if the item has a tag value at the specified path.
*
* @param path the path to the tag value
* @return true if the tag value exists, false otherwise
*/
boolean hasTag(Object... path);
/**
* Removes the tag value at the specified path.
*
* @param path the path to the tag value
* @return true if the tag was removed, false otherwise
*/
boolean removeTag(Object... path);
/**
* Retrieves the underlying item implementation.
*
* @return the item implementation of type {@link I}
*/
I getItem();
/**
* Loads changes to the item.
*
* @return the loaded item implementation of type {@link I}
*/
I load();
/**
* Loads the changes and gets a copy of the item.
*
* @return a copy of the loaded item implementation of type {@link I}
*/
I loadCopy();
/**
* Loads the {@link I}'s changes to the {@link Item} instance.
*/
void update();
}

View File

@@ -27,29 +27,112 @@ import net.momirealms.customfishing.common.plugin.scheduler.SchedulerAdapter;
import java.io.InputStream;
import java.nio.file.Path;
/**
* Interface representing the main CustomFishing plugin.
*/
public interface CustomFishingPlugin {
/**
* Retrieves an input stream for a resource file within the plugin.
*
* @param filePath the path to the resource file
* @return an {@link InputStream} for the resource file
*/
InputStream getResourceStream(String filePath);
/**
* Retrieves the plugin logger.
*
* @return the {@link PluginLogger} instance
*/
PluginLogger getPluginLogger();
/**
* Retrieves the class path appender.
*
* @return the {@link ClassPathAppender} instance
*/
ClassPathAppender getClassPathAppender();
/**
* Retrieves the scheduler adapter.
*
* @return the {@link SchedulerAdapter} instance
*/
SchedulerAdapter<?> getScheduler();
/**
* Retrieves the data directory path.
*
* @return the {@link Path} to the data directory
*/
Path getDataDirectory();
/**
* Retrieves the configuration directory path.
* By default, this is the same as the data directory.
*
* @return the {@link Path} to the configuration directory
*/
default Path getConfigDirectory() {
return getDataDirectory();
}
/**
* Retrieves the dependency manager.
*
* @return the {@link DependencyManager} instance
*/
DependencyManager getDependencyManager();
/**
* Retrieves the translation manager.
*
* @return the {@link TranslationManager} instance
*/
TranslationManager getTranslationManager();
/**
* Retrieves the configuration manager.
*
* @return the {@link ConfigLoader} instance
*/
ConfigLoader getConfigManager();
/**
* Retrieves the server version.
*
* @return the server version as a string
*/
String getServerVersion();
/**
* Retrieves the plugin version.
*
* @return the plugin version as a string
*/
String getPluginVersion();
/**
* Loads the plugin.
* This method is called during the plugin's loading phase.
*/
void load();
/**
* Enables the plugin.
* This method is called during the plugin's enabling phase.
*/
void enable();
/**
* Disables the plugin.
* This method is called during the plugin's disabling phase.
*/
void disable();
/**
* Reloads the plugin.
*/
void reload();
}

View File

@@ -34,5 +34,4 @@ public interface SchedulerTask {
* Cancels the task.
*/
void cancel();
}

View File

@@ -22,10 +22,22 @@ import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
/**
* Utility class for handling operations with arrays.
*/
public class ArrayUtils {
private ArrayUtils() {}
/**
* Creates a subarray from the specified array starting from the given index.
*
* @param array the original array
* @param index the starting index for the subarray
* @param <T> the type of the elements in the array
* @return the subarray starting from the given index
* @throws IllegalArgumentException if the index is less than 0
*/
public static <T> T[] subArray(T[] array, int index) {
if (index < 0) {
throw new IllegalArgumentException("Index should be a value no lower than 0");
@@ -41,6 +53,14 @@ public class ArrayUtils {
return subArray;
}
/**
* Splits the specified array into a list of subarrays, each with the specified chunk size.
*
* @param array the original array
* @param chunkSize the size of each chunk
* @param <T> the type of the elements in the array
* @return a list of subarrays
*/
public static <T> List<T[]> splitArray(T[] array, int chunkSize) {
List<T[]> result = new ArrayList<>();
for (int i = 0; i < array.length; i += chunkSize) {
@@ -53,12 +73,27 @@ public class ArrayUtils {
return result;
}
/**
* Appends an element to the specified array.
*
* @param array the original array
* @param element the element to append
* @param <T> the type of the elements in the array
* @return a new array with the appended element
*/
public static <T> T[] appendElementToArray(T[] array, T element) {
T[] newArray = Arrays.copyOf(array, array.length + 1);
newArray[array.length] = element;
return newArray;
}
/**
* Splits a string value into an array of substrings based on comma separation.
* The input string is expected to be in the format "[value1, value2, ...]".
*
* @param value the string value to split
* @return an array of substrings
*/
public static String[] splitValue(String value) {
return value.substring(value.indexOf('[') + 1, value.lastIndexOf(']'))
.replaceAll("\\s", "")

View File

@@ -29,6 +29,9 @@ import java.util.List;
import java.util.jar.JarEntry;
import java.util.jar.JarInputStream;
/**
* Utility class for handling classes.
*/
public class ClassUtils {
private ClassUtils() {}

View File

@@ -24,6 +24,9 @@ import java.util.concurrent.CompletableFuture;
import java.util.stream.Collector;
import java.util.stream.Stream;
/**
* Utility class for handling operations with {@link CompletableFuture}.
*/
public class CompletableFutures {
private CompletableFutures() {}

View File

@@ -25,30 +25,83 @@ import java.util.function.Function;
import static java.util.Objects.requireNonNull;
/**
* Interface representing a value that can be either of two types, primary or fallback.
* Provides methods to create instances of either type and to map between them.
*
* @param <U> the type of the primary value
* @param <V> the type of the fallback value
*/
public interface Either<U, V> {
/**
* Creates an {@link Either} instance with a primary value.
*
* @param value the primary value
* @param <U> the type of the primary value
* @param <V> the type of the fallback value
* @return an {@link Either} instance with the primary value
*/
static <U, V> @NotNull Either<U, V> ofPrimary(final @NotNull U value) {
return EitherImpl.of(requireNonNull(value, "value"), null);
}
/**
* Creates an {@link Either} instance with a fallback value.
*
* @param value the fallback value
* @param <U> the type of the primary value
* @param <V> the type of the fallback value
* @return an {@link Either} instance with the fallback value
*/
static <U, V> @NotNull Either<U, V> ofFallback(final @NotNull V value) {
return EitherImpl.of(null, requireNonNull(value, "value"));
}
/**
* Retrieves the primary value, if present.
*
* @return an {@link Optional} containing the primary value, or empty if not present
*/
@NotNull
Optional<U> primary();
/**
* Retrieves the fallback value, if present.
*
* @return an {@link Optional} containing the fallback value, or empty if not present
*/
@NotNull
Optional<V> fallback();
/**
* Retrieves the primary value, or maps the fallback value to the primary type if the primary is not present.
*
* @param mapFallback a function to map the fallback value to the primary type
* @return the primary value, or the mapped fallback value if the primary is not present
*/
default @Nullable U primaryOrMapFallback(final @NotNull Function<V, U> mapFallback) {
return this.primary().orElseGet(() -> mapFallback.apply(this.fallback().get()));
}
/**
* Retrieves the fallback value, or maps the primary value to the fallback type if the fallback is not present.
*
* @param mapPrimary a function to map the primary value to the fallback type
* @return the fallback value, or the mapped primary value if the fallback is not present
*/
default @Nullable V fallbackOrMapPrimary(final @NotNull Function<U, V> mapPrimary) {
return this.fallback().orElseGet(() -> mapPrimary.apply(this.primary().get()));
}
/**
* Maps either the primary or fallback value to a new type.
*
* @param mapPrimary a function to map the primary value
* @param mapFallback a function to map the fallback value
* @param <R> the type of the result
* @return the mapped result
*/
default @NotNull <R> R mapEither(
final @NotNull Function<U, R> mapPrimary,
final @NotNull Function<V, R> mapFallback

View File

@@ -23,10 +23,20 @@ import java.nio.file.FileAlreadyExistsException;
import java.nio.file.Files;
import java.nio.file.Path;
/**
* Utility class for handling file and directory operations.
*/
public class FileUtils {
private FileUtils() {}
/**
* Creates a file if it does not already exist.
*
* @param path the path to the file
* @return the path to the file
* @throws IOException if an I/O error occurs
*/
public static Path createFileIfNotExists(Path path) throws IOException {
if (!Files.exists(path)) {
Files.createFile(path);
@@ -34,6 +44,13 @@ public class FileUtils {
return path;
}
/**
* Creates a directory if it does not already exist.
*
* @param path the path to the directory
* @return the path to the directory
* @throws IOException if an I/O error occurs
*/
public static Path createDirectoryIfNotExists(Path path) throws IOException {
if (Files.exists(path) && (Files.isDirectory(path) || Files.isSymbolicLink(path))) {
return path;
@@ -48,6 +65,13 @@ public class FileUtils {
return path;
}
/**
* Creates directories if they do not already exist.
*
* @param path the path to the directories
* @return the path to the directories
* @throws IOException if an I/O error occurs
*/
public static Path createDirectoriesIfNotExists(Path path) throws IOException {
if (Files.exists(path) && (Files.isDirectory(path) || Files.isSymbolicLink(path))) {
return path;
@@ -62,6 +86,12 @@ public class FileUtils {
return path;
}
/**
* Deletes a directory and all its contents.
*
* @param path the path to the directory
* @throws IOException if an I/O error occurs
*/
public static void deleteDirectory(Path path) throws IOException {
if (!Files.exists(path) || !Files.isDirectory(path)) {
return;

View File

@@ -17,12 +17,29 @@
package net.momirealms.customfishing.common.util;
/**
* Represents a key consisting of a namespace and a value.
* This class provides methods for creating and manipulating keys.
*/
public record Key(String namespace, String value) {
/**
* Creates a new {@link Key} instance with the specified namespace and value.
*
* @param namespace the namespace of the key
* @param value the value of the key
* @return a new {@link Key} instance
*/
public static Key of(String namespace, String value) {
return new Key(namespace, value);
}
/**
* Creates a new {@link Key} instance from a string in the format "namespace:value".
*
* @param key the string representation of the key
* @return a new {@link Key} instance
*/
public static Key fromString(String key) {
String[] split = key.split(":", 2);
return of(split[0], split[1]);

View File

@@ -19,11 +19,23 @@ package net.momirealms.customfishing.common.util;
import java.util.List;
/**
* Utility class for handling operations related to lists.
*/
public class ListUtils {
private ListUtils() {
}
/**
* Converts an object to a list of strings.
* If the object is a string, it returns a list containing the string.
* If the object is a list, it casts and returns the list as a list of strings.
*
* @param obj the object to convert
* @return the resulting list of strings
* @throws IllegalArgumentException if the object cannot be converted to a list of strings
*/
@SuppressWarnings("unchecked")
public static List<String> toList(final Object obj) {
if (obj instanceof String s) {

View File

@@ -17,8 +17,24 @@
package net.momirealms.customfishing.common.util;
/**
* A generic class representing a pair of values.
* This class provides methods to create and access pairs of values.
*
* @param <L> the type of the left value
* @param <R> the type of the right value
*/
public record Pair<L, R>(L left, R right) {
/**
* Creates a new {@link Pair} with the specified left and right values.
*
* @param left the left value
* @param right the right value
* @param <L> the type of the left value
* @param <R> the type of the right value
* @return a new {@link Pair} with the specified values
*/
public static <L, R> Pair<L, R> of(final L left, final R right) {
return new Pair<>(left, right);
}

View File

@@ -20,6 +20,9 @@ package net.momirealms.customfishing.common.util;
import java.util.Random;
import java.util.concurrent.ThreadLocalRandom;
/**
* Utility class for generating random values.
*/
public class RandomUtils {
private final Random random;
@@ -28,39 +31,96 @@ public class RandomUtils {
random = ThreadLocalRandom.current();
}
/**
* Static inner class to hold the singleton instance of RandomUtils.
*/
private static class SingletonHolder {
private static final RandomUtils INSTANCE = new RandomUtils();
}
/**
* Retrieves the singleton instance of RandomUtils.
*
* @return the singleton instance
*/
private static RandomUtils getInstance() {
return SingletonHolder.INSTANCE;
}
/**
* Generates a random integer between the specified minimum and maximum values (inclusive).
*
* @param min the minimum value
* @param max the maximum value
* @return a random integer between min and max (inclusive)
*/
public static int generateRandomInt(int min, int max) {
return getInstance().random.nextInt(max - min + 1) + min;
}
/**
* Generates a random double between the specified minimum and maximum values (inclusive).
*
* @param min the minimum value
* @param max the maximum value
* @return a random double between min and max (inclusive)
*/
public static double generateRandomDouble(double min, double max) {
return min + (max - min) * getInstance().random.nextDouble();
}
/**
* Generates a random float between the specified minimum and maximum values (inclusive).
*
* @param min the minimum value
* @param max the maximum value
* @return a random float between min and max (inclusive)
*/
public static float generateRandomFloat(float min, float max) {
return min + (max - min) * getInstance().random.nextFloat();
}
/**
* Generates a random boolean value.
*
* @return a random boolean value
*/
public static boolean generateRandomBoolean() {
return getInstance().random.nextBoolean();
}
/**
* Selects a random element from the specified array.
*
* @param array the array to select a random element from
* @param <T> the type of the elements in the array
* @return a random element from the array
*/
public static <T> T getRandomElementFromArray(T[] array) {
int index = getInstance().random.nextInt(array.length);
return array[index];
}
/**
* Generates a random value based on a triangular distribution.
*
* @param mode the mode (peak) of the distribution
* @param deviation the deviation from the mode
* @return a random value based on a triangular distribution
*/
public static double triangle(double mode, double deviation) {
return mode + deviation * (generateRandomDouble(0,1) - generateRandomDouble(0,1));
}
/**
* Selects a specified number of random elements from the given array.
*
* @param array the array to select random elements from
* @param count the number of random elements to select
* @param <T> the type of the elements in the array
* @return an array containing the selected random elements
* @throws IllegalArgumentException if the count is greater than the array length
*/
public static <T> T[] getRandomElementsFromArray(T[] array, int count) {
if (count > array.length) {
throw new IllegalArgumentException("Count cannot be greater than array length");

View File

@@ -17,8 +17,27 @@
package net.momirealms.customfishing.common.util;
/**
* A generic class representing a tuple with three values.
* This class provides methods for creating and accessing tuples with three values.
*
* @param <L> the type of the left value
* @param <M> the type of the middle value
* @param <R> the type of the right value
*/
public record Tuple<L, M, R>(L left, M mid, R right) {
/**
* Creates a new {@link Tuple} with the specified left, middle, and right values.
*
* @param left the left value
* @param mid the middle value
* @param right the right value
* @param <L> the type of the left value
* @param <M> the type of the middle value
* @param <R> the type of the right value
* @return a new {@link Tuple} with the specified values
*/
public static <L, M, R> Tuple<L, M, R> of(final L left, final M mid, final R right) {
return new Tuple<>(left, mid, right);
}

View File

@@ -20,8 +20,18 @@ package net.momirealms.customfishing.common.util;
import java.math.BigInteger;
import java.util.UUID;
/**
* Utility class for handling operations related to UUIDs.
* Provides methods for converting between different UUID formats and representations.
*/
public class UUIDUtils {
/**
* Converts a UUID string without dashes to a {@link UUID} object.
*
* @param id the UUID string without dashes
* @return the corresponding {@link UUID} object, or null if the input string is null
*/
public static UUID fromUnDashedUUID(String id) {
return id == null ? null : new UUID(
new BigInteger(id.substring(0, 16), 16).longValue(),
@@ -29,20 +39,48 @@ public class UUIDUtils {
);
}
/**
* Converts a {@link UUID} object to a string without dashes.
*
* @param uuid the {@link UUID} object
* @return the UUID string without dashes
*/
public static String toUnDashedUUID(UUID uuid) {
return uuid.toString().replace("-", "");
}
/**
* Converts an integer array to a {@link UUID} object.
* The array must contain exactly four integers.
*
* @param array the integer array
* @return the corresponding {@link UUID} object
* @throws IllegalArgumentException if the array length is not four
*/
public static UUID uuidFromIntArray(int[] array) {
return new UUID((long)array[0] << 32 | (long)array[1] & 4294967295L, (long)array[2] << 32 | (long)array[3] & 4294967295L);
}
/**
* Converts a {@link UUID} object to an integer array.
* The resulting array contains exactly four integers.
*
* @param uuid the {@link UUID} object
* @return the integer array representation of the UUID
*/
public static int[] uuidToIntArray(UUID uuid) {
long l = uuid.getMostSignificantBits();
long m = uuid.getLeastSignificantBits();
return leastMostToIntArray(l, m);
}
/**
* Converts the most significant and least significant bits of a UUID to an integer array.
*
* @param uuidMost the most significant bits of the UUID
* @param uuidLeast the least significant bits of the UUID
* @return the integer array representation of the UUID bits
*/
private static int[] leastMostToIntArray(long uuidMost, long uuidLeast) {
return new int[]{(int)(uuidMost >> 32), (int)uuidMost, (int)(uuidLeast >> 32), (int)uuidLeast};
}

View File

@@ -19,7 +19,6 @@ package net.momirealms.customfishing.bukkit;
import net.momirealms.customfishing.api.BukkitCustomFishingPlugin;
import net.momirealms.customfishing.api.event.CustomFishingReloadEvent;
import net.momirealms.customfishing.api.event.FishingLootSpawnEvent;
import net.momirealms.customfishing.api.mechanic.MechanicType;
import net.momirealms.customfishing.api.mechanic.config.ConfigManager;
import net.momirealms.customfishing.api.mechanic.misc.cooldown.CoolDownManager;
@@ -58,7 +57,6 @@ 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.entity.Item;
import org.bukkit.plugin.Plugin;
import org.bukkit.plugin.java.JavaPlugin;

View File

@@ -31,12 +31,9 @@ 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.item.damage.DurabilityItem;
import net.momirealms.customfishing.bukkit.item.damage.VanillaDurabilityItem;
import net.momirealms.customfishing.bukkit.util.LocationUtils;
import net.momirealms.customfishing.bukkit.util.PlayerUtils;
import net.momirealms.customfishing.common.helper.AdventureHelper;
import net.momirealms.customfishing.common.item.Item;
import net.momirealms.customfishing.common.locale.MessageConstants;
import net.momirealms.customfishing.common.locale.TranslationManager;
import net.momirealms.customfishing.common.plugin.scheduler.SchedulerTask;
@@ -437,9 +434,9 @@ public class BukkitActionManager implements ActionManager<Player> {
if (itemStack.getItemMeta() == null)
return;
if (amount > 0) {
plugin.getItemManager().increaseDurability(context.getHolder(), itemStack, amount);
plugin.getItemManager().decreaseDamage(context.getHolder(), itemStack, amount);
} else {
plugin.getItemManager().decreaseDurability(context.getHolder(), itemStack, -amount, true);
plugin.getItemManager().increaseDamage(context.getHolder(), itemStack, -amount, true);
}
};
} else {

View File

@@ -258,11 +258,11 @@ public class BukkitFishingManager implements FishingManager, Listener {
if (player.getGameMode() != GameMode.CREATIVE) {
ItemStack itemStack = player.getInventory().getItemInMainHand();
if (itemStack.getType() != Material.FISHING_ROD) itemStack = player.getInventory().getItemInOffHand();
if (plugin.getItemManager().hasCustomDurability(itemStack)) {
if (plugin.getItemManager().hasCustomMaxDamage(itemStack)) {
event.getHook().pullHookedEntity();
event.getHook().remove();
event.setCancelled(true);
plugin.getItemManager().decreaseDurability(player, itemStack, event.getCaught() instanceof Item ? 3 : 5, true);
plugin.getItemManager().increaseDamage(player, itemStack, event.getCaught() instanceof Item ? 3 : 5, true);
}
}
}
@@ -322,10 +322,10 @@ public class BukkitFishingManager implements FishingManager, Listener {
ItemStack itemStack = player.getInventory().getItemInMainHand();
if (itemStack.getType() != Material.FISHING_ROD) itemStack = player.getInventory().getItemInOffHand();
if (itemStack.getType() == Material.FISHING_ROD) {
if (plugin.getItemManager().hasCustomDurability(itemStack)) {
if (plugin.getItemManager().hasCustomMaxDamage(itemStack)) {
event.setCancelled(true);
event.getHook().remove();
plugin.getItemManager().decreaseDurability(player, itemStack, 2, true);
plugin.getItemManager().increaseDamage(player, itemStack, 2, true);
}
}
}

View File

@@ -129,7 +129,7 @@ public class BukkitHookManager implements HookManager, Listener {
} else {
itemStack = plugin.getItemManager().buildInternal(Context.player(player), id);
}
plugin.getItemManager().setDurability(player, itemStack, damage);
plugin.getItemManager().setDamage(player, itemStack, damage);
wrapped.removeTag("CustomFishing", "hook_id");
wrapped.removeTag("CustomFishing", "hook_stack");
@@ -185,7 +185,7 @@ public class BukkitHookManager implements HookManager, Listener {
previousItemStack = plugin.getItemManager().buildInternal(Context.player(player), previousHookID);
}
if (previousItemStack != null) {
plugin.getItemManager().setDurability(player, previousItemStack, previousHookDamage);
plugin.getItemManager().setDamage(player, previousItemStack, previousHookDamage);
if (cursor.getAmount() == 0) {
event.setCursor(previousItemStack);
} else {

View File

@@ -248,7 +248,7 @@ public class BukkitItemManager implements ItemManager, Listener {
}
@Override
public boolean hasCustomDurability(ItemStack itemStack) {
public boolean hasCustomMaxDamage(ItemStack itemStack) {
if (itemStack == null || itemStack.getType() == Material.AIR || itemStack.getAmount() == 0)
return false;
Item<ItemStack> wrapped = factory.wrap(itemStack);
@@ -256,7 +256,19 @@ public class BukkitItemManager implements ItemManager, Listener {
}
@Override
public void increaseDurability(Player player, ItemStack itemStack, int amount) {
public int getMaxDamage(ItemStack itemStack) {
if (itemStack == null || itemStack.getType() == Material.AIR || itemStack.getAmount() == 0)
return 0;
Item<ItemStack> wrapped = factory.wrap(itemStack);
if (wrapped.hasTag("CustomFishing", "max_dur")) {
return new CustomDurabilityItem(wrapped).maxDamage();
} else {
return new VanillaDurabilityItem(wrapped).maxDamage();
}
}
@Override
public void decreaseDamage(Player player, ItemStack itemStack, int amount) {
if (itemStack == null || itemStack.getType() == Material.AIR || itemStack.getAmount() == 0)
return;
Item<ItemStack> wrapped = factory.wrap(itemStack);
@@ -271,7 +283,7 @@ public class BukkitItemManager implements ItemManager, Listener {
}
@Override
public void decreaseDurability(Player player, ItemStack itemStack, int amount, boolean incorrectUsage) {
public void increaseDamage(Player player, ItemStack itemStack, int amount, boolean incorrectUsage) {
if (itemStack == null || itemStack.getType() == Material.AIR || itemStack.getAmount() == 0)
return;
if (!incorrectUsage) {
@@ -307,7 +319,7 @@ public class BukkitItemManager implements ItemManager, Listener {
}
@Override
public void setDurability(Player player, ItemStack itemStack, int damage) {
public void setDamage(Player player, ItemStack itemStack, int damage) {
if (itemStack == null || itemStack.getType() == Material.AIR || itemStack.getAmount() == 0)
return;
Item<ItemStack> wrapped = factory.wrap(itemStack);
@@ -335,7 +347,7 @@ public class BukkitItemManager implements ItemManager, Listener {
@EventHandler (ignoreCancelled = true)
public void onMending(PlayerItemMendEvent event) {
ItemStack itemStack = event.getItem();
if (!hasCustomDurability(itemStack)) {
if (!hasCustomMaxDamage(itemStack)) {
return;
}
event.setCancelled(true);
@@ -343,7 +355,7 @@ public class BukkitItemManager implements ItemManager, Listener {
if (wrapped.unbreakable())
return;
DurabilityItem wrappedDurability = wrapDurabilityItem(wrapped);
setDurability(event.getPlayer(), itemStack, Math.max(wrappedDurability.damage() - event.getRepairAmount(), 0));
setDamage(event.getPlayer(), itemStack, Math.max(wrappedDurability.damage() - event.getRepairAmount(), 0));
}
@EventHandler (ignoreCancelled = true)
@@ -353,7 +365,7 @@ public class BukkitItemManager implements ItemManager, Listener {
ItemStack second = anvil.getSecondItem();
if (first != null && second != null
&& first.getType() == Material.FISHING_ROD && second.getType() == Material.FISHING_ROD && event.getResult() != null
&& hasCustomDurability(first)) {
&& hasCustomMaxDamage(first)) {
Item<ItemStack> wrapped1 = factory.wrap(anvil.getResult());
DurabilityItem wrappedDurability1 = wrapDurabilityItem(wrapped1);

View File

@@ -45,9 +45,9 @@ guava_version=33.2.0-jre
lz4_version=1.8.0
# Proxy settings
systemProp.socks.proxyHost=127.0.0.1
systemProp.socks.proxyPort=7890
systemProp.http.proxyHost=127.0.0.1
systemProp.http.proxyPort=7890
systemProp.https.proxyHost=127.0.0.1
systemProp.https.proxyPort=7890
#systemProp.socks.proxyHost=127.0.0.1
#systemProp.socks.proxyPort=7890
#systemProp.http.proxyHost=127.0.0.1
#systemProp.http.proxyPort=7890
#systemProp.https.proxyHost=127.0.0.1
#systemProp.https.proxyPort=7890