8000 Be more lenient with version checks when updating the minor version of the game by DerEchtePilz · Pull Request #594 · CommandAPI/CommandAPI · GitHub
[go: up one dir, main page]

Skip to content

Be more lenient with version checks when updating the minor version of the game #594

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 10 commits into from
Aug 14, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 9 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -409,6 +409,15 @@ This is the current roadmap for the CommandAPI (as of 30th April 2024):
</tr>
</thead>
<tbody>
<tr>
<td valign="top"><b>9.6.0</b></td>
<td valign="top">???</td>
<td valign="top">
<ul>
<li>https://github.com/JorelAli/CommandAPI/pull/594 Adds a config option to allow the CommandAPI to be more lenient when updating to a new minor version (e.g. from 1.21 to 1.21.1)</li>
</ul>
</td>
</tr>
<tr>
<td valign="top"><b>9.5.3</b></td>
<td valign="top">August 2024</td>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -109,8 +109,10 @@ public static void onLoad(CommandAPIConfig<?> config) {
CommandAPI.config = new InternalConfig(config);

// Initialize handlers
CommandAPIPlatform<?, ?, ?> platform = CommandAPIVersionHandler.getPlatform();
LoadContext loadContext = CommandAPIVersionHandler.getPlatform();
CommandAPIPlatform<?, ?, ?> platform = loadContext.platform();
new CommandAPIHandler<>(platform);
loadContext.context().run();

// Log platform load
final String platformClassHierarchy;
Expand Down
16 changes: 16 additions & 0 8000 deletions commandapi-core/src/main/java/dev/jorel/commandapi/CommandAPIConfig.java
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@ public abstract class CommandAPIConfig<Impl
boolean verboseOutput = false;
boolean silentLogs = false;
boolean useLatestNMSVersion = false;
boolean beLenientForMinorVersions = false;
String missingExecutorImplementationMessage = "This command has no implementations for %s";

File dispatcherFile = null;
Expand Down Expand Up @@ -90,6 +91,21 @@ public Impl useLatestNMSVersion(boolean value) {
return instance();
}

/**
* Sets whether the CommandAPI should load a (potentially unsupported) NMS version
* when updating to a minor release of Minecraft. As an example, this setting can allow
* updating to 1.21.2 from 1.21.1 but doesn't allow updating to 1.22 from 1.21.2.
* Unlike {@link #useLatestNMSVersion(boolean)}, this setting does
* not blindly load the latest NMS version, but will prefer loading the correct NMS implementation when available.
*
* @param value whether the CommandAPI should assume that minor Minecraft releases do not cause incompatibilities
* @return this CommandAPIConfig
*/
public Impl beLenientForMinorVersions(boolean value) {
this.beLenientForMinorVersions = value;
return instance();
}

/**
* Sets the message to display to users when a command has no executor.
* Available formatting parameters are:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ public interface CommandAPIVersionHandler {
*
* @return an instance of CommandAPIPlatform which can run on the currently active server
*/
static CommandAPIPlatform<?, ?, ?> getPlatform() {
static LoadContext getPlatform() {
throw new IllegalStateException("You have the wrong copy of the CommandAPI! If you're shading, did you use commandapi-core instead of commandapi-{platform}-shade?");
}
}
A3E2
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,8 @@ public class InternalConfig {
// Whether we should use the latest NMS version (which may not be compatible)
private final boolean useLatestNMSVersion;

private final boolean beLenientForMinorVersions;

// The message to display when an executor implementation is missing
private final String messageMissingExecutorImplementation;

Expand All @@ -65,6 +67,7 @@ public InternalConfig(CommandAPIConfig<?> config) {
this.verboseOutput = config.verboseOutput;
this.silentLogs = config.silentLogs;
this.useLatestNMSVersion = config.useLatestNMSVersion;
this.beLenientForMinorVersions = config.beLenientForMinorVersions;
this.messageMissingExecutorImplementation = config.missingExecutorImplementationMessage;
this.dispatcherFile = config.dispatcherFile;
this.skipSenderProxy = config.skipSenderProxy;
Expand Down Expand Up @@ -94,6 +97,13 @@ public boolean shouldUseLatestNMSVersion() {
return this.useLatestNMSVersion;
}

/**
* @return Whether the CommandAPI should assume that minor versions of officially unsupported versions do not cause incompatibilities
*/
public boolean shouldBeLenientForMinorVersions() {
return this.beLenientForMinorVersions;
}

/**
* @return The message to display if a command executor does not have an
* implementation for a given type
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
package dev.jorel.commandapi;

public record LoadContext(CommandAPIPlatform<?, ?, ?> platform, Runnable context) {

public LoadContext(CommandAPIPlatform<?, ?, ?> platform) {
this(platform, () -> {});
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,8 @@ public void onLoad() {
.missingExecutorImplementationMessage(fileConfig.getString("messages.missing-executor-implementation"))
.dispatcherFile(fileConfig.getBoolean("create-dispatcher-json") ? new File(getDataFolder(), "command_registration.json") : null)
.shouldHookPaperReload(fileConfig.getBoolean("hook-paper-reload"))
.skipReloadDatapacks(fileConfig.getBoolean("skip-initial-datapack-reload"));
.skipReloadDatapacks(fileConfig.getBoolean("skip-initial-datapack-reload"))
.beLenientForMinorVersions(fileConfig.getBoolean("be-lenient-for-minor-versions"));

for (String pluginName : fileConfig.getStringList("skip-sender-proxy")) {
if (Bukkit.getPluginManager().getPlugin(pluginName) != null) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,13 @@ create-dispatcher-json: false
# implementation is actually compatible with the current Minecraft version.
use-latest-nms-version: false

# Be lenient with version checks when loading for new minor Minecraft versions (default: false)
# If "true", the CommandAPI loads NMS implementations for (potentially unsupported) Minecraft versions.
# For example, this setting may allow updating from 1.21.1 to 1.21.2 as only the minor version is changing
# but will not allow an update from 1.21.2 to 1.22.
# Keep in mind that implementations may vary and actually updating the CommandAPI might be necessary.
be-lenient-for-minor-versions: false

# Hook into Paper's ServerResourcesReloadedEvent (default: true)
# If "true", and the CommandAPI detects it is running on a Paper server, it will
# hook into Paper's ServerResourcesReloadedEvent to detect when /minecraft:reload is run.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,8 @@ public void onLoad() {
.missingExecutorImplementationMessage(fileConfig.getString("messages.missing-executor-implementation"))
.dispatcherFile(fileConfig.getBoolean("create-dispatcher-json") ? new File(getDataFolder(), "command_registration.json") : null)
.shouldHookPaperReload(fileConfig.getBoolean("hook-paper-reload"))
.skipReloadDatapacks(fileConfig.getBoolean("skip-initial-datapack-reload"));
.skipReloadDatapacks(fileConfig.getBoolean("skip-initial-datapack-reload"))
.beLenientForMinorVersions(fileConfig.getBoolean("be-lenient-for-minor-versions"));

for (String pluginName : fileConfig.getStringList("skip-sender-proxy")) {
if (Bukkit.getPluginManager().getPlugin(pluginName) != null) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,13 @@ create-dispatcher-json: false
# implementation is actually compatible with the current Minecraft version.
use-latest-nms-version: false

# Be lenient with version checks when loading for new minor Minecraft versions (default: false)
# If "true", the CommandAPI loads NMS implementations for (potentially unsupported) Minecraft versions.
# For example, this setting may allow updating from 1.21.1 to 1.21.2 as only the minor version is changing
# but will not allow an update from 1.21.2 to 1.22.
# Keep in mind that implementations may vary and actually updating the CommandAPI might be necessary.
be-lenient-for-minor-versions: false

# Hook into Paper's ServerResourcesReloadedEvent (default: true)
# If "true", and the CommandAPI detects it is running on a Paper server, it will
# hook into Paper's ServerResourcesReloadedEvent to detect when /minecraft:reload is run.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,8 @@ interface CommandAPIVersionHandler {
companion object {

@JvmStatic
fun getPlatform() : CommandAPIPlatform<*, *, *> {
return MockNMS(NMS_1_19_1_R1());
fun getPlatform() : LoadContext {
return LoadContext(MockNMS(NMS_1_19_1_R1()))
}

}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -43,12 +43,12 @@ private static boolean isMojangMapped() {
}
}

static CommandAPIPlatform<?, ?, ?> getPlatform() {
static LoadContext getPlatform() {
if(profileId == null) {
System.out.println("Using default version 1.19.4");
return new MockNMS(new NMS_1_19_4_R3());
return new LoadContext(new MockNMS(new NMS_1_19_4_R3()));
} else {
return new MockNMS(switch(profileId) {
return new LoadContext(new MockNMS(switch(profileId) {
case "Minecraft_1_20_5" -> new NMS_1_20_R4();
case "Minecraft_1_20_3" -> new NMS_1_20_R3();
case "Minecraft_1_20_2" -> new NMS_1_20_R2();
Expand All @@ -59,7 +59,7 @@ private static boolean isMojangMapped() {
case "Minecraft_1_17" -> new NMS_1_17();
case "Minecraft_1_16_5" -> new NMS_1_16_R3();
default -> throw new IllegalArgumentException("Unexpected value: " + System.getProperty("profileId"));
});
}));
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,8 @@
import dev.jorel.commandapi.nms.*;
import org.bukkit.Bukkit;

import java.util.function.Supplier;

/**
* This file handles the NMS version to be loaded. The CommandAPIVersionHandler
* file within the commandapi-core module is NOT used at compile time. Instead,
Expand All @@ -48,12 +50,17 @@ public interface CommandAPIVersionHandler {
*
* @return an instance of NMS which can run on the specified Minecraft version
*/
static CommandAPIPlatform<?, ?, ?> getPlatform() {
static LoadContext getPlatform() {
String latestMajorVersion = "21"; // Change this for Minecraft's major update
Supplier<CommandAPIPlatform<?, ?, ?>> latestNMS = NMS_1_21_R1::new;
if (CommandAPI.getConfiguration().shouldUseLatestNMSVersion()) {
return new NMS_1_21_R1();
return new LoadContext(latestNMS.get(), () -> {
CommandAPI.logWarning("Loading the CommandAPI with the latest and potentially incompatible NMS implementation.");
CommandAPI.logWarning("While you may find success with this, further updates might be necessary to fully support the version you are using.");
});
} else {
String version = Bukkit.getBukkitVersion().split("-")[0];
return switch (version) {
CommandAPIPlatform<?, ?, ?> platform = switch (version) {
case "1.16.5" -> new NMS_1_16_R3();
case "1.17" -> new NMS_1_17();
case "1.17.1" -> new NMS_1_17_R1();
Expand All @@ -68,8 +75,21 @@ public interface CommandAPIVersionHandler {
case "1.20.3", "1.20.4" -> new NMS_1_20_R3();
case "1.20.5", "1.20.6" -> new NMS_1_20_R4();
case "1.21", "1.21.1" -> new NMS_1_21_R1();
default -> throw new UnsupportedVersionException(version);
default -> null;
};
if (platform != null) {
return new LoadContext(platform);
}
if (CommandAPI.getConfiguration().shouldBeLenientForMinorVersions()) {
String currentMajorVersion = version.split("\\.")[1];
179B if (latestMajorVersion.equals(currentMajorVersion)) {
return new LoadContext(latestNMS.get(), () -> {
CommandAPI.logWarning("Loading the CommandAPI with a potentially incompatible NMS implementation.");
CommandAPI.logWarning("While you may find success with this, further updates might be necessary to fully support the version you are using.");
});
}
}
throw new UnsupportedVersionException(version);
}
}

Expand Down
5 changes: 3 additions & 2 deletions commandapi-platforms/commandapi-bukkit/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -26,10 +26,11 @@

<!-- Outputs -->
<module>commandapi-bukkit-plugin</module>
<module>commandapi-bukkit-test</module>
<module>commandapi-bukkit-shade</module>

<module>commandapi-bukkit-plugin-mojang-mapped</module>
<module>commandapi-bukkit-shade-mojang-mapped</module>

<!-- Tests -->
<module>commandapi-bukkit-test</module>
</modules>
</project>
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
package dev.jorel.commandapi;

public interface CommandAPIVersionHandler {
static CommandAPIPlatform<?, ?, ?> getPlatform() {
return new CommandAPIVelocity();
static LoadContext getPlatform() {
return new LoadContext(new CommandAPIVelocity());
}
}
26 changes: 26 additions & 0 deletions docssrc/src/config.md
Original file line number Diff line number Diff line change
Expand Up @@ -120,6 +120,32 @@ use-latest-nms-version: true

-----

### `be-lenient-for-minor-versions`

Controls whether the CommandAPI should be more lenient when updating to a new Minecraft version.

Similar to the [`use-latest-nms-version`](#use-latest-nms-version) setting, this can allow the CommandAPI to run on a version higher than it officially supports. As an example, this setting can allow updating to 1.21.2 from 1.21.1 but doesn't allow updating to 1.22 from 1.21.2.

<div class="warning">

Take the warning from the [`use-latest-nms-version`](#use-latest-nms-version) and apply it here too. This is _not_ guaranteed to work either and also may cause unexpected side-effects.

</div>

**Default value**

```yml
be-lenient-for-minor-versions: false
```

**Example value**

```yml
be-lenient-for-minor-versions: true
```

-----

### `hook-paper-reload`

Controls whether the CommandAPI hooks into the Paper-exclusive `ServerResourcesReloadedEvent` when available.
Expand Down
1 change: 1 addition & 0 deletions docssrc/src/setup_shading.md
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ public class CommandAPIConfig {
CommandAPIConfig verboseOutput(boolean value); // Enables verbose logging
CommandAPIConfig silentLogs(boolean value); // Disables ALL logging (except errors)
CommandAPIConfig useLatestNMSVersion(boolean value); // Whether the latest NMS implementation should be used or not
CommandAPIConfig beLenientForMinorVersions(boolean value); // Whether the CommandAPI should be more lenient with minor Minecraft versions
CommandAPIConfig missingExecutorImplementationMessage(String value); // Set message to display when executor implementation is missing
CommandAPIConfig dispatcherFile(File file); // If not null, the CommandAPI will create a JSON file with Brigadier's command tree
CommandAPIConfig setNamespace(String namespace); // The namespace to use when the CommandAPI registers a command
Expand Down
Loading
0