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

merge modules

This commit is contained in:
XiaoMoMi
2025-01-26 23:20:27 +08:00
parent 88e4af721b
commit 8c1a858e2a
106 changed files with 1376 additions and 629 deletions

View File

@@ -25,7 +25,7 @@ Get the artifact under /target folder
## How to Contribute
#### Translations
Clone this project and create a new language file in the /common/src/main/resources/translations directory. \
Clone this project and create a new language file in the /backend/src/main/resources/translations directory. \
Once your changes are ready, open a pull request for review. We appreciate your works!
## Support the Developer

View File

@@ -1,5 +1,4 @@
plugins {
id("io.github.goooler.shadow") version "8.1.8"
id("maven-publish")
}
@@ -10,21 +9,32 @@ repositories {
}
dependencies {
implementation(project(":common"))
// Adventure
implementation("net.kyori:adventure-api:${rootProject.properties["adventure_bundle_version"]}")
compileOnly("net.kyori:adventure-text-minimessage:${rootProject.properties["adventure_bundle_version"]}")
compileOnly("net.kyori:adventure-text-serializer-gson:${rootProject.properties["adventure_bundle_version"]}")
compileOnly("net.kyori:adventure-text-minimessage:${rootProject.properties["adventure_bundle_version"]}")
compileOnly("net.kyori:adventure-text-serializer-gson:${rootProject.properties["adventure_bundle_version"]}")
// YAML
implementation(files("libs/boosted-yaml-${rootProject.properties["boosted_yaml_version"]}.jar"))
// Cache
compileOnly("com.github.ben-manes.caffeine:caffeine:${rootProject.properties["caffeine_version"]}")
// Netty
compileOnly("io.netty:netty-all:4.1.113.Final")
compileOnly("io.netty:netty-all:4.1.117.Final")
// GSON
compileOnly("com.google.code.gson:gson:${rootProject.properties["gson_version"]}")
// Fast util
compileOnly("it.unimi.dsi:fastutil:${rootProject.properties["fastutil_version"]}")
// Command
compileOnly("org.incendo:cloud-core:${rootProject.properties["cloud_core_version"]}")
compileOnly("org.incendo:cloud-minecraft-extras:${rootProject.properties["cloud_minecraft_extras_version"]}")
// Logger
compileOnly("org.slf4j:slf4j-api:${rootProject.properties["slf4j_version"]}")
compileOnly("org.apache.logging.log4j:log4j-core:${rootProject.properties["log4j_version"]}")
// Expression
compileOnly("net.objecthunter:exp4j:${rootProject.properties["exp4j_version"]}")
// code generator
compileOnly("net.bytebuddy:byte-buddy:${rootProject.properties["byte_buddy_version"]}")
}
java {
@@ -34,7 +44,6 @@ java {
languageVersion = JavaLanguageVersion.of(17)
}
withSourcesJar()
withJavadocJar()
}
tasks.withType<JavaCompile> {
@@ -45,7 +54,7 @@ tasks.withType<JavaCompile> {
tasks {
shadowJar {
// archiveClassifier.set("")
archiveClassifier.set("")
archiveFileName = "custom-nameplates-${rootProject.properties["project_version"]}.jar"
relocate ("net.kyori", "net.momirealms.customnameplates.libraries")
relocate("dev.dejvokep", "net.momirealms.customnameplates.libraries")
@@ -73,10 +82,18 @@ publishing {
groupId = "net.momirealms"
artifactId = "custom-nameplates"
version = rootProject.properties["project_version"].toString()
from(components["java"])
artifact(tasks["sourcesJar"])
from(components["shadow"])
pom {
name = "CustomNameplates API"
url = "https://momirealms.net"
url = "https://github.com/Xiao-MoMi/Custom-Nameplates"
licenses {
license {
name = "GNU General Public License v3.0"
url = "https://www.gnu.org/licenses/gpl-3.0.html"
distribution = "repo"
}
}
}
}
}

View File

@@ -0,0 +1,161 @@
/*
* Copyright (C) <2024> <XiaoMoMi>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
package net.momirealms.customnameplates.common.command;
import net.kyori.adventure.text.Component;
import net.kyori.adventure.text.TranslatableComponent;
import net.momirealms.customnameplates.common.sender.SenderFactory;
import org.incendo.cloud.Command;
import org.incendo.cloud.CommandManager;
import org.incendo.cloud.context.CommandContext;
/**
* Abstract base class for command feature implementations within the Custom Nameplates command system.
* This class provides utility methods for command registration, feedback handling, and configuration.
*
* @param <C> The type of the sender (e.g., a player or console sender) for the command.
*/
public abstract class AbstractCommandFeature<C> implements CommandFeature<C> {
/**
* The command manager
*/
protected final CustomNameplatesCommandManager<C> commandManager;
/**
* The command config
*/
protected CommandConfig commandConfig;
/**
* Constructs an AbstractCommandFeature instance with the given command manager.
*
* @param commandManager The command manager to manage the commands associated with this feature.
*/
public AbstractCommandFeature(CustomNameplatesCommandManager<C> commandManager) {
this.commandManager = commandManager;
}
/**
* Abstract method to retrieve the sender factory for the command.
* Implementations must provide the logic for creating senders of type C.
*
* @return The sender factory for the command.
*/
protected abstract SenderFactory<?, C> getSenderFactory();
/**
* Abstract method to assemble the command builder with the given manager.
* Implementations must define how to build the command.
*
* @param manager The command manager responsible for managing the command.
* @param builder The builder used to construct the command.
* @return A command builder ready to be built.
*/
public abstract Command.Builder<? extends C> assembleCommand(CommandManager<C> manager, Command.Builder<C> builder);
/**
* Registers the command with the provided command manager.
* This method builds the command and registers it with the command manager.
*
* @param manager The command manager to register the command with.
* @param builder The builder used to create the command.
* @return The registered command.
*/
@Override
@SuppressWarnings("unchecked")
public Command<C> registerCommand(CommandManager<C> manager, Command.Builder<C> builder) {
Command<C> command = (Command<C>) assembleCommand(manager, builder).build();
manager.command(command);
return command;
}
/**
* Registers any related functions or hooks. This method is a no-op by default
* and can be overridden in subclasses to register additional functionality.
*/
@Override
public void registerRelatedFunctions() {
// empty
}
/**
* Unregisters any related functions or hooks. This method is a no-op by default
* and can be overridden in subclasses to unregister additional functionality.
*/
@Override
public void unregisterRelatedFunctions() {
// empty
}
/**
* Handles feedback for the command execution, sending a translation message to the sender.
* The feedback is suppressed if the "silent" flag is present in the command context.
*
* @param context The command context containing information about the sender and flags.
* @param key The key for the translation component to be used as feedback.
* @param args The arguments to be passed to the translation.
*/
@Override
@SuppressWarnings("unchecked")
public void handleFeedback(CommandContext<?> context, TranslatableComponent.Builder key, Component... args) {
if (context.flags().hasFlag("silent")) {
return;
}
commandManager.handleCommandFeedback((C) context.sender(), key, args);
}
/**
* Handles feedback for the command execution, sending a translation message to the sender.
*
* @param sender The sender to receive the feedback.
* @param key The key for the translation component to be used as feedback.
* @param args The arguments to be passed to the translation.
*/
@Override
public void handleFeedback(C sender, TranslatableComponent.Builder key, Component... args) {
commandManager.handleCommandFeedback(sender, key, args);
}
/**
* Retrieves the command manager associated with this feature.
*
* @return The command manager.
*/
@Override
public CustomNameplatesCommandManager<C> getCustomNameplatesCommandManager() {
return commandManager;
}
/**
* Retrieves the configuration associated with the command.
*
* @return The command configuration.
*/
@Override
public CommandConfig getCommandConfig() {
return commandConfig;
}
/**
* Sets the configuration for the command.
*
* @param commandConfig The configuration to set for the command.
*/
public void setCommandConfig(CommandConfig commandConfig) {
this.commandConfig = commandConfig;
}
}

View File

@@ -49,17 +49,39 @@ import java.util.ArrayList;
import java.util.Collection;
import java.util.HashSet;
/**
* An abstract implementation of the {@link CustomNameplatesCommandManager} that handles the management and registration of command features,
* exception handling, and feedback handling within the Custom Nameplates plugin.
*
* @param <C> The type of the sender (e.g., player, console) for the commands.
*/
public abstract class AbstractCommandManager<C> implements CustomNameplatesCommandManager<C> {
/**
* Registered commands
*/
protected final HashSet<CommandComponent<C>> registeredRootCommandComponents = new HashSet<>();
/**
* Registered features
*/
protected final HashSet<CommandFeature<C>> registeredFeatures = new HashSet<>();
/**
* The command manager
*/
protected final CommandManager<C> commandManager;
/**
* The NameplatesPlugin
*/
protected final NameplatesPlugin plugin;
private final CustomNameplatesCaptionFormatter<C> captionFormatter = new CustomNameplatesCaptionFormatter<C>();
private final MinecraftExceptionHandler.Decorator<C> decorator = (formatter, ctx, msg) -> msg;
private TriConsumer<C, String, Component> feedbackConsumer;
/**
* Constructs an AbstractCommandManager instance with the provided plugin and command manager.
*
* @param plugin The plugin instance managing this command manager.
* @param commandManager The command manager instance that handles the command registration.
*/
public AbstractCommandManager(NameplatesPlugin plugin, CommandManager<C> commandManager) {
this.commandManager = commandManager;
this.plugin = plugin;
@@ -86,6 +108,12 @@ public abstract class AbstractCommandManager<C> implements CustomNameplatesComma
});
}
/**
* Wraps a sender base on platform
*
* @param c sender
* @return the wrapped sender
*/
protected abstract Sender wrapSender(C c);
private void inject() {
@@ -108,7 +136,7 @@ public abstract class AbstractCommandManager<C> implements CustomNameplatesComma
}
@Override
public CommandConfig<C> getCommandConfig(YamlDocument document, String featureID) {
public CommandConfig getCommandConfig(YamlDocument document, String featureID) {
Section section = document.getSection(featureID);
if (section == null) return null;
return new CommandConfig.Builder<C>()
@@ -119,7 +147,7 @@ public abstract class AbstractCommandManager<C> implements CustomNameplatesComma
}
@Override
public Collection<Command.Builder<C>> buildCommandBuilders(CommandConfig<C> config) {
public Collection<Command.Builder<C>> buildCommandBuilders(CommandConfig config) {
ArrayList<Command.Builder<C>> list = new ArrayList<>();
for (String usage : config.getUsages()) {
if (!usage.startsWith("/")) continue;
@@ -135,7 +163,7 @@ public abstract class AbstractCommandManager<C> implements CustomNameplatesComma
}
@Override
public void registerFeature(CommandFeature<C> feature, CommandConfig<C> config) {
public void registerFeature(CommandFeature<C> feature, CommandConfig config) {
if (!config.isEnable()) throw new RuntimeException("Registering a disabled command feature is not allowed");
for (Command.Builder<C> builder : buildCommandBuilders(config)) {
Command<C> command = feature.registerCommand(commandManager, builder);
@@ -155,7 +183,7 @@ public abstract class AbstractCommandManager<C> implements CustomNameplatesComma
throw new RuntimeException(e);
}
this.getFeatures().values().forEach(feature -> {
CommandConfig<C> config = getCommandConfig(document, feature.getFeatureID());
CommandConfig config = getCommandConfig(document, feature.getFeatureID());
if (config.isEnable()) {
registerFeature(feature, config);
}

View File

@@ -0,0 +1,116 @@
/*
* Copyright (C) <2024> <XiaoMoMi>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
package net.momirealms.customnameplates.common.command;
import org.incendo.cloud.Command;
import org.incendo.cloud.CommandManager;
/**
* A builder interface for constructing commands with configurable parameters.
* This interface allows setting permissions, command nodes (subcommands), and
* building the final {@link Command.Builder} object.
*/
public interface CommandBuilder<C> {
/**
* Sets the permission required to execute the command.
*
* @param permission the permission string required for executing the command.
* @return the current {@link CommandBuilder} instance for method chaining.
*/
CommandBuilder<C> setPermission(String permission);
/**
* Sets the subcommands (nodes) for the command.
* This allows defining a hierarchy of commands.
*
* @param subNodes the subcommands or nodes to add to the command.
* @return the current {@link CommandBuilder} instance for method chaining.
*/
CommandBuilder<C> setCommandNode(String... subNodes);
/**
* Retrieves the fully constructed {@link Command.Builder} instance.
* This method returns the builder object that can be used to further configure
* and register the command.
*
* @return the built {@link Command.Builder} instance.
*/
Command.Builder<C> getBuiltCommandBuilder();
/**
* Basic implementation of the {@link CommandBuilder} interface.
* This class provides a default implementation for constructing a command
* with the given root node, permission, and subcommand nodes.
*
* @param <C> The type of context or object associated with the command.
*/
class BasicCommandBuilder<C> implements CommandBuilder<C> {
/**
* The actual command builder used to construct the command.
*/
private Command.Builder<C> commandBuilder;
/**
* Constructs a new {@link BasicCommandBuilder} for building a command.
*
* @param commandManager the {@link CommandManager} instance used for creating the command builder.
* @param rootNode the root node for the command.
*/
public BasicCommandBuilder(CommandManager<C> commandManager, String rootNode) {
this.commandBuilder = commandManager.commandBuilder(rootNode);
}
/**
* Sets the permission for the command.
*
* @param permission the permission required for executing the command.
* @return the current {@link CommandBuilder} instance for method chaining.
*/
@Override
public CommandBuilder<C> setPermission(String permission) {
this.commandBuilder = this.commandBuilder.permission(permission);
return this;
}
/**
* Sets the subcommands (nodes) for the command.
*
* @param subNodes the subcommands to add to the command.
* @return the current {@link CommandBuilder} instance for method chaining.
*/
@Override
public CommandBuilder<C> setCommandNode(String... subNodes) {
for (String sub : subNodes) {
this.commandBuilder = this.commandBuilder.literal(sub);
}
return this;
}
/**
* Retrieves the built {@link Command.Builder} instance.
*
* @return the built {@link Command.Builder} instance.
*/
@Override
public Command.Builder<C> getBuiltCommandBuilder() {
return commandBuilder;
}
}
}

View File

@@ -0,0 +1,157 @@
/*
* Copyright (C) <2024> <XiaoMoMi>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
package net.momirealms.customnameplates.common.command;
import java.util.ArrayList;
import java.util.List;
/**
* A configuration class for setting up command-related options such as enabling/disabling,
* command usages, and required permissions.
* <p>
* This class provides a builder pattern implementation to easily create and configure
* a {@link CommandConfig} object with a fluent API.
*/
public class CommandConfig {
/**
* Flag indicating whether the command is enabled.
*/
private boolean enable = false;
/**
* List of command usage examples or syntax hints.
*/
private List<String> usages = new ArrayList<>();
/**
* Permission required to execute the command.
*/
private String permission = null;
/**
* Private constructor to prevent direct instantiation.
* Use the {@link Builder} class to construct an instance.
*/
private CommandConfig() {
}
/**
* Constructs a new {@link CommandConfig} with the specified values.
*
* @param enable whether the command is enabled.
* @param usages the list of command usages.
* @param permission the permission required to execute the command.
*/
public CommandConfig(boolean enable, List<String> usages, String permission) {
this.enable = enable;
this.usages = usages;
this.permission = permission;
}
/**
* Gets whether the command is enabled.
*
* @return true if the command is enabled, false otherwise.
*/
public boolean isEnable() {
return enable;
}
/**
* Gets the list of command usages or syntax examples.
*
* @return the list of command usages.
*/
public List<String> getUsages() {
return usages;
}
/**
* Gets the permission required to execute the command.
*
* @return the permission string.
*/
public String getPermission() {
return permission;
}
/**
* Builder class for constructing a {@link CommandConfig} object with customizable options.
* This allows setting values for enabling the command, defining usages, and setting permissions.
*
* @param <C> the context type associated with the command.
*/
public static class Builder<C> {
/**
* The {@link CommandConfig} object being built.
*/
private final CommandConfig config;
/**
* Constructs a new {@link Builder} for {@link CommandConfig}.
* Initializes the config object to default values.
*/
public Builder() {
this.config = new CommandConfig();
}
/**
* Sets the list of command usages (examples or syntax hints).
*
* @param usages the list of command usages.
* @return the current {@link Builder} instance for method chaining.
*/
public Builder<C> usages(List<String> usages) {
config.usages = usages;
return this;
}
/**
* Sets the permission required to execute the command.
*
* @param permission the permission string.
* @return the current {@link Builder} instance for method chaining.
*/
public Builder<C> permission(String permission) {
config.permission = permission;
return this;
}
/**
* Sets whether the command is enabled.
*
* @param enable true to enable the command, false to disable it.
* @return the current {@link Builder} instance for method chaining.
*/
public Builder<C> enable(boolean enable) {
config.enable = enable;
return this;
}
/**
* Builds and returns the constructed {@link CommandConfig} object.
*
* @return the {@link CommandConfig} object.
*/
public CommandConfig build() {
return config;
}
}
}

View File

@@ -0,0 +1,95 @@
/*
* Copyright (C) <2024> <XiaoMoMi>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
package net.momirealms.customnameplates.common.command;
import net.kyori.adventure.text.Component;
import net.kyori.adventure.text.TranslatableComponent;
import org.incendo.cloud.Command;
import org.incendo.cloud.CommandManager;
import org.incendo.cloud.context.CommandContext;
/**
* Represents the contract for a feature that provides a command in the Custom Nameplates system.
* This interface defines methods for registering commands, handling feedback, and managing related functionality.
*
* @param <C> The type of the sender (e.g., player, console) for the command.
*/
public interface CommandFeature<C> {
/**
* Registers the command with the provided command manager and builder.
*
* @param cloudCommandManager The command manager responsible for managing commands.
* @param builder The command builder used to create the command.
* @return The registered command.
*/
Command<C> registerCommand(CommandManager<C> cloudCommandManager, Command.Builder<C> builder);
/**
* Retrieves a unique identifier for this feature.
* The feature ID is used to identify the feature within the system.
*
* @return A unique identifier for this command feature.
*/
String getFeatureID();
/**
* Registers any related functions or hooks that this feature may require.
* This method may be used to register additional functionality necessary for the feature.
*/
void registerRelatedFunctions();
/**
* Unregisters any related functions or hooks that were previously registered.
* This method is used for cleaning up after the feature when it's no longer needed.
*/
void unregisterRelatedFunctions();
/**
* Handles feedback for the command execution, sending a translation message to the sender.
* The feedback may be affected by the flags in the command context (e.g., silent mode).
*
* @param context The command context containing information about the sender and flags.
* @param key The key for the translation component to be used as feedback.
* @param args The arguments to be passed to the translation.
*/
void handleFeedback(CommandContext<?> context, TranslatableComponent.Builder key, Component... args);
/**
* Handles feedback for the command execution, sending a translation message to the sender.
*
* @param sender The sender to receive the feedback.
* @param key The key for the translation component to be used as feedback.
* @param args The arguments to be passed to the translation.
*/
void handleFeedback(C sender, TranslatableComponent.Builder key, Component... args);
/**
* Retrieves the command manager associated with this feature.
*
* @return The command manager.
*/
CustomNameplatesCommandManager<C> getCustomNameplatesCommandManager();
/**
* Retrieves the configuration associated with the command.
*
* @return The command configuration.
*/
CommandConfig getCommandConfig();
}

View File

@@ -0,0 +1,124 @@
/*
* Copyright (C) <2024> <XiaoMoMi>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
package net.momirealms.customnameplates.common.command;
import dev.dejvokep.boostedyaml.YamlDocument;
import net.kyori.adventure.text.Component;
import net.kyori.adventure.text.TranslatableComponent;
import net.kyori.adventure.util.Index;
import net.momirealms.customnameplates.common.util.TriConsumer;
import org.incendo.cloud.Command;
import org.incendo.cloud.CommandManager;
import org.jetbrains.annotations.NotNull;
import java.util.Collection;
/**
* Interface for managing commands within the Custom Nameplates plugin. This interface defines methods for
* registering features, handling feedback, and interacting with the command manager and configurations.
*
* @param <C> The type of the sender (e.g., player, console) for the commands.
*/
public interface CustomNameplatesCommandManager<C> {
/**
* The default configuration file name for commands
*/
String commandsFile = "commands.yml";
/**
* Unregisters all previously registered command features.
*/
void unregisterFeatures();
/**
* Registers a command feature with the provided configuration.
*
* @param feature The command feature to register.
* @param config The configuration for the feature.
*/
void registerFeature(CommandFeature<C> feature, CommandConfig config);
/**
* Registers all default features based on the plugin configuration.
*/
void registerDefaultFeatures();
/**
* Retrieves all registered command features in the form of an index.
*
* @return The index of registered command features.
*/
Index<String, CommandFeature<C>> getFeatures();
/**
* Sets a custom feedback consumer that handles the feedback sent to the command sender.
*
* @param feedbackConsumer The custom feedback consumer.
*/
void setFeedbackConsumer(@NotNull TriConsumer<C, String, Component> feedbackConsumer);
/**
* Provides the default feedback consumer for sending feedback messages.
*
* @return The default feedback consumer.
*/
TriConsumer<C, String, Component> defaultFeedbackConsumer();
/**
* Retrieves the command configuration from a YAML document and a given feature ID.
*
* @param document The YAML document containing the configuration.
* @param featureID The ID of the feature to retrieve configuration for.
* @return The command configuration for the specified feature, or null if not found.
*/
CommandConfig getCommandConfig(YamlDocument document, String featureID);
/**
* Builds a collection of command builders based on the given configuration.
*
* @param config The command configuration.
* @return A collection of command builders.
*/
Collection<Command.Builder<C>> buildCommandBuilders(CommandConfig config);
/**
* Retrieves the command manager associated with this command manager.
*
* @return The command manager.
*/
CommandManager<C> getCommandManager();
/**
* Sends feedback to the sender based on the provided key and arguments.
*
* @param sender The sender of the command.
* @param key The key used to retrieve the feedback message.
* @param args The arguments to be included in the feedback message.
*/
void handleCommandFeedback(C sender, TranslatableComponent.Builder key, Component... args);
/**
* Sends feedback to the sender based on the provided node and component.
*
* @param sender The sender of the command.
* @param node The feedback node.
* @param component The component containing the feedback message.
*/
void handleCommandFeedback(C sender, String node, Component component);
}

View File

@@ -1,26 +1,18 @@
/*
* This file is part of LuckPerms, licensed under the MIT License.
* Copyright (C) <2024> <XiaoMoMi>
*
* Copyright (c) lucko (Luck) <luck@lucko.me>
* Copyright (c) contributors
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* any later version.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
package net.momirealms.customnameplates.common.dependency;
@@ -356,10 +348,27 @@ public enum Dependency {
private static final String MAVEN_FORMAT = "%s/%s/%s/%s-%s.jar";
/**
* Constructs a Dependency with the given group ID, artifact ID, repository, and custom artifact ID.
*
* @param groupId the group ID of the dependency
* @param artifactId the artifact ID of the dependency
* @param repo the repository for the dependency
* @param customArtifactID the custom artifact ID for the dependency
*/
Dependency(String groupId, String artifactId, String repo, String customArtifactID) {
this(groupId, artifactId, repo, customArtifactID, new Relocation[0]);
}
/**
* Constructs a Dependency with the given group ID, artifact ID, repository, custom artifact ID, and relocations.
*
* @param groupId the group ID of the dependency
* @param artifactId the artifact ID of the dependency
* @param repo the repository for the dependency
* @param customArtifactID the custom artifact ID for the dependency
* @param relocations any relocations associated with the dependency
*/
Dependency(String groupId, String artifactId, String repo, String customArtifactID, Relocation... relocations) {
this.artifactId = artifactId;
this.artifactIdSuffix = "";
@@ -369,6 +378,16 @@ public enum Dependency {
this.customArtifactID = customArtifactID;
}
/**
* Constructs a Dependency with the given group ID, artifact ID, repository, custom artifact ID, and relocations.
*
* @param groupId the group ID of the dependency
* @param artifactId the artifact ID of the dependency
* @param repo the repository for the dependency
* @param customArtifactID the custom artifact ID for the dependency
* @param artifactIdSuffix the custom artifact suffix
* @param relocations any relocations associated with the dependency
*/
Dependency(String groupId, String artifactId, String repo, String customArtifactID, String artifactIdSuffix, Relocation... relocations) {
this.artifactId = artifactId;
this.artifactIdSuffix = artifactIdSuffix;
@@ -378,10 +397,20 @@ public enum Dependency {
this.customArtifactID = customArtifactID;
}
/**
* Sets the artifact suffix
*
* @param artifactIdSuffix the artifact suffix
*/
public void setArtifactIdSuffix(String artifactIdSuffix) {
this.artifactIdSuffix = artifactIdSuffix;
}
/**
* Returns the version of the dependency based on the custom artifact ID.
*
* @return the version of the dependency
*/
public String getVersion() {
return CustomNameplatesProperties.getValue(customArtifactID);
}
@@ -390,6 +419,12 @@ public enum Dependency {
return s.replace("{}", ".");
}
/**
* Returns the filename for the dependency's JAR file, optionally with a classifier.
*
* @param classifier the classifier for the JAR (e.g., "sources" or "javadoc")
* @return the filename for the JAR
*/
public String getFileName(String classifier) {
String name = customArtifactID.toLowerCase(Locale.ROOT).replace('_', '-');
String extra = classifier == null || classifier.isEmpty()
@@ -398,6 +433,11 @@ public enum Dependency {
return name + "-" + this.getVersion() + extra + ".jar";
}
/**
* Returns the Maven repository path for the dependency.
*
* @return the Maven repository path
*/
String getMavenRepoPath() {
return String.format(MAVEN_FORMAT,
rewriteEscaping(groupId).replace(".", "/"),
@@ -408,6 +448,11 @@ public enum Dependency {
);
}
/**
* Returns the list of relocations for the dependency.
*
* @return a list of {@link Relocation} objects
*/
public List<Relocation> getRelocations() {
return this.relocations;
}
@@ -426,6 +471,11 @@ public enum Dependency {
}
}
/**
* Gets the repo
*
* @return the repo
*/
@Nullable
public String getRepo() {
return repo;

View File

@@ -30,18 +30,20 @@ package net.momirealms.customnameplates.common.dependency;
*/
public class DependencyDownloadException extends Exception {
public DependencyDownloadException() {
}
/**
* Constructs a new DependencyDownloadException with the specified detail message.
*
* @param message the detail message, which provides additional information about the error
*/
public DependencyDownloadException(String message) {
super(message);
}
public DependencyDownloadException(String message, Throwable cause) {
super(message, cause);
}
/**
* Constructs a new DependencyDownloadException with the specified cause.
*
* @param cause the cause of the exception, which can be retrieved later with {@link Throwable#getCause()}
*/
public DependencyDownloadException(Throwable cause) {
super(cause);
}

View File

@@ -61,6 +61,11 @@ public class DependencyManagerImpl implements DependencyManager {
private final Executor loadingExecutor;
private final NameplatesPlugin plugin;
/**
* Constructs a DependencyManagerImpl instance
*
* @param plugin plugin
*/
public DependencyManagerImpl(NameplatesPlugin plugin) {
this.plugin = plugin;
this.registry = new DependencyRegistry();

View File

@@ -32,6 +32,12 @@ import com.google.gson.JsonElement;
*/
public class DependencyRegistry {
/**
* Check if the dependency should be automatically loaded
*
* @param dependency dependency
* @return should be automatically loaded or not
*/
public boolean shouldAutoLoad(Dependency dependency) {
return switch (dependency) {
// all used within 'isolated' classloaders, and are therefore not
@@ -41,6 +47,11 @@ public class DependencyRegistry {
};
}
/**
* Checks if gson is relocated
*
* @return relocated or not
*/
@SuppressWarnings("ConstantConditions")
public static boolean isGsonRelocated() {
return JsonElement.class.getName().startsWith("net.momirealms");
@@ -58,5 +69,4 @@ public class DependencyRegistry {
private static boolean slf4jPresent() {
return classExists("org.slf4j.Logger") && classExists("org.slf4j.LoggerFactory");
}
}

View File

@@ -66,6 +66,11 @@ public enum DependencyRepository {
this.id = id;
}
/**
* Gets the url of this repo
*
* @return the url
*/
public String getUrl() {
return url;
}

View File

@@ -17,16 +17,23 @@
package net.momirealms.customnameplates.common.event;
import net.kyori.adventure.text.Component;
/**
* Interface representing an event or task that can be cancelled.
* This interface defines methods to check and set the cancellation state of the event or task.
*/
public interface Cancellable {
public interface CommandFeedbackEvent<C> extends NameplatesEvent, Cancellable {
/**
* Gets the current cancelled state of the event or task.
*
* @return true if the event or task has been cancelled, false otherwise.
*/
boolean cancelled();
@Param(0)
C sender();
@Param(1)
String key();
@Param(2)
Component message();
/**
* Sets the cancelled state of the event or task.
*
* @param cancelled a boolean indicating whether the event is cancelled
*/
void cancelled(final boolean cancelled);
}

View File

@@ -0,0 +1,53 @@
/*
* Copyright (C) <2024> <XiaoMoMi>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
package net.momirealms.customnameplates.common.event;
import net.kyori.adventure.text.Component;
/**
* An event that represents feedback generated by a command execution.
* This event contains the sender of the command, the associated key, and the feedback message.
*/
public interface CommandFeedbackEvent<C> extends NameplatesEvent, Cancellable {
/**
* Gets the sender of the command that triggered this event.
*
* @return the sender (e.g., player or entity) of the command.
*/
@Param(0)
C sender();
/**
* Gets the key associated with the feedback message.
* This key may be used to identify the context or specific type of feedback.
*
* @return the key for the feedback message.
*/
@Param(1)
String key();
/**
* Gets the feedback message that will be sent in response to the command.
* The message is represented by a {@link Component}, which allows for rich text formatting.
*
* @return the feedback message to be displayed or logged.
*/
@Param(2)
Component message();
}

View File

@@ -0,0 +1,129 @@
/*
* Copyright (C) <2024> <XiaoMoMi>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
package net.momirealms.customnameplates.common.event;
import net.momirealms.customnameplates.common.event.bus.EventBus;
import net.momirealms.customnameplates.common.plugin.NameplatesPlugin;
import java.util.OptionalInt;
/**
* Interface for managing and dispatching events within the Nameplates plugin system.
* <p>
* This interface provides methods to subscribe to events, dispatch events, and interact with the underlying
* {@link EventBus}. It allows plugins to register subscribers for specific events and manage the event lifecycle.
* </p>
*/
public interface EventManager {
/**
* A static inner class that holds the singleton instance of {@link EventManager}.
* This ensures that the {@link EventManager} is initialized only once.
*/
class SingletonHolder {
private static EventManager INSTANCE = null;
}
/**
* Creates and returns the singleton instance of {@link EventManager}.
* <p>
* This method ensures that only one instance of the {@link EventManager} is created during the lifecycle
* of the plugin. If the instance does not exist, it initializes the {@link EventManager} using the provided
* {@link NameplatesPlugin}.
* </p>
*
* @param plugin the {@link NameplatesPlugin} instance to be used for initializing the event manager
* @return the singleton instance of {@link EventManager}
*/
static EventManager create(NameplatesPlugin plugin) {
if (SingletonHolder.INSTANCE == null) {
SingletonHolder.INSTANCE = new EventManagerImpl(plugin);
}
return SingletonHolder.INSTANCE;
}
/**
* Subscribes a {@link EventSubscriber} to an event type.
* <p>
* This method allows subscribing a listener (subscriber) to a specific event type. The subscriber will be notified
* whenever the event is dispatched.
* </p>
*
* @param <T> the type of event to subscribe to
* @param event the {@link Class} object representing the event type
* @param subscriber the {@link EventSubscriber} that will handle the event
* @return an {@link EventSubscription} representing the subscription
*/
<T extends NameplatesEvent> EventSubscription<T> subscribe(Class<T> event, EventSubscriber<? super T> subscriber);
/**
* Subscribes a {@link EventSubscriber} to an event type with a custom event configuration.
* <p>
* This method allows subscribing a listener (subscriber) to a specific event type with additional configuration
* settings for the event. The subscriber will be notified based on the provided configuration when the event is
* dispatched.
* </p>
*
* @param <T> the type of event to subscribe to
* @param event the {@link Class} object representing the event type
* @param config the {@link EventConfig} containing additional event configuration
* @param subscriber the {@link EventSubscriber} that will handle the event
* @return an {@link EventSubscription} representing the subscription
*/
<T extends NameplatesEvent> EventSubscription<T> subscribe(Class<T> event, EventConfig config, EventSubscriber<? super T> subscriber);
/**
* Dispatches an event of the specified class with the provided parameters.
* <p>
* This method triggers the event, notifying all subscribers of the event. The event is dispatched synchronously
* to all registered subscribers.
* </p>
*
* @param eventClass the {@link Class} object representing the event type
* @param params the parameters to pass to the event
* @return the dispatched {@link NameplatesEvent}
*/
NameplatesEvent dispatch(Class<? extends NameplatesEvent> eventClass, Object... params);
/**
* Dispatches an event of the specified class with the provided order and parameters.
* <p>
* This method allows dispatching the event with an optional order. The order is used to prioritize events,
* allowing certain events to be processed before others. If the order is not provided, the event will be dispatched
* without any specific order.
* </p>
*
* @param eventClass the {@link Class} object representing the event type
* @param order the optional {@link OptionalInt} specifying the order of the event
* @param params the parameters to pass to the event
* @return the dispatched {@link NameplatesEvent}
*/
@SuppressWarnings("OptionalUsedAsFieldOrParameterType")
NameplatesEvent dispatch(Class<? extends NameplatesEvent> eventClass, OptionalInt order, Object... params);
/**
* Retrieves the underlying event bus that handles event dispatching and subscriptions.
* <p>
* The {@link EventBus} is responsible for managing the lifecycle of events, including dispatching and subscribing
* to events. This method allows direct access to the {@link EventBus}.
* </p>
*
* @return the underlying {@link EventBus} used by the event manager
*/
EventBus<?> getEventBus();
}

View File

@@ -3,10 +3,15 @@ package net.momirealms.customnameplates.common.event;
import net.momirealms.customnameplates.common.plugin.NameplatesPlugin;
import org.jetbrains.annotations.NotNull;
/**
* Interface for Nameplates Event
*/
public interface NameplatesEvent {
/**
* Get the plugin instance this event was dispatched from
*
* @return the plugin instance
*/
@NotNull
NameplatesPlugin plugin();

View File

@@ -0,0 +1,66 @@
/*
* Copyright (C) <2024> <XiaoMoMi>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
package net.momirealms.customnameplates.common.event.gen;
import net.momirealms.customnameplates.common.event.NameplatesEvent;
import net.momirealms.customnameplates.common.plugin.NameplatesPlugin;
import org.jetbrains.annotations.NotNull;
import java.lang.invoke.MethodHandles;
/**
* Abstract base class for events in the Nameplates plugin system.
*/
public abstract class AbstractNameplatesEvent implements NameplatesEvent {
private final NameplatesPlugin plugin;
/**
* Constructs an instance of {@code AbstractNameplatesEvent} with the given {@link NameplatesPlugin}.
*
* @param plugin the {@link NameplatesPlugin} instance associated with this event
*/
protected AbstractNameplatesEvent(NameplatesPlugin plugin) {
this.plugin = plugin;
}
/**
* Returns the {@link NameplatesPlugin} instance associated with this event.
*
* @return the plugin instance
*/
@NotNull
@Override
public NameplatesPlugin plugin() {
return plugin;
}
/**
* Returns a {@link MethodHandles.Lookup} instance for dynamic method invocation.
* <p>
* This method is currently unsupported and will throw an {@link UnsupportedOperationException} if invoked.
* It may be overridden in subclasses to provide custom logic for dynamic method handles.
* </p>
*
* @return the {@link MethodHandles.Lookup} instance
* @throws UnsupportedOperationException if the method is not overridden in a subclass
*/
public MethodHandles.Lookup mhl() {
throw new UnsupportedOperationException();
}
}

View File

@@ -51,6 +51,9 @@ import java.util.Map;
import static net.bytebuddy.matcher.ElementMatchers.*;
/**
* A class for generating event class
*/
public class EventGenerator {
/**

View File

@@ -25,6 +25,10 @@ import org.incendo.cloud.minecraft.extras.caption.ComponentCaptionFormatter;
import java.util.List;
/**
* CustomNameplatesCaptionFormatter
* @param <C> sender
*/
public class CustomNameplatesCaptionFormatter<C> implements ComponentCaptionFormatter<C> {
@Override

View File

@@ -19,9 +19,29 @@ package net.momirealms.customnameplates.common.locale;
import org.incendo.cloud.caption.Caption;
/**
* A utility class that defines keys for various captions used in the Custom Nameplates plugin.
* <p>
* This class provides static final constants for common caption keys that are used for
* error messages, argument parsing failures, and other localized messages in the plugin.
* These keys can be used with a captioning system to retrieve appropriate translations
* based on the user's locale.
* </p>
*/
public final class CustomNameplatesCaptionKeys {
/**
* Caption key for a failure when parsing a time argument.
* This key is used for error messages related to time arguments that failed to parse.
*/
public static final Caption ARGUMENT_PARSE_FAILURE_TIME = Caption.of("argument.parse.failure.time");
/**
* Caption key for a failure when parsing a URL argument.
* This key is used for error messages related to URL arguments that failed to parse.
*/
public static final Caption ARGUMENT_PARSE_FAILURE_URL = Caption.of("argument.parse.failure.url");
/**
* Caption key for a failure when parsing a named text color argument.
* This key is used for error messages related to named text color arguments that failed to parse.
*/
public static final Caption ARGUMENT_PARSE_FAILURE_NAMEDTEXTCOLOR = Caption.of("argument.parse.failure.namedtextcolor");
}

View File

@@ -21,6 +21,16 @@ import org.checkerframework.checker.nullness.qual.NonNull;
import org.incendo.cloud.caption.CaptionProvider;
import org.incendo.cloud.caption.DelegatingCaptionProvider;
/**
* A custom implementation of a {@link CaptionProvider} for the Custom Nameplates plugin.
* <p>
* This class provides a caption provider that delegates to a constant provider which includes
* predefined captions for argument parsing failure messages. It ensures that specific caption keys,
* such as those related to parsing time, URL, and named text color arguments, are available for use.
* </p>
*
* @param <C> the context type associated with the captions
*/
public final class CustomNameplatesCaptionProvider<C> extends DelegatingCaptionProvider<C> {
private static final CaptionProvider<?> PROVIDER = CaptionProvider.constantProvider()

View File

@@ -0,0 +1,101 @@
/*
* Copyright (C) <2024> <XiaoMoMi>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
package net.momirealms.customnameplates.common.plugin;
import java.io.IOException;
import java.io.InputStream;
import java.util.HashMap;
import java.util.Map;
import java.util.Properties;
/**
* A utility class for loading and retrieving properties from a custom properties file.
* <p>
* This class loads the properties from the {@code custom-nameplates.properties} file
* located in the classpath and provides a way to retrieve property values by key.
* The properties are loaded and stored in a singleton instance to ensure only
* one loading of the properties file throughout the lifetime of the application.
* </p>
*/
public class CustomNameplatesProperties {
/**
* A map that holds the key-value pairs of properties.
*/
private final HashMap<String, String> propertyMap;
/**
* Private constructor that initializes the property map.
*
* @param propertyMap the map holding the property key-value pairs
*/
private CustomNameplatesProperties(HashMap<String, String> propertyMap) {
this.propertyMap = propertyMap;
}
/**
* Retrieves the value of a property based on the provided key.
* <p>
* This method throws a {@link RuntimeException} if the key is not found in the properties file.
* </p>
*
* @param key the property key to retrieve
* @return the value associated with the given key
* @throws RuntimeException if the key is unknown or not found in the properties file
*/
public static String getValue(String key) {
if (!SingletonHolder.INSTANCE.propertyMap.containsKey(key)) {
throw new RuntimeException("Unknown key: " + key);
}
return SingletonHolder.INSTANCE.propertyMap.get(key);
}
/**
* A static inner class to hold the singleton instance of {@link CustomNameplatesProperties}.
* This class is used to lazily load the properties file and ensure only one instance is created.
*/
private static class SingletonHolder {
/**
* The singleton instance of {@link CustomNameplatesProperties}.
*/
private static final CustomNameplatesProperties INSTANCE = getInstance();
/**
* Loads the properties file and creates an instance of {@link CustomNameplatesProperties}.
*
* @return an instance of {@link CustomNameplatesProperties} containing the loaded properties
* @throws RuntimeException if there is an error reading the properties file
*/
private static CustomNameplatesProperties getInstance() {
try (InputStream inputStream = CustomNameplatesProperties.class.getClassLoader().getResourceAsStream("custom-nameplates.properties")) {
HashMap<String, String> versionMap = new HashMap<>();
Properties properties = new Properties();
properties.load(inputStream);
for (Map.Entry<Object, Object> entry : properties.entrySet()) {
if (entry.getKey() instanceof String key && entry.getValue() instanceof String value) {
versionMap.put(key, value);
}
}
return new CustomNameplatesProperties(versionMap);
} catch (IOException e) {
throw new RuntimeException("Error loading properties file", e);
}
}
}
}

View File

@@ -32,6 +32,12 @@ import java.nio.file.Path;
*/
public interface ClassPathAppender extends AutoCloseable {
/**
* Adds a JAR file to the classpath.
*
* @param file the {@link Path} to the JAR file to be added to the classpath.
* @throws IllegalArgumentException if the provided file is not a valid JAR file.
*/
void addJarToClasspath(Path file);
@Override

View File

@@ -47,6 +47,20 @@ public interface ConfigLoader {
*/
YamlDocument loadConfig(String filePath, char routeSeparator);
/**
* Loads a YAML configuration file from the specified file path with custom settings.
* <p>
* This method allows loading a YAML file with various settings, including general,
* loader, dumper, and updater settings, providing more flexibility in how the file is processed.
* </p>
*
* @param filePath the path to the configuration file.
* @param generalSettings the general settings to use for loading the configuration.
* @param loaderSettings the loader-specific settings to be applied.
* @param dumperSettings the dumper-specific settings to be applied.
* @param updaterSettings the updater-specific settings to be applied.
* @return the loaded {@link YamlDocument} representing the YAML data.
*/
YamlDocument loadConfig(String filePath, GeneralSettings generalSettings, LoaderSettings loaderSettings, DumperSettings dumperSettings, UpdaterSettings updaterSettings);
/**

View File

@@ -17,19 +17,34 @@
package net.momirealms.customnameplates.common.plugin.feature;
/**
* Interface for objects that can be reloaded, unloaded, and loaded again.
*/
public interface Reloadable {
/**
* Reloads the feature or component by first unloading it and then loading it again.
*/
default void reload() {
unload();
load();
}
/**
* Unloads the feature or component.
*/
default void unload() {
}
/**
* Loads the feature or component.
*/
default void load() {
}
/**
* Disables the feature or component by unloading it.
*/
default void disable() {
unload();
}

View File

@@ -45,6 +45,10 @@ public abstract class AbstractJavaScheduler<T> implements SchedulerAdapter<T> {
private final ScheduledThreadPoolExecutor scheduler;
private final ForkJoinPool worker;
/**
* Constructs an AbstractJavaScheduler
* @param plugin plugin
*/
public AbstractJavaScheduler(NameplatesPlugin plugin) {
this.plugin = plugin;

View File

@@ -19,19 +19,45 @@ package net.momirealms.customnameplates.common.plugin.scheduler;
import java.util.concurrent.ScheduledFuture;
/**
* Represents an asynchronous task that is scheduled to run at a later time.
* This class wraps a {@link ScheduledFuture} and provides methods to cancel
* the task and check if it has been cancelled.
*/
public class AsyncTask implements SchedulerTask {
/**
* The {@link ScheduledFuture} representing the scheduled task.
* This is used to interact with the task, such as cancelling it.
*/
private final ScheduledFuture<?> future;
/**
* Constructs an {@link AsyncTask} using the provided {@link ScheduledFuture}.
*
* @param future the {@link ScheduledFuture} representing the scheduled task.
*/
public AsyncTask(ScheduledFuture<?> future) {
this.future = future;
}
/**
* Cancels the scheduled task. The task will not run if it has not started yet,
* or it will stop if it is currently running.
*
* @see ScheduledFuture#cancel(boolean)
*/
@Override
public void cancel() {
future.cancel(false);
}
/**
* Checks if the task has been cancelled.
*
* @return true if the task has been cancelled, false otherwise.
* @see ScheduledFuture#isCancelled()
*/
@Override
public boolean cancelled() {
return future.isCancelled();

View File

@@ -60,6 +60,7 @@ public interface SchedulerAdapter<T> {
* Executes a task sync
*
* @param task the task
* @param location the location
*/
default void executeSync(Runnable task, T location) {
sync().run(task, location);
@@ -83,6 +84,7 @@ public interface SchedulerAdapter<T> {
* Executes the given task repeatedly at a given interval.
*
* @param task the task
* @param delay the delay
* @param interval the interval
* @param unit the unit of interval
* @return the resultant task instance

View File

@@ -35,5 +35,10 @@ public interface SchedulerTask {
*/
void cancel();
/**
* Check if the task is cancelled
*
* @return cancelled or not
*/
boolean cancelled();
}

View File

@@ -110,7 +110,7 @@ public interface Sender {
boolean isConsole();
/**
* Gets whether this sender is still valid & receiving messages.
* Gets whether this sender is still valid and receiving messages.
*
* @return if this sender is valid
*/

View File

@@ -19,30 +19,95 @@ package net.momirealms.customnameplates.common.util;
import java.util.Locale;
/**
* Enum representing the supported system architectures.
* This enum helps determine the architecture of the current system
* and provides utility methods for architecture-related operations.
* <p>
* The possible architectures include:
* - X64 (64-bit x86)
* - X86 (32-bit x86)
* - ARM64 (64-bit ARM)
* - ARM32 (32-bit ARM)
* - PPC64LE (64-bit PowerPC, Little Endian)
* - RISCV64 (64-bit RISC-V)
* <p>
* It also provides a utility method to get the native path representation of the architecture
* and a method to retrieve the current architecture of the system.
*/
public enum Architecture {
/**
* Represents a 64-bit x86 architecture.
*/
X64(true),
/**
* Represents a 32-bit x86 architecture.
*/
X86(false),
/**
* Represents a 64-bit ARM architecture.
*/
ARM64(true),
/**
* Represents a 32-bit ARM architecture.
*/
ARM32(false),
/**
* Represents a 64-bit PowerPC Little Endian architecture.
* Only 'ppc64le' is supported in this case.
*/
PPC64LE(true),
/**
* Represents a 64-bit RISC-V architecture.
* Only 'riscv64' is supported in this case.
*/
RISCV64(true);
/**
* The current architecture of the system, determined during class initialization.
*/
static final Architecture current;
/**
* A boolean flag indicating if the architecture is 64-bit.
*/
final boolean is64Bit;
/**
* Constructor to initialize the architecture with its 64-bit flag.
*
* @param is64Bit a boolean indicating if the architecture is 64-bit.
*/
Architecture(boolean is64Bit) {
this.is64Bit = is64Bit;
}
/**
* Returns the native path representation of the architecture.
* The name is returned in lowercase using English locale.
*
* @return the native path for the architecture (e.g., "x64", "arm64").
*/
public String getNativePath() {
return name().toLowerCase(Locale.ENGLISH);
}
/**
* Retrieves the current architecture of the system.
*
* @return the current system architecture as an {@link Architecture} enum.
*/
public static Architecture get() {
return current;
}
// Static block to determine the current system architecture based on system properties.
static {
String osArch = System.getProperty("os.arch");
boolean is64Bit = osArch.contains("64") || osArch.startsWith("armv8");

View File

@@ -1,26 +1,18 @@
/*
* This file is part of LuckPerms, licensed under the MIT License.
* Copyright (C) <2024> <XiaoMoMi>
*
* Copyright (c) lucko (Luck) <luck@lucko.me>
* Copyright (c) contributors
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* any later version.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
package net.momirealms.customnameplates.common.util;
@@ -28,15 +20,7 @@ package net.momirealms.customnameplates.common.util;
import org.jetbrains.annotations.NotNull;
/**
* Represents three different states of a setting.
*
* <p>Possible values:</p>
* <p></p>
* <ul>
* <li>{@link #TRUE} - a positive setting</li>
* <li>{@link #FALSE} - a negative (negated) setting</li>
* <li>{@link #UNDEFINED} - a non-existent setting</li>
* </ul>
* Tristate
*/
public enum Tristate {

View File

@@ -1,13 +1,8 @@
plugins {
id("io.github.goooler.shadow") version "8.1.8"
}
repositories {
maven("https://s01.oss.sonatype.org/content/repositories/snapshots/")
}
dependencies {
compileOnly(project(":common"))
compileOnly(project(":api"))
// YAML
compileOnly("dev.dejvokep:boosted-yaml:${rootProject.properties["boosted_yaml_version"]}")

View File

@@ -3,6 +3,7 @@ import java.io.ByteArrayOutputStream
plugins {
id("java")
id("com.gradleup.shadow") version "9.0.0-beta6"
}
val git : String = versionBanner()
@@ -11,9 +12,8 @@ ext["git_version"] = git
ext["builder"] = builder
subprojects {
apply(plugin = "java")
apply(plugin = "java-library")
apply(plugin = "com.gradleup.shadow")
repositories {
mavenCentral()

42
common/.gitignore vendored
View File

@@ -1,42 +0,0 @@
.gradle
build/
!gradle/wrapper/gradle-wrapper.jar
!**/src/main/**/build/
!**/src/test/**/build/
### IntelliJ IDEA ###
.idea/modules.xml
.idea/jarRepositories.xml
.idea/compiler.xml
.idea/libraries/
*.iws
*.iml
*.ipr
out/
!**/src/main/**/out/
!**/src/test/**/out/
### Eclipse ###
.apt_generated
.classpath
.factorypath
.project
.settings
.springBeans
.sts4-cache
bin/
!**/src/main/**/bin/
!**/src/test/**/bin/
### NetBeans ###
/nbproject/private/
/nbbuild/
/dist/
/nbdist/
/.nb-gradle/
### VS Code ###
.vscode/
### Mac OS ###
.DS_Store

View File

@@ -1,37 +0,0 @@
repositories {
maven("https://s01.oss.sonatype.org/content/repositories/snapshots/")
}
dependencies {
compileOnly("net.kyori:adventure-api:${rootProject.properties["adventure_bundle_version"]}") {
exclude(module = "adventure-bom")
exclude(module = "checker-qual")
exclude(module = "annotations")
}
compileOnly("org.incendo:cloud-core:${rootProject.properties["cloud_core_version"]}")
compileOnly("org.incendo:cloud-minecraft-extras:${rootProject.properties["cloud_minecraft_extras_version"]}")
compileOnly("dev.dejvokep:boosted-yaml:${rootProject.properties["boosted_yaml_version"]}")
compileOnly("org.jetbrains:annotations:${rootProject.properties["jetbrains_annotations_version"]}")
compileOnly("org.slf4j:slf4j-api:${rootProject.properties["slf4j_version"]}")
compileOnly("org.apache.logging.log4j:log4j-core:${rootProject.properties["log4j_version"]}")
compileOnly("net.kyori:adventure-text-minimessage:${rootProject.properties["adventure_bundle_version"]}")
compileOnly("net.kyori:adventure-text-serializer-gson:${rootProject.properties["adventure_bundle_version"]}")
compileOnly("com.github.ben-manes.caffeine:caffeine:${rootProject.properties["caffeine_version"]}")
compileOnly("com.google.code.gson:gson:${rootProject.properties["gson_version"]}")
compileOnly("net.objecthunter:exp4j:${rootProject.properties["exp4j_version"]}")
compileOnly("net.bytebuddy:byte-buddy:${rootProject.properties["byte_buddy_version"]}")
}
java {
sourceCompatibility = JavaVersion.VERSION_17
targetCompatibility = JavaVersion.VERSION_17
toolchain {
languageVersion = JavaLanguageVersion.of(17)
}
}
tasks.withType<JavaCompile> {
options.encoding = "UTF-8"
options.release.set(17)
dependsOn(tasks.clean)
}

View File

@@ -1,85 +0,0 @@
/*
* Copyright (C) <2024> <XiaoMoMi>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
package net.momirealms.customnameplates.common.command;
import net.kyori.adventure.text.Component;
import net.kyori.adventure.text.TranslatableComponent;
import net.momirealms.customnameplates.common.sender.SenderFactory;
import org.incendo.cloud.Command;
import org.incendo.cloud.CommandManager;
import org.incendo.cloud.context.CommandContext;
public abstract class AbstractCommandFeature<C> implements CommandFeature<C> {
protected final CustomNameplatesCommandManager<C> commandManager;
protected CommandConfig<C> commandConfig;
public AbstractCommandFeature(CustomNameplatesCommandManager<C> commandManager) {
this.commandManager = commandManager;
}
protected abstract SenderFactory<?, C> getSenderFactory();
public abstract Command.Builder<? extends C> assembleCommand(CommandManager<C> manager, Command.Builder<C> builder);
@Override
@SuppressWarnings("unchecked")
public Command<C> registerCommand(CommandManager<C> manager, Command.Builder<C> builder) {
Command<C> command = (Command<C>) assembleCommand(manager, builder).build();
manager.command(command);
return command;
}
@Override
public void registerRelatedFunctions() {
// empty
}
@Override
public void unregisterRelatedFunctions() {
// empty
}
@Override
@SuppressWarnings("unchecked")
public void handleFeedback(CommandContext<?> context, TranslatableComponent.Builder key, Component... args) {
if (context.flags().hasFlag("silent")) {
return;
}
commandManager.handleCommandFeedback((C) context.sender(), key, args);
}
@Override
public void handleFeedback(C sender, TranslatableComponent.Builder key, Component... args) {
commandManager.handleCommandFeedback(sender, key, args);
}
@Override
public CustomNameplatesCommandManager<C> getCustomNameplatesCommandManager() {
return commandManager;
}
@Override
public CommandConfig<C> getCommandConfig() {
return commandConfig;
}
public void setCommandConfig(CommandConfig<C> commandConfig) {
this.commandConfig = commandConfig;
}
}

View File

@@ -1,58 +0,0 @@
/*
* Copyright (C) <2024> <XiaoMoMi>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
package net.momirealms.customnameplates.common.command;
import org.incendo.cloud.Command;
import org.incendo.cloud.CommandManager;
public interface CommandBuilder<C> {
CommandBuilder<C> setPermission(String permission);
CommandBuilder<C> setCommandNode(String... subNodes);
Command.Builder<C> getBuiltCommandBuilder();
class BasicCommandBuilder<C> implements CommandBuilder<C> {
private Command.Builder<C> commandBuilder;
public BasicCommandBuilder(CommandManager<C> commandManager, String rootNode) {
this.commandBuilder = commandManager.commandBuilder(rootNode);
}
@Override
public CommandBuilder<C> setPermission(String permission) {
this.commandBuilder = this.commandBuilder.permission(permission);
return this;
}
@Override
public CommandBuilder<C> setCommandNode(String... subNodes) {
for (String sub : subNodes) {
this.commandBuilder = this.commandBuilder.literal(sub);
}
return this;
}
@Override
public Command.Builder<C> getBuiltCommandBuilder() {
return commandBuilder;
}
}
}

View File

@@ -1,77 +0,0 @@
/*
* Copyright (C) <2024> <XiaoMoMi>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
package net.momirealms.customnameplates.common.command;
import java.util.ArrayList;
import java.util.List;
public class CommandConfig<C> {
private boolean enable = false;
private List<String> usages = new ArrayList<>();
private String permission = null;
private CommandConfig() {
}
public CommandConfig(boolean enable, List<String> usages, String permission) {
this.enable = enable;
this.usages = usages;
this.permission = permission;
}
public boolean isEnable() {
return enable;
}
public List<String> getUsages() {
return usages;
}
public String getPermission() {
return permission;
}
public static class Builder<C> {
private final CommandConfig<C> config;
public Builder() {
this.config = new CommandConfig<>();
}
public Builder<C> usages(List<String> usages) {
config.usages = usages;
return this;
}
public Builder<C> permission(String permission) {
config.permission = permission;
return this;
}
public Builder<C> enable(boolean enable) {
config.enable = enable;
return this;
}
public CommandConfig<C> build() {
return config;
}
}
}

View File

@@ -1,43 +0,0 @@
/*
* Copyright (C) <2024> <XiaoMoMi>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
package net.momirealms.customnameplates.common.command;
import net.kyori.adventure.text.Component;
import net.kyori.adventure.text.TranslatableComponent;
import org.incendo.cloud.Command;
import org.incendo.cloud.CommandManager;
import org.incendo.cloud.context.CommandContext;
public interface CommandFeature<C> {
Command<C> registerCommand(CommandManager<C> cloudCommandManager, Command.Builder<C> builder);
String getFeatureID();
void registerRelatedFunctions();
void unregisterRelatedFunctions();
void handleFeedback(CommandContext<?> context, TranslatableComponent.Builder key, Component... args);
void handleFeedback(C sender, TranslatableComponent.Builder key, Component... args);
CustomNameplatesCommandManager<C> getCustomNameplatesCommandManager();
CommandConfig<C> getCommandConfig();
}

View File

@@ -1,56 +0,0 @@
/*
* Copyright (C) <2024> <XiaoMoMi>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
package net.momirealms.customnameplates.common.command;
import dev.dejvokep.boostedyaml.YamlDocument;
import net.kyori.adventure.text.Component;
import net.kyori.adventure.text.TranslatableComponent;
import net.kyori.adventure.util.Index;
import net.momirealms.customnameplates.common.util.TriConsumer;
import org.incendo.cloud.Command;
import org.incendo.cloud.CommandManager;
import org.jetbrains.annotations.NotNull;
import java.util.Collection;
public interface CustomNameplatesCommandManager<C> {
String commandsFile = "commands.yml";
void unregisterFeatures();
void registerFeature(CommandFeature<C> feature, CommandConfig<C> config);
void registerDefaultFeatures();
Index<String, CommandFeature<C>> getFeatures();
void setFeedbackConsumer(@NotNull TriConsumer<C, String, Component> feedbackConsumer);
TriConsumer<C, String, Component> defaultFeedbackConsumer();
CommandConfig<C> getCommandConfig(YamlDocument document, String featureID);
Collection<Command.Builder<C>> buildCommandBuilders(CommandConfig<C> config);
CommandManager<C> getCommandManager();
void handleCommandFeedback(C sender, TranslatableComponent.Builder key, Component... args);
void handleCommandFeedback(C sender, String node, Component component);
}

View File

@@ -1,14 +0,0 @@
package net.momirealms.customnameplates.common.event;
public interface Cancellable {
/**
* Gets the cancelled state.
*/
boolean cancelled();
/**
* Sets the cancelled state.
*/
void cancelled(final boolean cancelled);
}

View File

@@ -1,31 +0,0 @@
package net.momirealms.customnameplates.common.event;
import net.momirealms.customnameplates.common.event.bus.EventBus;
import net.momirealms.customnameplates.common.plugin.NameplatesPlugin;
import java.util.OptionalInt;
public interface EventManager {
class SingletonHolder {
private static EventManager INSTANCE = null;
}
static EventManager create(NameplatesPlugin plugin) {
if (SingletonHolder.INSTANCE == null) {
SingletonHolder.INSTANCE = new EventManagerImpl(plugin);
}
return SingletonHolder.INSTANCE;
}
<T extends NameplatesEvent> EventSubscription<T> subscribe(Class<T> event, EventSubscriber<? super T> subscriber);
<T extends NameplatesEvent> EventSubscription<T> subscribe(Class<T> event, EventConfig config, EventSubscriber<? super T> subscriber);
NameplatesEvent dispatch(Class<? extends NameplatesEvent> eventClass, Object... params);
@SuppressWarnings("OptionalUsedAsFieldOrParameterType")
NameplatesEvent dispatch(Class<? extends NameplatesEvent> eventClass, OptionalInt order, Object... params);
EventBus<?> getEventBus();
}

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