Utilities - litjisz/Astra GitHub Wiki
The Astra framework provides several utility classes to help with common tasks in plugin development. These utilities make it easier to work with text formatting, logging, and more.
The Text
class provides methods for formatting and colorizing text in Minecraft.
import lol.jisz.astra.utils.Text;
// Colorize text using Minecraft color codes
String coloredText = Text.colorize("&aThis text is green &cand this is red");
// Colorize a list of strings
List<String> coloredLines = Text.colorize(Arrays.asList(
"&aThis is green",
"&bThis is aqua"
));
// Create text with a color gradient
String gradientText = Text.gradient("Astra Framework", "9863E7", "C69FFF");
// Example from AstraCommand
private void sendGithubMessage(CommandSender sender) {
List<String> githubMessages = Arrays.asList(
Text.colorize(" "),
Text.gradient("☽ Astra", "9863E7", "C69FFF") +
Text.colorize(" &8| &fFramwork built with &c❤ &fby &aAstra Team"),
Text.colorize(" "),
Text.colorize("&8 ⏩ &fRepository: &bhttps://github.com/litjisz/Astra"),
Text.colorize("&8 ⚠ &fReport issues: &chttps://github.com/litjisz/Astra/issues"),
Text.colorize("&8 ✎ &fWiki: &dhttps://github.com/litjisz/Astra/wiki"),
Text.colorize(" ")
);
githubMessages.forEach(sender::sendMessage);
}
The Logger
class provides enhanced logging capabilities with color support and different log levels.
import lol.jisz.astra.utils.Logger;
// Create a logger with the plugin instance
Logger logger = new Logger(plugin);
// Create a logger with a custom prefix
Logger logger = new Logger(plugin, Text.gradient("AstraTask", "9863E7", "C69FFF") + " &8| &r");
// Log at different levels
logger.info("This is an info message");
logger.warning("This is a warning message");
logger.error("This is an error message");
logger.debug("This is a debug message");
// Log an error with an exception
try {
// Some code that might throw an exception
} catch (Exception e) {
logger.error("An error occurred", e);
}
// Example from TaskManager
logger.info("Task system initialized with limit of " + maxConcurrentAsyncTasks + " concurrent async tasks");
logger.debug("Task " + task.getId() + " added to queue with priority " + task.getPriority());
logger.error("Task " + task.getId() + " failed with error: " + throwable.getMessage(), throwable);
The ConfigManager
class provides methods for managing YAML configuration files.
import lol.jisz.astra.utils.ConfigManager;
// Load a configuration file (creates it if it doesn't exist)
FileConfiguration config = configManager.loadConfig("settings");
// Load without creating if it doesn't exist
FileConfiguration config = configManager.loadConfig("settings", false);
// Get values with defaults
String serverName = configManager.getString("config", "server.name", "My Server");
int maxPlayers = configManager.getInt("config", "server.max-players", 20);
double moneyMultiplier = configManager.getDouble("config", "economy.multiplier", 1.0);
Boolean enableFeature = configManager.get("config", "features.new-feature", false);
// Set values
configManager.set("config", "server.name", "New Server Name");
// Create a configuration section
ConfigurationSection section = configManager.createSection("config", "new-feature");
// Get keys from a configuration
Set<String> topLevelKeys = configManager.getKeys("config");
Set<String> featureKeys = configManager.getKeys("config", "features", true);
// Check if a configuration exists
boolean exists = configManager.exists("settings");
// Save a configuration
configManager.saveConfig("settings");
// Reload a configuration
configManager.reloadConfig("settings");
// Delete a configuration
configManager.deleteConfig("temporary");
// Save all configurations
configManager.saveAllConfigs();
// Reload all configurations
configManager.reloadAllConfigs();
// Get a string list
List<String> allowedCommands = configManager.getStringList("config", "commands.allowed");
In an AbstractModule
, you can access these utilities directly:
public class MyModule extends AbstractModule {
@Override
public void enable() {
// Access the logger
getLogger().info("Module enabled");
// Access the config manager
ConfigManager configManager = getConfig();
String value = configManager.getString("config", "my.setting", "default");
}
}
The ClassScanner
is a powerful utility in the Astra framework that automatically discovers and registers classes with specific annotations. This eliminates the need for manual registration of modules, commands, listeners, and tasks.
The ClassScanner
uses the Reflections library to scan packages for classes with specific annotations and automatically registers them with the appropriate systems. This reduces boilerplate code and makes your plugin more maintainable.
// The ClassScanner is typically created in the Astra plugin's initialization
ClassScanner classScanner = new ClassScanner(plugin);
// Scan a specific package for annotated classes
classScanner.scanPackage("com.example.myplugin");
// In your main plugin class, you can scan your plugin's package
scanPackage(getClass().getPackage().getName());
The ClassScanner
looks for classes with the following annotations:
-
@AutoRegisterModule
- For automatic module registration -
@AutoRegisterCommand
- For automatic command registration -
@AutoRegisterListener
- For automatic event listener registration -
@AutoRegisterTask
- For automatic task registration
@AutoRegisterModule(priority = 10)
public class MyModule extends AbstractModule {
// Module implementation
}
The ClassScanner
will:
- Find all classes annotated with
@AutoRegisterModule
- Filter for classes that extend
Module
and are not interfaces or abstract - Sort them by priority (higher numbers = higher priority)
- Instantiate each module using either:
- A constructor that takes an
Astra
parameter - A default no-args constructor
- A constructor that takes an
- Register the module with the
Implements
system
@AutoRegisterCommand(
name = "mycommand",
permission = "myplugin.command.mycommand",
playerOnly = false,
aliases = {"mc", "mycmd"}
)
public class MyCommand extends CommandBase {
// Command implementation
}
The ClassScanner
will:
- Find all classes annotated with
@AutoRegisterCommand
- Filter for classes that extend
CommandBase
and are not interfaces or abstract - Extract command information from the annotation
- Instantiate each command using either:
- A constructor that takes an
Astra
parameter - A default no-args constructor
- A constructor that takes name, permission, playerOnly, and aliases parameters
- A constructor that takes an
- Register the command with the plugin's
CommandManager
@AutoRegisterListener(priority = 5)
public class MyListener implements Listener {
// Event handlers
}
The ClassScanner
will:
- Find all classes annotated with
@AutoRegisterListener
- Filter for classes that implement
Listener
and are not interfaces or abstract - Sort them by priority (higher numbers = higher priority)
- Instantiate each listener using either:
- A constructor that takes an
Astra
parameter - A default no-args constructor
- A constructor that takes an
- Register the listener with Bukkit's event system
@AutoRegisterTask(
id = "my-task",
async = true,
executeOnStartup = true,
delay = 20,
period = 100,
priority = TaskPriority.HIGH
)
public class MyTask extends AsyncAstraTask {
// Task implementation
}
The ClassScanner
will:
- Find all classes annotated with
@AutoRegisterTask
- Filter for non-interface, non-abstract classes
- Extract task information from the annotation
- Instantiate each task using either:
- A constructor that takes an
Astra
parameter - A default no-args constructor
- A constructor that takes an
- Configure the task based on annotation parameters
- If
executeOnStartup
is true:- For repeating tasks (period > 0), schedule as repeating
- For delayed tasks (delay > 0), schedule as delayed
- For immediate tasks, execute immediately
The ClassScanner
uses the Reflections library to efficiently scan for annotated classes:
Reflections reflections = new Reflections(packageName, Scanners.TypesAnnotated, Scanners.SubTypes);
It handles errors gracefully, logging any issues that occur during scanning or registration:
try {
// Registration code
} catch (Exception e) {
plugin.logger().error("Could not register the module: " + clazz.getName(), e);
}
- Reduced Boilerplate: No need to manually register each module, command, listener, or task
- Automatic Dependency Management: Modules are registered in the correct order based on priority
- Simplified Development: Just add annotations to your classes and they'll be registered automatically
-
Improved Maintainability: Registration logic is centralized in the
ClassScanner
- Flexible Configuration: Annotations provide fine-grained control over how classes are registered
By using the ClassScanner
, you can focus on implementing your plugin's functionality rather than writing registration code, making your development process more efficient and your code more maintainable.