feat: transition to VexlioHub, clean up modules, add effects & localize configs
- Rename and relocate package from DeluxeHubReloaded to VexlioHub - Remove deprecated modules: antiwdl, scoreboard, tablist, pvp_mode, teleportation_bow, anti_swear, lockchat, vanish, holograms - Refactor all commands to standard Bukkit CommandExecutor/TabCompleter registered dynamically via Bukkit CommandMap - Add particle, sound, and trail configurations for launchpad and double jump modules - Implement actionbar announcements and join title welcome animation modules - Fully customize, translate to Czech, and restyle all configuration files in the 'uprava/' directory with the purple-cyan gradient theme
This commit is contained in:
@@ -0,0 +1,112 @@
|
||||
package eu.milujukockoholky.vexliolobby.config;
|
||||
|
||||
import org.bukkit.configuration.InvalidConfigurationException;
|
||||
import org.bukkit.configuration.file.FileConfiguration;
|
||||
import org.bukkit.configuration.file.YamlConfiguration;
|
||||
import org.bukkit.plugin.java.JavaPlugin;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
|
||||
public class ConfigHandler {
|
||||
|
||||
private final JavaPlugin plugin;
|
||||
private final String name;
|
||||
private final File file;
|
||||
private FileConfiguration configuration;
|
||||
private boolean needsMigration;
|
||||
|
||||
public ConfigHandler(JavaPlugin plugin, String name) {
|
||||
this.plugin = plugin;
|
||||
this.name = name + ".yml";
|
||||
this.file = new File(plugin.getDataFolder(), this.name);
|
||||
this.configuration = new YamlConfiguration();
|
||||
this.needsMigration = false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Saves the default config if it doesn't exist, otherwise loads the existing config
|
||||
* and marks it for migration.
|
||||
*/
|
||||
public void saveDefaultConfig() {
|
||||
boolean fileExists = file.exists();
|
||||
|
||||
if (!fileExists) {
|
||||
plugin.saveResource(name, false);
|
||||
} else {
|
||||
// If file exists, it might need migration when plugin updates
|
||||
needsMigration = true;
|
||||
}
|
||||
|
||||
try {
|
||||
configuration.load(file);
|
||||
} catch (InvalidConfigurationException | IOException e) {
|
||||
handleConfigError(e);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Saves the current configuration to file
|
||||
*/
|
||||
public void save() {
|
||||
if (configuration == null || file == null) return;
|
||||
try {
|
||||
getConfig().save(file);
|
||||
} catch (IOException e) {
|
||||
plugin.getLogger().severe("Failed to save configuration file: " + name + " — " + e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Reloads the configuration from file
|
||||
*/
|
||||
public void reload() {
|
||||
try {
|
||||
configuration = YamlConfiguration.loadConfiguration(file);
|
||||
} catch (Exception e) {
|
||||
handleConfigError(e);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the file configuration
|
||||
*/
|
||||
public FileConfiguration getConfig() {
|
||||
return configuration;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the file associated with this config handler
|
||||
*/
|
||||
public File getFile() {
|
||||
return file;
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if this configuration needs migration
|
||||
*/
|
||||
public boolean needsMigration() {
|
||||
return needsMigration;
|
||||
}
|
||||
|
||||
/**
|
||||
* Marks this configuration as migrated
|
||||
*/
|
||||
public void setMigrated() {
|
||||
this.needsMigration = false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Handle configuration errors
|
||||
*/
|
||||
private void handleConfigError(Exception e) {
|
||||
e.printStackTrace();
|
||||
plugin.getLogger().severe("============= CONFIGURATION ERROR =============");
|
||||
plugin.getLogger().severe("There was an error loading " + name);
|
||||
plugin.getLogger().severe("Please check for any obvious configuration mistakes");
|
||||
plugin.getLogger().severe("such as using tabs for spaces or forgetting to end quotes");
|
||||
plugin.getLogger().severe("before reporting to the developer. The plugin will now disable..");
|
||||
plugin.getLogger().severe("============= CONFIGURATION ERROR =============");
|
||||
plugin.getServer().getPluginManager().disablePlugin(plugin);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,76 @@
|
||||
package eu.milujukockoholky.vexliolobby.config;
|
||||
|
||||
import eu.milujukockoholky.vexliolobby.VexlioHubPlugin;
|
||||
import org.bukkit.configuration.file.FileConfiguration;
|
||||
import org.bukkit.configuration.file.YamlConfiguration;
|
||||
|
||||
import java.io.File;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
public class ConfigManager {
|
||||
|
||||
private final Map<ConfigType, ConfigHandler> configurations;
|
||||
private ConfigMigrator migrator;
|
||||
|
||||
public ConfigManager() {
|
||||
configurations = new HashMap<>();
|
||||
}
|
||||
|
||||
public void loadFiles(VexlioHubPlugin plugin) {
|
||||
// Initialize the config migrator
|
||||
migrator = new ConfigMigrator(plugin);
|
||||
|
||||
// Register all config files
|
||||
registerFile(ConfigType.SETTINGS, new ConfigHandler(plugin, "config"));
|
||||
registerFile(ConfigType.MESSAGES, new ConfigHandler(plugin, "messages"));
|
||||
registerFile(ConfigType.DATA, new ConfigHandler(plugin, "data"));
|
||||
registerFile(ConfigType.COMMANDS, new ConfigHandler(plugin, "commands"));
|
||||
|
||||
// Load all configs
|
||||
configurations.values().forEach(ConfigHandler::saveDefaultConfig);
|
||||
|
||||
// Perform migrations if needed
|
||||
migrateConfigs();
|
||||
|
||||
// Set the Messages configuration
|
||||
Messages.setConfiguration(getFile(ConfigType.MESSAGES).getConfig());
|
||||
}
|
||||
|
||||
/**
|
||||
* Migrates all configurations that need updating
|
||||
*/
|
||||
private void migrateConfigs() {
|
||||
for (Map.Entry<ConfigType, ConfigHandler> entry : configurations.entrySet()) {
|
||||
ConfigHandler handler = entry.getValue();
|
||||
if (handler.needsMigration()) {
|
||||
if (migrator.migrateConfig(entry.getKey(), handler)) {
|
||||
handler.setMigrated();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public ConfigHandler getFile(ConfigType type) {
|
||||
return configurations.get(type);
|
||||
}
|
||||
|
||||
public void reloadFiles() {
|
||||
configurations.values().forEach(ConfigHandler::reload);
|
||||
// Perform migrations after reload in case plugin has been updated
|
||||
migrateConfigs();
|
||||
Messages.setConfiguration(getFile(ConfigType.MESSAGES).getConfig());
|
||||
}
|
||||
|
||||
public void saveFiles() {
|
||||
configurations.values().forEach(ConfigHandler::save);
|
||||
}
|
||||
|
||||
public void registerFile(ConfigType type, ConfigHandler config) {
|
||||
configurations.put(type, config);
|
||||
}
|
||||
|
||||
public FileConfiguration getFileConfiguration(File file) {
|
||||
return YamlConfiguration.loadConfiguration(file);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,254 @@
|
||||
package eu.milujukockoholky.vexliolobby.config;
|
||||
|
||||
import org.bukkit.configuration.file.FileConfiguration;
|
||||
import org.bukkit.configuration.file.YamlConfiguration;
|
||||
import org.bukkit.plugin.java.JavaPlugin;
|
||||
|
||||
import java.io.InputStream;
|
||||
import java.io.InputStreamReader;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
import java.util.logging.Level;
|
||||
|
||||
public class ConfigMigrator {
|
||||
|
||||
private final JavaPlugin plugin;
|
||||
private final Version currentVersion;
|
||||
private final List<VersionMigration> versionMigrations;
|
||||
private final Set<String> excludedPaths;
|
||||
|
||||
/**
|
||||
* Creates a new ConfigMigrator with the current plugin version
|
||||
*/
|
||||
public ConfigMigrator(JavaPlugin plugin) {
|
||||
this.plugin = plugin;
|
||||
this.currentVersion = Version.parse(plugin.getPluginMeta().getVersion());
|
||||
this.versionMigrations = new ArrayList<>();
|
||||
this.excludedPaths = new HashSet<>();
|
||||
|
||||
// Register paths to exclude from migration
|
||||
registerExcludedPaths();
|
||||
|
||||
// Register any version-specific migrations here
|
||||
registerMigrations();
|
||||
}
|
||||
|
||||
/**
|
||||
* Register paths that should be excluded from migration
|
||||
*/
|
||||
private void registerExcludedPaths() {
|
||||
// Add the announcements section to excluded paths
|
||||
excludedPaths.add("announcements");
|
||||
excludedPaths.add("custom_join_items");
|
||||
excludedPaths.add("join_events");
|
||||
excludedPaths.add("custom_commands");
|
||||
excludedPaths.add("commands");
|
||||
excludedPaths.add("command_block");
|
||||
excludedPaths.add("anti_swear");
|
||||
excludedPaths.add("join_settings");
|
||||
excludedPaths.add("pvp_mode");
|
||||
|
||||
|
||||
|
||||
// Add other paths to exclude if needed
|
||||
// excludedPaths.add("another.path.to.exclude");
|
||||
}
|
||||
|
||||
private void registerMigrations() {
|
||||
// Example: Add migrations for specific version jumps
|
||||
// versionMigrations.add(new VersionMigration(
|
||||
// Version.parse("1.0.0"),
|
||||
// Version.parse("1.1.0"),
|
||||
// this::migrateFrom1_0_0To1_1_0
|
||||
// ));
|
||||
}
|
||||
|
||||
/**
|
||||
* Migrates a configuration file, adding missing options from the default config
|
||||
* while preserving existing values.
|
||||
*
|
||||
* @param configType The type of config to migrate
|
||||
* @param configHandler The config handler containing the file
|
||||
* @return True if changes were made, false otherwise
|
||||
*/
|
||||
public boolean migrateConfig(ConfigType configType, ConfigHandler configHandler) {
|
||||
String fileName = getFileNameForType(configType);
|
||||
if (fileName == null) {
|
||||
plugin.getLogger().warning("No file name found for config type: " + configType);
|
||||
return false;
|
||||
}
|
||||
|
||||
// Get the resource from jar
|
||||
InputStream defaultConfigStream = plugin.getResource(fileName);
|
||||
if (defaultConfigStream == null) {
|
||||
plugin.getLogger().warning("Could not find default configuration for: " + fileName);
|
||||
return false;
|
||||
}
|
||||
|
||||
// Load default config from jar
|
||||
FileConfiguration defaultConfig = YamlConfiguration.loadConfiguration(
|
||||
new InputStreamReader(defaultConfigStream));
|
||||
|
||||
// Get current config
|
||||
FileConfiguration currentConfig = configHandler.getConfig();
|
||||
|
||||
// Track if we made changes
|
||||
boolean changes = false;
|
||||
|
||||
// Check if we need to perform version-specific migrations
|
||||
String storedVersion = currentConfig.getString("version", "0.0.0");
|
||||
Version configVersion = Version.parse(storedVersion);
|
||||
|
||||
// Run version-specific migrations if config version is older than current version
|
||||
if (configVersion.isOlderThan(currentVersion)) {
|
||||
for (VersionMigration migration : versionMigrations) {
|
||||
if (configVersion.isOlderThan(migration.getTargetVersion()) &&
|
||||
(migration.getSourceVersion().isSameAs(configVersion) ||
|
||||
migration.getSourceVersion().isOlderThan(configVersion))) {
|
||||
|
||||
plugin.getLogger().info("Applying migration from " +
|
||||
migration.getSourceVersion() + " to " + migration.getTargetVersion() +
|
||||
" for " + fileName);
|
||||
|
||||
// Apply the migration
|
||||
if (migration.apply(configType, currentConfig)) {
|
||||
changes = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Update the version in the config
|
||||
currentConfig.set("version", currentVersion.toString());
|
||||
changes = true;
|
||||
}
|
||||
|
||||
// Add missing sections and values
|
||||
if (addMissingEntries(defaultConfig, currentConfig, "")) {
|
||||
changes = true;
|
||||
}
|
||||
|
||||
// Save if changes were made
|
||||
if (changes) {
|
||||
try {
|
||||
configHandler.save();
|
||||
plugin.getLogger().info("Updated configuration file: " + fileName);
|
||||
} catch (Exception e) {
|
||||
plugin.getLogger().log(Level.SEVERE, "Could not save updated configuration for: " + fileName, e);
|
||||
}
|
||||
}
|
||||
|
||||
return changes;
|
||||
}
|
||||
|
||||
/**
|
||||
* Recursively adds missing entries from default config to current config,
|
||||
* but skips excluded paths
|
||||
*
|
||||
* @param defaultConfig The default configuration from resources
|
||||
* @param currentConfig The current configuration file
|
||||
* @param path The current path being examined
|
||||
* @return True if changes were made, false otherwise
|
||||
*/
|
||||
private boolean addMissingEntries(FileConfiguration defaultConfig, FileConfiguration currentConfig, String path) {
|
||||
boolean changes = false;
|
||||
|
||||
// Skip this path and its children if it's in the excluded paths
|
||||
for (String excludedPath : excludedPaths) {
|
||||
if (path.equals(excludedPath) || path.startsWith(excludedPath + ".")) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
Set<String> defaultKeys = path.isEmpty()
|
||||
? defaultConfig.getKeys(false)
|
||||
: defaultConfig.getConfigurationSection(path).getKeys(false);
|
||||
|
||||
for (String key : defaultKeys) {
|
||||
String fullPath = path.isEmpty() ? key : path + "." + key;
|
||||
|
||||
// Skip excluded paths
|
||||
boolean shouldSkip = false;
|
||||
for (String excludedPath : excludedPaths) {
|
||||
if (fullPath.equals(excludedPath) || fullPath.startsWith(excludedPath + ".")) {
|
||||
shouldSkip = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (shouldSkip) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!currentConfig.contains(fullPath)) {
|
||||
// This key doesn't exist in the current config, so add it
|
||||
currentConfig.set(fullPath, defaultConfig.get(fullPath));
|
||||
changes = true;
|
||||
plugin.getLogger().info("Added missing config option: " + fullPath);
|
||||
} else if (defaultConfig.isConfigurationSection(fullPath)) {
|
||||
// This is a section, so recursively check its children
|
||||
changes |= addMissingEntries(defaultConfig, currentConfig, fullPath);
|
||||
}
|
||||
// If the path exists and isn't a section, keep the user's current value
|
||||
}
|
||||
|
||||
return changes;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the file name for the given config type
|
||||
*/
|
||||
private String getFileNameForType(ConfigType type) {
|
||||
switch (type) {
|
||||
case SETTINGS:
|
||||
return "config.yml";
|
||||
case MESSAGES:
|
||||
return "messages.yml";
|
||||
case COMMANDS:
|
||||
return "commands.yml";
|
||||
case DATA:
|
||||
return "data.yml";
|
||||
default:
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Class representing a migration between two specific versions
|
||||
*/
|
||||
private class VersionMigration {
|
||||
private final Version sourceVersion;
|
||||
private final Version targetVersion;
|
||||
private final MigrationFunction migrationFunction;
|
||||
|
||||
@SuppressWarnings("unused")
|
||||
public VersionMigration(Version sourceVersion, Version targetVersion,
|
||||
MigrationFunction migrationFunction) {
|
||||
this.sourceVersion = sourceVersion;
|
||||
this.targetVersion = targetVersion;
|
||||
this.migrationFunction = migrationFunction;
|
||||
}
|
||||
|
||||
public Version getSourceVersion() {
|
||||
return sourceVersion;
|
||||
}
|
||||
|
||||
public Version getTargetVersion() {
|
||||
return targetVersion;
|
||||
}
|
||||
|
||||
public boolean apply(ConfigType configType, FileConfiguration config) {
|
||||
return migrationFunction.migrate(configType, config);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Functional interface for migration functions
|
||||
*/
|
||||
@FunctionalInterface
|
||||
private interface MigrationFunction {
|
||||
boolean migrate(ConfigType configType, FileConfiguration config);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,10 @@
|
||||
package eu.milujukockoholky.vexliolobby.config;
|
||||
|
||||
public enum ConfigType {
|
||||
|
||||
SETTINGS,
|
||||
MESSAGES,
|
||||
COMMANDS,
|
||||
DATA
|
||||
|
||||
}
|
||||
@@ -0,0 +1,92 @@
|
||||
package eu.milujukockoholky.vexliolobby.config;
|
||||
|
||||
import eu.milujukockoholky.vexliolobby.utility.TextUtil;
|
||||
import org.bukkit.command.CommandSender;
|
||||
import org.bukkit.configuration.file.FileConfiguration;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public enum Messages {
|
||||
|
||||
PREFIX("GENERAL.PREFIX"),
|
||||
NO_PERMISSION("GENERAL.NO_PERMISSION"),
|
||||
CUSTOM_COMMAND_NO_PERMISSION("GENERAL.CUSTOM_COMMAND_NO_PERMISSION"),
|
||||
INVALID_PLAYER("GENERAL.INVALID_PLAYER"),
|
||||
CONFIG_RELOAD("GENERAL.CONFIG_RELOAD"),
|
||||
COOLDOWN_ACTIVE("GENERAL.COOLDOWN_ACTIVE"),
|
||||
|
||||
GAMEMODE_CHANGE("GAMEMODE.GAMEMODE_CHANGE"),
|
||||
GAMEMODE_CHANGE_OTHER("GAMEMODE.GAMEMODE_CHANGE_OTHER"),
|
||||
GAMEMODE_INVALID("GAMEMODE.GAMEMODE_INVALID"),
|
||||
|
||||
FLIGHT_ENABLE("FLIGHT.ENABLE"),
|
||||
FLIGHT_ENABLE_OTHER("FLIGHT.ENABLE_OTHER"),
|
||||
FLIGHT_DISABLE("FLIGHT.DISABLE"),
|
||||
FLIGHT_DISABLE_OTHER("FLIGHT.DISABLE_OTHER"),
|
||||
|
||||
PLAYER_HIDER_HIDDEN("PLAYER_HIDER.HIDDEN"),
|
||||
PLAYER_HIDER_SHOWN("PLAYER_HIDER.SHOWN"),
|
||||
|
||||
SET_LOBBY("LOBBY.SET_LOBBY"),
|
||||
|
||||
CLEARCHAT("CHAT.CLEARCHAT"),
|
||||
CLEARCHAT_PLAYER("CHAT.CLEARCHAT_PLAYER"),
|
||||
|
||||
DOUBLE_JUMP_COOLDOWN("DOUBLE_JUMP.COOLDOWN_ACTIVE"),
|
||||
|
||||
EVENT_ITEM_DROP("WORLD_EVENT_MODIFICATIONS.ITEM_DROP"),
|
||||
EVENT_ITEM_PICKUP("WORLD_EVENT_MODIFICATIONS.ITEM_PICKUP"),
|
||||
EVENT_BLOCK_PLACE("WORLD_EVENT_MODIFICATIONS.BLOCK_PLACE"),
|
||||
EVENT_BLOCK_BREAK("WORLD_EVENT_MODIFICATIONS.BLOCK_BREAK"),
|
||||
EVENT_BLOCK_INTERACT("WORLD_EVENT_MODIFICATIONS.BLOCK_INTERACT"),
|
||||
|
||||
BUILD_MODE_ENABLED_ACTIONBAR("BUILD_MODE.ENABLED_ACTION_BAR"),
|
||||
BUILD_MODE_ENABLED("BUILD_MODE.ENABLED"),
|
||||
BUILD_MODE_DISABLED("BUILD_MODE.DISABLED"),
|
||||
BUILD_MODE_COMMAND_TARGET_NOT_FOUND("BUILD_MODE.TARGET_NOT_FOUND"),
|
||||
BUILD_MODE_COMMAND_ENABLED_FOR_TARGET("BUILD_MODE.ENABLED_FOR_TARGET");
|
||||
|
||||
private static FileConfiguration config;
|
||||
private final String path;
|
||||
|
||||
Messages(String path) {
|
||||
this.path = path;
|
||||
}
|
||||
|
||||
public static void setConfiguration(FileConfiguration c) {
|
||||
config = c;
|
||||
}
|
||||
|
||||
public String toString() {
|
||||
Object value = config.get("Messages." + this.path);
|
||||
String message;
|
||||
if (value == null) {
|
||||
message = "VexlioHub: message not found (" + this.path + ") - Check your messages.yml!";
|
||||
} else {
|
||||
message = value instanceof List ? TextUtil.fromList((List<?>) value) : value.toString();
|
||||
}
|
||||
return message;
|
||||
}
|
||||
|
||||
public void send(CommandSender receiver, Object... replacements) {
|
||||
String message = toString();
|
||||
if (!message.isEmpty()) {
|
||||
receiver.sendMessage(TextUtil.color(replace(message, replacements)));
|
||||
}
|
||||
}
|
||||
|
||||
private String replace(String message, Object... replacements) {
|
||||
for (int i = 0; i < replacements.length; i += 2) {
|
||||
if (i + 1 >= replacements.length) break;
|
||||
message = message.replace(String.valueOf(replacements[i]), String.valueOf(replacements[i + 1]));
|
||||
}
|
||||
|
||||
String prefix = config.getString("Messages." + PREFIX.getPath());
|
||||
return message.replace("%prefix%", prefix != null && !prefix.isEmpty() ? prefix : "");
|
||||
}
|
||||
|
||||
public String getPath() {
|
||||
return this.path;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,97 @@
|
||||
package eu.milujukockoholky.vexliolobby.config;
|
||||
|
||||
/**
|
||||
* Represents a version in the format major.minor.patch
|
||||
* Used for tracking plugin versions and migrations
|
||||
*/
|
||||
public class Version implements Comparable<Version> {
|
||||
private final int major;
|
||||
private final int minor;
|
||||
private final int patch;
|
||||
|
||||
/**
|
||||
* Constructs a version from major, minor, and patch values
|
||||
*/
|
||||
public Version(int major, int minor, int patch) {
|
||||
this.major = major;
|
||||
this.minor = minor;
|
||||
this.patch = patch;
|
||||
}
|
||||
|
||||
/**
|
||||
* Parses a version string in the format "major.minor.patch"
|
||||
*/
|
||||
public static Version parse(String versionStr) {
|
||||
String[] parts = versionStr.split("\\.");
|
||||
|
||||
int major = 0, minor = 0, patch = 0;
|
||||
|
||||
if (parts.length >= 1) {
|
||||
try {
|
||||
major = Integer.parseInt(parts[0]);
|
||||
} catch (NumberFormatException e) {
|
||||
// Ignore and use default
|
||||
}
|
||||
}
|
||||
|
||||
if (parts.length >= 2) {
|
||||
try {
|
||||
minor = Integer.parseInt(parts[1]);
|
||||
} catch (NumberFormatException e) {
|
||||
// Ignore and use default
|
||||
}
|
||||
}
|
||||
|
||||
if (parts.length >= 3) {
|
||||
try {
|
||||
patch = Integer.parseInt(parts[2]);
|
||||
} catch (NumberFormatException e) {
|
||||
// Ignore and use default
|
||||
}
|
||||
}
|
||||
|
||||
return new Version(major, minor, patch);
|
||||
}
|
||||
|
||||
/**
|
||||
* Compares this version with another version
|
||||
*/
|
||||
@Override
|
||||
public int compareTo(Version other) {
|
||||
if (this.major != other.major) {
|
||||
return Integer.compare(this.major, other.major);
|
||||
}
|
||||
|
||||
if (this.minor != other.minor) {
|
||||
return Integer.compare(this.minor, other.minor);
|
||||
}
|
||||
|
||||
return Integer.compare(this.patch, other.patch);
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if this version is newer than another version
|
||||
*/
|
||||
public boolean isNewerThan(Version other) {
|
||||
return compareTo(other) > 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if this version is the same as another version
|
||||
*/
|
||||
public boolean isSameAs(Version other) {
|
||||
return compareTo(other) == 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if this version is older than another version
|
||||
*/
|
||||
public boolean isOlderThan(Version other) {
|
||||
return compareTo(other) < 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return major + "." + minor + "." + patch;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user