mirror of
https://github.com/BentoBoxWorld/BentoBox.git
synced 2025-02-09 17:01:51 +01:00
Added 'api-version' parameter to addon.yml to allow specifying a minimum required BentoBox version
Implements https://github.com/BentoBoxWorld/BentoBox/issues/1131 API: added InvalidAddonDescriptionException, AddonDescription#getApiVersion()
This commit is contained in:
parent
d8dda75ca5
commit
d8d9061f84
@ -20,6 +20,7 @@ import org.bukkit.util.permissions.DefaultPermissions;
|
||||
import org.eclipse.jdt.annotation.NonNull;
|
||||
import org.eclipse.jdt.annotation.Nullable;
|
||||
|
||||
import world.bentobox.bentobox.api.addons.exceptions.InvalidAddonDescriptionException;
|
||||
import world.bentobox.bentobox.api.addons.exceptions.InvalidAddonFormatException;
|
||||
import world.bentobox.bentobox.api.addons.exceptions.InvalidAddonInheritException;
|
||||
import world.bentobox.bentobox.managers.AddonsManager;
|
||||
@ -39,6 +40,7 @@ public class AddonClassLoader extends URLClassLoader {
|
||||
throws InvalidAddonInheritException,
|
||||
MalformedURLException,
|
||||
InvalidDescriptionException,
|
||||
InvalidAddonDescriptionException,
|
||||
InstantiationException,
|
||||
IllegalAccessException, InvocationTargetException, NoSuchMethodException {
|
||||
super(new URL[]{path.toURI().toURL()}, parent);
|
||||
@ -94,7 +96,7 @@ public class AddonClassLoader extends URLClassLoader {
|
||||
}
|
||||
|
||||
@NonNull
|
||||
private AddonDescription asDescription(YamlConfiguration data) {
|
||||
private AddonDescription asDescription(YamlConfiguration data) throws InvalidAddonDescriptionException {
|
||||
AddonDescription.Builder builder = new AddonDescription.Builder(data.getString("main"), data.getString("name"), data.getString("version"))
|
||||
.authors(data.getString("authors"))
|
||||
.metrics(data.getBoolean("metrics", true))
|
||||
@ -110,6 +112,14 @@ public class AddonClassLoader extends URLClassLoader {
|
||||
}
|
||||
builder.icon(Material.getMaterial(data.getString("icon", "PAPER")));
|
||||
|
||||
String apiVersion = data.getString("api-version");
|
||||
if (apiVersion != null) {
|
||||
if (!apiVersion.matches("^(\\d+\\.)?(\\d+\\.)?(\\*|\\d+)$")) {
|
||||
throw new InvalidAddonDescriptionException("Provided API version '" + apiVersion + "' is not valid. It must only contain digits and dots and not end with a dot.");
|
||||
}
|
||||
builder.apiVersion(apiVersion);
|
||||
}
|
||||
|
||||
return builder.build();
|
||||
}
|
||||
|
||||
|
@ -35,6 +35,12 @@ public final class AddonDescription {
|
||||
* @since 1.5.0
|
||||
*/
|
||||
private final @NonNull Material icon;
|
||||
/**
|
||||
* Minimum BentoBox version this addon requires in order to work properly.
|
||||
* Defaults to {@code "1"}.
|
||||
* @since 1.11.0
|
||||
*/
|
||||
private final @NonNull String apiVersion;
|
||||
|
||||
private AddonDescription(@NonNull Builder builder) {
|
||||
this.main = builder.main;
|
||||
@ -47,6 +53,7 @@ public final class AddonDescription {
|
||||
this.metrics = builder.metrics;
|
||||
this.repository = builder.repository;
|
||||
this.icon = builder.icon;
|
||||
this.apiVersion = builder.apiVersion;
|
||||
}
|
||||
|
||||
@NonNull
|
||||
@ -120,6 +127,29 @@ public final class AddonDescription {
|
||||
return icon;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the minimum BentoBox version this addon requires in order to work properly.
|
||||
* <br/>
|
||||
* Examples:
|
||||
* <ul>
|
||||
* <li>{@code "1"} means that the addon relies on BentoBox {@code 1.0.0} or higher.</li>
|
||||
* <li>Similarly, {@code "2"} sets the requirement to BentoBox {@code 2.0.0} or higher.</li>
|
||||
* <li>
|
||||
* More specific versions can be provided:
|
||||
* <ul>
|
||||
* <li>{@code "1.10"} -> BentoBox {@code 1.10.0} or higher.</li>
|
||||
* <li>{@code "1.9.2"} -> BentoBox {@code 1.9.2} or higher.</li>
|
||||
* </ul>
|
||||
* </li>
|
||||
* </ul>
|
||||
* Defaults to {@code "1"}.
|
||||
* @return the minimum BentoBox version this addon requires in order to work properly.
|
||||
*/
|
||||
@NonNull
|
||||
public String getApiVersion() {
|
||||
return apiVersion;
|
||||
}
|
||||
|
||||
public static class Builder {
|
||||
private @NonNull String main;
|
||||
private @NonNull String name;
|
||||
@ -131,6 +161,7 @@ public final class AddonDescription {
|
||||
private boolean metrics = true;
|
||||
private @NonNull String repository = "";
|
||||
private @NonNull Material icon = Material.PAPER;
|
||||
private @NonNull String apiVersion = "1";
|
||||
|
||||
/**
|
||||
* @since 1.1
|
||||
@ -196,6 +227,18 @@ public final class AddonDescription {
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the minimum BentoBox version this addon requires in order to work properly.
|
||||
* @param apiVersion the minimum BentoBox version this addon requires in order to work properly.
|
||||
* @since 1.11.0
|
||||
* @see AddonDescription#getApiVersion()
|
||||
*/
|
||||
@NonNull
|
||||
public Builder apiVersion(@NonNull String apiVersion) {
|
||||
this.apiVersion = apiVersion;
|
||||
return this;
|
||||
}
|
||||
|
||||
@NonNull
|
||||
public AddonDescription build() {
|
||||
return new AddonDescription(this);
|
||||
|
@ -0,0 +1,16 @@
|
||||
package world.bentobox.bentobox.api.addons.exceptions;
|
||||
|
||||
/**
|
||||
* @since 1.11.0
|
||||
*/
|
||||
public class InvalidAddonDescriptionException extends AddonException {
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
private static final long serialVersionUID = 7741502900847049986L;
|
||||
|
||||
public InvalidAddonDescriptionException(String errorMessage) {
|
||||
super(errorMessage);
|
||||
}
|
||||
}
|
@ -117,6 +117,16 @@ public class AddonsManager {
|
||||
// Add to the list of loaders
|
||||
loaders.put(addon, addonClassLoader);
|
||||
|
||||
// Checks if this addon is compatible with the current BentoBox version.
|
||||
if (!isAddonCompatibleWithBentoBox(addon)) {
|
||||
// It is not, abort.
|
||||
plugin.logWarning("Skipping " + addon.getDescription().getName() + " as it can only run on a more recent BentoBox version.");
|
||||
plugin.logWarning("NOTE: The addon relies on API that is not available in the BentoBox version you are using.");
|
||||
plugin.logWarning("NOTE: Please update BentoBox.");
|
||||
addon.setState(State.INCOMPATIBLE);
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
// Run the onLoad.
|
||||
addon.onLoad();
|
||||
@ -204,6 +214,32 @@ public class AddonsManager {
|
||||
plugin.log("NOTE: DO NOT report this as a bug from BentoBox.");
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if the addon does not explicitly rely on API from a more recent BentoBox version.
|
||||
* @param addon instance of the Addon.
|
||||
* @return {@code true} if the addon relies on available BentoBox API, {@code false} otherwise.
|
||||
* @since 1.11.0
|
||||
*/
|
||||
private boolean isAddonCompatibleWithBentoBox(@NonNull Addon addon) {
|
||||
// We have to use lists instead of arrays for dynamic changes and optimization (appending something to an array is O(n) whereas O(1) with lists).
|
||||
List<String> apiVersion = Arrays.asList(addon.getDescription().getApiVersion().split("\\."));
|
||||
List<String> bentoboxVersion = Arrays.asList(plugin.getDescription().getVersion().split("\\."));
|
||||
|
||||
while (bentoboxVersion.size() < apiVersion.size()) {
|
||||
bentoboxVersion.add("0");
|
||||
}
|
||||
|
||||
for (int i = 0; i < apiVersion.size(); i++) {
|
||||
int apiNumber = Integer.parseInt(apiVersion.get(i));
|
||||
int bentoboxNumber = Integer.parseInt(bentoboxVersion.get(i));
|
||||
if (bentoboxNumber < apiNumber) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Handles an addon which failed to load due to an error.
|
||||
* @param addon instance of the Addon.
|
||||
|
Loading…
Reference in New Issue
Block a user