9
0
mirror of https://github.com/Xiao-MoMi/Custom-Nameplates.git synced 2025-12-19 15:09:23 +00:00

update docs

This commit is contained in:
XiaoMoMi
2025-01-26 21:03:31 +08:00
parent b41e1bd2ab
commit 88e4af721b
70 changed files with 2132 additions and 218 deletions

View File

@@ -33,6 +33,8 @@ java {
toolchain {
languageVersion = JavaLanguageVersion.of(17)
}
withSourcesJar()
withJavadocJar()
}
tasks.withType<JavaCompile> {
@@ -43,20 +45,39 @@ tasks.withType<JavaCompile> {
tasks {
shadowJar {
archiveClassifier = ""
archiveFileName = "CustomNameplates-${rootProject.properties["project_version"]}.jar"
// archiveClassifier.set("")
archiveFileName = "custom-nameplates-${rootProject.properties["project_version"]}.jar"
relocate ("net.kyori", "net.momirealms.customnameplates.libraries")
relocate("dev.dejvokep", "net.momirealms.customnameplates.libraries")
}
javadoc {
options {
encoding = "UTF-8"
}
options.quiet()
}
}
publishing {
repositories {
maven {
url = uri("https://repo.momirealms.net/releases")
credentials(PasswordCredentials::class) {
username = System.getenv("REPO_USERNAME")
password = System.getenv("REPO_PASSWORD")
}
}
}
publications {
create<MavenPublication>("mavenJava") {
groupId = "net.momirealms"
artifactId = "CustomNameplates"
version = rootProject.version.toString()
artifact(tasks.shadowJar)
artifactId = "custom-nameplates"
version = rootProject.properties["project_version"].toString()
from(components["java"])
pom {
name = "CustomNameplates API"
url = "https://momirealms.net"
}
}
}
}

View File

@@ -39,11 +39,21 @@ import java.util.concurrent.CopyOnWriteArraySet;
import java.util.concurrent.locks.ReadWriteLock;
import java.util.concurrent.locks.ReentrantReadWriteLock;
/**
* Player instance adapted by CustomNameplates
*/
public abstract class AbstractCNPlayer implements CNPlayer {
/**
* The CustomNameplates plugin
*/
protected final CustomNameplates plugin;
/**
* Player netty channel
*/
protected final Channel channel;
/**
* Platform player instance
*/
protected Object player;
private volatile boolean isLoaded = false;
@@ -71,6 +81,12 @@ public abstract class AbstractCNPlayer implements CNPlayer {
private final ReadWriteLock trackerLock = new ReentrantReadWriteLock();
private final List<String> otherActionBarFeatures = new ArrayList<>();
/**
* Creates a player instance
*
* @param plugin CustomNameplates plugin
* @param channel netty channel
*/
protected AbstractCNPlayer(CustomNameplates plugin, Channel channel) {
this.plugin = plugin;
this.channel = channel;
@@ -204,6 +220,9 @@ public abstract class AbstractCNPlayer implements CNPlayer {
}
}
/**
* Reload the player instance, clear caches
*/
public void reload() {
cachedValues.clear();
cachedRelationalValues.clear();
@@ -214,6 +233,11 @@ public abstract class AbstractCNPlayer implements CNPlayer {
feature2Placeholders.clear();
}
/**
* Sets the platform player instance on join
*
* @param player player
*/
public void setPlayer(Object player) {
this.player = player;
}
@@ -233,10 +257,20 @@ public abstract class AbstractCNPlayer implements CNPlayer {
return player;
}
/**
* Sets if the player data is loaded
*
* @param loaded loaded or not
*/
public void setLoaded(boolean loaded) {
isLoaded = loaded;
}
/**
* Sets if the player is temporarily previewing the nameplate
*
* @param previewing is previewing or not
*/
public void setTempPreviewing(boolean previewing) {
this.tempPreviewing = previewing;
}
@@ -246,6 +280,11 @@ public abstract class AbstractCNPlayer implements CNPlayer {
return tempPreviewing;
}
/**
* Sets if the player is using toggle command to preview his nameplate
*
* @param previewing is previewing or not
*/
public void setToggleablePreviewing(boolean previewing) {
this.toggleablePreviewing = previewing;
}

View File

@@ -36,6 +36,9 @@ import java.util.List;
import java.util.Set;
import java.util.UUID;
/**
* CustomNameplates Player
*/
public interface CNPlayer {
/**

View File

@@ -42,10 +42,27 @@ import java.nio.file.Files;
import java.nio.file.Path;
import java.util.Locale;
/**
* Manages the loading and handling of configuration files for the Custom Nameplates plugin.
*/
public abstract class ConfigManager implements ConfigLoader, Reloadable {
/**
* The main configuration document that stores all settings for the plugin.
* <p>
* This document is loaded during the initialization of the plugin and is used to retrieve various configuration values.
* </p>
*/
private static YamlDocument MAIN_CONFIG;
/**
* Returns the main configuration document.
* <p>
* If the configuration has not been loaded yet, an {@code IllegalStateException} will be thrown.
* </p>
*
* @return The main configuration document
* @throws IllegalStateException If the configuration has not been loaded
*/
public static YamlDocument getMainConfig() {
if (MAIN_CONFIG == null) {
throw new IllegalStateException("Main config not loaded");
@@ -53,79 +70,292 @@ public abstract class ConfigManager implements ConfigLoader, Reloadable {
return MAIN_CONFIG;
}
/**
* The singleton instance of the {@code ConfigManager}.
*/
private static ConfigManager instance;
/**
* The {@code CustomNameplates} plugin instance associated with this {@code ConfigManager}.
*/
protected final CustomNameplates plugin;
/**
* Indicates whether debugging is enabled.
*/
protected boolean debug;
/**
* Indicates whether plugin updates are checked automatically.
*/
protected boolean checkUpdate;
/**
* Metrics flag to enable or disable the metrics system.
*/
protected boolean metrics;
/**
* Flag to enable or disable the nametag module.
*/
protected boolean nametagModule;
/**
* Flag to enable or disable the action bar module.
*/
protected boolean actionbarModule;
/**
* Flag to enable or disable the image module.
*/
protected boolean imageModule;
/**
* Flag to enable or disable the boss bar module.
*/
protected boolean bossBarModule;
/**
* Flag to enable or disable the bubble module.
*/
protected boolean bubbleModule;
/**
* Flag to enable or disable the nameplate module.
*/
protected boolean nameplateModule;
/**
* Flag to enable or disable the background module.
*/
protected boolean backgroundModule;
/**
* Flag to hide or display team names.
*/
protected boolean hideTeamNames;
/**
* The default placeholder refresh interval (in seconds).
*/
protected int defaultPlaceholderRefreshInterval;
/**
* The default condition refresh interval (in seconds).
*/
protected int defaultConditionRefreshInterval;
/**
* The delay (in milliseconds) before sending updates.
*/
protected int delaySend;
/**
* Flag to catch other action bar events.
*/
protected boolean catchOtherActionBar;
/**
* Flag to display system chat messages.
*/
protected boolean displaySystemChat;
/**
* The duration (in seconds) that other action bars will stay visible.
*/
protected int otherActionBarStayTime;
/**
* The namespace used for resource identification.
*/
protected String namespace;
/**
* The font used for rendering text.
*/
protected String font;
/**
* Flag to generate configurations on plugin start.
*/
protected boolean generateOnStart;
/**
* The initial character used in text or formatting.
*/
protected char initialChar;
/**
* The path to the image resource.
*/
protected String imagePath;
/**
* The path to the nameplate resource.
*/
protected String nameplatePath;
/**
* The path to the bubble resource.
*/
protected String bubblePath;
/**
* The path used for splitting space resources.
*/
protected String spaceSplitPath;
/**
* The path to the background resource.
*/
protected String backgroundPath;
/**
* Flag to enable or disable shader effects.
*/
protected boolean enableShader;
/**
* Flag to hide or show scoreboard numbers.
*/
protected boolean hideScoreBoardNumber;
/**
* Flag to enable or disable animated text.
*/
protected boolean animatedText;
/**
* Flag to enable or disable the ItemsAdder effect.
*/
protected boolean itemsAdderEffect;
/**
* The color used for the boss bar when removed.
*/
protected BossBar.Color removedBarColor;
/**
* Flag to enable compatibility for version 1.20.2 of Minecraft.
*/
protected boolean bossBar1_20_2;
/**
* Flag to enable compatibility for version 1.17 of Minecraft.
*/
protected boolean bossBar1_17;
/**
* Flag to enable or disable legacy Unicode support.
*/
protected boolean legacyUnicodes;
/**
* Flag to enable or disable ItemsAdder pack.
*/
protected boolean packItemsAdder;
/**
* Flag to enable or disable legacy ItemsAdder pack.
*/
protected boolean packItemsAdderLegacy;
/**
* Flag to enable or disable Oraxen pack.
*/
protected boolean packOraxen;
/**
* Flag to enable or disable Nexo pack.
*/
protected boolean packNexo;
/**
* Flag to enable or disable Creative Central pack.
*/
protected boolean packCreativeCentral;
/**
* Flag to enable or disable CraftEngine pack.
*/
protected boolean packCraftEngine;
/**
* Flag to enable or disable unsafe chat features.
*/
protected boolean chatUnsafe;
/**
* Flag to enable or disable chat features for TR (text roleplay).
*/
protected boolean chatTR;
/**
* Flag to enable or disable chat features for Venture.
*/
protected boolean chatVenture;
/**
* Flag to enable or disable chat features for Husk.
*/
protected boolean chatHusk;
/**
* Flag to enable or disable chat features for Carbon.
*/
protected boolean chatCarbon;
/**
* Flag to enable or disable chat features for Advanced.
*/
protected boolean chatAdvanced;
/**
* Flag to enable or disable chat features for Essentials.
*/
protected boolean chatEss;
/**
* Flag to enable or disable chat features for ChatControlRed.
*/
protected boolean chatChatControlRed;
/**
* Flag to enable or disable chat features for Chatty.
*/
protected boolean chatChatty;
/**
* Flag to enable or disable dialogue features for TW (text world).
*/
protected boolean twDialogue;
/**
* Flag to enable or disable cinematic features for TW (text world).
*/
protected boolean twCinematic;
/**
* The version of the current configuration.
*/
protected String configVersion;
/**
* Constructs a new {@code ConfigManager} for the specified {@code CustomNameplates} plugin instance.
*
* @param plugin The {@code CustomNameplates} plugin instance
*/
public ConfigManager(CustomNameplates plugin) {
this.plugin = plugin;
instance = this;
}
/**
* Loads the configuration file from the specified path and initializes various settings.
* <p>
* This method reads the {@code config.yml} file and sets up all configuration options such as modules,
* integrations, and resource packs. It also handles versioning and saves the loaded configuration back
* to the file system.
* </p>
*
* @throws RuntimeException If an error occurs while loading or saving the configuration
*/
@Override
public void load() {
configVersion = CustomNameplatesProperties.getValue("config");
@@ -163,6 +393,13 @@ public abstract class ConfigManager implements ConfigLoader, Reloadable {
loadSettings();
}
/**
* Loads the settings from the configuration document into various fields.
* <p>
* This method parses the {@code MAIN_CONFIG} document and assigns values to the class fields.
* It also applies settings such as locale and legacy support.
* </p>
*/
private void loadSettings() {
YamlDocument config = MAIN_CONFIG;
AdventureHelper.legacySupport = config.getBoolean("other-settings.legacy-color-code-support", true);
@@ -242,218 +479,440 @@ public abstract class ConfigManager implements ConfigLoader, Reloadable {
public void unload() {
Reloadable.super.unload();
}
/**
* Retrieves the delay before sending updates.
* @return the delay time (in milliseconds).
*/
public static int delaySend() {
return instance.delaySend;
}
/**
* Retrieves the path used for splitting space resources.
* @return the space split path.
*/
public static String spaceSplitPath() {
return instance.spaceSplitPath;
}
/**
* Retrieves the path to the bubble resource.
* @return the bubble path.
*/
public static String bubblePath() {
return instance.bubblePath;
}
/**
* Retrieves the path to the image resource.
* @return the image path.
*/
public static String imagePath() {
return instance.imagePath;
}
/**
* Retrieves the path to the background resource.
* @return the background path.
*/
public static String backgroundPath() {
return instance.backgroundPath;
}
/**
* Retrieves the path to the nameplate resource.
* @return the nameplate path.
*/
public static String nameplatePath() {
return instance.nameplatePath;
}
/**
* Retrieves whether configuration generation is enabled on startup.
* @return true if configuration generation is enabled on start; false otherwise.
*/
public static boolean generateOnStart() {
return instance.generateOnStart;
}
/**
* Retrieves the namespace used for resource identification.
* @return the namespace.
*/
public static String namespace() {
return instance.namespace;
}
/**
* Retrieves the font used for rendering text.
* @return the font.
*/
public static String font() {
return instance.font;
}
/**
* Retrieves the version of the current configuration.
* @return the config version.
*/
public static String configVersion() {
return instance.configVersion;
}
/**
* Retrieves the initial character used for formatting.
* @return the initial character.
*/
public static char initialChar() {
return instance.initialChar;
}
/**
* Retrieves whether team names are hidden.
* @return true if team names are hidden; false otherwise.
*/
public static boolean hideTeamNames() {
return instance.hideTeamNames;
}
/**
* Retrieves whether the action bar module is enabled.
* @return true if the action bar module is enabled; false otherwise.
*/
public static boolean actionbarModule() {
return instance.actionbarModule;
}
/**
* Retrieves whether the nametag module is enabled.
* @return true if the nametag module is enabled; false otherwise.
*/
public static boolean nametagModule() {
return instance.nametagModule;
}
/**
* Retrieves whether other action bars should be caught.
* @return true if other action bars are caught; false otherwise.
*/
public static boolean catchOtherActionBar() {
return instance.catchOtherActionBar;
}
/**
* Retrieves whether system chat should be displayed.
* @return true if system chat is displayed; false otherwise.
*/
public static boolean displaySystemChat() {
return instance.displaySystemChat;
}
/**
* Retrieves whether the ItemsAdder pack is enabled.
* @return true if the ItemsAdder pack is enabled; false otherwise.
*/
public static boolean packItemsAdder() {
return instance.packItemsAdder;
}
/**
* Retrieves whether the legacy ItemsAdder pack is enabled.
* @return true if the legacy ItemsAdder pack is enabled; false otherwise.
*/
public static boolean packItemsAdderLegacy() {
return instance.packItemsAdderLegacy;
}
/**
* Retrieves whether the Oraxen pack is enabled.
* @return true if the Oraxen pack is enabled; false otherwise.
*/
public static boolean packOraxen() {
return instance.packOraxen;
}
/**
* Retrieves whether the Nexo pack is enabled.
* @return true if the Nexo pack is enabled; false otherwise.
*/
public static boolean packNexo() {
return instance.packNexo;
}
/**
* Retrieves whether the CraftEngine pack is enabled.
* @return true if the CraftEngine pack is enabled; false otherwise.
*/
public static boolean packCraftEngine() {
return instance.packCraftEngine;
}
public static boolean packCreativeCentral() { return instance.packCreativeCentral; }
/**
* Retrieves whether the Creative Central pack is enabled.
* @return true if the Creative Central pack is enabled; false otherwise.
*/
public static boolean packCreativeCentral() {
return instance.packCreativeCentral;
}
/**
* Retrieves whether the scoreboard numbers should be hidden.
* @return true if scoreboard numbers are hidden; false otherwise.
*/
public static boolean hideScoreBoardNumber() {
return instance.hideScoreBoardNumber;
}
/**
* Retrieves whether animated text is enabled.
* @return true if animated text is enabled; false otherwise.
*/
public static boolean animatedText() {
return instance.animatedText;
}
/**
* Retrieves whether the ItemsAdder effect is enabled.
* @return true if the ItemsAdder effect is enabled; false otherwise.
*/
public static boolean itemsAdderEffect() {
return instance.itemsAdderEffect;
}
/**
* Retrieves the color to be used for a removed boss bar.
* @return the color for the removed bar.
*/
public static BossBar.Color removedBarColor() {
return instance.removedBarColor;
}
/**
* Retrieves whether the image module is enabled.
* @return true if the image module is enabled; false otherwise.
*/
public static boolean imageModule() {
return instance.imageModule;
}
/**
* Retrieves whether the boss bar module is enabled.
* @return true if the boss bar module is enabled; false otherwise.
*/
public static boolean bossbarModule() {
return instance.bossBarModule;
}
/**
* Retrieves whether the bubble module is enabled.
* @return true if the bubble module is enabled; false otherwise.
*/
public static boolean bubbleModule() {
return instance.bubbleModule;
}
/**
* Retrieves whether the background module is enabled.
* @return true if the background module is enabled; false otherwise.
*/
public static boolean backgroundModule() {
return instance.backgroundModule;
}
/**
* Retrieves whether the nameplate module is enabled.
* @return true if the nameplate module is enabled; false otherwise.
*/
public static boolean nameplateModule() {
return instance.nameplateModule;
}
/**
* Retrieves whether debugging is enabled.
* @return true if debugging is enabled; false otherwise.
*/
public static boolean debug() {
return instance.debug;
}
/**
* Retrieves whether the plugin checks for updates.
* @return true if update checks are enabled; false otherwise.
*/
public static boolean checkUpdate() {
return instance.checkUpdate;
}
/**
* Retrieves whether the metrics system is enabled.
* @return true if the metrics system is enabled; false otherwise.
*/
public static boolean metrics() {
return instance.metrics;
}
/**
* Retrieves whether dialogue features for text world (TW) are enabled.
* @return true if TW dialogue is enabled; false otherwise.
*/
public static boolean twDialogue() {
return instance.twDialogue;
}
/**
* Retrieves whether cinematic features for text world (TW) are enabled.
* @return true if TW cinematic is enabled; false otherwise.
*/
public static boolean twCinematic() {
return instance.twCinematic;
}
/**
* Retrieves the default placeholder refresh interval (in seconds).
* @return the default placeholder refresh interval.
*/
public static int defaultPlaceholderRefreshInterval() {
return instance.defaultPlaceholderRefreshInterval;
}
/**
* Retrieves the default condition refresh interval (in seconds).
* @return the default condition refresh interval.
*/
public static int defaultConditionRefreshInterval() {
return instance.defaultConditionRefreshInterval;
}
/**
* Retrieves the duration (in seconds) that other action bars will stay visible.
* @return the duration for other action bars to stay visible.
*/
public static int otherActionBarStayTime() {
return instance.otherActionBarStayTime;
}
/**
* Retrieves whether shader effects are enabled.
* @return true if shader effects are enabled; false otherwise.
*/
public static boolean enableShader() {
return instance.enableShader;
}
/**
* Retrieves whether legacy Unicode support is enabled.
* @return true if legacy Unicode support is enabled; false otherwise.
*/
public static boolean legacyUnicodes() {
return instance.legacyUnicodes;
}
/**
* Retrieves whether compatibility with Minecraft 1.20.2 is enabled for the boss bar.
* @return true if the boss bar is compatible with Minecraft 1.20.2; false otherwise.
*/
public static boolean bossBar1_20_2() {
return instance.bossBar1_20_2;
}
/**
* Retrieves whether compatibility with Minecraft 1.17 is enabled for the boss bar.
* @return true if the boss bar is compatible with Minecraft 1.17; false otherwise.
*/
public static boolean bossBar1_17() {
return instance.bossBar1_17;
}
/**
* Retrieves whether unsafe chat features are enabled.
* @return true if unsafe chat is enabled; false otherwise.
*/
public static boolean chatUnsafe() {
return instance.chatUnsafe;
}
/**
* Retrieves whether TrChat features are enabled.
* @return true if TR chat is enabled; false otherwise.
*/
public static boolean chatTrChat() {
return instance.chatTR;
}
/**
* Retrieves whether VentureChat features are enabled.
* @return true if Venture chat is enabled; false otherwise.
*/
public static boolean chatVenture() {
return instance.chatVenture;
}
/**
* Retrieves whether HuskChat features are enabled.
* @return true if Husk chat is enabled; false otherwise.
*/
public static boolean chatHusk() {
return instance.chatHusk;
}
/**
* Retrieves whether Essentials chat features are enabled.
* @return true if Essentials chat is enabled; false otherwise.
*/
public static boolean chatEss() {
return instance.chatEss;
}
/**
* Retrieves whether CarbonChat features are enabled.
* @return true if Carbon chat is enabled; false otherwise.
*/
public static boolean chatCarbon() {
return instance.chatCarbon;
}
/**
* Retrieves whether AdvancedChat features are enabled.
* @return true if Advanced chat is enabled; false otherwise.
*/
public static boolean chatAdvanced() {
return instance.chatAdvanced;
}
/**
* Retrieves whether RedChatControl is enabled.
* @return true if Red chat control is enabled; false otherwise.
*/
public static boolean chatChatControlRed() {
return instance.chatChatControlRed;
}
/**
* Retrieves whether Chatty chat features are enabled.
* @return true if Chatty chat is enabled; false otherwise.
*/
public static boolean chatChatty() {
return instance.chatChatty;
}
/**
* Returns the configuration file at the specified path with a custom route separator.
*
* @param filePath The path to the configuration file
* @return The {@code YamlDocument} representing the loaded configuration
*/
@Override
public YamlDocument loadConfig(String filePath) {
return loadConfig(filePath, '.');
}
/**
* Returns the configuration file at the specified path with a custom route separator.
*
* @param filePath The path to the configuration file
* @param routeSeparator The character used to separate route segments in the YAML file
* @return The {@code YamlDocument} representing the loaded configuration
*/
@Override
public YamlDocument loadConfig(String filePath, char routeSeparator) {
try (InputStream inputStream = new FileInputStream(resolveConfig(filePath).toFile())) {
@@ -485,6 +944,17 @@ public abstract class ConfigManager implements ConfigLoader, Reloadable {
}
}
/**
* Loads the configuration file from the specified file path.
*
* @param filePath the relative or absolute path to the configuration file.
* @param generalSettings settings for general YAML loading behavior.
* @param loaderSettings settings for YAML loader behavior.
* @param dumperSettings settings for YAML dumping behavior.
* @param updaterSettings settings for YAML updating behavior.
* @return a {@link YamlDocument} containing the loaded YAML content.
* @throws RuntimeException if the configuration file could not be loaded or an error occurs.
*/
@Override
public YamlDocument loadConfig(String filePath, GeneralSettings generalSettings, LoaderSettings loaderSettings, DumperSettings dumperSettings, UpdaterSettings updaterSettings) {
try (InputStream inputStream = new FileInputStream(resolveConfig(filePath).toFile())) {
@@ -502,6 +972,13 @@ public abstract class ConfigManager implements ConfigLoader, Reloadable {
}
}
/**
* Loads the YAML data from the specified file.
*
* @param file the file containing the YAML data.
* @return a {@link YamlDocument} containing the loaded YAML data.
* @throws RuntimeException if the data file could not be loaded or an error occurs.
*/
@Override
public YamlDocument loadData(File file) {
try (InputStream inputStream = new FileInputStream(file)) {
@@ -512,6 +989,15 @@ public abstract class ConfigManager implements ConfigLoader, Reloadable {
}
}
/**
* Resolves the configuration file path and ensures the file exists.
* If the configuration file does not exist, it is created from an embedded resource.
*
* @param filePath the relative or absolute path to the configuration file.
* @return the resolved {@link Path} to the configuration file.
* @throws IllegalArgumentException if the filePath is null or empty, or if the embedded resource cannot be found.
* @throws RuntimeException if an error occurs during file creation or copying.
*/
public Path resolveConfig(String filePath) {
if (filePath == null || filePath.isEmpty()) {
throw new IllegalArgumentException("ResourcePath cannot be null or empty");

View File

@@ -17,7 +17,6 @@
package net.momirealms.customnameplates.api;
import it.unimi.dsi.fastutil.ints.Int2ObjectOpenHashMap;
import it.unimi.dsi.fastutil.objects.ObjectArrayList;
import net.momirealms.customnameplates.api.feature.actionbar.ActionBarManager;
import net.momirealms.customnameplates.api.feature.advance.AdvanceManager;
@@ -52,34 +51,137 @@ import java.util.function.Supplier;
* Provides access to managers for various features.
*/
public abstract class CustomNameplates implements NameplatesPlugin {
private static CustomNameplates instance;
/**
* Manages the dependencies required by the plugin or system.
*/
protected DependencyManager dependencyManager;
/**
* Handles translations for the plugin, ensuring text is localized based on the player's language.
*/
protected TranslationManager translationManager;
/**
* A debugger function that logs debug information with a "[DEBUG]" prefix.
* It consumes a supplier of strings and logs the result.
*/
protected Consumer<Supplier<String>> debugger = (s) -> getPluginLogger().info("[DEBUG] " + s.get());
/**
* Manages configuration settings, loading and accessing configuration data for the plugin.
*/
protected ConfigManager configManager;
/**
* Responsible for sending packets to clients or other network entities.
*/
protected PacketSender packetSender;
/**
* Injects custom pipelines into the system to modify or handle data processing flows.
*/
protected PipelineInjector pipelineInjector;
/**
* Manages placeholders used for dynamic text replacements in the plugin's output.
*/
protected PlaceholderManager placeholderManager;
/**
* Manages requirements or conditions that must be met for certain actions or events to occur.
*/
protected RequirementManager requirementManager;
/**
* Manages the action bar, responsible for displaying dynamic text to players in the action bar.
*/
protected ActionBarManager actionBarManager;
/**
* Manages the boss bar, which displays a customizable progress bar and messages to players.
*/
protected BossBarManager bossBarManager;
/**
* Manages unlimited tags that can be applied to players, items, or other entities.
*/
protected UnlimitedTagManager unlimitedTagManager;
/**
* Represents the platform on which the plugin or system is running (e.g., Spigot, Bukkit, etc.).
*/
protected Platform platform;
/**
* The main task or process that the plugin or system executes.
*/
protected MainTask mainTask;
/**
* A scheduled task that runs alongside the main task, typically used for periodic or delayed actions.
*/
protected SchedulerTask scheduledMainTask;
/**
* A map that tracks online players by their unique UUID, allowing quick access to player data.
*/
protected ConcurrentHashMap<UUID, CNPlayer> onlinePlayerMap = new ConcurrentHashMap<>();
/**
* A fast lookup map that associates entity IDs to player data (CNPlayer) for quick access.
*/
protected ConcurrentHashMap<Integer, CNPlayer> entityIDFastLookup = new ConcurrentHashMap<>();
/**
* Manages advances or progressions for players, such as achievements or level ups.
*/
protected AdvanceManager advanceManager;
/**
* Manages background tasks, likely for asynchronous processing or UI updates.
*/
protected BackgroundManager backgroundManager;
/**
* Manages events and event handling within the plugin or system.
*/
protected EventManager eventManager;
/**
* Manages the plugin's data storage system, including saving and retrieving player data.
*/
protected StorageManager storageManager;
/**
* Manages bubble effects, likely for UI or visual effects displayed to players.
*/
protected BubbleManager bubbleManager;
/**
* Manages chat functionality, including message formatting, commands, and interactions.
*/
protected ChatManager chatManager;
/**
* Manages images, such as textures or images for resource packs or player displays.
*/
protected ImageManager imageManager;
/**
* Manages nameplates displayed above players or entities.
*/
protected NameplateManager nameplateManager;
/**
* Manages resource packs, allowing the plugin to send custom content to players.
*/
protected ResourcePackManager resourcePackManager;
/**
* Provides an API for external access to the plugin's functionality and data.
*/
protected CustomNameplatesAPI api;
private String buildByBit = "%%__BUILTBYBIT__%%";
@@ -89,6 +191,9 @@ public abstract class CustomNameplates implements NameplatesPlugin {
private String username = "%%__USERNAME__%%";
private boolean isLatest = false;
/**
* Creates the CustomNameplates instance
*/
protected CustomNameplates() {
instance = this;
}

View File

@@ -30,15 +30,12 @@ import org.jetbrains.annotations.Nullable;
import java.util.Optional;
import java.util.UUID;
/**
* CustomNameplatesAPI
*/
public record CustomNameplatesAPI(CustomNameplates plugin) {
private static CustomNameplatesAPI instance;
public CustomNameplatesAPI(CustomNameplates plugin) {
this.plugin = plugin;
instance = this;
}
/**
* Gets the CustomNameplates plugin instance.
*

View File

@@ -24,30 +24,51 @@ import java.util.Map;
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;
/**
* MainTask is a periodic task that handles various operations related to the plugin, such as refreshing conditions,
* managing placeholders, and monitoring performance. It runs periodically and executes different plugin managers
* in each cycle to maintain the smooth operation of the system.
*/
public class MainTask implements Runnable {
private static int RUN_TICKS = 0;
private static final Map<Integer, Integer> TIME_1 = new ConcurrentHashMap<>(2048);
private static final Map<Integer, Integer> TIME_2 = new ConcurrentHashMap<>(2048);
private static final Set<Integer> requestedSharedPlaceholders = Collections.synchronizedSet(new ObjectOpenHashSet<>());
private int timer;
private final CustomNameplates plugin;
private boolean state;
/**
* Constructs a new MainTask instance.
*
* @param plugin the plugin instance associated with this task
*/
public MainTask(CustomNameplates plugin) {
this.plugin = plugin;
}
/**
* Returns the total number of ticks the task has executed.
*
* @return the number of ticks
*/
public static int getTicks() {
return RUN_TICKS;
}
/**
* Checks if a shared placeholder request for the specified count ID has already been made.
*
* @param countId the ID to check
* @return true if the request has been made, false otherwise
*/
public static boolean hasRequested(int countId) {
return !requestedSharedPlaceholders.add(countId);
}
/**
* Resets the tick counter to 0.
*/
public static void reset() {
RUN_TICKS = 0;
}
@@ -82,6 +103,11 @@ public class MainTask implements Runnable {
}
}
/**
* Retrieves the performance profile of the task based on the execution time and load.
*
* @return a HealthyProfile object containing the performance statistics
*/
public static HealthyProfile getHealthyProfile() {
long total1 = TIME_1.values().stream().mapToLong(Integer::longValue).sum();
long total2 = TIME_2.values().stream().mapToLong(Integer::longValue).sum();
@@ -99,14 +125,23 @@ public class MainTask implements Runnable {
);
}
/**
* Represents the health profile of the task, including performance metrics such as load and execution times.
*/
public static class HealthyProfile {
private final double load;
private final long totalTimeNS;
private final int actionBarConditionNS;
private final int refreshPlaceholderNS;
/**
* Constructs a new HealthyProfile instance with the provided metrics.
*
* @param load the load factor based on execution time
* @param totalTimeNS the total time spent on the task, in nanoseconds
* @param actionBarConditionNS the average time spent on action bar conditions, in nanoseconds
* @param refreshPlaceholderNS the average time spent refreshing placeholders, in nanoseconds
*/
public HealthyProfile(
double load,
long totalTimeNS,
@@ -119,18 +154,38 @@ public class MainTask implements Runnable {
this.totalTimeNS = totalTimeNS;
}
/**
* Gets the average time spent on action bar condition checks, in nanoseconds.
*
* @return the action bar condition time in nanoseconds
*/
public int getActionBarConditionNS() {
return actionBarConditionNS;
}
/**
* Gets the average time spent refreshing placeholders, in nanoseconds.
*
* @return the placeholder refresh time in nanoseconds
*/
public int getRefreshPlaceholderNS() {
return refreshPlaceholderNS;
}
/**
* Gets the load factor based on the task's execution time.
*
* @return the load factor
*/
public double getLoad() {
return load;
}
/**
* Gets the total time spent on the task, in nanoseconds.
*
* @return the total execution time in nanoseconds
*/
public long getTotalTimeNS() {
return totalTimeNS;
}

View File

@@ -17,6 +17,15 @@
package net.momirealms.customnameplates.api.feature;
/**
* Interface representing an adaptive image with methods for generating image
* prefixes, suffixes, and the full image string based on specified parameters.
* <p>
* The implementation of this interface should define how the image is adapted
* based on the given margins and advance, which are used for layout and
* positioning purposes.
* </p>
*/
public interface AdaptiveImage {
/**

View File

@@ -17,64 +17,241 @@
package net.momirealms.customnameplates.api.feature;
import java.util.HashMap;
/**
* Enum representing different font offsets used for handling character spacing and height.
* The offsets are categorized into positive and negative values, each corresponding to
* a specific advance (horizontal movement) and height (vertical movement).
*/
public enum OffsetFont {
/**
* Represents a font with a character value of '\uf800', horizontal advance of -1, and vertical height of -3.
*/
NEG_1('\uf800', -1, -3),
/**
* Represents a font with a character value of '\uf801', horizontal advance of -2, and vertical height of -4.
*/
NEG_2('\uf801', -2, -4),
/**
* Represents a font with a character value of '\uf802', horizontal advance of -3, and vertical height of -5.
*/
NEG_3('\uf802', -3, -5),
/**
* Represents a font with a character value of '\uf803', horizontal advance of -4, and vertical height of -6.
*/
NEG_4('\uf803', -4, -6),
/**
* Represents a font with a character value of '\uf804', horizontal advance of -5, and vertical height of -7.
*/
NEG_5('\uf804', -5, -7),
/**
* Represents a font with a character value of '\uf805', horizontal advance of -6, and vertical height of -8.
*/
NEG_6('\uf805', -6, -8),
/**
* Represents a font with a character value of '\uf806', horizontal advance of -7, and vertical height of -9.
*/
NEG_7('\uf806', -7, -9),
/**
* Represents a font with a character value of '\uf807', horizontal advance of -8, and vertical height of -10.
*/
NEG_8('\uf807', -8, -10),
/**
* Represents a font with a character value of '\uf808', horizontal advance of -9, and vertical height of -11.
*/
NEG_9('\uf808', -9, -11),
/**
* Represents a font with a character value of '\uf809', horizontal advance of -10, and vertical height of -12.
*/
NEG_10('\uf809', -10, -12),
/**
* Represents a font with a character value of '\uf80a', horizontal advance of -11, and vertical height of -13.
*/
NEG_11('\uf80a', -11, -13),
/**
* Represents a font with a character value of '\uf80b', horizontal advance of -12, and vertical height of -14.
*/
NEG_12('\uf80b', -12, -14),
/**
* Represents a font with a character value of '\uf80c', horizontal advance of -13, and vertical height of -15.
*/
NEG_13('\uf80c', -13, -15),
/**
* Represents a font with a character value of '\uf80d', horizontal advance of -14, and vertical height of -16.
*/
NEG_14('\uf80d', -14, -16),
/**
* Represents a font with a character value of '\uf80e', horizontal advance of -15, and vertical height of -17.
*/
NEG_15('\uf80e', -15, -17),
/**
* Represents a font with a character value of '\uf80f', horizontal advance of -16, and vertical height of -18.
*/
NEG_16('\uf80f', -16, -18),
/**
* Represents a font with a character value of '\uf810', horizontal advance of -24, and vertical height of -26.
*/
NEG_24('\uf810', -24, -26),
/**
* Represents a font with a character value of '\uf811', horizontal advance of -32, and vertical height of -34.
*/
NEG_32('\uf811', -32, -34),
/**
* Represents a font with a character value of '\uf812', horizontal advance of -48, and vertical height of -50.
*/
NEG_48('\uf812', -48, -50),
/**
* Represents a font with a character value of '\uf813', horizontal advance of -64, and vertical height of -66.
*/
NEG_64('\uf813', -64, -66),
/**
* Represents a font with a character value of '\uf814', horizontal advance of -128, and vertical height of -130.
*/
NEG_128('\uf814', -128, -130),
/**
* Represents a font with a character value of '\uf815', horizontal advance of -256, and vertical height of -258.
*/
NEG_256('\uf815', -256, -258),
/**
* Represents a font with a character value of '\uf830', horizontal advance of 1, and vertical height of -1.
*/
POS_1('\uf830', 1, -1),
/**
* Represents a font with a character value of '\uf831', horizontal advance of 2, and vertical height of 1.
*/
POS_2('\uf831', 2, 1),
/**
* Represents a font with a character value of '\uf832', horizontal advance of 3, and vertical height of 2.
*/
POS_3('\uf832', 3, 2),
/**
* Represents a font with a character value of '\uf833', horizontal advance of 4, and vertical height of 3.
*/
POS_4('\uf833', 4, 3),
/**
* Represents a font with a character value of '\uf834', horizontal advance of 5, and vertical height of 4.
*/
POS_5('\uf834', 5, 4),
/**
* Represents a font with a character value of '\uf835', horizontal advance of 6, and vertical height of 5.
*/
POS_6('\uf835', 6, 5),
/**
* Represents a font with a character value of '\uf836', horizontal advance of 7, and vertical height of 6.
*/
POS_7('\uf836', 7, 6),
/**
* Represents a font with a character value of '\uf837', horizontal advance of 8, and vertical height of 7.
*/
POS_8('\uf837', 8, 7),
/**
* Represents a font with a character value of '\uf838', horizontal advance of 9, and vertical height of 8.
*/
POS_9('\uf838', 9, 8),
/**
* Represents a font with a character value of '\uf839', horizontal advance of 10, and vertical height of 9.
*/
POS_10('\uf839', 10, 9),
/**
* Represents a font with a character value of '\uf83a', horizontal advance of 11, and vertical height of 10.
*/
POS_11('\uf83a', 11, 10),
/**
* Represents a font with a character value of '\uf83b', horizontal advance of 12, and vertical height of 11.
*/
POS_12('\uf83b', 12, 11),
/**
* Represents a font with a character value of '\uf83c', horizontal advance of 13, and vertical height of 12.
*/
POS_13('\uf83c', 13, 12),
/**
* Represents a font with a character value of '\uf83d', horizontal advance of 14, and vertical height of 13.
*/
POS_14('\uf83d', 14, 13),
/**
* Represents a font with a character value of '\uf83e', horizontal advance of 15, and vertical height of 14.
*/
POS_15('\uf83e', 15, 14),
/**
* Represents a font with a character value of '\uf83f', horizontal advance of 16, and vertical height of 15.
*/
POS_16('\uf83f', 16, 15),
/**
* Represents a font with a character value of '\uf840', horizontal advance of 24, and vertical height of 23.
*/
POS_24('\uf840', 24, 23),
/**
* Represents a font with a character value of '\uf841', horizontal advance of 32, and vertical height of 31.
*/
POS_32('\uf841', 32, 31),
/**
* Represents a font with a character value of '\uf842', horizontal advance of 48, and vertical height of 47.
*/
POS_48('\uf842', 48, 47),
/**
* Represents a font with a character value of '\uf843', horizontal advance of 64, and vertical height of 63.
*/
POS_64('\uf843', 64, 63),
/**
* Represents a font with a character value of '\uf844', horizontal advance of 128, and vertical height of 127.
*/
POS_128('\uf844', 128, 127),
/**
* Represents a font with a character value of '\uf845', horizontal advance of 256, and vertical height of 255.
*/
POS_256('\uf845', 256, 255);
private static final HashMap<Integer, OffsetFont> negFastLookup = new HashMap<>();
private static final HashMap<Integer, OffsetFont> posFastLookup = new HashMap<>();
private static final OffsetFont[] negFastLookup = new OffsetFont[17];
private static final OffsetFont[] posFastLookup = new OffsetFont[17];
static {
for (OffsetFont f : OffsetFont.values()) {
if (f.advance > 0) {
posFastLookup.put(f.advance, f);
} else {
negFastLookup.put(-f.advance, f);
if (f.advance > 0 && f.advance <= 16) {
posFastLookup[f.advance] = f;
} else if (f.advance < 0 && f.advance >= -16) {
negFastLookup[-f.advance] = f;
}
}
}
@@ -83,24 +260,53 @@ public enum OffsetFont {
private final int advance;
private final int height;
/**
* Constructor to initialize the OffsetFont with a specific character, advance, and height.
*
* @param character the character associated with the offset
* @param advance the horizontal movement (positive or negative)
* @param height the vertical movement (positive or negative)
*/
OffsetFont(char character, int advance, int height) {
this.character = character;
this.advance = advance;
this.height = height;
}
/**
* Gets the character associated with this offset font.
*
* @return the character of this offset font
*/
public char character() {
return this.character;
}
/**
* Gets the advance value for this offset font.
*
* @return the advance (horizontal movement) for this offset font
*/
public float advance() {
return this.advance;
}
/**
* Gets the height value for this offset font.
*
* @return the height (vertical movement) for this offset font
*/
public int height() {
return this.height;
}
/**
* Creates a string of offset characters based on the given offset value.
* The result depends on whether the offset is positive or negative.
*
* @param offset the offset value
* @return a string of offset characters
*/
public static String createOffsets(float offset) {
if (offset >= 0) {
return shortestPosChars(offset);
@@ -109,6 +315,13 @@ public enum OffsetFont {
}
}
/**
* Generates a string of the shortest possible negative offset characters
* that sum up to the given advance value.
*
* @param advance the negative advance value
* @return the shortest string of negative offset characters
*/
public static String shortestNegChars(float advance) {
int n = (int) Math.ceil(advance);
StringBuilder stringBuilder = new StringBuilder();
@@ -141,10 +354,17 @@ public enum OffsetFont {
n -= 16;
}
if (n == 0) return stringBuilder.toString();
stringBuilder.append(negFastLookup.get(n).character());
stringBuilder.append(negFastLookup[n].character());
return stringBuilder.toString();
}
/**
* Generates a string of the shortest possible positive offset characters
* that sum up to the given advance value.
*
* @param advance the positive advance value
* @return the shortest string of positive offset characters
*/
public static String shortestPosChars(float advance) {
int n = (int) Math.ceil(advance);
StringBuilder stringBuilder = new StringBuilder();
@@ -177,7 +397,7 @@ public enum OffsetFont {
n -= 16;
}
if (n == 0) return stringBuilder.toString();
stringBuilder.append(posFastLookup.get(n).character());
stringBuilder.append(posFastLookup[n].character());
return stringBuilder.toString();
}
}

View File

@@ -29,22 +29,44 @@ import java.util.Objects;
import java.util.Set;
import java.util.function.Function;
/**
* Represents a dynamically parsed text that can contain placeholders.
* The text is parsed at initialization and placeholders are replaced with corresponding values.
* This class provides functionality to manage placeholders and generate dynamic text for players.
*/
public class PreParsedDynamicText {
private final String text;
private final List<Function<CNPlayer, Function<CNPlayer, String>>> textFunctions = new ObjectArrayList<>();
private final Set<Placeholder> set = new ObjectOpenHashSet<>();
private boolean init = false;
/**
* Constructs a PreParsedDynamicText with the given text.
*
* @param text the original text containing placeholders to be parsed
* @throws NullPointerException if the provided text is null
*/
public PreParsedDynamicText(String text) {
this.text = Objects.requireNonNull(text);
}
/**
* Constructs a PreParsedDynamicText with the given text and initializes it (parses placeholders).
*
* @param text the original text containing placeholders to be parsed
* @param init flag indicating whether to initialize the text immediately
* @throws NullPointerException if the provided text is null
*/
public PreParsedDynamicText(String text, boolean init) {
this.text = Objects.requireNonNull(text);
if (init) init();
}
/**
* Initializes the PreParsedDynamicText by parsing the text for placeholders and creating
* corresponding functions for replacing the placeholders with values.
* This method is called automatically if the constructor is provided with `true` for the init flag.
*/
public void init() {
if (init) return;
init = true;
@@ -101,6 +123,13 @@ public class PreParsedDynamicText {
set.addAll(new ObjectArrayList<>(placeholders));
}
/**
* Creates a dynamic text based on the current pre-parsed text, tailored to the given player.
* This method uses the player's data to generate the final text.
*
* @param player the player for whom the dynamic text is being generated
* @return a DynamicText object containing the final text for the player
*/
public DynamicText fastCreate(CNPlayer player) {
List<Function<CNPlayer, String>> functions = new ObjectArrayList<>();
for (Function<CNPlayer, Function<CNPlayer, String>> textFunction : textFunctions) {
@@ -109,6 +138,11 @@ public class PreParsedDynamicText {
return new DynamicText(text, functions, set);
}
/**
* Returns a set of placeholders detected in the text.
*
* @return a set of placeholders used in the text
*/
public Set<Placeholder> placeholders() {
return set;
}

View File

@@ -20,6 +20,9 @@ package net.momirealms.customnameplates.api.feature.actionbar;
import net.momirealms.customnameplates.api.feature.CarouselText;
import net.momirealms.customnameplates.api.requirement.Requirement;
/**
* ActionBar Config
*/
public interface ActionBarConfig {
/**

View File

@@ -22,13 +22,15 @@ import net.momirealms.customnameplates.api.requirement.Requirement;
import static java.util.Objects.requireNonNull;
/**
* Implementation of ActionBarConfig
*/
public class ActionBarConfigImpl implements ActionBarConfig {
private final String id;
private final Requirement[] requirements;
private final CarouselText[] carouselTexts;
public ActionBarConfigImpl(String id, Requirement[] requirements, CarouselText[] carouselTexts) {
private ActionBarConfigImpl(String id, Requirement[] requirements, CarouselText[] carouselTexts) {
this.id = requireNonNull(id);
this.requirements = requireNonNull(requirements);
this.carouselTexts = requireNonNull(carouselTexts);
@@ -49,8 +51,10 @@ public class ActionBarConfigImpl implements ActionBarConfig {
return carouselTexts;
}
/**
* Builder Implementation
*/
public static class BuilderImpl implements Builder {
private String id;
private Requirement[] requirements;
private CarouselText[] carouselTexts;

View File

@@ -21,6 +21,9 @@ import net.momirealms.customnameplates.api.CNPlayer;
import net.momirealms.customnameplates.common.plugin.feature.Reloadable;
import org.jetbrains.annotations.Nullable;
/**
* Interface representing a manager for handling ActionBars.
*/
public interface ActionBarManager extends Reloadable {
/**

View File

@@ -25,6 +25,9 @@ import org.jetbrains.annotations.Nullable;
import java.util.List;
/**
* Interface that defines methods for managing and calculating text advance data,
*/
public interface AdvanceManager extends Reloadable {
/**

View File

@@ -23,6 +23,9 @@ import java.util.List;
import java.util.Map;
import java.util.function.Function;
/**
* Interface representing character font advance data.
*/
public interface CharacterFontAdvanceData {
/**

View File

@@ -26,13 +26,22 @@ import java.util.function.Function;
import static java.util.Objects.requireNonNull;
/**
* Implementation of the CharacterFontAdvanceData interface.
*/
public class CharacterFontAdvanceDataImpl implements CharacterFontAdvanceData {
private final Map<Integer, Float> data;
private final String id;
private final Function<Map<String, Object>, List<JsonObject>> fontProviderFunction;
public CharacterFontAdvanceDataImpl(String id, Map<Integer, Float> data, Function<Map<String, Object>, List<JsonObject>> fontProviderFunction) {
/**
* Constructs a new instance of CharacterFontAdvanceDataImpl.
*
* @param id the unique identifier for this font advance data
* @param data a map of character code points and their corresponding advance values
* @param fontProviderFunction a function that generates font provider configurations
*/
private CharacterFontAdvanceDataImpl(String id, Map<Integer, Float> data, Function<Map<String, Object>, List<JsonObject>> fontProviderFunction) {
this.data = data;
this.id = requireNonNull(id);
this.fontProviderFunction = requireNonNull(fontProviderFunction);
@@ -63,8 +72,10 @@ public class CharacterFontAdvanceDataImpl implements CharacterFontAdvanceData {
return fontProviderFunction.apply(properties);
}
/**
* The builder implementation
*/
public static class BuilderImpl implements Builder {
private final Int2FloatOpenHashMap data = new Int2FloatOpenHashMap();
private String id;
private Function<Map<String, Object>, List<JsonObject>> fontProviderFunction = (stringObjectMap -> null);

View File

@@ -24,14 +24,16 @@ import java.util.*;
import static java.util.Objects.requireNonNull;
/**
* Implementation of ConfigurableFontAdvanceData
*/
public class ConfigurableFontAdvanceDataImpl implements ConfigurableFontAdvanceData {
private final float defaultAdvance;
private final Map<Integer, Float> data = new Int2FloatOpenHashMap();
private final List<CharacterFontAdvanceData> parents = new ObjectArrayList<>();
private final String id;
public ConfigurableFontAdvanceDataImpl(String id, float defaultAdvance, HashMap<Integer, Float> customData, List<CharacterFontAdvanceData> parentFonts) {
private ConfigurableFontAdvanceDataImpl(String id, float defaultAdvance, HashMap<Integer, Float> customData, List<CharacterFontAdvanceData> parentFonts) {
this.id = requireNonNull(id);
this.defaultAdvance = defaultAdvance;
for (CharacterFontAdvanceData parent : parentFonts) {
@@ -71,8 +73,10 @@ public class ConfigurableFontAdvanceDataImpl implements ConfigurableFontAdvanceD
return id;
}
/**
* The builder implementation
*/
public static class BuilderImpl implements Builder {
private final HashMap<Integer, Float> customData = new HashMap<>();
private final List<CharacterFontAdvanceData> parents = new ArrayList<>();
private float defaultAdvance = 0;

View File

@@ -22,101 +22,14 @@ import net.momirealms.customnameplates.api.feature.OffsetFont;
import java.util.Objects;
/**
* Implements the {@link Background} interface, representing the detailed configuration of a background.
*/
@SuppressWarnings("DuplicatedCode")
public class BackgroundImpl implements Background {
private final String id;
private final ConfiguredCharacter left;
private final ConfiguredCharacter width_1;
private final ConfiguredCharacter width_2;
private final ConfiguredCharacter width_4;
private final ConfiguredCharacter width_8;
private final ConfiguredCharacter width_16;
private final ConfiguredCharacter width_32;
private final ConfiguredCharacter width_64;
private final ConfiguredCharacter width_128;
private final ConfiguredCharacter right;
public BackgroundImpl(
String id,
ConfiguredCharacter left,
ConfiguredCharacter width_1,
ConfiguredCharacter width_2,
ConfiguredCharacter width_4,
ConfiguredCharacter width_8,
ConfiguredCharacter width_16,
ConfiguredCharacter width_32,
ConfiguredCharacter width_64,
ConfiguredCharacter width_128,
ConfiguredCharacter right
) {
this.id = id;
this.left = left;
this.width_1 = width_1;
this.width_2 = width_2;
this.width_4 = width_4;
this.width_8 = width_8;
this.width_16 = width_16;
this.width_32 = width_32;
this.width_64 = width_64;
this.width_128 = width_128;
this.right = right;
}
@Override
public String id() {
return id;
}
@Override
public ConfiguredCharacter left() {
return left;
}
@Override
public ConfiguredCharacter width_1() {
return width_1;
}
@Override
public ConfiguredCharacter width_2() {
return width_2;
}
@Override
public ConfiguredCharacter width_4() {
return width_4;
}
@Override
public ConfiguredCharacter width_8() {
return width_8;
}
@Override
public ConfiguredCharacter width_16() {
return width_16;
}
@Override
public ConfiguredCharacter width_32() {
return width_32;
}
@Override
public ConfiguredCharacter width_64() {
return width_64;
}
@Override
public ConfiguredCharacter width_128() {
return width_128;
}
@Override
public ConfiguredCharacter right() {
return right;
}
public record BackgroundImpl(String id, ConfiguredCharacter left, ConfiguredCharacter width_1,
ConfiguredCharacter width_2, ConfiguredCharacter width_4, ConfiguredCharacter width_8,
ConfiguredCharacter width_16, ConfiguredCharacter width_32, ConfiguredCharacter width_64,
ConfiguredCharacter width_128, ConfiguredCharacter right) implements Background {
@Override
public String createImagePrefix(float advance, float leftMargin, float rightMargin) {
@@ -239,8 +152,10 @@ public class BackgroundImpl implements Background {
return Objects.hashCode(id);
}
/**
* The builder implementation
*/
public static class BuilderImpl implements Builder {
private String id;
private ConfiguredCharacter left;
private ConfiguredCharacter width_1;

View File

@@ -22,6 +22,9 @@ import org.jetbrains.annotations.Nullable;
import java.util.Collection;
/**
* Interface representing a manager for background configurations.
*/
public interface BackgroundManager extends Reloadable {
/**

View File

@@ -19,6 +19,9 @@ package net.momirealms.customnameplates.api.feature.bossbar;
import java.util.UUID;
/**
* Represents a BossBar
*/
public interface BossBar {
/**
@@ -50,21 +53,74 @@ public interface BossBar {
*/
Overlay overlay();
/**
* Enum representing the different overlay styles for the BossBar.
* The overlay style determines how the bar is divided, either as a simple progress bar or as notches.
*/
enum Overlay {
/**
* The bar is displayed as a simple progress bar.
*/
PROGRESS,
/**
* The bar is divided into 6 notches.
*/
NOTCHED_6,
/**
* The bar is divided into 10 notches.
*/
NOTCHED_10,
/**
* The bar is divided into 12 notches.
*/
NOTCHED_12,
/**
* The bar is divided into 20 notches.
*/
NOTCHED_20
}
/**
* Enum representing the different colors for the BossBar.
*/
enum Color {
/**
* Blue color for the BossBar.
*/
BLUE,
/**
* Green color for the BossBar.
*/
GREEN,
/**
* Pink color for the BossBar.
*/
PINK,
/**
* Purple color for the BossBar.
*/
PURPLE,
/**
* Red color for the BossBar.
*/
RED,
/**
* White color for the BossBar.
*/
WHITE,
/**
* Yellow color for the BossBar.
*/
YELLOW
}
}

View File

@@ -20,6 +20,9 @@ package net.momirealms.customnameplates.api.feature.bossbar;
import net.momirealms.customnameplates.api.feature.CarouselText;
import net.momirealms.customnameplates.api.requirement.Requirement;
/**
* Interface for BossBarConfig
*/
public interface BossBarConfig {
/**

View File

@@ -22,8 +22,10 @@ import net.momirealms.customnameplates.api.requirement.Requirement;
import static java.util.Objects.requireNonNull;
/**
* Implementation of BossBar Config
*/
public class BossBarConfigImpl implements BossBarConfig {
private final String id;
private final Requirement[] requirements;
private final CarouselText[] carouselTexts;
@@ -31,7 +33,18 @@ public class BossBarConfigImpl implements BossBarConfig {
private final BossBar.Color color;
private final float progress;
public BossBarConfigImpl(String id, Requirement[] requirements, CarouselText[] carouselTexts, BossBar.Overlay overlay, BossBar.Color color, float progress) {
/**
* Constructor for creating a new BossBarConfigImpl.
* Ensures that all fields are non-null and properly initialized.
*
* @param id the unique ID of the BossBar configuration
* @param requirements the requirements for the BossBar
* @param carouselTexts the carousel texts associated with the BossBar
* @param overlay the overlay style of the BossBar
* @param color the color of the BossBar
* @param progress the progress value of the BossBar (between 0.0 and 1.0)
*/
private BossBarConfigImpl(String id, Requirement[] requirements, CarouselText[] carouselTexts, BossBar.Overlay overlay, BossBar.Color color, float progress) {
this.id = requireNonNull(id);
this.requirements = requireNonNull(requirements);
this.carouselTexts = requireNonNull(carouselTexts);
@@ -70,8 +83,10 @@ public class BossBarConfigImpl implements BossBarConfig {
return progress;
}
/**
* Builder Implementation
*/
public static class BuilderImpl implements Builder {
private String id;
private Requirement[] requirements;
private CarouselText[] carouselTexts;

View File

@@ -19,6 +19,9 @@ package net.momirealms.customnameplates.api.feature.bossbar;
import net.momirealms.customnameplates.common.plugin.feature.Reloadable;
/**
* Manager interface for handling BossBar configurations and their updates.
*/
public interface BossBarManager extends Reloadable {
/**

View File

@@ -20,6 +20,9 @@ package net.momirealms.customnameplates.api.feature.bubble;
import net.momirealms.customnameplates.api.feature.AdaptiveImage;
import net.momirealms.customnameplates.api.feature.ConfiguredCharacter;
/**
* Bubble
*/
public interface Bubble extends AdaptiveImage {
/**

View File

@@ -19,6 +19,9 @@ package net.momirealms.customnameplates.api.feature.bubble;
import net.momirealms.customnameplates.api.util.Vector3;
/**
* Bubble configuration
*/
public interface BubbleConfig {
/**

View File

@@ -21,8 +21,10 @@ import net.momirealms.customnameplates.api.util.Vector3;
import static java.util.Objects.requireNonNull;
/**
* Implementation of the BubbleConfig interface
*/
public class BubbleConfigImpl implements BubbleConfig {
private final String id;
private final int backgroundColor;
private final int lineWidth;
@@ -33,6 +35,19 @@ public class BubbleConfigImpl implements BubbleConfig {
private final String displayName;
private final Vector3 scale;
/**
* Constructs a new BubbleConfigImpl.
*
* @param id the unique ID for the bubble configuration
* @param displayName the name to be displayed for the bubble configuration
* @param backgroundColor the background color for the bubble (in integer format)
* @param lineWidth the line width for the bubble display
* @param maxLines the maximum number of lines that can be displayed in the bubble
* @param bubbles an array of Bubble objects representing the actual bubbles
* @param textPrefix a prefix that will be added before the text in the bubble
* @param textSuffix a suffix that will be added after the text in the bubble
* @param scale the scale of the bubble display (as a Vector3)
*/
public BubbleConfigImpl(String id, String displayName, int backgroundColor, int lineWidth, int maxLines, Bubble[] bubbles, String textPrefix, String textSuffix, Vector3 scale) {
this.backgroundColor = backgroundColor;
this.lineWidth = lineWidth;
@@ -90,8 +105,10 @@ public class BubbleConfigImpl implements BubbleConfig {
return scale;
}
/**
* Builder implementation for creating BubbleConfigImpl instances.
*/
public static class BuilderImpl implements Builder {
private int backgroundColor;
private int lineWidth;
private int maxLines;

View File

@@ -22,14 +22,25 @@ import net.momirealms.customnameplates.api.feature.OffsetFont;
import java.util.Objects;
/**
* Implementation of the Bubble interface
*/
public class BubbleImpl implements Bubble {
private final String id;
private final ConfiguredCharacter left;
private final ConfiguredCharacter right;
private final ConfiguredCharacter middle;
private final ConfiguredCharacter tail;
/**
* Constructs a new BubbleImpl.
*
* @param id the unique ID for the bubble
* @param left the character representing the left part of the bubble
* @param right the character representing the right part of the bubble
* @param middle the character representing the middle part of the bubble
* @param tail the character representing the tail part of the bubble
*/
public BubbleImpl(String id, ConfiguredCharacter left, ConfiguredCharacter right, ConfiguredCharacter middle, ConfiguredCharacter tail) {
this.id = id;
this.left = left;
@@ -149,8 +160,10 @@ public class BubbleImpl implements Bubble {
return sb.toString();
}
/**
* Builder implementation for creating BubbleImpl instances.
*/
public static class BuilderImpl implements Builder {
private String id;
private ConfiguredCharacter left;
private ConfiguredCharacter right;

View File

@@ -25,6 +25,10 @@ import org.jetbrains.annotations.Nullable;
import java.util.Collection;
import java.util.Set;
/**
* The BubbleManager interface is responsible for managing the configuration and display of Bubbles,
* including retrieving available Bubbles, managing Bubble configurations, and controlling display settings.
*/
public interface BubbleManager extends Reloadable {
/**

View File

@@ -17,9 +17,21 @@
package net.momirealms.customnameplates.api.feature.bubble;
/**
* Enum representing the different modes for Bubble channels.
* The mode determines the visibility and access rules for Bubbles in various channels.
*/
public enum ChannelMode {
/**
* The ALL mode means that Bubbles can be displayed in all channels, regardless of the player's status or permissions.
*/
ALL,
/**
* The JOINED mode means that Bubbles can only be displayed in channels where the player is currently a member.
*/
JOINED,
/**
* The CAN_JOIN mode means that Bubbles can be displayed in channels that the player can join, even if they are not currently in them.
*/
CAN_JOIN
}

View File

@@ -24,8 +24,13 @@ import net.momirealms.customnameplates.api.CustomNameplates;
* for managing the plugin and chat manager.
*/
public abstract class AbstractChatMessageProvider implements ChatMessageProvider {
/**
* The CustomNameplates plugin
*/
protected CustomNameplates plugin;
/**
* The chat manager
*/
protected ChatManager manager;
/**

View File

@@ -17,5 +17,8 @@
package net.momirealms.customnameplates.api.feature.image;
/**
* A record representing an animation with a speed and a number of frames.
*/
public record Animation(int speed, int frames) {
}

View File

@@ -20,6 +20,9 @@ package net.momirealms.customnameplates.api.feature.image;
import net.momirealms.customnameplates.api.feature.ConfiguredCharacter;
import org.jetbrains.annotations.Nullable;
/**
* An interface represents the image
*/
public interface Image {
/**

View File

@@ -22,14 +22,16 @@ import org.jetbrains.annotations.Nullable;
import java.util.Objects;
/**
* Implementation of Image
*/
public class ImageImpl implements Image {
private final String id;
private final boolean removeShadow;
private final ConfiguredCharacter character;
private final Animation animation;
public ImageImpl(String id, boolean removeShadow, Animation animation, ConfiguredCharacter character) {
private ImageImpl(String id, boolean removeShadow, Animation animation, ConfiguredCharacter character) {
this.id = id;
this.removeShadow = removeShadow;
this.character = character;
@@ -69,8 +71,10 @@ public class ImageImpl implements Image {
return Objects.hashCode(id);
}
/**
* The builder Implementation
*/
public static class BuilderImpl implements Builder {
private String id;
private boolean removeShadow;
private ConfiguredCharacter character;

View File

@@ -22,6 +22,9 @@ import org.jetbrains.annotations.Nullable;
import java.util.Collection;
/**
* Manages image configurations
*/
public interface ImageManager extends Reloadable {
/**

View File

@@ -20,6 +20,9 @@ package net.momirealms.customnameplates.api.feature.nameplate;
import net.momirealms.customnameplates.api.feature.AdaptiveImage;
import net.momirealms.customnameplates.api.feature.ConfiguredCharacter;
/**
* Nameplate
*/
public interface Nameplate extends AdaptiveImage {
/**

View File

@@ -22,8 +22,10 @@ import net.momirealms.customnameplates.api.feature.OffsetFont;
import java.util.Objects;
/**
* Implementation of Nameplate
*/
public class NameplateImpl implements Nameplate {
private final String id;
private final String displayName;
private final ConfiguredCharacter left;
@@ -31,7 +33,7 @@ public class NameplateImpl implements Nameplate {
private final ConfiguredCharacter right;
private final int minWidth;
public NameplateImpl(String id, String displayName, int minWidth, ConfiguredCharacter left, ConfiguredCharacter middle, ConfiguredCharacter right) {
private NameplateImpl(String id, String displayName, int minWidth, ConfiguredCharacter left, ConfiguredCharacter middle, ConfiguredCharacter right) {
this.id = id;
this.displayName = displayName;
this.minWidth = minWidth;
@@ -134,8 +136,10 @@ public class NameplateImpl implements Nameplate {
return sb.toString();
}
/**
* The builder implementation
*/
public static class BuilderImpl implements Builder {
private String id;
private String displayName;
private ConfiguredCharacter left;

View File

@@ -23,6 +23,10 @@ import org.jetbrains.annotations.Nullable;
import java.util.Collection;
/**
* Manages the nameplates system, providing functionality to retrieve, check access,
* and manipulate nameplates associated with players.
*/
public interface NameplateManager extends Reloadable {
/**

View File

@@ -19,6 +19,9 @@ package net.momirealms.customnameplates.api.feature.pack;
import net.momirealms.customnameplates.common.plugin.feature.Reloadable;
/**
* Interface to manager resource packs
*/
public interface ResourcePackManager extends Reloadable {
/**

View File

@@ -28,23 +28,59 @@ import java.util.UUID;
import java.util.Vector;
import java.util.function.Consumer;
/**
* Represents an abstract tag for a {@link CNPlayer} that can be shown to specific viewers.
* This class handles the rendering of the tag, showing and hiding it for specific players,
* and managing tag attributes such as opacity and scale.
*/
public abstract class AbstractTag implements Tag {
/**
* The owner of this tag
*/
protected CNPlayer owner;
/**
* The {@link TagRenderer} responsible for rendering this tag.
*/
protected TagRenderer renderer;
/**
* The unique UUID assigned to this tag.
*/
protected final UUID uuid = UUID.randomUUID();
/**
* The unique entity ID assigned to this tag, used to track visibility and actions.
*/
protected final int entityID = SelfIncreaseEntityID.getAndIncrease();
/**
* A flag indicating whether the tag is currently visible to viewers.
*/
protected boolean isShown = false;
/**
* A list of players who are currently viewing this tag.
*/
protected final Vector<CNPlayer> viewers = new Vector<>();
/**
* An array representation of the viewers, used for optimization.
*/
protected CNPlayer[] viewerArray = new CNPlayer[0];
public AbstractTag(CNPlayer owner, TagRenderer renderer) {
/**
* Constructs a new {@link AbstractTag} for the given {@link CNPlayer} owner and
* {@link TagRenderer}.
*
* @param owner the {@link CNPlayer} who owns this tag
* @param renderer the {@link TagRenderer} used to render this tag
*/
protected AbstractTag(CNPlayer owner, TagRenderer renderer) {
this.owner = owner;
this.renderer = renderer;
}
/**
* Spawns the tag for the given viewer by sending a packet to the viewer.
*
* @param viewer the {@link CNPlayer} who will see the tag
* @return a list of objects representing the spawn packet for the tag
*/
protected abstract List<Object> spawnPacket(CNPlayer viewer);
@Override
@@ -188,6 +224,9 @@ public abstract class AbstractTag implements Tag {
return uuid;
}
/**
* Resets the viewer array
*/
protected void resetViewerArray() {
this.viewerArray = viewers.toArray(new CNPlayer[0]);
}

View File

@@ -22,6 +22,9 @@ import net.momirealms.customnameplates.api.requirement.Requirement;
import net.momirealms.customnameplates.api.util.Alignment;
import net.momirealms.customnameplates.api.util.Vector3;
/**
* NameTag Configuration
*/
public interface NameTagConfig {
/**

View File

@@ -22,8 +22,10 @@ import net.momirealms.customnameplates.api.requirement.Requirement;
import net.momirealms.customnameplates.api.util.Alignment;
import net.momirealms.customnameplates.api.util.Vector3;
/**
* Implementation of NameTagConfig
*/
public class NameTagConfigImpl implements NameTagConfig {
private final String id;
private final Requirement[] ownerRequirements;
private final Requirement[] viewerRequirements;
@@ -44,7 +46,7 @@ public class NameTagConfigImpl implements NameTagConfig {
private final boolean affectedByScale;
private final boolean affectedBySpectator;
public NameTagConfigImpl(String id, Requirement[] ownerRequirements, Requirement[] viewerRequirements, CarouselText[] carouselTexts, int lineWidth, byte opacity, int backgroundColor, boolean hasShadow, boolean isSeeThrough, boolean useDefaultBackgroundColor, Alignment alignment, float viewRange, float shadowRadius, float shadowStrength, Vector3 scale, Vector3 translation, boolean affectedByCrouching, boolean affectedByScale, boolean affectedBySpectator) {
private NameTagConfigImpl(String id, Requirement[] ownerRequirements, Requirement[] viewerRequirements, CarouselText[] carouselTexts, int lineWidth, byte opacity, int backgroundColor, boolean hasShadow, boolean isSeeThrough, boolean useDefaultBackgroundColor, Alignment alignment, float viewRange, float shadowRadius, float shadowStrength, Vector3 scale, Vector3 translation, boolean affectedByCrouching, boolean affectedByScale, boolean affectedBySpectator) {
this.id = id;
this.ownerRequirements = ownerRequirements;
this.viewerRequirements = viewerRequirements;
@@ -161,6 +163,9 @@ public class NameTagConfigImpl implements NameTagConfig {
return lineWidth;
}
/**
* The builder implementation
*/
public static class BuilderImpl implements Builder {
private String id;
private Requirement[] ownerRequirements;

View File

@@ -22,6 +22,9 @@ import net.momirealms.customnameplates.api.util.Vector3;
import java.util.UUID;
/**
* Represents a tag
*/
public interface Tag {
/**
@@ -59,6 +62,11 @@ public interface Tag {
*/
boolean affectedByScaling();
/**
* Checks if the tag is affected by spectator mode.
*
* @return true if affected by spectator mode, false otherwise
*/
boolean affectedBySpectator();
/**
@@ -189,6 +197,8 @@ public interface Tag {
/**
* Updates the translation of the tag for a certain player
*
* @param viewer the player to update
*/
void updateTranslation(CNPlayer viewer);

View File

@@ -19,6 +19,9 @@ package net.momirealms.customnameplates.api.feature.tag;
import java.util.function.Predicate;
/**
* An interface to control the rendering of tags
*/
public interface TagRenderer {
/**

View File

@@ -25,19 +25,49 @@ import java.util.Collection;
import java.util.Map;
import java.util.Set;
/**
* Represents a view of teams and their associated members.
* <p>
* This class allows you to manage a collection of teams, with each team having a set of member names.
* You can add or remove members from teams, retrieve the list of members for a specific team,
* or remove entire teams.
* </p>
*/
public class TeamView {
/**
* A map that stores the team names as keys and their associated members as values.
* The members are stored as a set of strings to avoid duplicates.
*/
private final Map<String, Set<String>> teamMembers = new Object2ObjectOpenHashMap<>();
/**
* Retrieves the members of a given team.
*
* @param team the name of the team
* @return a set of member names, or {@code null} if the team does not exist
*/
@Nullable
public Set<String> getTeamMembers(String team) {
return teamMembers.get(team);
}
/**
* Adds a collection of members to a team. If the team does not exist, it will be created.
*
* @param team the name of the team
* @param members the collection of members to add
*/
public void addTeamMembers(String team, Collection<String> members) {
teamMembers.computeIfAbsent(team, k -> new ObjectOpenHashSet<>(members));
}
/**
* Removes a collection of members from a team. If the team exists, the members will be removed
* from the team's member set.
*
* @param team the name of the team
* @param members the collection of members to remove
*/
public void removeTeamMembers(String team, Collection<String> members) {
Set<String> membersSet = teamMembers.get(team);
if (membersSet != null) {
@@ -45,6 +75,11 @@ public class TeamView {
}
}
/**
* Removes an entire team and all its members.
*
* @param team the name of the team to remove
*/
public void removeTeam(String team) {
this.teamMembers.remove(team);
}

View File

@@ -22,6 +22,9 @@ import net.momirealms.customnameplates.common.plugin.feature.Reloadable;
import org.jetbrains.annotations.ApiStatus;
import org.jetbrains.annotations.Nullable;
/**
* An interface manages unlimited tags
*/
public interface UnlimitedTagManager extends Reloadable {
/**

View File

@@ -35,10 +35,14 @@ import java.util.concurrent.TimeUnit;
*/
public class AdventureHelper {
/**
* Whether to enable legacy color code support
*/
public static boolean legacySupport = false;
private final MiniMessage miniMessage;
private final MiniMessage miniMessageStrict;
private final GsonComponentSerializer gsonComponentSerializer;
public static boolean legacySupport = false;
private final Cache<String, Component> miniMessageToComponentCache;
private final Cache<String, Object> miniMessageToMinecraftComponentCache;
@@ -84,6 +88,9 @@ public class AdventureHelper {
.build();
}
/**
* Clear cache
*/
public static void clearCache() {
AdventureHelper instance = getInstance();
instance.miniMessageToMinecraftComponentCache.cleanUp();
@@ -217,6 +224,12 @@ public class AdventureHelper {
return "<#FFFEFD>" + text + "</#FFFEFD>";
}
/**
* Removes shadow from the provided text using a specific color code.
*
* @param text the text to modify
* @return the text wrapped in a color tag to remove shadows
*/
public static String removeShadow(String text) {
return "<#F0F0F0>" + text + "</#F0F0F0>";
}

View File

@@ -27,6 +27,9 @@ public class GsonHelper {
private final Gson gson;
/**
* Create the gson
*/
public GsonHelper() {
this.gson = new GsonBuilder()
.create();

View File

@@ -28,11 +28,14 @@ import java.util.concurrent.CompletableFuture;
import java.util.function.Function;
/**
* This class implements the VersionManager interface and is responsible for managing version-related information.
* VersionHelper is a utility class that provides methods for managing and checking version-related information,
* including plugin updates and server version details. It implements the VersionManager interface.
*/
public class VersionHelper {
// Method to asynchronously check for plugin updates
/**
* A function to check for plugin updates asynchronously by comparing the plugin's current version with the latest version available.
*/
public static final Function<NameplatesPlugin, CompletableFuture<Boolean>> UPDATE_CHECKER = (plugin) -> {
CompletableFuture<Boolean> updateFuture = new CompletableFuture<>();
plugin.getScheduler().async().execute(() -> {
@@ -64,6 +67,12 @@ public class VersionHelper {
private static boolean mohist;
private static boolean paper;
/**
* Initializes version-specific settings based on the server version.
* This method checks if the server is running Mojmap, Folia, Mohist, or Paper.
*
* @param serverVersion The server version string.
*/
public static void init(String serverVersion) {
String[] split = serverVersion.split("\\.");
version = Float.parseFloat(split[1] + "." + (split.length == 3 ? split[2] : "0"));
@@ -75,12 +84,19 @@ public class VersionHelper {
paper = paper && !isModdedServer;
}
/**
* Gets the current server version as a float.
*
* @return The server version as a float.
*/
public static float version() {
return version;
}
/**
* Checks if the server is running Mojmap.
*/
private static void checkMojMap() {
// Check if the server is Mojmap
try {
Class.forName("net.minecraft.network.protocol.game.ClientboundBossEventPacket");
mojmap = true;
@@ -88,6 +104,9 @@ public class VersionHelper {
}
}
/**
* Checks if the server is running Folia.
*/
private static void checkFolia() {
try {
Class.forName("io.papermc.paper.threadedregions.RegionizedServer");
@@ -96,6 +115,9 @@ public class VersionHelper {
}
}
/**
* Checks if the server is running Mohist.
*/
private static void checkMohist() {
try {
Class.forName("com.mohistmc.api.ServerAPI");
@@ -104,6 +126,9 @@ public class VersionHelper {
}
}
/**
* Checks if the server is running Paper or its forks.
*/
private static void checkPaper() {
try {
Class.forName("com.destroystokyo.paper.Metrics");
@@ -112,47 +137,103 @@ public class VersionHelper {
}
}
/**
* Checks if the server version is newer than 1.21.2.
*
* @return True if the version is newer than 1.21.2, otherwise false.
*/
public static boolean isVersionNewerThan1_21_2() {
return version >= 21.19;
}
/**
* Checks if the server version is newer than 1.20.5.
*
* @return True if the version is newer than 1.20.5, otherwise false.
*/
public static boolean isVersionNewerThan1_20_5() {
return version >= 20.49;
}
/**
* Checks if the server version is newer than 1.20.4.
*
* @return True if the version is newer than 1.20.4, otherwise false.
*/
public static boolean isVersionNewerThan1_20_4() {
return version >= 20.39;
}
/**
* Checks if the server version is newer than 1.19.4.
*
* @return True if the version is newer than 1.19.4, otherwise false.
*/
public static boolean isVersionNewerThan1_19_4() {
return version >= 19.39;
}
/**
* Checks if the server version is newer than 1.20.2.
*
* @return True if the version is newer than 1.20.2, otherwise false.
*/
public static boolean isVersionNewerThan1_20_2() {
return version >= 20.19;
}
/**
* Checks if the server version is newer than 1.20.
*
* @return True if the version is newer than 1.20, otherwise false.
*/
public static boolean isVersionNewerThan1_20() {
return version >= 20;
}
/**
* Checks if the server is running Folia.
*
* @return True if the server is running Folia, otherwise false.
*/
public static boolean isFolia() {
return folia;
}
/**
* Checks if the server is running Mohist.
*
* @return True if the server is running Mohist, otherwise false.
*/
public static boolean isMohist() {
return mohist;
}
/**
* Checks if the server is running Paper or its forks.
*
* @return True if the server is running Paper or its forks, otherwise false.
*/
public static boolean isPaperOrItsForks() {
return paper;
}
/**
* Checks if the server is using Mojmap.
*
* @return True if the server is using Mojmap, otherwise false.
*/
public static boolean isMojmap() {
return mojmap;
}
// Method to compare two version strings
/**
* Compares two version strings to determine if the first version is newer than the second.
*
* @param newV The new version string.
* @param currentV The current version string.
* @return True if the new version is newer than the current version, otherwise false.
*/
private static boolean compareVer(String newV, String currentV) {
if (newV == null || currentV == null || newV.isEmpty() || currentV.isEmpty()) {
return false;
@@ -170,31 +251,11 @@ public class VersionHelper {
return true;
} else if (newNum < currentNum) {
return false;
} else if (newPart.length > 1 && currentPart.length > 1) {
String[] newHotfix = newPart[1].split("(?<=\\D)(?=\\d)|(?<=\\d)(?=\\D)");
String[] currentHotfix = currentPart[1].split("(?<=\\D)(?=\\d)|(?<=\\d)(?=\\D)");
if (newHotfix.length == 2 && currentHotfix.length == 1) return true;
else if (newHotfix.length > 1 && currentHotfix.length > 1) {
int newHotfixNum = Integer.parseInt(newHotfix[1]);
int currentHotfixNum = Integer.parseInt(currentHotfix[1]);
if (newHotfixNum > currentHotfixNum) {
return true;
} else if (newHotfixNum < currentHotfixNum) {
return false;
} else {
return newHotfix[0].compareTo(currentHotfix[0]) > 0;
}
}
} else if (newPart.length > 1) {
return true;
} else if (currentPart.length > 1) {
return false;
}
}
catch (NumberFormatException ignored) {
return false;
} catch (NumberFormatException e) {
// handle error
}
}
return newVS.length > currentVS.length;
return false;
}
}

View File

@@ -27,15 +27,43 @@ import org.jetbrains.annotations.ApiStatus;
*/
public interface PipelineInjector {
/**
* Sets the user (player) associated with the given Netty channel.
* This is an internal method for managing the mapping between a channel and a player.
*
* @param channel the Netty channel to associate with the player
* @param user the player to associate with the channel
*/
@ApiStatus.Internal
void setUser(Channel channel, CNPlayer user);
/**
* Retrieves the player associated with the given Netty channel.
* This is an internal method for fetching the player mapped to a specific channel.
*
* @param channel the Netty channel for which the player is being retrieved
* @return the player associated with the given channel
*/
@ApiStatus.Internal
CNPlayer getUser(Channel channel);
/**
* Removes the player associated with the specified Netty channel.
* This is an internal method for detaching a player from the given channel.
*
* @param channel the Netty channel from which the player will be removed
* @return the player that was removed, or null if no player was associated
*/
@ApiStatus.Internal
CNPlayer removeUser(Channel channel);
/**
* Retrieves the player associated with the specified object.
* This method is internal and can be used to get a player from various representations.
*
* @param player the object representing the player (could be a reference or other object type)
* @return the player associated with the object
*/
@ApiStatus.Internal
CNPlayer getUser(Object player);

View File

@@ -23,19 +23,21 @@ import net.momirealms.customnameplates.api.CNPlayer;
import java.util.Set;
import java.util.concurrent.CopyOnWriteArrayList;
/**
* Represents a tracker for a specific player. This class stores and manages the state of the player
* being tracked, including their crouching status, scale, spectator status, and passengers.
*/
public class Tracker {
private boolean isCrouching;
private double scale;
private boolean isSpectator;
private final CNPlayer tracker;
private final CopyOnWriteArrayList<Integer> passengerIDs = new CopyOnWriteArrayList<>();
/**
* Constructs a new Tracker for the specified player.
* Constructs a new Tracker
*
* @param tracker the player being tracked
* @param tracker the tracker who is tracking the player
*/
public Tracker(CNPlayer tracker) {
this.isCrouching = false;
@@ -43,46 +45,101 @@ public class Tracker {
this.tracker = tracker;
}
/**
* Retrieves the tracker
*
* @return the tracker
*/
public CNPlayer tracker() {
return tracker;
}
/**
* Checks if the tracked player is currently crouching.
*
* @return true if the player is crouching, false otherwise
*/
public boolean isCrouching() {
return isCrouching;
}
/**
* Sets the crouching status for the tracked player.
*
* @param crouching the new crouching status
*/
public void setCrouching(boolean crouching) {
isCrouching = crouching;
}
/**
* Checks if the tracked player is in spectator mode.
*
* @return true if the player is a spectator, false otherwise
*/
public boolean isSpectator() {
return isSpectator;
}
/**
* Sets the spectator status for the tracked player.
*
* @param spectator the new spectator status
*/
public void setSpectator(boolean spectator) {
isSpectator = spectator;
}
/**
* Retrieves the current scale of the tracked player.
*
* @return the scale of the player
*/
public double getScale() {
return scale;
}
/**
* Sets the scale for the tracked player.
*
* @param scale the new scale value
*/
public void setScale(double scale) {
this.scale = scale;
}
/**
* Adds a passenger ID to the list of passengers attached to the tracked player.
*
* @param passengerID the ID of the passenger to add
*/
public void addPassengerID(int passengerID) {
this.passengerIDs.add(passengerID);
}
/**
* Removes a passenger ID from the list of passengers attached to the tracked player.
*
* @param passengerID the ID of the passenger to remove
*/
public void removePassengerID(int passengerID) {
this.passengerIDs.remove((Object) passengerID);
}
/**
* Retrieves the set of passenger IDs attached to the tracked player.
*
* @return a set of passenger IDs
*/
public Set<Integer> getPassengerIDs() {
return new ObjectOpenHashSet<>(passengerIDs);
}
/**
* Checks if the tracked player has no passengers attached.
*
* @return true if the player has no passengers, false otherwise
*/
public boolean isEmpty() {
return passengerIDs.isEmpty();
}

View File

@@ -23,15 +23,42 @@ import net.momirealms.customnameplates.api.CustomNameplates;
import java.util.Objects;
import java.util.Set;
/**
* An abstract placeholder class
*/
public abstract class AbstractPlaceholder implements Placeholder {
/**
* Placeholder in string format
*/
protected String id;
/**
* The internal id
*/
protected int countId = PlaceholderCounter.getAndIncrease();
/**
* Refresh internal
*/
protected int refreshInterval;
/**
* The PlaceholderManager instance
*/
protected PlaceholderManager manager;
/**
* The nested placeholders
*/
protected Set<Placeholder> children = new ObjectOpenHashSet<>();
/**
* The parent placeholders
*/
protected Set<Placeholder> parents = new ObjectOpenHashSet<>();
/**
* Constructs a new placeholder
*
* @param manager manager
* @param id id
* @param refreshInterval refreshInterval
*/
protected AbstractPlaceholder(PlaceholderManager manager, String id, int refreshInterval) {
if (refreshInterval == 0) {
refreshInterval = -1;

View File

@@ -19,6 +19,9 @@ package net.momirealms.customnameplates.api.placeholder;
import java.util.Set;
/**
* Placeholder
*/
public interface Placeholder {
/**

View File

@@ -27,9 +27,18 @@ import net.momirealms.customnameplates.api.helper.AdventureHelper;
import org.jetbrains.annotations.ApiStatus;
import org.jetbrains.annotations.NotNull;
/**
* A class that represents an adaptive image combined with dynamic text, allowing
* for the generation of image strings with custom margins, and dynamically rendered text.
* <p>
* This class provides methods to create the full image and text output, including
* any necessary font and shadow adjustments based on specific settings.
* </p>
*
* @param <T> the type of {@link AdaptiveImage} associated with this class
*/
@ApiStatus.Internal
public class AdaptiveImageText<T extends AdaptiveImage> {
private final String id;
private final String text;
private final T t;
@@ -39,6 +48,17 @@ public class AdaptiveImageText<T extends AdaptiveImage> {
private final int leftMargin;
private final int rightMargin;
/**
* Constructs an instance of {@link AdaptiveImageText} with the given parameters.
*
* @param id the unique identifier for this adaptive image text
* @param text the base text to be used in the image
* @param t the {@link AdaptiveImage} object that provides the image
* @param removeShadowOld flag to indicate whether to remove shadow using old method
* @param removeShadowNew flag to indicate whether to remove shadow using new method
* @param leftMargin the left margin for positioning the image
* @param rightMargin the right margin for positioning the image
*/
public AdaptiveImageText(String id, String text, T t, boolean removeShadowOld, boolean removeShadowNew, int rightMargin, int leftMargin) {
this.text = text;
this.id = id;
@@ -50,22 +70,58 @@ public class AdaptiveImageText<T extends AdaptiveImage> {
this.rightMargin = rightMargin;
}
/**
* Creates an instance of {@link AdaptiveImageText} with the specified parameters.
*
* @param id the unique identifier for this adaptive image text
* @param text the base text to be used in the image
* @param t the {@link AdaptiveImage} object that provides the image
* @param removeShadowOld flag to indicate whether to remove shadow using old method
* @param removeShadowNew flag to indicate whether to remove shadow using new method
* @param leftMargin the left margin for positioning the image
* @param rightMargin the right margin for positioning the image
* @param <T> the type of {@link AdaptiveImage} associated with this class
* @return a new instance of {@link AdaptiveImageText}
*/
public static <T extends AdaptiveImage> AdaptiveImageText<T> create(String id, final String text, final T t, final boolean removeShadowOld, final boolean removeShadowNew, int leftMargin, int rightMargin) {
return new AdaptiveImageText<>(id, text, t, removeShadowOld, removeShadowNew, rightMargin, leftMargin);
}
/**
* Gets the pre-parsed dynamic text associated with this adaptive image text.
*
* @return the pre-parsed dynamic text
*/
public PreParsedDynamicText getPreParsedDynamicText() {
return preParsedDynamicText;
}
/**
* Gets the unique identifier for this adaptive image text.
*
* @return the unique identifier
*/
public String getId() {
return id;
}
/**
* Gets the base text associated with this adaptive image text.
*
* @return the base text
*/
public String getText() {
return text;
}
/**
* Generates the full string of text with both the prefix and suffix of the image,
* rendering dynamic content and applying font and shadow adjustments.
*
* @param p1 the first {@link CNPlayer} used for dynamic text rendering
* @param p2 the second {@link CNPlayer} used for dynamic text rendering
* @return the full image and text string
*/
@NotNull
public String getFull(CNPlayer p1, CNPlayer p2) {
String parsed = preParsedDynamicText.fastCreate(p1).render(p2);
@@ -85,6 +141,14 @@ public class AdaptiveImageText<T extends AdaptiveImage> {
return prefixWithFont + parsed + suffixWithFont;
}
/**
* Generates the image string with dynamic content applied, rendering
* the image and applying font and shadow adjustments.
*
* @param p1 the first {@link CNPlayer} used for dynamic text rendering
* @param p2 the second {@link CNPlayer} used for dynamic text rendering
* @return the generated image string
*/
@NotNull
public String getImage(CNPlayer p1, CNPlayer p2) {
String parsed = preParsedDynamicText.fastCreate(p1).render(p2);
@@ -97,11 +161,26 @@ public class AdaptiveImageText<T extends AdaptiveImage> {
return imageWithFont;
}
/**
* Gets the rendered dynamic text for the specified players.
*
* @param p1 the first {@link CNPlayer} used for dynamic text rendering
* @param p2 the second {@link CNPlayer} used for dynamic text rendering
* @return the rendered dynamic text
*/
@NotNull
public String getText(CNPlayer p1, CNPlayer p2) {
return preParsedDynamicText.fastCreate(p1).render(p2);
}
/**
* Generates the text offset characters for the specified players.
* The offsets are calculated based on the rendered text and its advance.
*
* @param p1 the first {@link CNPlayer} used for dynamic text rendering
* @param p2 the second {@link CNPlayer} used for dynamic text rendering
* @return the generated text offset characters
*/
@NotNull
public String getTextOffsetCharacters(CNPlayer p1, CNPlayer p2) {
return OffsetFont.createOffsets(CustomNameplatesAPI.getInstance().getTextAdvance(preParsedDynamicText.fastCreate(p1).render(p2)));

View File

@@ -20,21 +20,48 @@ package net.momirealms.customnameplates.api.placeholder.internal;
import net.momirealms.customnameplates.api.feature.PreParsedDynamicText;
import org.jetbrains.annotations.ApiStatus;
/**
* Shift Text
*/
@ApiStatus.Internal
public class ShiftText {
/**
* The font associated with the text.
*/
private final String font;
/**
* The pre-parsed dynamic text, allowing for the use of placeholders and dynamic content.
*/
private final PreParsedDynamicText text;
/**
* Constructs a ShiftText instance with the specified font and text.
* The text is parsed dynamically for placeholders and other content.
*
* @param font the font to be associated with the text
* @param text the dynamic text that may contain placeholders to be parsed
*/
public ShiftText(String font, String text) {
this.font = font;
this.text = new PreParsedDynamicText(text);
}
/**
* Retrieves the font associated with this ShiftText.
*
* @return the font as a String
*/
public String getFont() {
return font;
}
/**
* Retrieves the pre-parsed dynamic text associated with this ShiftText.
*
* @return the PreParsedDynamicText instance
*/
public PreParsedDynamicText getText() {
return text;
}

View File

@@ -17,7 +17,20 @@
package net.momirealms.customnameplates.api.placeholder.internal;
/**
* Enum representing the static positions that an element can occupy.
*/
public enum StaticPosition {
LEFT, RIGHT, MIDDLE
/**
* Represents the leftmost position.
*/
LEFT,
/**
* Represents the rightmost position.
*/
RIGHT,
/**
* Represents the center position.
*/
MIDDLE
}

View File

@@ -22,43 +22,95 @@ import net.momirealms.customnameplates.api.CustomNameplatesAPI;
import net.momirealms.customnameplates.api.feature.PreParsedDynamicText;
import org.jetbrains.annotations.ApiStatus;
/**
* Class representing a static text element with customizable width, position, and content.
*/
@ApiStatus.Internal
public class StaticText {
private final int width;
private final StaticPosition position;
private final PreParsedDynamicText text;
/**
* Constructs a new StaticText instance.
*
* @param width the width of the text element (e.g., for layout purposes)
* @param position the static position of the text element (LEFT, RIGHT, MIDDLE)
* @param text the text content to be displayed, which can contain placeholders for dynamic rendering
*/
public StaticText(int width, StaticPosition position, String text) {
this.width = width;
this.position = position;
this.text = new PreParsedDynamicText(text);
}
/**
* Gets the width of the text element.
*
* @return the width of the text element
*/
public int getWidth() {
return width;
}
/**
* Gets the static position of the text element.
*
* @return the position of the text element (LEFT, RIGHT, MIDDLE)
*/
public StaticPosition getPosition() {
return position;
}
/**
* Gets the pre-parsed dynamic text associated with this static text element.
*
* @return the PreParsedDynamicText instance
*/
public PreParsedDynamicText getText() {
return text;
}
/**
* Creates and renders the static text element, using null as the player context.
* <p>
* This method can be useful when rendering static text without needing player-specific dynamic values.
*
* @return the rendered static text as a String
*/
public String create() {
return create(text.fastCreate(null).render(null));
}
/**
* Creates and renders the static text element for a specific player context.
*
* @param player the player whose context will be used for dynamic text rendering
* @return the rendered static text as a String
*/
public String create(CNPlayer player) {
return create(text.fastCreate(player).render(player));
}
/**
* Creates and renders the static text element with two player contexts (for relational rendering).
*
* @param p1 the first player whose context will be used for dynamic text rendering
* @param p2 the second player whose context will be used for relational rendering
* @return the rendered static text as a String
*/
public String create(CNPlayer p1, CNPlayer p2) {
return create(text.fastCreate(p1).render(p2));
}
/**
* A helper method to create and render the static text element with a given plain text.
* <p>
* This method will pass the rendered text, width, and position to the API for final rendering.
*
* @param text the plain text to be rendered
* @return the rendered static text as a String
*/
public String create(String text) {
return CustomNameplatesAPI.getInstance().createStaticText(text, width, position);
}

View File

@@ -25,9 +25,14 @@ import net.momirealms.customnameplates.api.feature.image.Image;
import net.momirealms.customnameplates.api.helper.AdventureHelper;
import org.jetbrains.annotations.ApiStatus;
/**
* Represents a Vanilla HUD (Heads-Up Display) for displaying a dynamic progress bar,
* typically used for showing health, energy, or other stats in a game.
* This class handles the rendering of the HUD, which includes handling the current and maximum values,
* and creating a visual display using a combination of empty, half, and full symbols.
*/
@ApiStatus.Internal
public class VanillaHud {
private final String empty;
private final String half;
private final String full;
@@ -35,6 +40,16 @@ public class VanillaHud {
private final PreParsedDynamicText current;
private final PreParsedDynamicText max;
/**
* Constructs a VanillaHud with the specified parameters.
*
* @param empty The image representing an empty portion of the bar.
* @param half The image representing a half-filled portion of the bar.
* @param full The image representing a fully-filled portion of the bar.
* @param reverse Whether the bar should be reversed (starts from full to empty).
* @param current The current value to be displayed.
* @param max The maximum value to be displayed.
*/
public VanillaHud(Image empty, Image half, Image full, boolean reverse, String current, String max) {
this.empty = String.valueOf(empty.character().character()) + OffsetFont.NEG_2.character();
this.half = String.valueOf(half.character().character()) + OffsetFont.NEG_2.character();
@@ -44,26 +59,61 @@ public class VanillaHud {
this.max = new PreParsedDynamicText(max);
}
/**
* Gets the dynamic text for the current value.
*
* @return The dynamic text for the current value.
*/
public PreParsedDynamicText getCurrent() {
return current;
}
/**
* Gets the dynamic text for the maximum value.
*
* @return The dynamic text for the maximum value.
*/
public PreParsedDynamicText getMax() {
return max;
}
/**
* Creates and renders the HUD for a general case (with no player context).
*
* @return The rendered HUD as a string.
*/
public String create() {
return create(current.fastCreate(null).render(null), max.fastCreate(null).render(null));
}
/**
* Creates and renders the HUD for a specific player.
*
* @param player The player whose current and max values will be rendered.
* @return The rendered HUD as a string.
*/
public String create(CNPlayer player) {
return create(current.fastCreate(player).render(player), max.fastCreate(player).render(player));
}
/**
* Creates and renders the HUD for two players, using their respective values.
*
* @param p1 The first player.
* @param p2 The second player.
* @return The rendered HUD as a string.
*/
public String create(CNPlayer p1, CNPlayer p2) {
return create(current.fastCreate(p1).render(p2), max.fastCreate(p1).render(p2));
}
/**
* Creates the actual HUD string representation, based on current and max values.
*
* @param current The current value as a string.
* @param max The maximum value as a string.
* @return The constructed and rendered HUD as a string.
*/
private String create(String current, String max) {
double currentDouble;
double maxDouble;

View File

@@ -24,7 +24,9 @@ import net.momirealms.customnameplates.api.CustomNameplates;
* A requirement that is always satisfied, representing an "empty" or default requirement.
*/
public class EmptyRequirement implements Requirement {
/**
* A requirement that is always satisfied, representing an "empty" or default requirement.
*/
public static final EmptyRequirement INSTANCE = new EmptyRequirement();
/**

View File

@@ -23,6 +23,9 @@ import org.jetbrains.annotations.NotNull;
import java.util.UUID;
/**
* Interface to manage data storage
*/
public interface StorageManager extends Reloadable {
/**

View File

@@ -17,14 +17,67 @@
package net.momirealms.customnameplates.api.storage;
/**
* Enum representing the various types of storage systems supported for data persistence.
* <p>
* Each enum constant corresponds to a different type of storage backend that can be used
* for saving and retrieving data. This includes file-based storage (JSON, YAML), relational
* databases (H2, SQLite, MySQL, MariaDB), NoSQL databases (MongoDB), and caching systems (Redis).
* </p>
*/
public enum StorageType {
/**
* Represents storage in JSON format.
* This format is typically used for lightweight data storage and easy serialization.
*/
JSON,
/**
* Represents storage in YAML format.
* YAML is often used for configuration files and is human-readable.
*/
YAML,
/**
* Represents storage in an H2 database.
* H2 is an in-memory SQL database that can also be used in file-based mode.
*/
H2,
/**
* Represents storage in an SQLite database.
* SQLite is a serverless, self-contained SQL database engine.
*/
SQLITE,
/**
* Represents storage in a MySQL database.
* MySQL is a widely used relational database management system (RDBMS).
*/
MYSQL,
/**
* Represents storage in a MariaDB database.
* MariaDB is a community-developed, open-source RDBMS that is a fork of MySQL.
*/
MARIADB,
MONGODB,
/**
* Represents storage in a MongoDB database.
* MongoDB is a NoSQL database that stores data in flexible, JSON-like documents.
*/
MONGODB,
/**
* Represents storage in Redis.
* Redis is an in-memory data structure store, used as a database, cache, and message broker.
*/
Redis,
/**
* Represents the absence of a storage type.
* This is used when no storage system is configured or required.
*/
NONE
}

View File

@@ -36,33 +36,57 @@ public class JsonData {
private int flags;
/**
* Constructs a new {@link JsonData} instance.
* Constructs a new {@link JsonData} instance with the specified nameplate and bubble, setting flags to 0.
*
* @param nameplate the nameplate value
* @param bubble the bubble value
*/
public JsonData(String nameplate, String bubble) {
this.nameplate = nameplate;
this.bubble = bubble;
this.flags = 0;
this(nameplate, bubble, 0);
}
/**
* Constructs a new {@link JsonData} instance with the specified nameplate, bubble, and flags.
*
* @param nameplate the nameplate value
* @param bubble the bubble value
* @param flags the flags value
*/
public JsonData(String nameplate, String bubble, int flags) {
this.nameplate = nameplate;
this.bubble = bubble;
this.flags = flags;
}
/**
* Constructs a new {@link JsonData} instance with the specified nameplate, bubble, and a preview state flag.
*
* @param nameplate the nameplate value
* @param bubble the bubble value
* @param previewState the preview state
*/
public JsonData(String nameplate, String bubble, boolean previewState) {
this.nameplate = nameplate;
this.bubble = bubble;
this.flags = encodeFlags(previewState);
}
/**
* Encodes the preview state as a flag (0 or 1).
*
* @param previewState the preview state
* @return 1 if preview state is true, otherwise 0
*/
public static int encodeFlags(boolean previewState) {
return previewState ? 1 : 0;
}
/**
* Decodes the preview state from the flags.
*
* @param flags the flags value
* @return true if the preview state flag is set, otherwise false
*/
public static boolean decodePreviewState(int flags) {
return (flags & 1) == 1;
}

View File

@@ -23,8 +23,13 @@ import java.util.UUID;
* Represents player-specific data, including the player's nameplate, bubble, and UUID.
*/
public interface PlayerData {
/**
* Default nameplate
*/
String DEFAULT_NAMEPLATE = "none";
/**
* Default bubble
*/
String DEFAULT_BUBBLE = "none";
/**

View File

@@ -24,13 +24,27 @@ import java.util.UUID;
* It includes the player's name, their nameplate and bubble data.
*/
public class PlayerDataImpl implements PlayerData {
/**
* The UUID of the player
*/
protected UUID uuid;
/**
* The nameplate identifier for the player
*/
protected String nameplate;
/**
* The bubble identifier for the player
*/
protected String bubble;
/**
* Flag indicating whether preview tags are enabled
*/
protected boolean previewTags;
public PlayerDataImpl(UUID uuid, String nameplate, String bubble, boolean previewTags) {
private PlayerDataImpl(UUID uuid, String nameplate, String bubble, boolean previewTags) {
this.uuid = uuid;
this.nameplate = nameplate;
this.bubble = bubble;

View File

@@ -17,18 +17,44 @@
package net.momirealms.customnameplates.api.util;
/**
* Enum representing text alignment options.
* <p>
* This enum provides three types of text alignment: CENTER, LEFT, and RIGHT, each associated
* with a unique ID for easy identification. These values are typically used to define the
* positioning of text in layouts or UI components.
* </p>
*/
public enum Alignment {
/**
* Represents center-aligned text.
*/
CENTER(0),
/**
* Represents left-aligned text.
*/
LEFT(1),
/**
* Represents right-aligned text.
*/
RIGHT(2);
final int id;
/**
* Constructs an {@code Alignment} instance with the specified ID.
*
* @param id the unique ID representing this alignment type
*/
Alignment(int id) {
this.id = id;
}
/**
* Retrieves the ID associated with this alignment.
*
* @return the unique ID of this alignment
*/
public int getId() {
return id;
}

View File

@@ -19,8 +19,21 @@ package net.momirealms.customnameplates.api.util;
import java.util.ArrayList;
/**
* Utility class for handling character and Unicode conversions.
* This class provides methods to convert between Unicode escape sequences, character arrays,
* and code points, as well as converting characters to their Unicode representations.
*/
public class CharacterUtils {
private CharacterUtils() {}
/**
* Converts a Unicode string (e.g., "\\u0041\\u0042") into an array of characters.
*
* @param unicodeString a string containing Unicode escape sequences (e.g., "\\u0041\\u0042")
* @return a character array corresponding to the Unicode string
*/
public static char[] unicodeToChars(String unicodeString) {
String processedString = unicodeString.replace("\\u", "");
int length = processedString.length() / 4;
@@ -37,6 +50,14 @@ public class CharacterUtils {
return chars;
}
/**
* Converts a character array to a single Unicode code point. If the array contains two characters
* (a high surrogate and a low surrogate), it is combined into a single supplementary code point.
*
* @param chars the character array to convert
* @return the Unicode code point corresponding to the character(s)
* @throws IllegalArgumentException if the character array contains more than 2 characters
*/
public static int toCodePoint(char[] chars) {
if (chars.length == 1) {
return chars[0];
@@ -47,6 +68,14 @@ public class CharacterUtils {
}
}
/**
* Converts a character array to an array of Unicode code points. If the array contains surrogate pairs,
* they are combined into a single supplementary code point.
*
* @param chars the character array to convert
* @return an array of Unicode code points corresponding to the characters
* @throws IllegalArgumentException if there is an illegal surrogate pair
*/
public static int[] toCodePoints(char[] chars) {
ArrayList<Integer> codePoints = new ArrayList<>();
for (int i = 0; i < chars.length; i++) {
@@ -67,6 +96,12 @@ public class CharacterUtils {
return codePoints.stream().mapToInt(i -> i).toArray();
}
/**
* Converts a single character to its Unicode escape sequence (e.g., '\\u0041' for 'A').
*
* @param c the character to convert
* @return a string representing the Unicode escape sequence for the character
*/
public static String char2Unicode(char c) {
StringBuilder stringBuilder_1 = new StringBuilder("\\u");
StringBuilder stringBuilder_2 = new StringBuilder(Integer.toHexString(c));
@@ -76,6 +111,12 @@ public class CharacterUtils {
return stringBuilder_1.toString();
}
/**
* Converts an array of characters to their Unicode escape sequences.
*
* @param c the character array to convert
* @return a string representing the Unicode escape sequences for all characters in the array
*/
public static String char2Unicode(char[] c) {
StringBuilder builder = new StringBuilder();
for (char value : c) {

View File

@@ -25,8 +25,19 @@ import net.momirealms.customnameplates.api.requirement.Requirement;
import java.io.File;
import java.util.*;
/**
* Utility class providing various helper methods for handling configuration data
*/
public class ConfigUtils {
private ConfigUtils() {}
/**
* Creates a {@link CarouselText} object from the provided configuration section.
*
* @param section the configuration section containing properties for the CarouselText.
* @return a {@link CarouselText} instance created from the section data.
*/
public static CarouselText carouselText(Section section) {
return new CarouselText(
section.getInt("duration", 200),
@@ -36,6 +47,12 @@ public class ConfigUtils {
);
}
/**
* Creates an array of {@link CarouselText} objects, sorted by their order from the given configuration section.
*
* @param section the configuration section containing multiple CarouselText entries.
* @return an array of {@link CarouselText} instances, sorted by order.
*/
public static CarouselText[] carouselTexts(Section section) {
TreeMap<Integer, CarouselText> map = new TreeMap<>();
if (section == null) {
@@ -58,10 +75,22 @@ public class ConfigUtils {
return map.values().toArray(new CarouselText[0]);
}
/**
* Converts a comma-separated string to an ARGB color value.
*
* @param arg the comma-separated string representing the ARGB color.
* @return the corresponding ARGB color integer value.
*/
public static int argb(String arg) {
return argb(arg.split(","));
}
/**
* Converts an array of strings to an ARGB color value.
*
* @param args an array of strings representing ARGB components (alpha, red, green, blue).
* @return the corresponding ARGB color integer value.
*/
public static int argb(String[] args) {
int alpha = args.length >= 1 ? Integer.parseInt(args[0]) : 64;
int red = args.length >= 2 ? Integer.parseInt(args[1]) : 0;
@@ -70,14 +99,35 @@ public class ConfigUtils {
return argb(alpha, red, green, blue);
}
/**
* Converts the given ARGB components to a single ARGB integer value.
*
* @param alpha the alpha component of the color.
* @param red the red component of the color.
* @param green the green component of the color.
* @param blue the blue component of the color.
* @return the corresponding ARGB color integer value.
*/
public static int argb(int alpha, int red, int green, int blue) {
return (alpha << 24) | (red << 16) | (green << 8) | blue;
}
/**
* Converts a comma-separated string to a {@link Vector3} object.
*
* @param arg the comma-separated string representing the vector (x, y, z).
* @return the corresponding {@link Vector3} object.
*/
public static Vector3 vector3(String arg) {
return vector3(arg.split(","));
}
/**
* Converts an array of strings to a {@link Vector3} object.
*
* @param args an array of strings representing the x, y, and z components of the vector.
* @return the corresponding {@link Vector3} object.
*/
public static Vector3 vector3(String[] args) {
float x = args.length >= 1 ? Float.parseFloat(args[0]) : 0f;
float y = args.length >= 2 ? Float.parseFloat(args[1]) : 0f;
@@ -85,10 +135,24 @@ public class ConfigUtils {
return vector3(x, y, z);
}
/**
* Creates a {@link Vector3} object from the provided float components.
*
* @param x the x component of the vector.
* @param y the y component of the vector.
* @param z the z component of the vector.
* @return the corresponding {@link Vector3} object.
*/
public static Vector3 vector3(float x, float y, float z) {
return new Vector3(x, y, z);
}
/**
* Recursively retrieves all configuration files with a ".yml" extension from the given folder and its subfolders.
*
* @param configFolder the root folder to start searching for YAML files.
* @return a list of valid configuration files sorted by name.
*/
public static List<File> getConfigsDeeply(File configFolder) {
ArrayList<File> validConfigs = new ArrayList<>();
Deque<File> fileDeque = new ArrayDeque<>();
@@ -109,11 +173,26 @@ public class ConfigUtils {
return validConfigs;
}
/**
* Retrieves a file located in the same folder as the provided file, with a new name.
*
* @param file the base file.
* @param fileName the name of the file to retrieve.
* @return the file located in the same folder with the specified name.
*/
public static File getFileInTheSameFolder(File file, String fileName) {
File folder = file.getParentFile();
return new File(folder, fileName);
}
/**
* Safely casts an object to the specified type, logging an error if the cast fails.
*
* @param object the object to cast.
* @param clazz the class type to cast to.
* @param <T> the type to cast to.
* @return the cast object if successful, or null if the cast fails.
*/
public static <T> T safeCast(Object object, Class<T> clazz) {
try {
return clazz.cast(object);
@@ -123,3 +202,4 @@ public class ConfigUtils {
}
}
}

View File

@@ -19,10 +19,30 @@ package net.momirealms.customnameplates.api.util;
import java.util.concurrent.ThreadLocalRandom;
/**
* A utility class for generating self-incrementing entity IDs.
* The class provides a thread-safe method for generating unique IDs that increase with each call.
* The IDs are randomly initialized within a specific range to ensure non-repetition across instances.
*/
public class SelfIncreaseEntityID {
/**
* Private constructor to prevent instantiation of this utility class.
*/
private SelfIncreaseEntityID() {}
/**
* The current entity ID, initialized with a random value in a specific range.
* The value is incremented each time {@link #getAndIncrease()} is called.
*/
private static int id = ThreadLocalRandom.current().nextInt(Integer.MAX_VALUE / 4, Integer.MAX_VALUE / 3);
/**
* Retrieves the current entity ID and increments it for the next call.
* This method ensures that each ID is unique and increases incrementally.
*
* @return the current entity ID before it is incremented
*/
public static int getAndIncrease() {
int i = id;
id++;

View File

@@ -19,22 +19,55 @@ package net.momirealms.customnameplates.api.util;
import net.momirealms.customnameplates.api.CustomNameplates;
/**
* A simple record representing a 3D vector with `x`, `y`, and `z` coordinates.
* Provides utility methods for vector arithmetic such as addition and scaling.
*/
public record Vector3(double x, double y, double z) {
/**
* A constant representing a zero vector (0, 0, 0).
*/
public static final Vector3 ZERO = new Vector3(0, 0, 0);
/**
* Converts the vector into a platform-specific 3D vector representation.
*
* @return A platform-specific 3D vector object.
*/
public Object toVec3() {
return CustomNameplates.getInstance().getPlatform().vec3(x, y, z);
}
/**
* Adds another vector to this vector and returns a new resulting vector.
*
* @param another The vector to be added to this vector.
* @return A new `Vector3` representing the sum of this vector and the given vector.
*/
public Vector3 add(Vector3 another) {
return new Vector3(this.x + another.x, this.y + another.y, this.z + another.z);
}
/**
* Adds the given `x`, `y`, and `z` values to the respective components of this vector
* and returns a new resulting vector.
*
* @param x The value to add to the `x` component.
* @param y The value to add to the `y` component.
* @param z The value to add to the `z` component.
* @return A new `Vector3` representing the sum of this vector and the given values.
*/
public Vector3 add(double x, double y, double z) {
return new Vector3(this.x + x, this.y + y, this.z + z);
}
/**
* Scales this vector by a given factor and returns a new resulting vector.
*
* @param value The factor to multiply each component of the vector by.
* @return A new `Vector3` representing the scaled vector.
*/
public Vector3 multiply(double value) {
return new Vector3(this.x * value, this.y * value, this.z * value);
}

View File

@@ -26,8 +26,25 @@ import java.util.stream.Stream;
import java.util.zip.ZipEntry;
import java.util.zip.ZipOutputStream;
/**
* Utility class for zipping files and directories.
* Provides methods for zipping entire directories and adding individual files to a zip archive.
*/
public class ZipUtils {
/**
* Private constructor to prevent instantiation of utility class.
*/
private ZipUtils() {}
/**
* Zips the contents of a directory into a zip file.
* This method recursively walks through the directory and adds each file to the zip archive.
*
* @param folderPath The path to the folder to be zipped.
* @param zipFilePath The path to the output zip file.
* @throws IOException If an I/O error occurs while reading the directory or writing the zip file.
*/
public static void zipDirectory(Path folderPath, Path zipFilePath) throws IOException {
try (ZipOutputStream zos = new ZipOutputStream(new FileOutputStream(zipFilePath.toFile()))) {
try (Stream<Path> paths = Files.walk(folderPath)) {
@@ -45,6 +62,14 @@ public class ZipUtils {
}
}
/**
* Adds a file's contents to the zip archive.
*
* @param zipEntry The zip entry (file) to be added to the zip archive.
* @param is The input stream from which the file contents are read.
* @param zos The zip output stream where the file will be written.
* @throws IOException If an I/O error occurs while writing the file to the zip archive.
*/
public static void addToZip(ZipEntry zipEntry, InputStream is, ZipOutputStream zos) throws IOException {
zos.putNextEntry(zipEntry);
byte[] buffer = new byte[4096];

View File

@@ -19,8 +19,6 @@ package net.momirealms.customnameplates.bukkit;
import it.unimi.dsi.fastutil.ints.IntList;
import me.clip.placeholderapi.PlaceholderAPI;
import net.kyori.adventure.platform.bukkit.BukkitAudiences;
import net.kyori.adventure.text.Component;
import net.momirealms.customnameplates.api.CNPlayer;
import net.momirealms.customnameplates.api.ConfigManager;
import net.momirealms.customnameplates.api.CustomNameplates;