9
0
mirror of https://github.com/Xiao-MoMi/Custom-Fishing.git synced 2025-12-23 00:49:24 +00:00

checkpoint - 1

This commit is contained in:
XiaoMoMi
2024-05-18 03:16:02 +08:00
parent f19d0e05c5
commit 5166989a48
397 changed files with 6706 additions and 6383 deletions

View File

@@ -9,7 +9,7 @@
<img src="https://img.shields.io/badge/docs-gitbook-brightgreen" alt="Gitbook"/>
</a>
CustomFishing is a Paper plugin that provides minigames and a powerful condition & action library for fishing.
CustomFishing is a Paper plugin that provides minigames and a powerful playerContext & action library for fishing.
With the new concept of weight system, CustomFishing brings unlimited customization possibilities and best performance.
## How to build

View File

@@ -1,11 +1,44 @@
dependencies {
compileOnly("io.papermc.paper:paper-api:1.20.4-R0.1-SNAPSHOT")
compileOnly("com.comphenix.protocol:ProtocolLib:5.1.0")
compileOnly("de.tr7zw:item-nbt-api:2.12.4")
plugins {
id("io.github.goooler.shadow") version "8.1.7"
}
repositories {
maven("https://repo.codemc.io/repository/maven-public/")
maven("https://jitpack.io/")
}
dependencies {
implementation(project(":common"))
implementation("dev.dejvokep:boosted-yaml:${rootProject.properties["boosted_yaml_version"]}")
implementation("net.kyori:adventure-api:${rootProject.properties["adventure_bundle_version"]}") {
exclude(module = "adventure-bom")
exclude(module = "checker-qual")
exclude(module = "annotations")
}
implementation("com.saicone.rtag:rtag:1.5.3")
implementation("com.saicone.rtag:rtag-item:1.5.3")
compileOnly("dev.folia:folia-api:${rootProject.properties["paper_version"]}-R0.1-SNAPSHOT")
compileOnly("com.google.code.gson:gson:${rootProject.properties["gson_version"]}")
}
java {
sourceCompatibility = JavaVersion.VERSION_17
targetCompatibility = JavaVersion.VERSION_17
toolchain {
languageVersion = JavaLanguageVersion.of(17)
}
}
tasks.withType<JavaCompile> {
options.encoding = "UTF-8"
options.release.set(17)
dependsOn(tasks.clean)
}
tasks {
shadowJar {
relocate ("de.tr7zw.changeme", "net.momirealms.customfishing.libraries")
relocate("net.kyori", "net.momirealms.customfishing.libraries")
relocate("dev.dejvokep", "net.momirealms.customfishing.libraries")
}
}

View File

@@ -17,17 +17,36 @@
package net.momirealms.customfishing.api;
import net.momirealms.customfishing.api.integration.IntegrationManager;
import net.momirealms.customfishing.api.manager.*;
import net.momirealms.customfishing.api.scheduler.Scheduler;
import net.momirealms.customfishing.api.mechanic.action.ActionManager;
import net.momirealms.customfishing.api.mechanic.bag.BagManager;
import net.momirealms.customfishing.api.mechanic.block.BlockManager;
import net.momirealms.customfishing.api.mechanic.competition.CompetitionManager;
import net.momirealms.customfishing.api.mechanic.effect.EffectManager;
import net.momirealms.customfishing.api.mechanic.entity.EntityManager;
import net.momirealms.customfishing.api.mechanic.fishing.FishingManager;
import net.momirealms.customfishing.api.mechanic.game.GameManager;
import net.momirealms.customfishing.api.mechanic.hook.HookManager;
import net.momirealms.customfishing.api.mechanic.item.ItemManager;
import net.momirealms.customfishing.api.mechanic.loot.LootManager;
import net.momirealms.customfishing.api.mechanic.market.MarketManager;
import net.momirealms.customfishing.api.mechanic.requirement.RequirementManager;
import net.momirealms.customfishing.api.mechanic.statistic.StatisticsManager;
import net.momirealms.customfishing.api.mechanic.totem.TotemManager;
import net.momirealms.customfishing.common.command.CustomFishingCommandManager;
import net.momirealms.customfishing.common.plugin.CustomFishingPlugin;
import net.momirealms.customfishing.common.plugin.scheduler.SchedulerAdapter;
import org.bukkit.Location;
import org.bukkit.command.CommandSender;
import org.bukkit.configuration.file.YamlConfiguration;
import org.bukkit.plugin.java.JavaPlugin;
import org.jetbrains.annotations.NotNull;
public abstract class CustomFishingPlugin extends JavaPlugin {
public abstract class BukkitCustomFishingPlugin extends JavaPlugin implements CustomFishingPlugin {
protected boolean initialized;
protected Scheduler scheduler;
protected CommandManager commandManager;
protected SchedulerAdapter<Location> scheduler;
protected CustomFishingCommandManager<CommandSender> commandManager;
protected VersionManager versionManager;
protected ItemManager itemManager;
protected RequirementManager requirementManager;
@@ -37,7 +56,6 @@ public abstract class CustomFishingPlugin extends JavaPlugin {
protected EffectManager effectManager;
protected EntityManager entityManager;
protected BlockManager blockManager;
protected AdventureManager adventure;
protected BagManager bagManager;
protected GameManager gameManager;
protected MarketManager marketManager;
@@ -49,29 +67,20 @@ public abstract class CustomFishingPlugin extends JavaPlugin {
protected TotemManager totemManager;
protected HookManager hookManager;
private static CustomFishingPlugin instance;
private static BukkitCustomFishingPlugin instance;
public CustomFishingPlugin() {
public BukkitCustomFishingPlugin() {
instance = this;
}
public static CustomFishingPlugin get() {
public static BukkitCustomFishingPlugin get() {
return getInstance();
}
@NotNull
public static CustomFishingPlugin getInstance() {
public static BukkitCustomFishingPlugin getInstance() {
return instance;
}
public Scheduler getScheduler() {
return scheduler;
}
public CommandManager getCommandManager() {
return commandManager;
}
public VersionManager getVersionManager() {
return versionManager;
}

View File

@@ -1,46 +0,0 @@
/*
* 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.common;
public record Key(String namespace, String value) {
public static Key of(String namespace, String value) {
return new Key(namespace, value);
}
@Override
public int hashCode() {
int result = this.namespace.hashCode();
result = (31 * result) + this.value.hashCode();
return result;
}
@Override
public boolean equals(Object obj) {
if (obj == null) {
return false;
}
if (!(obj instanceof Key key)) return false;
return this.namespace.equals(key.namespace()) && this.value.equals(key.value());
}
@Override
public String toString() {
return namespace + ":" + value;
}
}

View File

@@ -1,33 +0,0 @@
/*
* 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.data;
import java.util.Optional;
import java.util.UUID;
import java.util.concurrent.CompletableFuture;
public interface LegacyDataStorageInterface extends DataStorageInterface {
/**
* Retrieve legacy player data from the SQL database.
*
* @param uuid The UUID of the player.
* @return A CompletableFuture containing the optional legacy player data.
*/
CompletableFuture<Optional<PlayerData>> getLegacyPlayerData(UUID uuid);
}

View File

@@ -17,7 +17,7 @@
package net.momirealms.customfishing.api.event;
import net.momirealms.customfishing.api.CustomFishingPlugin;
import net.momirealms.customfishing.api.BukkitCustomFishingPlugin;
import org.bukkit.event.Event;
import org.bukkit.event.HandlerList;
import org.jetbrains.annotations.NotNull;
@@ -25,9 +25,9 @@ import org.jetbrains.annotations.NotNull;
public class CustomFishingReloadEvent extends Event {
private static final HandlerList handlerList = new HandlerList();
private final CustomFishingPlugin plugin;
private final BukkitCustomFishingPlugin plugin;
public CustomFishingReloadEvent(CustomFishingPlugin plugin) {
public CustomFishingReloadEvent(BukkitCustomFishingPlugin plugin) {
this.plugin = plugin;
}
@@ -41,7 +41,7 @@ public class CustomFishingReloadEvent extends Event {
return getHandlerList();
}
public CustomFishingPlugin getPluginInstance() {
public BukkitCustomFishingPlugin getPluginInstance() {
return plugin;
}
}

View File

@@ -33,7 +33,7 @@ public class FishHookLandEvent extends PlayerEvent {
private final Target target;
private final FishHook fishHook;
private final Effect effect;
private boolean isFirst;
private final boolean isFirst;
/**
* Constructs a new FishHookLandEvent.

View File

@@ -17,7 +17,6 @@
package net.momirealms.customfishing.api.event;
import net.momirealms.customfishing.api.mechanic.condition.FishingPreparation;
import net.momirealms.customfishing.api.mechanic.effect.Effect;
import org.bukkit.event.Cancellable;
import org.bukkit.event.HandlerList;

View File

@@ -17,19 +17,19 @@
package net.momirealms.customfishing.api.integration;
import net.kyori.adventure.key.Key;
import net.momirealms.customfishing.common.util.Pair;
import org.bukkit.inventory.ItemStack;
import java.util.List;
public interface EnchantmentInterface {
public interface EnchantmentProvider extends ExternalProvider {
/**
* Get a list of enchantments with level for itemStack
* format: plugin:enchantment:level
* example: minecraft:sharpness:5
*
* @param itemStack itemStack
* @return enchantment list
*/
List<String> getEnchants(ItemStack itemStack);
List<Pair<Key, Short>> getEnchants(ItemStack itemStack);
}

View File

@@ -0,0 +1,43 @@
/*
* 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.integration;
import org.bukkit.Location;
import org.bukkit.entity.Entity;
import org.jetbrains.annotations.NotNull;
import java.util.HashMap;
import java.util.Map;
public interface EntityProvider extends ExternalProvider {
/**
* Spawns an entity at the specified location with the given properties.
*
* @param location The location where the entity will be spawned.
* @param id The identifier of the entity to be spawned.
* @param propertyMap A map containing additional properties for the entity.
* @return The spawned entity.
*/
@NotNull
Entity spawn(@NotNull Location location, @NotNull String id, @NotNull Map<String, Object> propertyMap);
default Entity spawn(@NotNull Location location, @NotNull String id) {
return spawn(location, id, new HashMap<>());
}
}

View File

@@ -0,0 +1,11 @@
package net.momirealms.customfishing.api.integration;
public interface ExternalProvider {
/**
* Gets the identification of the external provider.
*
* @return The identification string of the external provider.
*/
String identifier();
}

View File

@@ -0,0 +1,107 @@
/*
* 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.integration;
import org.jetbrains.annotations.Nullable;
/**
* Interface for managing integration providers in the custom fishing API.
* This allows for the registration and retrieval of various types of providers
* such as Leveler, Enchantment, and Season providers.
*/
public interface IntegrationManager {
/**
* Registers a LevelerProvider.
*
* @param level the LevelerProvider to register
* @return true if registration is successful, false otherwise
*/
boolean registerLevelerProvider(LevelerProvider level);
/**
* Unregisters a LevelerProvider by its ID.
*
* @param id the ID of the LevelerProvider to unregister
* @return true if unregistration is successful, false otherwise
*/
boolean unregisterLevelerProvider(String id);
/**
* Registers an EnchantmentProvider.
*
* @param enchantment the EnchantmentProvider to register
* @return true if registration is successful, false otherwise
*/
boolean registerEnchantmentProvider(EnchantmentProvider enchantment);
/**
* Unregisters an EnchantmentProvider by its ID.
*
* @param id the ID of the EnchantmentProvider to unregister
* @return true if unregistration is successful, false otherwise
*/
boolean unregisterEnchantmentProvider(String id);
/**
* Registers a SeasonProvider.
*
* @param season the SeasonProvider to register
* @return true if registration is successful, false otherwise
*/
boolean registerSeasonProvider(SeasonProvider season);
/**
* Unregisters a SeasonProvider by its ID.
*
* @param id the ID of the SeasonProvider to unregister
* @return true if unregistration is successful, false otherwise
*/
boolean unregisterSeasonProvider(String id);
boolean registerEntityProvider(EntityProvider entity);
boolean unregisterEntityProvider(String identifier);
/**
* Retrieves a registered LevelerProvider by its ID.
*
* @param id the ID of the LevelerProvider to retrieve
* @return the LevelerProvider if found, or null if not found
*/
@Nullable
LevelerProvider getLevelerProvider(String id);
/**
* Retrieves a registered EnchantmentProvider by its ID.
*
* @param id the ID of the EnchantmentProvider to retrieve
* @return the EnchantmentProvider if found, or null if not found
*/
@Nullable
EnchantmentProvider getEnchantmentProvider(String id);
/**
* Retrieves a registered SeasonProvider by its ID.
*
* @param id the ID of the SeasonProvider to retrieve
* @return the SeasonProvider if found, or null if not found
*/
@Nullable
SeasonProvider getSeasonProvider(String id);
}

View File

@@ -15,13 +15,18 @@
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
package net.momirealms.customfishing.api.mechanic.misc;
package net.momirealms.customfishing.api.integration;
import org.bukkit.entity.Player;
import org.bukkit.inventory.ItemStack;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.util.Map;
public interface ItemProvider extends ExternalProvider {
public interface Value {
@NotNull
ItemStack buildItem(Player player, String id);
double get(Player player, Map<String, String> values);
@Nullable
String itemID(ItemStack itemStack);
}

View File

@@ -19,7 +19,7 @@ package net.momirealms.customfishing.api.integration;
import org.bukkit.entity.Player;
public interface LevelInterface {
public interface LevelerProvider extends ExternalProvider {
/**
* Add exp to a certain skill or job

View File

@@ -17,10 +17,11 @@
package net.momirealms.customfishing.api.integration;
import net.momirealms.customfishing.api.mechanic.misc.season.Season;
import org.bukkit.World;
import org.jetbrains.annotations.NotNull;
public interface SeasonInterface {
public interface SeasonProvider extends ExternalProvider {
/**
* Get a world's season
@@ -28,5 +29,6 @@ public interface SeasonInterface {
* @param world world
* @return spring, summer, autumn, winter or disabled
*/
@NotNull String getSeason(World world);
@NotNull
Season getSeason(World world);
}

View File

@@ -1,139 +0,0 @@
/*
* 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.manager;
import net.kyori.adventure.key.Key;
import net.kyori.adventure.sound.Sound;
import net.kyori.adventure.text.Component;
import org.bukkit.command.CommandSender;
import org.bukkit.entity.Player;
public interface AdventureManager {
/**
* Get component from text
* @param text text
* @return component
*/
Component getComponentFromMiniMessage(String text);
/**
* Send a message to a command sender
* @param sender sender
* @param msg message
*/
void sendMessage(CommandSender sender, String msg);
/**
* Send a message with prefix
*
* @param sender command sender
* @param s message
*/
void sendMessageWithPrefix(CommandSender sender, String s);
/**
* Send a message to console
* @param msg message
*/
void sendConsoleMessage(String msg);
/**
* Send a message to a player
* @param player player
* @param msg message
*/
void sendPlayerMessage(Player player, String msg);
/**
* Send a title to a player
* @param player player
* @param title title
* @param subtitle subtitle
* @param in in (ms)
* @param duration duration (ms)
* @param out out (ms)
*/
void sendTitle(Player player, String title, String subtitle, int in, int duration, int out);
/**
* Send a title to a player
* @param player player
* @param title title
* @param subtitle subtitle
* @param in in (ms)
* @param duration duration (ms)
* @param out out (ms)
*/
void sendTitle(Player player, Component title, Component subtitle, int in, int duration, int out);
/**
* Send actionbar
* @param player player
* @param msg msg
*/
void sendActionbar(Player player, String msg);
/**
* Play a sound to a player
* @param player player
* @param source sound source
* @param key sound key
* @param volume volume
* @param pitch pitch
*/
void sendSound(Player player, Sound.Source source, Key key, float volume, float pitch);
void sendSound(Player player, Sound sound);
/**
* Replace legacy color codes to MiniMessage format
* @param legacy legacy text
* @return MiniMessage format text
*/
String legacyToMiniMessage(String legacy);
/**
* if a char is legacy color code
* @param c char
* @return is legacy color
*/
@SuppressWarnings("BooleanMethodIsAlwaysInverted")
boolean isColorCode(char c);
/**
* Get legacy format text
* @param component component
* @return legacy format text
*/
String componentToLegacy(Component component);
/**
* Get json
* @param component component
* @return json
*/
String componentToJson(Component component);
/**
* Get paper component
* @param component shaded component
* @return paper component
*/
Object shadedComponentToOriginalComponent(Component component);
}

View File

@@ -1,101 +0,0 @@
/*
* 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.manager;
import net.momirealms.customfishing.api.integration.EnchantmentInterface;
import net.momirealms.customfishing.api.integration.LevelInterface;
import net.momirealms.customfishing.api.integration.SeasonInterface;
import org.bukkit.inventory.ItemStack;
import org.jetbrains.annotations.Nullable;
import java.util.List;
public interface IntegrationManager {
/**
* Registers a level plugin with the specified name.
*
* @param plugin The name of the level plugin.
* @param level The implementation of the LevelInterface.
* @return true if the registration was successful, false if the plugin name is already registered.
*/
boolean registerLevelPlugin(String plugin, LevelInterface level);
/**
* Unregisters a level plugin with the specified name.
*
* @param plugin The name of the level plugin to unregister.
* @return true if the unregistration was successful, false if the plugin name is not found.
*/
boolean unregisterLevelPlugin(String plugin);
/**
* Registers an enchantment provided by a plugin.
*
* @param plugin The name of the plugin providing the enchantment.
* @param enchantment The enchantment to register.
* @return true if the registration was successful, false if the enchantment name is already in use.
*/
boolean registerEnchantment(String plugin, EnchantmentInterface enchantment);
/**
* Unregisters an enchantment provided by a plugin.
*
* @param plugin The name of the plugin providing the enchantment.
* @return true if the enchantment was successfully unregistered, false if the enchantment was not found.
*/
boolean unregisterEnchantment(String plugin);
/**
* Get the LevelInterface provided by a plugin.
*
* @param plugin The name of the plugin providing the LevelInterface.
* @return The LevelInterface provided by the specified plugin, or null if the plugin is not registered.
*/
@Nullable LevelInterface getLevelPlugin(String plugin);
/**
* Get an enchantment plugin by its plugin name.
*
* @param plugin The name of the enchantment plugin.
* @return The enchantment plugin interface, or null if not found.
*/
@Nullable EnchantmentInterface getEnchantmentPlugin(String plugin);
/**
* Get a list of enchantment keys with level applied to the given ItemStack.
*
* @param itemStack The ItemStack to check for enchantments.
* @return A list of enchantment names applied to the ItemStack.
*/
List<String> getEnchantments(ItemStack itemStack);
/**
* Get the current season interface, if available.
*
* @return The current season interface, or null if not available.
*/
@Nullable SeasonInterface getSeasonInterface();
/**
* Set the current season interface.
*
* @param season The season interface to set.
*/
void setSeasonInterface(SeasonInterface season);
}

View File

@@ -1,207 +0,0 @@
/*
* 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.manager;
import net.momirealms.customfishing.api.common.Key;
import net.momirealms.customfishing.api.mechanic.condition.Condition;
import net.momirealms.customfishing.api.mechanic.item.BuildableItem;
import net.momirealms.customfishing.api.mechanic.item.ItemBuilder;
import net.momirealms.customfishing.api.mechanic.item.ItemLibrary;
import org.bukkit.Location;
import org.bukkit.configuration.ConfigurationSection;
import org.bukkit.entity.Player;
import org.bukkit.inventory.ItemStack;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.util.Map;
import java.util.Set;
public interface ItemManager {
/**
* Build an ItemStack with a specified namespace and value for a player.
*
* @param player The player for whom the ItemStack is being built.
* @param namespace The namespace of the item.
* @param value The value of the item.
* @return The constructed ItemStack.
*/
@Nullable
ItemStack build(Player player, String namespace, String value);
/**
* Build an ItemStack with a specified namespace and value, replacing placeholders,
* for a player.
*
* @param player The player for whom the ItemStack is being built.
* @param namespace The namespace of the item.
* @param value The value of the item.
* @param placeholders The placeholders to replace in the item's attributes.
* @return The constructed ItemStack, or null if the item doesn't exist.
*/
@Nullable
ItemStack build(Player player, String namespace, String value, Map<String, String> placeholders);
/**
* Build an ItemStack using an ItemBuilder for a player.
*
* @param player The player for whom the ItemStack is being built.
* @param builder The ItemBuilder used to construct the ItemStack.
* @return The constructed ItemStack.
*/
@NotNull ItemStack build(Player player, ItemBuilder builder);
/**
* Build an ItemStack using the provided ItemBuilder, player, and placeholders.
*
* @param player The player for whom the item is being built.
* @param builder The ItemBuilder that defines the item's properties.
* @param placeholders A map of placeholders and their corresponding values to be applied to the item.
* @return The constructed ItemStack.
*/
@NotNull ItemStack build(Player player, ItemBuilder builder, Map<String, String> placeholders);
/**
* Build an ItemStack for a player based on the provided item ID.
*
* @param player The player for whom the ItemStack is being built.
* @param id The item ID, which include an identification (e.g., "Oraxen:id").
* @return The constructed ItemStack or null if the ID is not valid.
*/
@Nullable ItemStack buildAnyPluginItemByID(Player player, String id);
/**
* Get the item ID associated with the given ItemStack, if available.
*
* @param itemStack The ItemStack to retrieve the item ID from.
* @return The item ID without type or null if not found or if the ItemStack is null or empty.
*/
@Nullable String getCustomFishingItemID(ItemStack itemStack);
/**
* Get the item ID associated with the given ItemStack by checking all available item libraries.
* The detection order is determined by the configuration.
*
* @param itemStack The ItemStack to retrieve the item ID from.
* @return The item ID or "AIR" if not found or if the ItemStack is null or empty.
*/
@NotNull String getAnyPluginItemID(ItemStack itemStack);
/**
* Create a ItemBuilder instance for an item configuration section
* <p>
* xxx_item: <- section
* material: xxx
* custom-model-data: xxx
*
* @param section The configuration section containing item settings.
* @param type The type of the item (e.g., "rod", "bait").
* @param id The unique identifier for the item.
* @return A CFBuilder instance representing the configured item, or null if the section is null.
*/
@Nullable ItemBuilder getItemBuilder(ConfigurationSection section, String type, String id);
/**
* Get a set of all item keys in the CustomFishing plugin.
*
* @return A set of item keys.
*/
Set<Key> getAllItemsKey();
/**
* Retrieve a BuildableItem by its namespace and value.
*
* @param namespace The namespace of the BuildableItem.
* @param value The value of the BuildableItem.
* @return The BuildableItem with the specified namespace and value, or null if not found.
*/
@Nullable
BuildableItem getBuildableItem(String namespace, String value);
/**
* Get an itemStack's appearance (material + custom model data)
*
* @param player player
* @param material id
* @return appearance
*/
ItemStack getItemStackAppearance(Player player, String material);
/**
* Register an item library.
*
* @param itemLibrary The item library to register.
* @return True if the item library was successfully registered, false if it already exists.
*/
boolean registerItemLibrary(ItemLibrary itemLibrary);
/**
* Unregister an item library.
*
* @param identification The item library to unregister.
* @return True if the item library was successfully unregistered, false if it doesn't exist.
*/
boolean unRegisterItemLibrary(String identification);
/**
* Drops an item based on the provided loot, applying velocity from a hook location to a player location.
*
* @param player The player for whom the item is intended.
* @param hookLocation The location where the item will initially drop.
* @param playerLocation The target location towards which the item's velocity is applied.
* @param itemStack The loot to drop
* @param condition A map of placeholders for item customization.
*/
void dropItem(Player player, Location hookLocation, Location playerLocation, ItemStack itemStack, Condition condition);
/**
* Checks if the provided ItemStack is a custom fishing item
*
* @param itemStack The ItemStack to check.
* @return True if the ItemStack is a custom fishing item; otherwise, false.
*/
boolean isCustomFishingItem(ItemStack itemStack);
/**
* Decreases the durability of an ItemStack by a specified amount and optionally updates its lore.
*
* @param itemStack The ItemStack to modify.
* @param amount The amount by which to decrease the durability.
* @param updateLore Whether to update the lore of the ItemStack.
*/
void decreaseDurability(Player player, ItemStack itemStack, int amount, boolean updateLore);
/**
* Increases the durability of an ItemStack by a specified amount and optionally updates its lore.
*
* @param itemStack The ItemStack to modify.
* @param amount The amount by which to increase the durability.
* @param updateLore Whether to update the lore of the ItemStack.
*/
void increaseDurability(ItemStack itemStack, int amount, boolean updateLore);
/**
* Sets the durability of an ItemStack to a specific amount and optionally updates its lore.
*
* @param itemStack The ItemStack to modify.
* @param amount The new durability value.
* @param updateLore Whether to update the lore of the ItemStack.
*/
void setDurability(ItemStack itemStack, int amount, boolean updateLore);
}

View File

@@ -23,14 +23,16 @@ public interface VersionManager {
boolean isVersionNewerThan1_19();
boolean isVersionNewerThan1_19_R3();
boolean isVersionNewerThan1_19_4();
boolean isVersionNewerThan1_19_R2();
boolean isVersionNewerThan1_19_3();
CompletableFuture<Boolean> checkUpdate();
boolean isVersionNewerThan1_20();
boolean isNewerThan1_20_5();
boolean isSpigot();
public boolean hasRegionScheduler();

View File

@@ -17,10 +17,9 @@
package net.momirealms.customfishing.api.mechanic;
import net.momirealms.customfishing.api.CustomFishingPlugin;
import net.momirealms.customfishing.api.BukkitCustomFishingPlugin;
import net.momirealms.customfishing.api.mechanic.action.Action;
import net.momirealms.customfishing.api.mechanic.action.ActionTrigger;
import net.momirealms.customfishing.api.mechanic.condition.Condition;
import net.momirealms.customfishing.api.mechanic.effect.EffectModifier;
import org.bukkit.configuration.ConfigurationSection;
@@ -47,7 +46,7 @@ public class GlobalSettings {
if (section == null) return;
for (Map.Entry<String, Object> entry : section.getValues(false).entrySet()) {
if (entry.getValue() instanceof ConfigurationSection inner) {
HashMap<ActionTrigger, Action[]> map = CustomFishingPlugin.get().getActionManager().getActionMap(inner);
HashMap<ActionTrigger, Action[]> map = BukkitCustomFishingPlugin.get().getActionManager().getActionMap(inner);
switch (entry.getKey()) {
case "loot" -> lootActions = map;
case "rod" -> rodActions = map;
@@ -79,13 +78,13 @@ public class GlobalSettings {
* Triggers loot-related actions for a specific trigger and condition.
*
* @param trigger The trigger to activate actions for.
* @param condition The condition that triggered the actions.
* @param playerContext The condition that triggered the actions.
*/
public static void triggerLootActions(ActionTrigger trigger, Condition condition) {
public static void triggerLootActions(ActionTrigger trigger, PlayerContext playerContext) {
Action[] actions = lootActions.get(trigger);
if (actions != null) {
for (Action action : actions) {
action.trigger(condition);
action.trigger(playerContext);
}
}
}
@@ -94,13 +93,13 @@ public class GlobalSettings {
* Triggers rod-related actions for a specific trigger and condition.
*
* @param trigger The trigger to activate actions for.
* @param condition The condition that triggered the actions.
* @param playerContext The condition that triggered the actions.
*/
public static void triggerRodActions(ActionTrigger trigger, Condition condition) {
public static void triggerRodActions(ActionTrigger trigger, PlayerContext playerContext) {
Action[] actions = rodActions.get(trigger);
if (actions != null) {
for (Action action : actions) {
action.trigger(condition);
action.trigger(playerContext);
}
}
}
@@ -109,13 +108,13 @@ public class GlobalSettings {
* Triggers bait-related actions for a specific trigger and condition.
*
* @param trigger The trigger to activate actions for.
* @param condition The condition that triggered the actions.
* @param playerContext The condition that triggered the actions.
*/
public static void triggerBaitActions(ActionTrigger trigger, Condition condition) {
public static void triggerBaitActions(ActionTrigger trigger, PlayerContext playerContext) {
Action[] actions = baitActions.get(trigger);
if (actions != null) {
for (Action action : actions) {
action.trigger(condition);
action.trigger(playerContext);
}
}
}
@@ -124,13 +123,13 @@ public class GlobalSettings {
* Triggers hook-related actions for a specific trigger and condition.
*
* @param trigger The trigger to activate actions for.
* @param condition The condition that triggered the actions.
* @param playerContext The condition that triggered the actions.
*/
public static void triggerHookActions(ActionTrigger trigger, Condition condition) {
public static void triggerHookActions(ActionTrigger trigger, PlayerContext playerContext) {
Action[] actions = hookActions.get(trigger);
if (actions != null) {
for (Action action : actions) {
action.trigger(condition);
action.trigger(playerContext);
}
}
}

View File

@@ -17,7 +17,6 @@
package net.momirealms.customfishing.api.mechanic;
import net.momirealms.customfishing.api.mechanic.condition.FishingPreparation;
import net.momirealms.customfishing.api.mechanic.effect.Effect;
import net.momirealms.customfishing.api.mechanic.loot.Loot;

View File

@@ -17,10 +17,14 @@
package net.momirealms.customfishing.api.mechanic.action;
import net.momirealms.customfishing.api.mechanic.condition.Condition;
import net.momirealms.customfishing.api.mechanic.context.Context;
public interface Action {
void trigger(Condition condition);
public interface Action<T> {
/**
* Triggers the action based on the provided condition.
*
* @param context the context
*/
void trigger(Context<T> context);
}

View File

@@ -17,13 +17,39 @@
package net.momirealms.customfishing.api.mechanic.action;
public abstract class ActionExpansion {
/**
* Abstract class representing an expansion of an action in the custom fishing API.
* This class should be extended to provide specific implementations of actions.
*
* @param <T> the type parameter for the action factory
*/
public abstract class ActionExpansion<T> {
/**
* Retrieves the version of this action expansion.
*
* @return a String representing the version of the action expansion
*/
public abstract String getVersion();
/**
* Retrieves the author of this action expansion.
*
* @return a String representing the author of the action expansion
*/
public abstract String getAuthor();
/**
* Retrieves the type of this action.
*
* @return a String representing the type of action
*/
public abstract String getActionType();
public abstract ActionFactory getActionFactory();
/**
* Retrieves the action factory associated with this action expansion.
*
* @return an ActionFactory of type T that creates instances of the action
*/
public abstract ActionFactory<T> getActionFactory();
}

View File

@@ -17,7 +17,18 @@
package net.momirealms.customfishing.api.mechanic.action;
public interface ActionFactory {
/**
* Interface representing a factory for creating actions.
*
* @param <T> the type of object that the action will operate on
*/
public interface ActionFactory<T> {
Action build(Object args, double chance);
/**
* Constructs an action based on the provided arguments.
*
* @param args the args containing the arguments needed to build the action
* @return the constructed action
*/
Action<T> process(Object args);
}

View File

@@ -15,17 +15,16 @@
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
package net.momirealms.customfishing.api.manager;
package net.momirealms.customfishing.api.mechanic.action;
import net.momirealms.customfishing.api.mechanic.action.Action;
import net.momirealms.customfishing.api.mechanic.action.ActionFactory;
import net.momirealms.customfishing.api.mechanic.action.ActionTrigger;
import net.momirealms.customfishing.api.mechanic.condition.Condition;
import org.bukkit.configuration.ConfigurationSection;
import dev.dejvokep.boostedyaml.block.implementation.Section;
import net.momirealms.customfishing.api.mechanic.context.Context;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.util.HashMap;
public interface ActionManager {
public interface ActionManager<T> {
/**
* Registers an ActionFactory for a specific action type.
@@ -35,7 +34,7 @@ public interface ActionManager {
* @param actionFactory The ActionFactory responsible for creating actions of the specified type.
* @return True if the registration was successful (the action type was not already registered), false otherwise.
*/
boolean registerAction(String type, ActionFactory actionFactory);
boolean registerAction(String type, ActionFactory<T> actionFactory);
/**
* Unregisters an ActionFactory for a specific action type.
@@ -59,7 +58,7 @@ public interface ActionManager {
* @param section The ConfigurationSection containing the action configuration.
* @return An Action object created based on the configuration, or an EmptyAction instance if the action type is invalid.
*/
Action getAction(ConfigurationSection section);
Action<T> getAction(Section section);
/**
* Retrieves a mapping of ActionTriggers to arrays of Actions from a ConfigurationSection.
@@ -74,7 +73,7 @@ public interface ActionManager {
* @param section The ConfigurationSection containing action mappings.
* @return A HashMap where keys are ActionTriggers and values are arrays of Action objects.
*/
HashMap<ActionTrigger, Action[]> getActionMap(ConfigurationSection section);
HashMap<ActionTrigger, Action<T>[]> getActionMap(Section section);
/**
* Retrieves an array of Action objects from a ConfigurationSection.
@@ -89,7 +88,8 @@ public interface ActionManager {
* @param section The ConfigurationSection containing action configurations.
* @return An array of Action objects created based on the configurations in the section.
*/
Action[] getActions(ConfigurationSection section);
@NotNull
Action<T>[] getActions(@NotNull Section section);
/**
* Retrieves an ActionFactory associated with a specific action type.
@@ -97,7 +97,8 @@ public interface ActionManager {
* @param type The action type for which to retrieve the ActionFactory.
* @return The ActionFactory associated with the specified action type, or null if not found.
*/
ActionFactory getActionFactory(String type);
@Nullable
ActionFactory<T> getActionFactory(@NotNull String type);
/**
* Retrieves a mapping of success times to corresponding arrays of actions from a ConfigurationSection.
@@ -111,18 +112,19 @@ public interface ActionManager {
* @param section The ConfigurationSection containing success times actions.
* @return A HashMap where success times associated with actions.
*/
HashMap<Integer, Action[]> getTimesActionMap(ConfigurationSection section);
@NotNull
HashMap<Integer, Action<T>[]> getTimesActionMap(@NotNull Section section);
/**
* Triggers a list of actions with the given condition.
* If the list of actions is not null, each action in the list is triggered.
*
* @param actions The list of actions to trigger.
* @param condition The condition associated with the actions.
* @param context The context associated with the actions.
*/
static void triggerActions(Condition condition, Action... actions) {
static <T> void trigger(@NotNull Context<T> context, @Nullable Action<T>... actions) {
if (actions != null)
for (Action action : actions)
action.trigger(condition);
for (Action<T> action : actions)
action.trigger(context);
}
}

View File

@@ -15,7 +15,7 @@
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
package net.momirealms.customfishing.api.manager;
package net.momirealms.customfishing.api.mechanic.bag;
import net.momirealms.customfishing.api.data.user.OfflineUser;
import net.momirealms.customfishing.api.mechanic.action.Action;
@@ -30,7 +30,7 @@ import java.util.UUID;
public interface BagManager {
/**
* Is bag enabled
* Is bag mechanics enabled
*
* @return enabled or not
*/

View File

@@ -21,5 +21,6 @@ import org.bukkit.block.data.BlockData;
import org.bukkit.entity.Player;
public interface BlockDataModifier {
void apply(Player player, BlockData blockData);
}

View File

@@ -15,11 +15,8 @@
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
package net.momirealms.customfishing.api.manager;
package net.momirealms.customfishing.api.mechanic.block;
import net.momirealms.customfishing.api.mechanic.block.BlockDataModifierBuilder;
import net.momirealms.customfishing.api.mechanic.block.BlockLibrary;
import net.momirealms.customfishing.api.mechanic.block.BlockStateModifierBuilder;
import net.momirealms.customfishing.api.mechanic.loot.Loot;
import org.bukkit.Location;
import org.bukkit.block.Block;

View File

@@ -21,5 +21,6 @@ import org.bukkit.block.BlockState;
import org.bukkit.entity.Player;
public interface BlockStateModifier {
void apply(Player player, BlockState blockState);
}

View File

@@ -1,54 +0,0 @@
/*
* 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.competition;
public class ActionBarConfig extends AbstractCompetitionInfo {
public static class Builder {
private final ActionBarConfig config;
public Builder() {
this.config = new ActionBarConfig();
}
public Builder showToAll(boolean showToAll) {
this.config.showToAll = showToAll;
return this;
}
public Builder refreshRate(int rate) {
this.config.refreshRate = rate;
return this;
}
public Builder switchInterval(int interval) {
this.config.switchInterval = interval;
return this;
}
public Builder text(String[] texts) {
this.config.texts = texts;
return this;
}
public ActionBarConfig build() {
return this.config;
}
}
}

View File

@@ -1,85 +0,0 @@
/*
* 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.competition;
import org.bukkit.boss.BarColor;
public class BossBarConfig extends AbstractCompetitionInfo {
private BarColor color;
private Overlay overlay;
public BarColor getColor() {
return color;
}
public Overlay getOverlay() {
return overlay;
}
public static class Builder {
private final BossBarConfig config;
public Builder() {
this.config = new BossBarConfig();
}
public Builder showToAll(boolean showToAll) {
this.config.showToAll = showToAll;
return this;
}
public Builder refreshRate(int rate) {
this.config.refreshRate = rate;
return this;
}
public Builder switchInterval(int interval) {
this.config.switchInterval = interval;
return this;
}
public Builder text(String[] texts) {
this.config.texts = texts;
return this;
}
public Builder color(BarColor color) {
this.config.color = color;
return this;
}
public Builder overlay(Overlay overlay) {
this.config.overlay = overlay;
return this;
}
public BossBarConfig build() {
return this.config;
}
}
public enum Overlay {
NOTCHED_6,
NOTCHED_10,
NOTCHED_12,
NOTCHED_20,
PROGRESS
}
}

View File

@@ -18,6 +18,8 @@
package net.momirealms.customfishing.api.mechanic.competition;
import net.momirealms.customfishing.api.mechanic.action.Action;
import net.momirealms.customfishing.api.mechanic.competition.info.ActionBarConfigImpl;
import net.momirealms.customfishing.api.mechanic.competition.info.BossBarConfigImpl;
import net.momirealms.customfishing.api.mechanic.requirement.Requirement;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
@@ -29,8 +31,8 @@ public class CompetitionConfig {
private final String key;
private int duration;
private int minPlayers;
private BossBarConfig bossBarConfig;
private ActionBarConfig actionBarConfig;
private BossBarConfigImpl bossBarConfigImpl;
private ActionBarConfigImpl actionBarConfigImpl;
private Action[] skipActions;
private Action[] startActions;
private Action[] endActions;
@@ -110,13 +112,13 @@ public class CompetitionConfig {
}
@Nullable
public BossBarConfig getBossBarConfig() {
return bossBarConfig;
public BossBarConfigImpl getBossBarConfig() {
return bossBarConfigImpl;
}
@Nullable
public ActionBarConfig getActionBarConfig() {
return actionBarConfig;
public ActionBarConfigImpl getActionBarConfig() {
return actionBarConfigImpl;
}
public static Builder builder(String key) {
@@ -162,14 +164,14 @@ public class CompetitionConfig {
}
@SuppressWarnings("UnusedReturnValue")
public Builder actionbar(ActionBarConfig actionBarConfig) {
config.actionBarConfig = actionBarConfig;
public Builder actionbar(ActionBarConfigImpl actionBarConfigImpl) {
config.actionBarConfigImpl = actionBarConfigImpl;
return this;
}
@SuppressWarnings("UnusedReturnValue")
public Builder bossbar(BossBarConfig bossBarConfig) {
config.bossBarConfig = bossBarConfig;
public Builder bossbar(BossBarConfigImpl bossBarConfigImpl) {
config.bossBarConfigImpl = bossBarConfigImpl;
return this;
}

View File

@@ -17,17 +17,64 @@
package net.momirealms.customfishing.api.mechanic.competition;
import net.kyori.adventure.key.Key;
import net.kyori.adventure.util.Index;
import java.util.concurrent.ThreadLocalRandom;
public enum CompetitionGoal {
public final class CompetitionGoal {
CATCH_AMOUNT,
TOTAL_SCORE,
MAX_SIZE,
TOTAL_SIZE,
RANDOM;
public static final CompetitionGoal CATCH_AMOUNT = new CompetitionGoal(Key.key("customfishing", "catch_amount"));
public static final CompetitionGoal TOTAL_SCORE = new CompetitionGoal(Key.key("customfishing", "total_score"));
public static final CompetitionGoal MAX_SIZE = new CompetitionGoal(Key.key("customfishing", "max_size"));
public static final CompetitionGoal TOTAL_SIZE = new CompetitionGoal(Key.key("customfishing", "total_size"));
public static final CompetitionGoal RANDOM = new CompetitionGoal(Key.key("customfishing", "random"));
private static final CompetitionGoal[] values = new CompetitionGoal[] {
CATCH_AMOUNT, TOTAL_SCORE, MAX_SIZE, TOTAL_SIZE, RANDOM
};
private static final Index<Key, CompetitionGoal> index = Index.create(CompetitionGoal::key, values());
/**
* Gets an array containing all defined competition goals.
*
* @return An array of all competition goals.
*/
public static CompetitionGoal[] values() {
return values;
}
/**
* Gets the index of competition goals by their keys.
*
* @return An index mapping keys to competition goals.
*/
public static Index<Key, CompetitionGoal> index() {
return index;
}
/**
* Gets a randomly selected competition goal.
*
* @return A randomly selected competition goal.
*/
public static CompetitionGoal getRandom() {
return CompetitionGoal.values()[ThreadLocalRandom.current().nextInt(CompetitionGoal.values().length - 1)];
}
private final Key key;
private CompetitionGoal(Key key) {
this.key = key;
}
/**
* Gets the key representing this competition goal.
*
* @return The key of the competition goal.
*/
public Key key() {
return key;
}
}

View File

@@ -15,11 +15,8 @@
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
package net.momirealms.customfishing.api.manager;
package net.momirealms.customfishing.api.mechanic.competition;
import net.momirealms.customfishing.api.mechanic.competition.CompetitionConfig;
import net.momirealms.customfishing.api.mechanic.competition.CompetitionGoal;
import net.momirealms.customfishing.api.mechanic.competition.FishingCompetition;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;

View File

@@ -21,7 +21,7 @@ import org.jetbrains.annotations.NotNull;
public class CompetitionPlayer implements Comparable<CompetitionPlayer>{
public static CompetitionPlayer empty = new CompetitionPlayer("", 0);
private static CompetitionPlayer empty = new CompetitionPlayer("", 0);
private long time;
private final String player;
private double score;
@@ -34,6 +34,7 @@ public class CompetitionPlayer implements Comparable<CompetitionPlayer>{
public void addScore(double score) {
this.score += score;
if (score <= 0) return;
this.time = System.currentTimeMillis();
}

View File

@@ -29,7 +29,7 @@ public interface FishingCompetition {
/**
* Start the fishing competition
*/
void start();
void start(boolean triggerEvent);
/**
* Stop the fishing competition

View File

@@ -17,7 +17,7 @@
package net.momirealms.customfishing.api.mechanic.competition;
import net.momirealms.customfishing.api.common.Pair;
import net.momirealms.customfishing.common.util.Pair;
import org.jetbrains.annotations.Nullable;
import java.util.Iterator;

View File

@@ -15,7 +15,7 @@
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
package net.momirealms.customfishing.api.mechanic.competition;
package net.momirealms.customfishing.api.mechanic.competition.info;
/**
* Abstract base class for competition information.
@@ -28,12 +28,19 @@ public abstract class AbstractCompetitionInfo {
protected boolean showToAll;
protected String[] texts;
protected AbstractCompetitionInfo(int refreshRate, int switchInterval, boolean showToAll, String[] texts) {
this.refreshRate = refreshRate;
this.switchInterval = switchInterval;
this.showToAll = showToAll;
this.texts = texts;
}
/**
* Get the refresh rate for updating competition information.
*
* @return The refresh rate in ticks.
*/
public int getRefreshRate() {
public int refreshRate() {
return refreshRate;
}
@@ -42,7 +49,7 @@ public abstract class AbstractCompetitionInfo {
*
* @return The switch interval in ticks.
*/
public int getSwitchInterval() {
public int switchInterval() {
return switchInterval;
}
@@ -51,7 +58,7 @@ public abstract class AbstractCompetitionInfo {
*
* @return True if information is shown to all players, otherwise only to participants.
*/
public boolean isShowToAll() {
public boolean showToAll() {
return showToAll;
}
@@ -60,7 +67,7 @@ public abstract class AbstractCompetitionInfo {
*
* @return An array of competition information texts.
*/
public String[] getTexts() {
public String[] texts() {
return texts;
}
}

View File

@@ -0,0 +1,91 @@
package net.momirealms.customfishing.api.mechanic.competition.info;
public interface ActionBarConfig {
int DEFAULT_REFRESH_RATE = 20;
int DEFAULT_SWITCH_INTERVAL = 200;
boolean DEFAULT_VISIBILITY = true;
String[] DEFAULT_TEXTS = new String[]{""};
/**
* Get the refresh rate for updating the competition information on the action bar.
*
* @return The refresh rate in ticks.
*/
int refreshRate();
/**
* Get the switch interval for displaying different competition texts.
*
* @return The switch interval in ticks.
*/
int switchInterval();
/**
* Check if competition information should be shown to all players.
*
* @return True if information is shown to all players, otherwise only to participants.
*/
boolean showToAll();
/**
* Get an array of competition information texts.
*
* @return An array of competition information texts.
*/
String[] texts();
/**
* Creates a new builder instance for constructing {@code ActionBarConfig} objects.
*
* @return A new {@code Builder} instance.
*/
static Builder builder() {
return new ActionBarConfigImpl.BuilderImpl();
}
/**
* Builder interface for constructing {@code ActionBarConfig} objects.
*/
interface Builder {
/**
* 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.
*/
Builder showToAll(boolean showToAll);
/**
* Sets the refresh rate for updating the competition information.
*
* @param rate The refresh rate in ticks.
* @return The current {@code Builder} instance.
*/
Builder refreshRate(int rate);
/**
* Sets the interval for switching between different competition texts.
*
* @param interval The switch interval in ticks.
* @return The current {@code Builder} instance.
*/
Builder switchInterval(int interval);
/**
* 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.
*/
Builder text(String[] texts);
/**
* Builds the {@code ActionBarConfig} object with the configured settings.
*
* @return The constructed {@code ActionBarConfig} object.
*/
ActionBarConfig build();
}
}

View File

@@ -0,0 +1,56 @@
/*
* 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.competition.info;
public class ActionBarConfigImpl extends AbstractCompetitionInfo implements ActionBarConfig {
public ActionBarConfigImpl(int refreshRate, int switchInterval, boolean showToAll, String[] texts) {
super(refreshRate, switchInterval, showToAll, texts);
}
public static class BuilderImpl implements Builder {
private int refreshRate = DEFAULT_REFRESH_RATE;
private int switchInterval = DEFAULT_SWITCH_INTERVAL;
private boolean showToAll = DEFAULT_VISIBILITY;
private String[] texts = DEFAULT_TEXTS;
@Override
public BuilderImpl showToAll(boolean showToAll) {
this.showToAll = showToAll;
return this;
}
@Override
public BuilderImpl refreshRate(int rate) {
this.refreshRate = rate;
return this;
}
@Override
public BuilderImpl switchInterval(int interval) {
this.switchInterval = interval;
return this;
}
@Override
public BuilderImpl text(String[] texts) {
this.texts = texts;
return this;
}
@Override
public ActionBarConfigImpl build() {
return new ActionBarConfigImpl(refreshRate, switchInterval, showToAll, texts);
}
}
}

View File

@@ -0,0 +1,125 @@
package net.momirealms.customfishing.api.mechanic.competition.info;
import net.kyori.adventure.bossbar.BossBar;
public interface BossBarConfig {
int DEFAULT_REFRESH_RATE = 20;
int DEFAULT_SWITCH_INTERVAL = 200;
boolean DEFAULT_VISIBILITY = true;
String[] DEFAULT_TEXTS = new String[]{""};
BossBar.Color DEFAULT_COLOR = BossBar.Color.BLUE;
BossBar.Overlay DEFAULT_OVERLAY = BossBar.Overlay.PROGRESS;
/**
* Get the refresh rate for updating competition information.
*
* @return The refresh rate in ticks.
*/
int refreshRate();
/**
* Get the switch interval for displaying different competition texts.
*
* @return The switch interval in ticks.
*/
int switchInterval();
/**
* Check if competition information should be shown to all players.
*
* @return True if information is shown to all players, otherwise only to participants.
*/
boolean showToAll();
/**
* Get an array of competition information texts.
*
* @return An array of competition information texts.
*/
String[] texts();
/**
* Gets the color of the boss bar.
*
* @return The color of the boss bar.
*/
BossBar.Color color();
/**
* Gets the overlay style of the boss bar.
*
* @return The overlay style of the boss bar.
*/
BossBar.Overlay overlay();
/**
* Creates a new builder instance for constructing {@code BossBarConfig} objects.
*
* @return A new {@code Builder} instance.
*/
static Builder builder() {
return new BossBarConfigImpl.BuilderImpl();
}
/**
* Builder interface for constructing {@code BossBarConfig} objects.
*/
interface Builder {
/**
* 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.
*/
Builder showToAll(boolean showToAll);
/**
* Sets the refresh rate for updating the competition information.
*
* @param rate The refresh rate in ticks.
* @return The current {@code Builder} instance.
*/
Builder refreshRate(int rate);
/**
* Sets the interval for switching between different competition texts.
*
* @param interval The switch interval in ticks.
* @return The current {@code Builder} instance.
*/
Builder switchInterval(int interval);
/**
* 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.
*/
Builder text(String[] texts);
/**
* Sets the color of the boss bar.
*
* @param color The color of the boss bar.
* @return The current {@code Builder} instance.
*/
Builder color(BossBar.Color color);
/**
* Sets the overlay style of the boss bar.
*
* @param overlay The overlay style of the boss bar.
* @return The current {@code Builder} instance.
*/
Builder overlay(BossBar.Overlay overlay);
/**
* Builds the {@code BossBarConfig} object with the configured settings.
*
* @return The constructed {@code BossBarConfig} object.
*/
BossBarConfig build();
}
}

View File

@@ -0,0 +1,85 @@
/*
* 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.competition.info;
import net.kyori.adventure.bossbar.BossBar;
public class BossBarConfigImpl extends AbstractCompetitionInfo implements BossBarConfig {
private final BossBar.Color color;
private final BossBar.Overlay overlay;
public BossBarConfigImpl(int refreshRate, int switchInterval, boolean showToAll, String[] texts, BossBar.Color color, BossBar.Overlay overlay) {
super(refreshRate, switchInterval, showToAll, texts);
this.color = color;
this.overlay = overlay;
}
@Override
public BossBar.Color color() {
return color;
}
@Override
public BossBar.Overlay overlay() {
return overlay;
}
public static class BuilderImpl implements Builder {
private int refreshRate = DEFAULT_REFRESH_RATE;
private int switchInterval = DEFAULT_SWITCH_INTERVAL;
private boolean showToAll = DEFAULT_VISIBILITY;
private String[] texts = DEFAULT_TEXTS;
private BossBar.Overlay overlay = DEFAULT_OVERLAY;
public BossBar.Color color = DEFAULT_COLOR;
@Override
public BuilderImpl showToAll(boolean showToAll) {
this.showToAll = showToAll;
return this;
}
@Override
public BuilderImpl refreshRate(int rate) {
this.refreshRate = rate;
return this;
}
@Override
public BuilderImpl switchInterval(int interval) {
this.switchInterval = interval;
return this;
}
@Override
public BuilderImpl text(String[] texts) {
this.texts = texts;
return this;
}
@Override
public BuilderImpl color(BossBar.Color color) {
this.color = color;
return this;
}
@Override
public BuilderImpl overlay(BossBar.Overlay overlay) {
this.overlay = overlay;
return this;
}
@Override
public BossBarConfigImpl build() {
return new BossBarConfigImpl(refreshRate, switchInterval, showToAll, texts, color, overlay);
}
}
}

View File

@@ -1,148 +0,0 @@
/*
* 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.condition;
import org.bukkit.Location;
import org.bukkit.entity.Player;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.util.HashMap;
import java.util.Map;
/**
* Represents a condition with associated data
*/
public class Condition {
protected Location location;
protected final Player player;
protected final @NotNull Map<String, String> args;
/**
* Creates a new Condition object based on a player's location.
*
* @param player The player associated with this condition.
*/
public Condition(@NotNull Player player) {
this(player.getLocation(), player, new HashMap<>());
}
/**
* Creates a new Condition object with specified arguments.
*
* @param player The player associated with this condition.
* @param args A map of arguments associated with this condition.
*/
public Condition(@NotNull Player player, @NotNull Map<String, String> args) {
this(player.getLocation(), player, args);
}
/**
* Creates a new Condition object with a specific location, player, and arguments.
*
* @param location The location associated with this condition.
* @param player The player associated with this condition.
* @param args A map of arguments associated with this condition.
*/
public Condition(Location location, Player player, @NotNull Map<String, String> args) {
this.location = location;
this.player = player;
this.args = args;
if (player != null)
this.args.put("{player}", player.getName());
if (location != null) {
this.args.put("{x}", String.valueOf(location.getX()));
this.args.put("{y}", String.valueOf(location.getY()));
this.args.put("{z}", String.valueOf(location.getZ()));
this.args.put("{world}", location.getWorld().getName());
}
}
/**
* Sets the location associated with this condition.
*
* @param location The new location to set.
*/
public void setLocation(@NotNull Location location) {
this.location = location;
this.args.put("{x}", String.valueOf(location.getX()));
this.args.put("{y}", String.valueOf(location.getY()));
this.args.put("{z}", String.valueOf(location.getZ()));
this.args.put("{world}", location.getWorld().getName());
}
/**
* Gets the location associated with this condition.
*
* @return The location associated with this condition.
*/
public Location getLocation() {
return location;
}
/**
* Gets the player associated with this condition.
*
* @return The player associated with this condition.
*/
public Player getPlayer() {
return player;
}
/**
* Gets the map of arguments associated with this condition.
*
* @return A map of arguments associated with this condition.
*/
@NotNull
public Map<String, String> getArgs() {
return args;
}
/**
* Gets the value of a specific argument by its key.
*
* @param key The key of the argument to retrieve.
* @return The value of the argument or null if not found.
*/
@Nullable
public String getArg(String key) {
return args.get(key);
}
/**
* Inserts or updates an argument with the specified key and value.
*
* @param key The key of the argument to insert or update.
* @param value The value to set for the argument.
*/
public void insertArg(String key, String value) {
args.put(key, value);
}
/**
* Deletes an argument with the specified key.
*
* @param key The key of the argument to delete.
* @return The value of the deleted argument or null if not found.
*/
public String delArg(String key) {
return args.remove(key);
}
}

View File

@@ -1,69 +0,0 @@
/*
* 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.condition;
import net.momirealms.customfishing.api.mechanic.action.ActionTrigger;
import net.momirealms.customfishing.api.mechanic.effect.FishingEffect;
import org.bukkit.entity.Player;
import org.bukkit.inventory.ItemStack;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
public abstract class FishingPreparation extends Condition {
public FishingPreparation(Player player) {
super(player);
}
/**
* Retrieves the ItemStack representing the fishing rod.
*
* @return The ItemStack representing the fishing rod.
*/
@NotNull
public abstract ItemStack getRodItemStack();
/**
* Retrieves the ItemStack representing the bait (if available).
*
* @return The ItemStack representing the bait, or null if no bait is set.
*/
@Nullable
public abstract ItemStack getBaitItemStack();
/**
* Checks if player meet the requirements for fishing gears
*
* @return True if can fish, false otherwise.
*/
public abstract boolean canFish();
/**
* Merges a FishingEffect into this fishing rod, applying effect modifiers.
*
* @param effect The FishingEffect to merge into this rod.
*/
public abstract void mergeEffect(FishingEffect effect);
/**
* Triggers actions associated with a specific action trigger.
*
* @param actionTrigger The action trigger that initiates the actions.
*/
public abstract void triggerActions(ActionTrigger actionTrigger);
}

View File

@@ -0,0 +1,163 @@
package net.momirealms.customfishing.api.mechanic.config;
import dev.dejvokep.boostedyaml.YamlDocument;
import dev.dejvokep.boostedyaml.dvs.versioning.BasicVersioning;
import dev.dejvokep.boostedyaml.settings.dumper.DumperSettings;
import dev.dejvokep.boostedyaml.settings.general.GeneralSettings;
import dev.dejvokep.boostedyaml.settings.loader.LoaderSettings;
import dev.dejvokep.boostedyaml.settings.updater.UpdaterSettings;
import net.momirealms.customfishing.api.mechanic.context.Context;
import net.momirealms.customfishing.api.mechanic.context.ContextKeys;
import net.momirealms.customfishing.api.mechanic.misc.function.FormatFunction;
import net.momirealms.customfishing.api.mechanic.misc.function.ItemPropertyFunction;
import net.momirealms.customfishing.api.mechanic.misc.value.MathValue;
import net.momirealms.customfishing.api.mechanic.misc.value.TextValue;
import net.momirealms.customfishing.common.config.ConfigManager;
import net.momirealms.customfishing.common.config.node.Node;
import net.momirealms.customfishing.common.helper.AdventureHelper;
import net.momirealms.customfishing.common.item.Item;
import net.momirealms.customfishing.common.plugin.CustomFishingPlugin;
import net.momirealms.customfishing.common.util.ListUtils;
import org.bukkit.entity.Player;
import org.bukkit.inventory.ItemStack;
import java.io.IOException;
import java.io.InputStream;
import java.nio.file.Files;
import java.nio.file.Path;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.function.BiConsumer;
import java.util.function.Function;
public class BukkitConfigManager implements ConfigManager {
private final CustomFishingPlugin plugin;
private final HashMap<String, Node<FormatFunction>> formatFunctions = new HashMap<>();
public BukkitConfigManager(CustomFishingPlugin plugin) {
this.plugin = plugin;
this.registerBuiltInItemProperties();
}
private void registerBuiltInItemProperties() {
this.registerItemFunction(arg -> {
MathValue<Player> mathValue = MathValue.auto(arg);
return (item, context) -> item.customModelData((int) mathValue.evaluate(context));
}, 4000, "custom-model-data");
this.registerItemFunction(arg -> {
TextValue<Player> textValue = TextValue.auto((String) arg);
return (item, context) -> {
item.displayName(AdventureHelper.miniMessageToJson(textValue.render(context)));
};
}, 3000, "display", "name");
this.registerItemFunction(arg -> {
List<String> list = ListUtils.toList(arg);
List<TextValue<Player>> lore = new ArrayList<>();
for (String text : list) {
lore.add(TextValue.auto(text));
}
return (item, context) -> {
item.lore(lore.stream()
.map(it -> AdventureHelper.miniMessageToJson(it.render(context)))
.toList());
};
}, 2000, "display", "lore");
this.registerItemFunction(arg -> {
boolean enable = (boolean) arg;
return (item, context) -> {
if (!enable) return;
item.setTag(context.arg(ContextKeys.ID), "CustomFishing", "id");
item.setTag(context.arg(ContextKeys.TYPE), "CustomFishing", "type");
};
}, 1000, "tag");
}
private void registerItemFunction(Function<Object, BiConsumer<Item<ItemStack>, Context<Player>>> function, int priority, String... nodes) {
registerNodeFunction(nodes, new ItemPropertyFunction(priority, function));
}
public void registerNodeFunction(String[] nodes, FormatFunction formatFunction) {
Map<String, Node<FormatFunction>> functionMap = formatFunctions;
for (int i = 0; i < nodes.length; i++) {
if (functionMap.containsKey(nodes[i])) {
Node<FormatFunction> functionNode = functionMap.get(nodes[i]);
if (functionNode.nodeValue() != null) {
throw new IllegalArgumentException("Format function '" + nodes[i] + "' already exists");
}
functionMap = functionNode.getChildTree();
} else {
if (i != nodes.length - 1) {
Node<FormatFunction> newNode = new Node<>();
functionMap.put(nodes[i], newNode);
functionMap = newNode.getChildTree();
} else {
functionMap.put(nodes[i], new Node<>(formatFunction));
}
}
}
}
protected Path resolveConfig(String filePath) {
if (filePath == null || filePath.equals("")) {
throw new IllegalArgumentException("ResourcePath cannot be null or empty");
}
filePath = filePath.replace('\\', '/');
Path configFile = plugin.getConfigDirectory().resolve(filePath);
// if the config doesn't exist, create it based on the template in the resources dir
if (!Files.exists(configFile)) {
try {
Files.createDirectories(configFile.getParent());
} catch (IOException e) {
// ignore
}
try (InputStream is = plugin.getResourceStream(filePath)) {
if (is == null) {
throw new IllegalArgumentException("The embedded resource '" + filePath + "' cannot be found");
}
Files.copy(is, configFile);
} catch (IOException e) {
throw new RuntimeException(e);
}
}
return configFile;
}
@Override
public YamlDocument loadConfig(String filePath) {
return loadConfig(filePath, '.');
}
@Override
public YamlDocument loadConfig(String filePath, char routeSeparator) {
try {
return YamlDocument.create(
resolveConfig(filePath).toFile(),
plugin.getResourceStream(filePath),
GeneralSettings.builder().setRouteSeparator(routeSeparator).build(),
LoaderSettings
.builder()
.setAutoUpdate(true)
.build(),
DumperSettings.DEFAULT,
UpdaterSettings
.builder()
.setVersioning(new BasicVersioning("config-version"))
.build()
);
} catch (IOException e) {
plugin.getPluginLogger().severe("Failed to load config " + filePath, e);
return null;
}
}
}

View File

@@ -0,0 +1,62 @@
package net.momirealms.customfishing.api.mechanic.config;
import dev.dejvokep.boostedyaml.block.implementation.Section;
import net.momirealms.customfishing.api.mechanic.context.Context;
import net.momirealms.customfishing.api.mechanic.item.CustomFishingItem;
import net.momirealms.customfishing.api.mechanic.misc.function.FormatFunction;
import net.momirealms.customfishing.api.mechanic.misc.function.ItemPropertyFunction;
import net.momirealms.customfishing.api.mechanic.misc.function.PriorityFunction;
import net.momirealms.customfishing.common.config.node.Node;
import net.momirealms.customfishing.common.item.Item;
import net.momirealms.customfishing.common.util.Key;
import org.bukkit.entity.Player;
import org.bukkit.inventory.ItemStack;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.function.BiConsumer;
public class ItemConfig {
private final String id;
private final String material;
private final List<PriorityFunction<BiConsumer<Item<ItemStack>, Context<Player>>>> tagConsumers = new ArrayList<>();
public ItemConfig(String id, Section section, Map<String, Node<FormatFunction>> functionMap) {
this.id = id;
this.material = section.getString("material");
analyze(section, functionMap);
}
private void analyze(Section section, Map<String, Node<FormatFunction>> functionMap) {
Map<String, Object> dataMap = section.getStringRouteMappedValues(false);
for (Map.Entry<String, Object> entry : dataMap.entrySet()) {
String key = entry.getKey();
Node<FormatFunction> node = functionMap.get(key);
if (node == null) continue;
FormatFunction function = node.nodeValue();
if (function != null) {
if (function instanceof ItemPropertyFunction propertyFunction) {
BiConsumer<Item<ItemStack>, Context<Player>> result = propertyFunction.accept(entry.getValue());
tagConsumers.add(new PriorityFunction<>(, result));
}
continue;
}
if (entry.getValue() instanceof Section innerSection) {
analyze(innerSection, node.getChildTree());
}
}
}
public Key key() {
return Key.of("item", id);
}
public CustomFishingItem getItem() {
return CustomFishingItem.builder()
.material(material)
.tagConsumers(tagConsumers)
.build();
}
}

View File

@@ -0,0 +1,62 @@
/*
* 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.context;
import org.bukkit.entity.Player;
import org.jetbrains.annotations.NotNull;
import java.util.Map;
/**
* The Context interface represents a generic context for custom fishing mechanics.
* It allows for storing and retrieving arguments, as well as getting the holder
* of the context. This can be used to maintain state or pass parameters within
* the custom fishing mechanics.
*
* @param <T> the type of the holder object for this context
*/
public interface Context<T> {
/**
* Retrieves the map of arguments associated with this context.
*
* @return a map where the keys are argument names and the values are argument values.
*/
Map<ContextKeys<?>, Object> args();
<C> Context<T> arg(ContextKeys<C> key, C value);
<C> C arg(ContextKeys<C> key);
/**
* Gets the holder of this context.
*
* @return the holder object of type T.
*/
T getHolder();
/**
* Creates a player-specific context.
*
* @param player the player to be used as the holder of the context.
* @return a new Context instance with the specified player as the holder.
*/
static Context<Player> player(@NotNull Player player) {
return new PlayerContextImpl(player);
}
}

View File

@@ -0,0 +1,70 @@
/*
* 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.context;
import org.bukkit.Location;
import java.util.Objects;
public class ContextKeys<T> {
public static final ContextKeys<Location> LOCATION = of("location", Location.class);
public static final ContextKeys<Integer> X = of("x", Integer.class);
public static final ContextKeys<Integer> Y = of("y", Integer.class);
public static final ContextKeys<Integer> Z = of("z", Integer.class);
public static final ContextKeys<String> WORLD = of("world", String.class);
public static final ContextKeys<String> ID = of("id", String.class);
public static final ContextKeys<String> TYPE = of("type", String.class);
private final String key;
private final Class<T> type;
private ContextKeys(String key, Class<T> type) {
this.key = key;
this.type = type;
}
public String key() {
return key;
}
public Class<T> type() {
return type;
}
public static <T> ContextKeys<T> of(String key, Class<T> type) {
return new ContextKeys<T>(key, type);
}
@Override
public final boolean equals(final Object other) {
if (this == other) {
return true;
} else if (other != null && this.getClass() == other.getClass()) {
ContextKeys<?> that = (ContextKeys) other;
return Objects.equals(this.key, that.key);
} else {
return false;
}
}
@Override
public final int hashCode() {
return Objects.hashCode(this.key);
}
}

View File

@@ -0,0 +1,97 @@
/*
* 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.context;
import org.bukkit.Location;
import org.bukkit.entity.Player;
import org.jetbrains.annotations.NotNull;
import java.util.HashMap;
import java.util.Map;
/**
* 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.
*/
public final class PlayerContextImpl implements Context<Player> {
private final Player player;
private final HashMap<ContextKeys<?>, Object> args = new HashMap<>();
/**
* Constructs a new PlayerContextImpl with the specified player.
*
* @param player the player to be associated with this context.
*/
public PlayerContextImpl(@NotNull Player player) {
this.player = player;
final Location location = player.getLocation();
arg(ContextKeys.LOCATION, location)
.arg(ContextKeys.X, location.getBlockX())
.arg(ContextKeys.Y, location.getBlockY())
.arg(ContextKeys.Z, location.getBlockZ())
.arg(ContextKeys.WORLD, location.getWorld().getName());
}
/**
* Retrieves the map of arguments associated with this context.
*
* @return a map where the keys are argument names and the values are argument values.
*/
@Override
public Map<ContextKeys<?>, Object> args() {
return args;
}
/**
* Adds an argument to the context and returns the context itself
* to allow for method chaining.
*
* @param key the name of the argument to add.
* @param value the value of the argument to add.
* @return the PlayerContextImpl instance to allow for method chaining.
*/
@Override
public <C> PlayerContextImpl arg(ContextKeys<C> key, C value) {
args.put(key, value);
return this;
}
/**
* Retrieves the value of a specific argument from the context.
*
* @param key the name of the argument to retrieve.
* @return the value of the argument, or null if no argument with the given key exists.
*/
@Override
@SuppressWarnings("unchecked")
public <C> C arg(ContextKeys<C> key) {
return (C) args.get(key);
}
/**
* Gets the player associated with this context.
*
* @return the player object associated with this context.
*/
@Override
public Player getHolder() {
return player;
}
}

View File

@@ -1,20 +1,20 @@
package net.momirealms.customfishing.api.mechanic.effect;
import net.momirealms.customfishing.api.mechanic.misc.Value;
import net.momirealms.customfishing.api.mechanic.misc.value.MathValue;
import org.bukkit.entity.Player;
import java.util.Map;
public class BaseEffect {
private final Value waitTime;
private final Value waitTimeMultiplier;
private final Value difficulty;
private final Value difficultyMultiplier;
private final Value gameTime;
private final Value gameTimeMultiplier;
private final MathValue<Player> waitTime;
private final MathValue<Player> waitTimeMultiplier;
private final MathValue<Player> difficulty;
private final MathValue<Player> difficultyMultiplier;
private final MathValue<Player> gameTime;
private final MathValue<Player> gameTimeMultiplier;
public BaseEffect(Value waitTime, Value waitTimeMultiplier, Value difficulty, Value difficultyMultiplier, Value gameTime, Value gameTimeMultiplier) {
public BaseEffect(MathValue<Player> waitTime, MathValue<Player> waitTimeMultiplier, MathValue<Player> difficulty, MathValue difficultyMultiplier, MathValue gameTime, MathValue gameTimeMultiplier) {
this.waitTime = waitTime;
this.waitTimeMultiplier = waitTimeMultiplier;
this.difficulty = difficulty;

View File

@@ -17,40 +17,45 @@
package net.momirealms.customfishing.api.mechanic.effect;
import net.momirealms.customfishing.api.common.Pair;
import net.momirealms.customfishing.api.mechanic.misc.WeightModifier;
import net.momirealms.customfishing.common.util.Pair;
import org.bukkit.entity.Player;
import java.util.List;
import java.util.function.BiFunction;
public interface Effect {
boolean canLavaFishing();
boolean allowLavaFishing();
double getMultipleLootChance();
double multipleLootChance();
double getSize();
double sizeAdder();
double getSizeMultiplier();
double sizeMultiplier();
double getScore();
double scoreAdder();
double getScoreMultiplier();
double scoreMultiplier();
double getWaitTime();
double waitTimeAdder();
double getWaitTimeMultiplier();
double getGameTime();
double gameTimeAdder();
double getGameTimeMultiplier();
double gameTimeMultiplier();
double getDifficulty();
double difficultyAdder();
double getDifficultyMultiplier();
double difficultyMultiplier();
List<Pair<String, WeightModifier>> getWeightModifier();
List<Pair<String, BiFunction<Player, Double, Double>>> weightModifier();
List<Pair<String, WeightModifier>> getWeightModifierIgnored();
List<Pair<String, BiFunction<Player, Double, Double>>> weightModifierIgnored();
void merge(Effect effect);
interface Builder {
}
}

View File

@@ -17,10 +17,9 @@
package net.momirealms.customfishing.api.mechanic.effect;
import net.momirealms.customfishing.api.common.Key;
import net.kyori.adventure.key.Key;
import net.momirealms.customfishing.api.mechanic.action.Action;
import net.momirealms.customfishing.api.mechanic.action.ActionTrigger;
import net.momirealms.customfishing.api.mechanic.condition.Condition;
import net.momirealms.customfishing.api.mechanic.requirement.Requirement;
import org.jetbrains.annotations.Nullable;
@@ -102,10 +101,10 @@ public class EffectCarrier {
}
@SuppressWarnings("BooleanMethodIsAlwaysInverted")
public boolean isConditionMet(Condition condition) {
public boolean isConditionMet(PlayerContext playerContext) {
if (requirements == null) return true;
for (Requirement requirement : requirements) {
if (!requirement.isConditionMet(condition)) {
if (!requirement.check(playerContext)) {
return false;
}
}

View File

@@ -0,0 +1,4 @@
package net.momirealms.customfishing.api.mechanic.effect;
public class EffectImpl {
}

View File

@@ -15,13 +15,9 @@
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
package net.momirealms.customfishing.api.manager;
package net.momirealms.customfishing.api.mechanic.effect;
import net.momirealms.customfishing.api.common.Key;
import net.momirealms.customfishing.api.mechanic.effect.BaseEffect;
import net.momirealms.customfishing.api.mechanic.effect.EffectCarrier;
import net.momirealms.customfishing.api.mechanic.effect.EffectModifier;
import net.momirealms.customfishing.api.mechanic.effect.FishingEffect;
import net.kyori.adventure.key.Key;
import org.bukkit.configuration.ConfigurationSection;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;

View File

@@ -17,9 +17,10 @@
package net.momirealms.customfishing.api.mechanic.effect;
import net.momirealms.customfishing.api.mechanic.condition.Condition;
import net.momirealms.customfishing.api.mechanic.context.Context;
import org.bukkit.entity.Player;
public interface EffectModifier {
void modify(FishingEffect effect, Condition condition);
void modify(FishingEffect effect, Context<Player> playerContext);
}

View File

@@ -18,7 +18,6 @@
package net.momirealms.customfishing.api.mechanic.effect;
import net.momirealms.customfishing.api.common.Pair;
import net.momirealms.customfishing.api.mechanic.misc.WeightModifier;
import java.util.ArrayList;
import java.util.List;
@@ -214,7 +213,7 @@ public class FishingEffect implements Effect {
* @return True if lava fishing is enabled, false otherwise.
*/
@Override
public boolean canLavaFishing() {
public boolean allowLavaFishing() {
return lavaFishing;
}
@@ -224,7 +223,7 @@ public class FishingEffect implements Effect {
* @return The multiple loot chance value.
*/
@Override
public double getMultipleLootChance() {
public double multipleLootChance() {
return multipleLootChance;
}
@@ -234,7 +233,7 @@ public class FishingEffect implements Effect {
* @return The size multiplier value.
*/
@Override
public double getSizeMultiplier() {
public double sizeMultiplier() {
return sizeMultiplier;
}
@@ -244,7 +243,7 @@ public class FishingEffect implements Effect {
* @return The size value.
*/
@Override
public double getSize() {
public double sizeAdder() {
return size;
}
@@ -254,7 +253,7 @@ public class FishingEffect implements Effect {
* @return The score multiplier value.
*/
@Override
public double getScoreMultiplier() {
public double scoreMultiplier() {
return scoreMultiplier;
}
@@ -274,7 +273,7 @@ public class FishingEffect implements Effect {
* @return The wait time .
*/
@Override
public double getWaitTime() {
public double waitTimeAdder() {
return waitTime;
}
@@ -284,7 +283,7 @@ public class FishingEffect implements Effect {
* @return The game time value.
*/
@Override
public double getGameTime() {
public double gameTimeAdder() {
return gameTime;
}
@@ -294,7 +293,7 @@ public class FishingEffect implements Effect {
* @return The game time value multiplier.
*/
@Override
public double getGameTimeMultiplier() {
public double gameTimeMultiplier() {
return gameTimeMultiplier;
}
@@ -304,7 +303,7 @@ public class FishingEffect implements Effect {
* @return The score value.
*/
@Override
public double getScore() {
public double scoreAdder() {
return score;
}
@@ -314,7 +313,7 @@ public class FishingEffect implements Effect {
* @return The difficulty value.
*/
@Override
public double getDifficulty() {
public double difficultyAdder() {
return difficulty;
}
@@ -324,7 +323,7 @@ public class FishingEffect implements Effect {
* @return The difficulty multiplier value.
*/
@Override
public double getDifficultyMultiplier() {
public double difficultyMultiplier() {
return difficultyMultiplier;
}
@@ -334,7 +333,7 @@ public class FishingEffect implements Effect {
* @return The list of weight modifiers.
*/
@Override
public List<Pair<String, WeightModifier>> getWeightModifier() {
public List<Pair<String, WeightModifier>> weightModifier() {
return weightModifier;
}
@@ -344,7 +343,7 @@ public class FishingEffect implements Effect {
* @return The list of weight modifiers ignoring conditions.
*/
@Override
public List<Pair<String, WeightModifier>> getWeightModifierIgnored() {
public List<Pair<String, WeightModifier>> weightModifierIgnored() {
return weightModifierIgnored;
}
@@ -356,18 +355,18 @@ public class FishingEffect implements Effect {
@Override
public void merge(Effect another) {
if (another == null) return;
if (another.canLavaFishing()) this.lavaFishing = true;
this.scoreMultiplier += (another.getScoreMultiplier() -1);
this.score += another.getScore();
this.sizeMultiplier += (another.getSizeMultiplier() -1);
this.size += another.getSize();
this.difficultyMultiplier += (another.getDifficultyMultiplier() -1);
this.difficulty += another.getDifficulty();
this.gameTimeMultiplier += (another.getGameTimeMultiplier() - 1);
this.gameTime += another.getGameTime();
if (another.allowLavaFishing()) this.lavaFishing = true;
this.scoreMultiplier += (another.scoreMultiplier() -1);
this.score += another.scoreAdder();
this.sizeMultiplier += (another.sizeMultiplier() -1);
this.size += another.sizeAdder();
this.difficultyMultiplier += (another.difficultyMultiplier() -1);
this.difficulty += another.difficultyAdder();
this.gameTimeMultiplier += (another.gameTimeMultiplier() - 1);
this.gameTime += another.gameTimeAdder();
this.waitTimeMultiplier += (another.getWaitTimeMultiplier() -1);
this.multipleLootChance += another.getMultipleLootChance();
this.weightModifierIgnored.addAll(another.getWeightModifierIgnored());
this.weightModifier.addAll(another.getWeightModifier());
this.multipleLootChance += another.multipleLootChance();
this.weightModifierIgnored.addAll(another.weightModifierIgnored());
this.weightModifier.addAll(another.weightModifier());
}
}

View File

@@ -17,76 +17,104 @@
package net.momirealms.customfishing.api.mechanic.entity;
import org.jetbrains.annotations.NotNull;
import java.util.HashMap;
import java.util.Map;
public class EntityConfig implements EntitySettings {
/**
* The EntityConfig interface defines the configuration for an entity used in custom fishing mechanics.
* 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.
*/
public interface EntityConfig {
private String entity;
private double horizontalVector;
private double verticalVector;
private Map<String, Object> propertyMap;
private boolean persist;
double DEFAULT_HORIZONTAL_VECTOR = 1;
double DEFAULT_VERTICAL_VECTOR = 1;
String DEFAULT_ENTITY_ID = "";
Map<String, Object> DEFAULT_PROPERTY_MAP = Map.of();
@Override
public boolean isPersist() {
return persist;
/**
* Retrieves the horizontal vector value for the entity.
*
* @return the horizontal vector value as a double
*/
double getHorizontalVector();
/**
* Retrieves the vertical vector value for the entity.
*
* @return the vertical vector value as a double
*/
double getVerticalVector();
/**
* Retrieves the unique identifier for the entity.
*
* @return the entity ID as a non-null String
*/
@NotNull
String getEntityID();
/**
* Retrieves a map of properties associated with the entity.
*
* @return a non-null map where keys are property names and values are property values
*/
@NotNull
Map<String, Object> getPropertyMap();
/**
* Creates a new Builder instance for constructing an EntityConfig.
*
* @return a new Builder instance
*/
static Builder builder() {
return new EntityConfigImpl.BuilderImpl();
}
@Override
public double getHorizontalVector() {
return horizontalVector;
}
/**
* Builder interface for constructing instances of EntityConfig.
*/
interface Builder {
@Override
public double getVerticalVector() {
return verticalVector;
}
/**
* Sets the entity ID for the EntityConfig being built.
*
* @param value the entity ID as a String
* @return the current Builder instance
*/
Builder entityID(String value);
@Override
public String getEntityID() {
return entity;
}
/**
* Sets the vertical vector value for the EntityConfig being built.
*
* @param value the vertical vector value as a double
* @return the current Builder instance
*/
Builder verticalVector(double value);
@Override
public Map<String, Object> getPropertyMap() {
return propertyMap;
}
/**
* Sets the horizontal vector value for the EntityConfig being built.
*
* @param value the horizontal vector value as a double
* @return the current Builder instance
*/
Builder horizontalVector(double value);
public static class Builder {
/**
* Sets the property map for the EntityConfig being built.
*
* @param value a map of properties where keys are property names and values are property values
* @return the current Builder instance
*/
Builder propertyMap(Map<String, Object> value);
private final EntityConfig config;
public Builder() {
this.config = new EntityConfig();
}
public Builder entityID(String value) {
this.config.entity = value;
return this;
}
public Builder persist(boolean value) {
this.config.persist = value;
return this;
}
public Builder verticalVector(double value) {
this.config.verticalVector = value;
return this;
}
public Builder horizontalVector(double value) {
this.config.horizontalVector = value;
return this;
}
public Builder propertyMap(Map<String, Object> value) {
this.config.propertyMap = value;
return this;
}
public EntityConfig build() {
return config;
}
/**
* Builds and returns the EntityConfig instance based on the current state of the Builder.
*
* @return a new EntityConfig instance
*/
EntityConfig build();
}
}

View File

@@ -0,0 +1,90 @@
/*
* 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.entity;
import org.jetbrains.annotations.NotNull;
import java.util.Map;
public class EntityConfigImpl implements EntityConfig {
private final String id;
private final double horizontalVector;
private final double verticalVector;
private final Map<String, Object> propertyMap;
public EntityConfigImpl(String id, double horizontalVector, double verticalVector, Map<String, Object> propertyMap) {
this.id = id;
this.horizontalVector = horizontalVector;
this.verticalVector = verticalVector;
this.propertyMap = propertyMap;
}
@Override
public double getHorizontalVector() {
return horizontalVector;
}
@Override
public double getVerticalVector() {
return verticalVector;
}
@NotNull
@Override
public String getEntityID() {
return id;
}
@NotNull
@Override
public Map<String, Object> getPropertyMap() {
return propertyMap;
}
public static class BuilderImpl implements Builder {
private String entity = DEFAULT_ENTITY_ID;
private double horizontalVector = DEFAULT_HORIZONTAL_VECTOR;
private double verticalVector = DEFAULT_VERTICAL_VECTOR;
private Map<String, Object> propertyMap = DEFAULT_PROPERTY_MAP;
@Override
public BuilderImpl entityID(String value) {
this.entity = value;
return this;
}
@Override
public BuilderImpl verticalVector(double value) {
this.verticalVector = value;
return this;
}
@Override
public BuilderImpl horizontalVector(double value) {
this.horizontalVector = value;
return this;
}
@Override
public BuilderImpl propertyMap(Map<String, Object> value) {
this.propertyMap = value;
return this;
}
@Override
public EntityConfigImpl build() {
return new EntityConfigImpl(entity, horizontalVector, verticalVector, propertyMap);
}
}
}

View File

@@ -1,30 +0,0 @@
/*
* 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.entity;
import org.bukkit.Location;
import org.bukkit.entity.Entity;
import java.util.Map;
public interface EntityLibrary {
String identification();
Entity spawn(Location location, String id, Map<String, Object> propertyMap);
}

View File

@@ -15,30 +15,13 @@
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
package net.momirealms.customfishing.api.manager;
package net.momirealms.customfishing.api.mechanic.entity;
import net.momirealms.customfishing.api.mechanic.entity.EntityLibrary;
import net.momirealms.customfishing.api.mechanic.loot.Loot;
import org.bukkit.Location;
public interface EntityManager {
/**
* Registers an entity library for use in the plugin.
*
* @param entityLibrary The entity library to register.
* @return {@code true} if the entity library was successfully registered, {@code false} if it already exists.
*/
boolean registerEntityLibrary(EntityLibrary entityLibrary);
/**
* Unregisters an entity library by its identification key.
*
* @param identification The identification key of the entity library to unregister.
* @return {@code true} if the entity library was successfully unregistered, {@code false} if it does not exist.
*/
boolean unregisterEntityLibrary(String identification);
/**
* Summons an entity based on the given loot configuration to a specified location.
*

View File

@@ -1,32 +0,0 @@
/*
* 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.entity;
import java.util.Map;
public interface EntitySettings {
boolean isPersist();
double getHorizontalVector();
double getVerticalVector();
String getEntityID();
Map<String, Object> getPropertyMap();
}

View File

@@ -15,10 +15,9 @@
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
package net.momirealms.customfishing.api.manager;
package net.momirealms.customfishing.api.mechanic.fishing;
import net.momirealms.customfishing.api.mechanic.TempFishingState;
import net.momirealms.customfishing.api.mechanic.condition.Condition;
import net.momirealms.customfishing.api.mechanic.effect.Effect;
import net.momirealms.customfishing.api.mechanic.game.GameInstance;
import net.momirealms.customfishing.api.mechanic.game.GameSettings;
@@ -81,10 +80,10 @@ public interface FishingManager {
* Starts a fishing game for the specified player with the given condition and effect.
*
* @param player The player starting the fishing game.
* @param condition The condition used to determine the game.
* @param playerContext The condition used to determine the game.
* @param effect The effect applied to the game.
*/
boolean startFishingGame(Player player, Condition condition, Effect effect);
boolean startFishingGame(Player player, PlayerContext playerContext, Effect effect);
/**
* Starts a fishing game for the specified player with the given settings and game instance.

View File

@@ -17,8 +17,8 @@
package net.momirealms.customfishing.api.mechanic.game;
import net.momirealms.customfishing.api.CustomFishingPlugin;
import net.momirealms.customfishing.api.manager.FishingManager;
import net.momirealms.customfishing.api.BukkitCustomFishingPlugin;
import net.momirealms.customfishing.api.mechanic.fishing.FishingManager;
import net.momirealms.customfishing.api.mechanic.effect.Effect;
import net.momirealms.customfishing.api.scheduler.CancellableTask;
import org.bukkit.Material;
@@ -41,13 +41,13 @@ public abstract class AbstractGamingPlayer implements GamingPlayer, Runnable {
this.player = player;
this.fishHook = hook;
this.settings = settings;
this.manager = CustomFishingPlugin.get().getFishingManager();
this.manager = BukkitCustomFishingPlugin.get().getFishingManager();
this.deadline = (long) (System.currentTimeMillis() + settings.getTime() * 1000L);
this.arrangeTask();
}
public void arrangeTask() {
this.task = CustomFishingPlugin.get().getScheduler().runTaskSyncTimer(this, fishHook.getLocation(), 1, 1);
this.task = BukkitCustomFishingPlugin.get().getScheduler().runTaskSyncTimer(this, fishHook.getLocation(), 1, 1);
}
@Override

View File

@@ -79,8 +79,8 @@ public class BasicGameConfig {
@Nullable
public GameSettings getGameSetting(Effect effect) {
return new GameSettings(
ThreadLocalRandom.current().nextInt(minTime, maxTime + 1) * effect.getGameTimeMultiplier() + effect.getGameTime(),
(int) Math.min(100, Math.max(1, ThreadLocalRandom.current().nextInt(minDifficulty, maxDifficulty + 1) * effect.getDifficultyMultiplier() + effect.getDifficulty()))
ThreadLocalRandom.current().nextInt(minTime, maxTime + 1) * effect.gameTimeMultiplier() + effect.gameTimeAdder(),
(int) Math.min(100, Math.max(1, ThreadLocalRandom.current().nextInt(minDifficulty, maxDifficulty + 1) * effect.difficultyMultiplier() + effect.difficultyAdder()))
);
}
}

View File

@@ -15,13 +15,9 @@
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
package net.momirealms.customfishing.api.manager;
package net.momirealms.customfishing.api.mechanic.game;
import net.momirealms.customfishing.api.common.Pair;
import net.momirealms.customfishing.api.mechanic.condition.Condition;
import net.momirealms.customfishing.api.mechanic.game.BasicGameConfig;
import net.momirealms.customfishing.api.mechanic.game.GameFactory;
import net.momirealms.customfishing.api.mechanic.game.GameInstance;
import org.jetbrains.annotations.Nullable;
import java.util.HashMap;
@@ -65,8 +61,8 @@ public interface GameManager {
/**
* Retrieves a map of game names and their associated weights based on the specified conditions.
*
* @param condition The condition to evaluate game weights.
* @param playerContext The condition to evaluate game weights.
* @return A {@code HashMap} containing game names as keys and their associated weights as values.
*/
HashMap<String, Double> getGameWithWeight(Condition condition);
HashMap<String, Double> getGameWithWeight(PlayerContext playerContext);
}

View File

@@ -15,9 +15,8 @@
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
package net.momirealms.customfishing.api.manager;
package net.momirealms.customfishing.api.mechanic.hook;
import net.momirealms.customfishing.api.mechanic.hook.HookSetting;
import org.bukkit.inventory.ItemStack;
import org.jetbrains.annotations.Nullable;

View File

@@ -1,42 +0,0 @@
/*
* 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.item;
import org.bukkit.entity.Player;
import org.bukkit.inventory.ItemStack;
import java.util.HashMap;
import java.util.Map;
public interface BuildableItem {
default ItemStack build() {
return build(null, new HashMap<>());
}
default ItemStack build(Player player) {
return build(player, new HashMap<>());
}
ItemStack build(Player player, Map<String, String> placeholders);
/**
* Whether the item would be removed from cache when reloading
*/
boolean persist();
}

View File

@@ -0,0 +1,69 @@
package net.momirealms.customfishing.api.mechanic.item;
import net.momirealms.customfishing.api.mechanic.context.Context;
import net.momirealms.customfishing.api.mechanic.misc.function.PriorityFunction;
import net.momirealms.customfishing.common.item.Item;
import org.bukkit.entity.Player;
import org.bukkit.inventory.ItemStack;
import java.util.List;
import java.util.TreeSet;
import java.util.function.BiConsumer;
public interface CustomFishingItem {
String DEFAULT_MATERIAL = "PAPER";
/**
* Returns the material type of the custom fishing item.
*
* @return the material type as a String.
*/
String material();
/**
* Returns a list of tag consumers which are functions that take an item and context as parameters
* and perform some operation on them.
*
* @return a set of BiConsumer instances.
*/
List<BiConsumer<Item<ItemStack>, Context<Player>>> tagConsumers();
/**
* Creates a new Builder instance to construct a CustomFishingItem.
*
* @return a new Builder instance.
*/
static Builder builder() {
return new CustomFishingItemImpl.BuilderImpl();
}
/**
* Builder interface for constructing instances of CustomFishingItem.
*/
interface Builder {
/**
* Sets the material type for the CustomFishingItem being built.
*
* @param material the material type as a String.
* @return the Builder instance for method chaining.
*/
Builder material(String material);
/**
* Sets the list of tag consumers for the CustomFishingItem being built.
*
* @param tagConsumers a list of BiConsumer instances.
* @return the Builder instance for method chaining.
*/
Builder tagConsumers(List<PriorityFunction<BiConsumer<Item<ItemStack>, Context<Player>>>> tagConsumers);
/**
* Builds and returns a new CustomFishingItem instance.
*
* @return a new CustomFishingItem instance.
*/
CustomFishingItem build();
}
}

View File

@@ -0,0 +1,57 @@
package net.momirealms.customfishing.api.mechanic.item;
import net.momirealms.customfishing.api.mechanic.context.Context;
import net.momirealms.customfishing.api.mechanic.misc.function.PriorityFunction;
import net.momirealms.customfishing.common.item.Item;
import org.bukkit.entity.Player;
import org.bukkit.inventory.ItemStack;
import java.util.List;
import java.util.TreeSet;
import java.util.function.BiConsumer;
public class CustomFishingItemImpl implements CustomFishingItem {
private final String material;
private final List<BiConsumer<Item<ItemStack>, Context<Player>>> tagConsumers;
public CustomFishingItemImpl(String material, List<BiConsumer<Item<ItemStack>, Context<Player>>> tagConsumers) {
this.material = material;
this.tagConsumers = tagConsumers;
}
@Override
public String material() {
return material;
}
@Override
public List<BiConsumer<Item<ItemStack>, Context<Player>>> tagConsumers() {
return tagConsumers;
}
public static class BuilderImpl implements Builder {
private String material = DEFAULT_MATERIAL;
private final TreeSet<PriorityFunction<BiConsumer<Item<ItemStack>, Context<Player>>>> tagConsumers = new TreeSet<>();
@Override
public Builder material(String material) {
this.material = material;
return this;
}
@Override
public Builder tagConsumers(List<PriorityFunction<BiConsumer<Item<ItemStack>, Context<Player>>>> tagConsumers) {
this.tagConsumers.addAll(tagConsumers);
return this;
}
@Override
public CustomFishingItem build() {
return new CustomFishingItemImpl(material, tagConsumers.stream().map(PriorityFunction::get).toList());
}
}
}

View File

@@ -1,99 +0,0 @@
/*
* 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.item;
import de.tr7zw.changeme.nbtapi.NBTItem;
import net.momirealms.customfishing.api.common.Pair;
import net.momirealms.customfishing.api.common.Tuple;
import net.momirealms.customfishing.api.mechanic.misc.Value;
import org.bukkit.configuration.ConfigurationSection;
import org.bukkit.entity.Player;
import org.bukkit.inventory.ItemFlag;
import org.jetbrains.annotations.NotNull;
import java.util.Collection;
import java.util.List;
import java.util.Map;
public interface ItemBuilder extends BuildableItem {
ItemBuilder customModelData(int value);
ItemBuilder name(String name);
ItemBuilder amount(int amount);
ItemBuilder amount(int min_amount, int max_amount);
ItemBuilder tag(boolean tag, String type, String id);
ItemBuilder unbreakable(boolean unbreakable);
ItemBuilder placeable(boolean placeable);
ItemBuilder lore(List<String> lore);
ItemBuilder nbt(Map<String, Object> nbt);
ItemBuilder itemFlag(List<ItemFlag> itemFlags);
ItemBuilder nbt(ConfigurationSection section);
ItemBuilder enchantment(List<Pair<String, Short>> enchantments, boolean store);
ItemBuilder randomEnchantments(List<Tuple<Double, String, Short>> enchantments, boolean store);
ItemBuilder enchantmentPool(List<Pair<Integer, Value>> amountPairs, List<Pair<Pair<String, Short>, Value>> enchantments, boolean store);
ItemBuilder maxDurability(int max);
ItemBuilder price(float base, float bonus);
ItemBuilder size(Pair<Float, Float> size);
ItemBuilder stackable(boolean stackable);
ItemBuilder preventGrabbing(boolean prevent);
ItemBuilder head(String base64);
ItemBuilder randomDamage(boolean damage);
@NotNull
String getId();
@NotNull
String getLibrary();
int getAmount();
Collection<ItemPropertyEditor> getEditors();
ItemBuilder removeEditor(String type);
ItemBuilder registerCustomEditor(String type, ItemPropertyEditor editor);
interface ItemPropertyEditor {
void edit(Player player, NBTItem nbtItem, Map<String, String> placeholders);
default void edit(Player player, NBTItem nbtItem) {
edit(player, nbtItem, null);
}
}
}

View File

@@ -17,14 +17,14 @@
package net.momirealms.customfishing.api.mechanic.item;
import net.kyori.adventure.key.Key;
import net.momirealms.customfishing.api.mechanic.context.Context;
import org.bukkit.entity.Player;
import org.bukkit.inventory.ItemStack;
import org.jetbrains.annotations.Nullable;
public interface ItemLibrary {
public interface ItemManager {
String identification();
ItemStack buildItem(Player player, String id);
String getItemID(ItemStack itemStack);
@Nullable
ItemStack build(Context<Player> context, Key key);
}

View File

@@ -1,328 +0,0 @@
/*
* 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.loot;
import net.momirealms.customfishing.api.mechanic.action.Action;
import net.momirealms.customfishing.api.mechanic.action.ActionTrigger;
import net.momirealms.customfishing.api.mechanic.condition.Condition;
import net.momirealms.customfishing.api.mechanic.effect.BaseEffect;
import net.momirealms.customfishing.api.mechanic.statistic.StatisticsKey;
import org.jetbrains.annotations.NotNull;
import java.util.HashMap;
public class CFLoot implements Loot {
private final String id;
private final LootType type;
private final HashMap<ActionTrigger, Action[]> actionMap;
private final HashMap<Integer, Action[]> successTimesActionMap;
private String nick;
private boolean showInFinder;
private boolean disableGame;
private boolean disableGlobalAction;
private boolean disableStats;
private boolean instanceGame;
private double score;
private String[] lootGroup;
private StatisticsKey statisticsKey;
private BaseEffect effect;
public CFLoot(String id, LootType type) {
this.id = id;
this.type = type;
this.actionMap = new HashMap<>();
this.successTimesActionMap = new HashMap<>();
}
public static Builder builder(String id, LootType type) {
return new Builder(id, type);
}
/**
* Builder class for CFLoot.
*/
public static class Builder {
private final CFLoot loot;
public Builder(String id, LootType type) {
this.loot = new CFLoot(id, type);
}
/**
* Set the file path for this loot.
*
* @param path file path
* @return The builder.
*/
public Builder filePath(String path) {
return this;
}
/**
* Set the nickname for this loot.
*
* @param nick The nickname.
* @return The builder.
*/
public Builder nick(String nick) {
this.loot.nick = nick;
return this;
}
/**
* Set whether this loot should be shown in the finder.
*
* @param show True if it should be shown, false otherwise.
* @return The builder.
*/
public Builder showInFinder(boolean show) {
this.loot.showInFinder = show;
return this;
}
/**
* Set whether this loot should have an instance game.
*
* @param instant True if it should be an instance game, false otherwise.
* @return The builder.
*/
public Builder instantGame(boolean instant) {
this.loot.instanceGame = instant;
return this;
}
/**
* Set whether games are disabled for this loot.
*
* @param disable True if games are disabled, false otherwise.
* @return The builder.
*/
public Builder disableGames(boolean disable) {
this.loot.disableGame = disable;
return this;
}
/**
* Set whether statistics are disabled for this loot.
*
* @param disable True if statistics are disabled, false otherwise.
* @return The builder.
*/
public Builder disableStats(boolean disable) {
this.loot.disableStats = disable;
return this;
}
/**
* Set whether global actions are disabled for this loot.
*
* @param disable True if statistics are disabled, false otherwise.
* @return The builder.
*/
public Builder disableGlobalActions(boolean disable) {
this.loot.disableGlobalAction = disable;
return this;
}
/**
* Set the score for this loot.
*
* @param score The score.
* @return The builder.
*/
public Builder score(double score) {
this.loot.score = score;
return this;
}
/**
* Set the loot group for this loot.
*
* @param groups The loot group.
* @return The builder.
*/
public Builder lootGroup(String[] groups) {
this.loot.lootGroup = groups;
return this;
}
/**
* Set the statistics key for this loot
*
* @param statisticsKey statistics key
* @return The builder.
*/
public Builder statsKey(StatisticsKey statisticsKey) {
this.loot.statisticsKey = statisticsKey;
return this;
}
/**
* Set the effects for the loot
*
* @param effect effect
* @return The builder.
*/
public Builder baseEffect(BaseEffect effect) {
this.loot.effect = effect;
return this;
}
/**
* Add actions triggered by a specific trigger.
*
* @param trigger The trigger for the actions.
* @param actions The actions to add.
* @return The builder.
*/
public Builder addActions(ActionTrigger trigger, Action[] actions) {
this.loot.actionMap.put(trigger, actions);
return this;
}
/**
* Add actions triggered by multiple triggers.
*
* @param actionMap A map of triggers to actions.
* @return The builder.
*/
public Builder addActions(HashMap<ActionTrigger, Action[]> actionMap) {
this.loot.actionMap.putAll(actionMap);
return this;
}
/**
* Add actions triggered by the number of successes.
*
* @param times The number of successes for triggering the actions.
* @param actions The actions to add.
* @return The builder.
*/
public Builder addTimesActions(int times, Action[] actions) {
this.loot.successTimesActionMap.put(times, actions);
return this;
}
/**
* Add actions triggered by multiple numbers of successes.
*
* @param actionMap A map of numbers of successes to actions.
* @return The builder.
*/
public Builder addTimesActions(HashMap<Integer, Action[]> actionMap) {
this.loot.successTimesActionMap.putAll(actionMap);
return this;
}
/**
* Build the CFLoot object.
*
* @return The built CFLoot object.
*/
public CFLoot build() {
return loot;
}
}
@Override
public boolean instanceGame() {
return this.instanceGame;
}
@Override
public String getID() {
return this.id;
}
@Override
public LootType getType() {
return this.type;
}
@Override
public @NotNull String getNick() {
return this.nick;
}
@Override
public StatisticsKey getStatisticKey() {
return this.statisticsKey;
}
@Override
public boolean showInFinder() {
return this.showInFinder;
}
@Override
public double getScore() {
return this.score;
}
@Override
public boolean disableGame() {
return this.disableGame;
}
@Override
public boolean disableStats() {
return this.disableStats;
}
@Override
public boolean disableGlobalAction() {
return this.disableGlobalAction;
}
@Override
public String[] getLootGroup() {
return lootGroup;
}
@Override
public Action[] getActions(ActionTrigger actionTrigger) {
return actionMap.get(actionTrigger);
}
@Override
public void triggerActions(ActionTrigger actionTrigger, Condition condition) {
Action[] actions = getActions(actionTrigger);
if (actions != null) {
for (Action action : actions) {
action.trigger(condition);
}
}
}
@Override
public BaseEffect getBaseEffect() {
return effect;
}
@Override
public Action[] getSuccessTimesActions(int times) {
return successTimesActionMap.get(times);
}
@Override
public HashMap<Integer, Action[]> getSuccessTimesActionMap() {
return successTimesActionMap;
}
}

View File

@@ -19,9 +19,9 @@ package net.momirealms.customfishing.api.mechanic.loot;
import net.momirealms.customfishing.api.mechanic.action.Action;
import net.momirealms.customfishing.api.mechanic.action.ActionTrigger;
import net.momirealms.customfishing.api.mechanic.condition.Condition;
import net.momirealms.customfishing.api.mechanic.effect.BaseEffect;
import net.momirealms.customfishing.api.mechanic.statistic.StatisticsKey;
import net.momirealms.customfishing.api.mechanic.statistic.StatisticsKeys;
import org.bukkit.entity.Player;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
@@ -63,7 +63,7 @@ public interface Loot {
@NotNull
String getNick();
StatisticsKey getStatisticKey();
StatisticsKeys getStatisticKey();
/**
* Check if this loot should be shown in the finder.
@@ -113,9 +113,9 @@ public interface Loot {
* Trigger actions associated with a specific action trigger.
*
* @param actionTrigger The action trigger.
* @param condition The condition under which the actions are triggered.
* @param playerContext The condition under which the actions are triggered.
*/
void triggerActions(ActionTrigger actionTrigger, Condition condition);
void triggerActions(ActionTrigger actionTrigger, PlayerContext playerContext);
/**
* Get effects that bond to this loot
@@ -130,12 +130,12 @@ public interface Loot {
* @param times The number of successes.
* @return The actions triggered by the specified number of successes.
*/
Action[] getSuccessTimesActions(int times);
Action<Player>[] getRecordActions(int times);
/**
* Get a map of actions triggered by different numbers of successes.
*
* @return A map of actions triggered by success times.
*/
HashMap<Integer, Action[]> getSuccessTimesActionMap();
HashMap<Integer, Action<Player>[]> getRecordActionMap();
}

View File

@@ -15,11 +15,9 @@
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
package net.momirealms.customfishing.api.manager;
package net.momirealms.customfishing.api.mechanic.loot;
import net.momirealms.customfishing.api.mechanic.condition.Condition;
import net.momirealms.customfishing.api.mechanic.effect.Effect;
import net.momirealms.customfishing.api.mechanic.loot.Loot;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
@@ -63,34 +61,34 @@ public interface LootManager {
/**
* Retrieves loot configurations with weights based on a given condition.
*
* @param condition The condition used to filter loot configurations.
* @param playerContext The condition used to filter loot configurations.
* @return A mapping of loot configuration keys to their associated weights.
*/
HashMap<String, Double> getLootWithWeight(Condition condition);
HashMap<String, Double> getLootWithWeight(PlayerContext playerContext);
/**
* Get a collection of possible loot keys based on a given condition.
*
* @param condition The condition to determine possible loot.
* @param playerContext The condition to determine possible loot.
* @return A collection of loot keys.
*/
Collection<String> getPossibleLootKeys(Condition condition);
Collection<String> getPossibleLootKeys(PlayerContext playerContext);
/**
* Get a map of possible loot keys with their corresponding weights, considering fishing effect and condition.
*
* @param initialEffect The effect to apply weight modifiers.
* @param condition The condition to determine possible loot.
* @param playerContext The condition to determine possible loot.
* @return A map of loot keys and their weights.
*/
@NotNull Map<String, Double> getPossibleLootKeysWithWeight(Effect initialEffect, Condition condition);
@NotNull Map<String, Double> getPossibleLootKeysWithWeight(Effect initialEffect, PlayerContext playerContext);
/**
* Get the next loot item based on fishing effect and condition.
*
* @param effect The effect to apply weight modifiers.
* @param condition The condition to determine possible loot.
* @param playerContext The condition to determine possible loot.
* @return The next loot item, or null if it doesn't exist.
*/
@Nullable Loot getNextLoot(Effect effect, Condition condition);
@Nullable Loot getNextLoot(Effect effect, PlayerContext playerContext);
}

View File

@@ -15,7 +15,7 @@
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
package net.momirealms.customfishing.api.manager;
package net.momirealms.customfishing.api.mechanic.market;
import org.bukkit.entity.Player;
import org.bukkit.inventory.Inventory;
@@ -44,7 +44,7 @@ public interface MarketManager {
*
* @return An integer representing the current date.
*/
int getDate();
int getRealTimeDate();
/**
* Calculates the price of an ItemStack based on custom data or a predefined price map.

View File

@@ -1,25 +0,0 @@
/*
* 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.misc;
import org.bukkit.entity.Player;
public interface WeightModifier {
double modify(Player player, double weight);
}

View File

@@ -0,0 +1,4 @@
package net.momirealms.customfishing.api.mechanic.misc.function;
public interface FormatFunction {
}

View File

@@ -0,0 +1,27 @@
package net.momirealms.customfishing.api.mechanic.misc.function;
import net.momirealms.customfishing.api.mechanic.context.Context;
import net.momirealms.customfishing.common.item.Item;
import org.bukkit.entity.Player;
import org.bukkit.inventory.ItemStack;
import java.util.function.BiConsumer;
import java.util.function.Function;
public class ItemPropertyFunction implements FormatFunction {
private Function<Object, BiConsumer<Item<ItemStack>, Context<Player>>> function;
private int priority;
public ItemPropertyFunction(int priority, Function<Object, BiConsumer<Item<ItemStack>, Context<Player>>> function) {
this.function = function;
}
public BiConsumer<Item<ItemStack>, Context<Player>> accept(Object object) {
return function.apply(object);
}
public int getPriority() {
return priority;
}
}

View File

@@ -0,0 +1,23 @@
package net.momirealms.customfishing.api.mechanic.misc.function;
import org.jetbrains.annotations.NotNull;
public class PriorityFunction<T> implements Comparable<PriorityFunction<T>> {
private final int priority;
private final T function;
public PriorityFunction(int priority, T function) {
this.priority = priority;
this.function = function;
}
public T get() {
return function;
}
@Override
public int compareTo(@NotNull PriorityFunction<T> o) {
return Integer.compare(this.priority, o.priority);
}
}

View File

@@ -0,0 +1,9 @@
package net.momirealms.customfishing.api.mechanic.misc.season;
public enum Season {
SPRING,
SUMMER,
AUTUMN,
WINTER,
DISABLE
}

View File

@@ -0,0 +1,17 @@
package net.momirealms.customfishing.api.mechanic.misc.value;
import net.momirealms.customfishing.api.mechanic.context.Context;
public class ExpressionMathValueImpl<T> implements MathValue<T> {
private String raw;
public ExpressionMathValueImpl(String raw) {
this.raw = raw;
}
@Override
public double evaluate(Context<T> context) {
return 0;
}
}

View File

@@ -0,0 +1,79 @@
/*
* 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.misc.value;
import net.momirealms.customfishing.api.mechanic.context.Context;
/**
* The MathValue interface represents a mathematical value that can be evaluated
* within a specific context. This interface allows for the evaluation of mathematical
* expressions or plain numerical values in the context of custom fishing mechanics.
*
* @param <T> the type of the holder object for the context
*/
public interface MathValue<T> {
/**
* Evaluates the mathematical value within the given context.
*
* @param context the context in which the value is evaluated
* @return the evaluated value as a double
*/
double evaluate(Context<T> context);
/**
* Creates a MathValue based on a mathematical expression.
*
* @param expression the mathematical expression to evaluate
* @param <T> the type of the holder object for the context
* @return a MathValue instance representing the given expression
*/
static <T> MathValue<T> expression(String expression) {
return new ExpressionMathValueImpl<>(expression);
}
/**
* Creates a MathValue based on a plain numerical value.
*
* @param value the numerical value to represent
* @param <T> the type of the holder object for the context
* @return a MathValue instance representing the given plain value
*/
static <T> MathValue<T> plain(double value) {
return new PlainMathValueImpl<>(value);
}
/**
* Automatically creates a MathValue based on the given object.
* If the object is a String, it is treated as a mathematical expression.
* If the object is a numerical type (Double, Integer, Long, Float), it is treated as a plain value.
*
* @param o the object to evaluate and create a MathValue from
* @param <T> the type of the holder object for the context
* @return a MathValue instance representing the given object, either as an expression or a plain value
* @throws IllegalArgumentException if the object type is not supported
*/
static <T> MathValue<T> auto(Object o) {
if (o instanceof String s) {
return expression(s);
} else if (o instanceof Number n) {
return plain(n.doubleValue());
}
throw new IllegalArgumentException("Unsupported type: " + o.getClass());
}
}

View File

@@ -0,0 +1,17 @@
package net.momirealms.customfishing.api.mechanic.misc.value;
import net.momirealms.customfishing.api.mechanic.context.Context;
public class PlaceholderTextValueImpl<T> implements TextValue<T> {
private final String raw;
public PlaceholderTextValueImpl(String raw) {
this.raw = raw;
}
@Override
public String render(Context<T> context) {
return raw;
}
}

View File

@@ -0,0 +1,17 @@
package net.momirealms.customfishing.api.mechanic.misc.value;
import net.momirealms.customfishing.api.mechanic.context.Context;
public class PlainMathValueImpl<T> implements MathValue<T> {
private final double value;
public PlainMathValueImpl(double value) {
this.value = value;
}
@Override
public double evaluate(Context<T> context) {
return value;
}
}

View File

@@ -0,0 +1,17 @@
package net.momirealms.customfishing.api.mechanic.misc.value;
import net.momirealms.customfishing.api.mechanic.context.Context;
public class PlainTextValueImpl<T> implements TextValue<T> {
private final String raw;
public PlainTextValueImpl(String raw) {
this.raw = raw;
}
@Override
public String render(Context<T> context) {
return raw;
}
}

View File

@@ -0,0 +1,65 @@
package net.momirealms.customfishing.api.mechanic.misc.value;
import net.momirealms.customfishing.api.mechanic.context.Context;
import java.util.regex.Pattern;
/**
* The TextValue interface represents a text value that can be rendered
* within a specific context. This interface allows for the rendering of
* placeholder-based or plain text values in the context of custom fishing mechanics.
*
* @param <T> the type of the holder object for the context
*/
public interface TextValue<T> {
Pattern pattern = Pattern.compile("\\{[^{}]+}");
/**
* Renders the text value within the given context.
*
* @param context the context in which the text value is rendered
* @return the rendered text as a String
*/
String render(Context<T> context);
/**
* Creates a TextValue based on a placeholder text.
* Placeholders can be dynamically replaced with context-specific values.
*
* @param text the placeholder text to render
* @param <T> the type of the holder object for the context
* @return a TextValue instance representing the given placeholder text
*/
static <T> TextValue<T> placeholder(String text) {
return new PlaceholderTextValueImpl<>(text);
}
/**
* Creates a TextValue based on plain text.
*
* @param text the plain text to render
* @param <T> the type of the holder object for the context
* @return a TextValue instance representing the given plain text
*/
static <T> TextValue<T> plain(String text) {
return new PlainTextValueImpl<>(text);
}
/**
* Automatically creates a TextValue based on the given argument.
* If the argument contains placeholders (detected by a regex pattern),
* a PlaceholderTextValueImpl instance is created. Otherwise, a PlainTextValueImpl
* instance is created.
*
* @param arg the text to evaluate and create a TextValue from
* @param <T> the type of the holder object for the context
* @return a TextValue instance representing the given text, either as a placeholder or plain text
*/
static <T> TextValue<T> auto(String arg) {
if (pattern.matcher(arg).find())
return placeholder(arg);
else
return plain(arg);
}
}

View File

@@ -17,15 +17,21 @@
package net.momirealms.customfishing.api.mechanic.requirement;
import net.momirealms.customfishing.api.mechanic.condition.Condition;
public interface Requirement {
import net.momirealms.customfishing.api.mechanic.context.Context;
/**
* Is condition met the requirement
* Interface representing a requirement that must be met in the custom fishing API.
* This can be used to define conditions that need to be satisfied within a given context.
*
* @param condition condition
* @return meet or not
* @param <T> the type parameter for the context
*/
boolean isConditionMet(Condition condition);
public interface Requirement<T> {
/**
* Evaluates whether the requirement is met within the given context.
*
* @param context the context in which the requirement is evaluated
* @return true if the requirement is met, false otherwise
*/
boolean isSatisfied(Context<T> context);
}

View File

@@ -21,7 +21,7 @@ package net.momirealms.customfishing.api.mechanic.requirement;
* An abstract class representing a requirement expansion
* Requirement expansions are used to define custom requirements for various functionalities.
*/
public abstract class RequirementExpansion {
public abstract class RequirementExpansion<T> {
/**
* Get the version of this requirement expansion.
@@ -49,5 +49,5 @@ public abstract class RequirementExpansion {
*
* @return The requirement factory.
*/
public abstract RequirementFactory getRequirementFactory();
public abstract RequirementFactory<T> getRequirementFactory();
}

View File

@@ -22,19 +22,21 @@ import net.momirealms.customfishing.api.mechanic.action.Action;
import java.util.List;
/**
* An interface for a requirement factory that builds requirements.
* Interface representing a factory for creating requirements.
*
* @param <T> the type of object that the requirement will operate on
*/
public interface RequirementFactory {
public interface RequirementFactory<T> {
/**
* Build a requirement with the given arguments, not met actions, and check action flag.
* Build a requirement with the given arguments, not satisfied actions, and check run actions flag.
*
* @param args The arguments used to build the requirement.
* @param notMetActions Actions to be triggered when the requirement is not met (can be null).
* @param advanced Flag indicating whether to check the action when building the requirement.
* @param notSatisfiedActions Actions to be triggered when the requirement is not met (can be null).
* @param runActions Flag indicating whether to run the action if the requirement is not met.
* @return The built requirement.
*/
Requirement build(Object args, List<Action> notMetActions, boolean advanced);
Requirement<T> process(Object args, List<Action<T>> notSatisfiedActions, boolean runActions);
/**
* Build a requirement with the given arguments.
@@ -42,7 +44,7 @@ public interface RequirementFactory {
* @param args The arguments used to build the requirement.
* @return The built requirement.
*/
default Requirement build(Object args) {
return build(args, null, false);
default Requirement<T> process(Object args) {
return process(args, List.of(), false);
}
}

View File

@@ -15,26 +15,14 @@
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
package net.momirealms.customfishing.api.manager;
package net.momirealms.customfishing.api.mechanic.requirement;
import net.momirealms.customfishing.api.mechanic.condition.Condition;
import net.momirealms.customfishing.api.mechanic.requirement.Requirement;
import net.momirealms.customfishing.api.mechanic.requirement.RequirementFactory;
import org.bukkit.configuration.ConfigurationSection;
import dev.dejvokep.boostedyaml.block.implementation.Section;
import net.momirealms.customfishing.api.mechanic.context.Context;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
public interface RequirementManager {
/**
* Legacy format support
* @param key key
* @param requirements requirements
* @param weight weight
* @return success or not
*/
@Deprecated
boolean putLegacyLootToMap(String key, Requirement[] requirements, double weight);
public interface RequirementManager<T> {
/**
* Registers a custom requirement type with its corresponding factory.
@@ -43,7 +31,7 @@ public interface RequirementManager {
* @param requirementFactory The factory responsible for creating instances of the requirement.
* @return True if registration was successful, false if the type is already registered.
*/
boolean registerRequirement(String type, RequirementFactory requirementFactory);
boolean registerRequirement(@NotNull String type, @NotNull RequirementFactory<T> requirementFactory);
/**
* Unregisters a custom requirement type.
@@ -51,16 +39,17 @@ public interface RequirementManager {
* @param type The type identifier of the requirement to unregister.
* @return True if unregistration was successful, false if the type is not registered.
*/
boolean unregisterRequirement(String type);
boolean unregisterRequirement(@NotNull String type);
/**
* Retrieves an array of requirements based on a configuration section.
*
* @param section The configuration section containing requirement definitions.
* @param advanced A flag indicating whether to use advanced requirements.
* @param runActions A flag indicating whether to use advanced requirements.
* @return An array of Requirement objects based on the configuration section
*/
@Nullable Requirement[] getRequirements(ConfigurationSection section, boolean advanced);
@Nullable
Requirement<T>[] getRequirements(@NotNull Section section, boolean runActions);
/**
* If a requirement type exists
@@ -68,7 +57,7 @@ public interface RequirementManager {
* @param type type
* @return exists or not
*/
boolean hasRequirement(String type);
boolean hasRequirement(@NotNull String type);
/**
* Retrieves a Requirement object based on a configuration section and advanced flag.
@@ -78,10 +67,11 @@ public interface RequirementManager {
* value: xxx
*
* @param section The configuration section containing requirement definitions.
* @param advanced A flag indicating whether to use advanced requirements.
* @param runActions A flag indicating whether to use advanced requirements.
* @return A Requirement object based on the configuration section, or an EmptyRequirement if the section is null or invalid.
*/
@NotNull Requirement getRequirement(ConfigurationSection section, boolean advanced);
@NotNull
Requirement<T> getRequirement(@NotNull Section section, boolean runActions);
/**
* Gets a requirement based on the provided type and value.
@@ -95,7 +85,8 @@ public interface RequirementManager {
* @param value The value associated with the requirement.
* @return A Requirement instance based on the type and value, or an EmptyRequirement if the type is invalid.
*/
@NotNull Requirement getRequirement(String type, Object value);
@NotNull
Requirement<T> getRequirement(@NotNull String type, @NotNull Object value);
/**
* Retrieves a RequirementFactory based on the specified requirement type.
@@ -103,19 +94,13 @@ public interface RequirementManager {
* @param type The requirement type for which to retrieve a factory.
* @return A RequirementFactory for the specified type, or null if no factory is found.
*/
@Nullable RequirementFactory getRequirementFactory(String type);
@Nullable
RequirementFactory<T> getRequirementFactory(@NotNull String type);
/**
* Checks if an array of requirements is met for a given condition.
*
* @param condition The Condition object to check against the requirements.
* @param requirements An array of Requirement instances to be evaluated.
* @return True if all requirements are met, false otherwise. Returns true if the requirements array is null.
*/
static boolean isRequirementMet(Condition condition, Requirement... requirements) {
static <T> boolean isSatisfied(Context<T> context, @Nullable Requirement<T>... requirements) {
if (requirements == null) return true;
for (Requirement requirement : requirements) {
if (!requirement.isConditionMet(condition)) {
for (Requirement<T> requirement : requirements) {
if (!requirement.isSatisfied(context)) {
return false;
}
}

View File

@@ -19,8 +19,9 @@ package net.momirealms.customfishing.api.mechanic.statistic;
import net.momirealms.customfishing.api.data.StatisticData;
import net.momirealms.customfishing.api.mechanic.action.Action;
import net.momirealms.customfishing.api.mechanic.condition.Condition;
import net.momirealms.customfishing.api.mechanic.context.Context;
import net.momirealms.customfishing.api.mechanic.loot.Loot;
import org.bukkit.entity.Player;
import java.util.HashMap;
import java.util.Map;
@@ -50,23 +51,23 @@ public class Statistics {
* Adds an amount of loot to the statistics.
*
* @param loot The loot item.
* @param condition The condition associated with the loot.
* @param playerContext The condition associated with the loot.
* @param amount The amount of loot to add.
*/
public synchronized void addLootAmount(Loot loot, Condition condition, int amount) {
public synchronized void addLootAmount(Loot loot, Context<Player> playerContext, int amount) {
if (amount < 1) {
return;
}
if (amount == 1) {
addSingleLootAmount(loot, condition);
addSingleLootAmount(loot, playerContext);
return;
}
Integer previous = statisticMap.get(loot.getStatisticKey().getAmountKey());
Integer previous = statisticMap.get(loot.getStatisticKey().amountKey());
if (previous == null) previous = 0;
int after = previous + amount;
statisticMap.put(loot.getStatisticKey().getAmountKey(), after);
statisticMap.put(loot.getStatisticKey().amountKey(), after);
total += amount;
doSuccessTimesAction(previous, after, condition, loot);
doSuccessTimesAction(previous, after, playerContext, loot);
}
/**
@@ -74,16 +75,16 @@ public class Statistics {
*
* @param previous The previous success times.
* @param after The updated success times.
* @param condition The condition associated with the loot.
* @param playerContext The condition associated with the loot.
* @param loot The loot item.
*/
private void doSuccessTimesAction(Integer previous, int after, Condition condition, Loot loot) {
HashMap<Integer, Action[]> actionMap = loot.getSuccessTimesActionMap();
private void doSuccessTimesAction(Integer previous, int after, Context<Player> playerContext, Loot loot) {
HashMap<Integer, Action<Player>[]> actionMap = loot.getRecordActionMap();
if (actionMap != null) {
for (Map.Entry<Integer, Action[]> entry : actionMap.entrySet()) {
for (Map.Entry<Integer, Action<Player>[]> entry : actionMap.entrySet()) {
if (entry.getKey() > previous && entry.getKey() <= after) {
for (Action action : entry.getValue()) {
action.trigger(condition);
for (Action<Player> action : entry.getValue()) {
action.trigger(playerContext);
}
}
}
@@ -101,18 +102,18 @@ public class Statistics {
* Adds a single loot amount to the statistics.
*
* @param loot The loot item.
* @param condition The condition associated with the loot.
* @param playerContext The condition associated with the loot.
*/
private void addSingleLootAmount(Loot loot, Condition condition) {
private void addSingleLootAmount(Loot loot, Context<Player> playerContext) {
Integer previous = statisticMap.get(loot.getID());
if (previous == null) previous = 0;
int after = previous + 1;
statisticMap.put(loot.getID(), after);
total += 1;
Action[] actions = loot.getSuccessTimesActionMap().get(after);
Action<Player>[] actions = loot.getRecordActionMap().get(after);
if (actions != null)
for (Action action : actions) {
action.trigger(condition);
for (Action<Player> action : actions) {
action.trigger(playerContext);
}
}

View File

@@ -1,20 +0,0 @@
package net.momirealms.customfishing.api.mechanic.statistic;
public class StatisticsKey {
private final String amountKey;
private final String sizeKey;
public StatisticsKey(String amountKey, String sizeKey) {
this.amountKey = amountKey;
this.sizeKey = sizeKey;
}
public String getAmountKey() {
return amountKey;
}
public String getSizeKey() {
return sizeKey;
}
}

View File

@@ -15,11 +15,7 @@
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
package net.momirealms.customfishing.api.manager;
package net.momirealms.customfishing.api.mechanic.statistic;
public interface CommandManager {
void load();
void unload();
public record StatisticsKeys(String amountKey, String sizeKey) {
}

View File

@@ -15,9 +15,8 @@
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
package net.momirealms.customfishing.api.manager;
package net.momirealms.customfishing.api.mechanic.statistic;
import net.momirealms.customfishing.api.mechanic.statistic.Statistics;
import org.jetbrains.annotations.Nullable;
import java.util.List;
@@ -31,7 +30,8 @@ public interface StatisticsManager {
* @param uuid The UUID of the player for whom statistics are retrieved.
* @return The player's statistics or null if the player is not found.
*/
@Nullable Statistics getStatistics(UUID uuid);
@Nullable
Statistics getStatistics(UUID uuid);
/**
* Get a list of strings associated with a specific key in a category map.
@@ -39,5 +39,6 @@ public interface StatisticsManager {
* @param key The key to look up in the category map.
* @return A list of strings associated with the key or null if the key is not found.
*/
@Nullable List<String> getCategory(String key);
@Nullable
List<String> getCategory(String key);
}

View File

@@ -15,7 +15,7 @@
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
package net.momirealms.customfishing.api.manager;
package net.momirealms.customfishing.api.mechanic.totem;
import net.momirealms.customfishing.api.mechanic.effect.EffectCarrier;
import org.bukkit.Location;

View File

@@ -17,7 +17,7 @@
package net.momirealms.customfishing.api.mechanic.totem.block.type;
import net.momirealms.customfishing.api.CustomFishingPlugin;
import net.momirealms.customfishing.api.BukkitCustomFishingPlugin;
import org.bukkit.block.Block;
import java.io.Serializable;
@@ -41,7 +41,7 @@ public class EqualType implements TypeCondition, Serializable {
*/
@Override
public boolean isMet(Block type) {
return this.type.equals(CustomFishingPlugin.get().getBlockManager().getAnyPluginBlockID(type));
return this.type.equals(BukkitCustomFishingPlugin.get().getBlockManager().getAnyPluginBlockID(type));
}
/**

View File

@@ -1,33 +0,0 @@
/*
* 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.scheduler;
public interface CancellableTask {
/**
* Cancel the task
*/
void cancel();
/**
* Get if the task is cancelled or not
*
* @return cancelled or not
*/
boolean isCancelled();
}

View File

@@ -1,93 +0,0 @@
/*
* 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.scheduler;
import org.bukkit.Location;
import java.util.concurrent.TimeUnit;
public interface Scheduler {
/**
* Runs a task synchronously on the main server thread or region thread.
*
* @param runnable The task to run.
* @param location The location associated with the task.
*/
void runTaskSync(Runnable runnable, Location location);
/**
* Runs a task synchronously with a specified delay and period.
*
* @param runnable The task to run.
* @param location The location associated with the task.
* @param delayTicks The delay in ticks before the first execution.
* @param periodTicks The period between subsequent executions in ticks.
* @return A CancellableTask for managing the scheduled task.
*/
CancellableTask runTaskSyncTimer(Runnable runnable, Location location, long delayTicks, long periodTicks);
/**
* Runs a task asynchronously with a specified delay.
*
* @param runnable The task to run.
* @param delay The delay before the task execution.
* @param timeUnit The time unit for the delay.
* @return A CancellableTask for managing the scheduled task.
*/
CancellableTask runTaskAsyncLater(Runnable runnable, long delay, TimeUnit timeUnit);
/**
* Runs a task asynchronously.
*
* @param runnable The task to run.
*/
void runTaskAsync(Runnable runnable);
/**
* Runs a task synchronously with a specified delay.
*
* @param runnable The task to run.
* @param location The location associated with the task.
* @param delay The delay before the task execution.
* @param timeUnit The time unit for the delay.
* @return A CancellableTask for managing the scheduled task.
*/
CancellableTask runTaskSyncLater(Runnable runnable, Location location, long delay, TimeUnit timeUnit);
/**
* Runs a task synchronously with a specified delay in ticks.
*
* @param runnable The task to run.
* @param location The location associated with the task.
* @param delayTicks The delay in ticks before the task execution.
* @return A CancellableTask for managing the scheduled task.
*/
CancellableTask runTaskSyncLater(Runnable runnable, Location location, long delayTicks);
/**
* Runs a task asynchronously with a specified delay and period.
*
* @param runnable The task to run.
* @param delay The delay before the first execution.
* @param period The period between subsequent executions.
* @param timeUnit The time unit for the delay and period.
* @return A CancellableTask for managing the scheduled task.
*/
CancellableTask runTaskAsyncTimer(Runnable runnable, long delay, long period, TimeUnit timeUnit);
}

View File

@@ -1,39 +0,0 @@
/*
* 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;
/**
* Utility class for working with fonts in text.
*/
public class FontUtils {
private FontUtils() {
throw new UnsupportedOperationException("This class cannot be instantiated");
}
/**
* Surrounds the given text with a specified font tag.
*
* @param text The text to be surrounded with the font tag.
* @param font The font to use in the font tag.
* @return The input text surrounded by the font tag.
*/
public static String surroundWithFont(String text, String font) {
return "<font:" + font + ">" + text + "</font>";
}
}

View File

@@ -1,185 +0,0 @@
/*
* 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.kyori.adventure.text.Component;
import net.momirealms.customfishing.api.CustomFishingPlugin;
import org.bukkit.event.inventory.InventoryType;
import org.bukkit.inventory.Inventory;
import org.bukkit.inventory.InventoryHolder;
import org.bukkit.inventory.ItemStack;
import org.bukkit.util.io.BukkitObjectInputStream;
import org.bukkit.util.io.BukkitObjectOutputStream;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.yaml.snakeyaml.external.biz.base64Coder.Base64Coder;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
/**
* Utility class for working with Bukkit Inventories and item stacks.
*/
public class InventoryUtils {
private InventoryUtils() {
throw new UnsupportedOperationException("This class cannot be instantiated");
}
/**
* Create a custom inventory with a specified size and title component.
*
* @param inventoryHolder The holder of the inventory.
* @param size The size of the inventory.
* @param component The title component of the inventory.
* @return The created Inventory instance.
*/
public static Inventory createInventory(InventoryHolder inventoryHolder, int size, Component component) {
try {
boolean isSpigot = CustomFishingPlugin.get().getVersionManager().isSpigot();
Method createInvMethod = ReflectionUtils.bukkitClass.getMethod(
"createInventory",
InventoryHolder.class,
int.class,
isSpigot ? String.class : ReflectionUtils.componentClass
);
return (Inventory) createInvMethod.invoke(
null,
inventoryHolder,
size,
isSpigot ? CustomFishingPlugin.get().getAdventure().componentToLegacy(component) : CustomFishingPlugin.get().getAdventure().shadedComponentToOriginalComponent(component)
);
} catch (NoSuchMethodException | InvocationTargetException | IllegalAccessException exception) {
exception.printStackTrace();
return null;
}
}
/**
* Create a custom inventory with a specified type and title component.
*
* @param inventoryHolder The holder of the inventory.
* @param type The type of the inventory.
* @param component The title component of the inventory.
* @return The created Inventory instance.
*/
public static Inventory createInventory(InventoryHolder inventoryHolder, InventoryType type, Component component) {
try {
boolean isSpigot = CustomFishingPlugin.get().getVersionManager().isSpigot();
Method createInvMethod = ReflectionUtils.bukkitClass.getMethod(
"createInventory",
InventoryHolder.class,
InventoryType.class,
isSpigot ? String.class : ReflectionUtils.componentClass
);
return (Inventory) createInvMethod.invoke(
null,
inventoryHolder,
type,
isSpigot ? CustomFishingPlugin.get().getAdventure().componentToLegacy(component) : CustomFishingPlugin.get().getAdventure().shadedComponentToOriginalComponent(component)
);
} catch (NoSuchMethodException | InvocationTargetException | IllegalAccessException exception) {
exception.printStackTrace();
return null;
}
}
/**
* Serialize an array of ItemStacks to a Base64-encoded string.
*
* @param contents The ItemStack array to serialize.
* @return The Base64-encoded string representing the serialized ItemStacks.
*/
public static @NotNull String stacksToBase64(ItemStack[] contents) {
if (contents.length == 0) {
return "";
}
try {
ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
BukkitObjectOutputStream dataOutput = new BukkitObjectOutputStream(outputStream);
dataOutput.writeInt(contents.length);
for (ItemStack itemStack : contents) {
dataOutput.writeObject(itemStack);
}
dataOutput.close();
byte[] byteArr = outputStream.toByteArray();
outputStream.close();
return Base64Coder.encodeLines(byteArr);
} catch (IOException e) {
LogUtils.warn("Encoding error", e);
}
return "";
}
/**
* Deserialize an ItemStack array from a Base64-encoded string.
*
* @param base64 The Base64-encoded string representing the serialized ItemStacks.
* @return An array of ItemStacks deserialized from the input string.
*/
@Nullable
public static ItemStack[] getInventoryItems(String base64) {
ItemStack[] itemStacks = null;
try {
itemStacks = stacksFromBase64(base64);
} catch (IllegalArgumentException exception) {
exception.printStackTrace();
}
return itemStacks;
}
private static ItemStack[] stacksFromBase64(String data) {
if (data == null || data.equals("")) return new ItemStack[]{};
ByteArrayInputStream inputStream;
try {
inputStream = new ByteArrayInputStream(Base64Coder.decodeLines(data));
} catch (IllegalArgumentException e) {
return new ItemStack[]{};
}
BukkitObjectInputStream dataInput = null;
ItemStack[] stacks = null;
try {
dataInput = new BukkitObjectInputStream(inputStream);
stacks = new ItemStack[dataInput.readInt()];
} catch (IOException e) {
e.printStackTrace();
}
if (stacks == null) return new ItemStack[]{};
for (int i = 0; i < stacks.length; i++) {
try {
stacks[i] = (ItemStack) dataInput.readObject();
} catch (IOException | ClassNotFoundException | NullPointerException e) {
try {
dataInput.close();
} catch (IOException exception) {
LogUtils.severe("Failed to read fishing bag data");
}
return null;
}
}
try {
dataInput.close();
} catch (IOException ignored) {
}
return stacks;
}
}

Some files were not shown because too many files have changed in this diff Show More