mirror of
				https://github.com/GeyserMC/Geyser.git
				synced 2024-08-14 23:57:35 +00:00 
			
		
		
		
	Extensions should specify geyser api version in the extension.yml (#3880)
* let extensions specify geyser api version instead of base api version * fix spacing, @link formatting, properly check for compat * Proper warning, update to API changes to also check patch version * Bump base-api version * adapt to new base api changes * Actually bump to 2.4.1 * Update api/src/main/java/org/geysermc/geyser/api/extension/ExtensionDescription.java * Address reviews * Address reviews * Update to latest base api changes; proper extension *human* version checking * no need to apply a plugin, that's the default --------- Co-authored-by: Konicai <71294714+Konicai@users.noreply.github.com>
This commit is contained in:
		
							parent
							
								
									03187b6139
								
							
						
					
					
						commit
						f3ba5848c2
					
				
					 8 changed files with 141 additions and 32 deletions
				
			
		| 
						 | 
				
			
			@ -1,8 +1,24 @@
 | 
			
		|||
plugins {
 | 
			
		||||
    // Allow blossom to mark sources root of templates
 | 
			
		||||
    idea
 | 
			
		||||
    id("geyser.publish-conventions")
 | 
			
		||||
    alias(libs.plugins.blossom)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
dependencies {
 | 
			
		||||
    api(libs.base.api)
 | 
			
		||||
    api(libs.math)
 | 
			
		||||
}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
version = property("version")!!
 | 
			
		||||
val apiVersion = (version as String).removeSuffix("-SNAPSHOT")
 | 
			
		||||
 | 
			
		||||
sourceSets {
 | 
			
		||||
    main {
 | 
			
		||||
        blossom {
 | 
			
		||||
            javaSources {
 | 
			
		||||
                property("version", apiVersion)
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -0,0 +1,53 @@
 | 
			
		|||
/*
 | 
			
		||||
 * Copyright (c) 2024 GeyserMC. http://geysermc.org
 | 
			
		||||
 *
 | 
			
		||||
 * 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:
 | 
			
		||||
 *
 | 
			
		||||
 * 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.
 | 
			
		||||
 *
 | 
			
		||||
 * @author GeyserMC
 | 
			
		||||
 * @link https://github.com/GeyserMC/Geyser
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
package org.geysermc.geyser.api;
 | 
			
		||||
 | 
			
		||||
import org.geysermc.api.util.ApiVersion;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Not a public API. For internal use only. May change without notice.
 | 
			
		||||
 * This class is processed before compilation to insert build properties.
 | 
			
		||||
 */
 | 
			
		||||
class BuildData {
 | 
			
		||||
    static final String VERSION = "{{ version }}";
 | 
			
		||||
    static final ApiVersion API_VERSION;
 | 
			
		||||
 | 
			
		||||
    static {
 | 
			
		||||
        String[] parts = VERSION.split("\\.");
 | 
			
		||||
        if (parts.length != 3) {
 | 
			
		||||
            throw new RuntimeException("Invalid api version: " + VERSION);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        try {
 | 
			
		||||
            int human = Integer.parseInt(parts[0]);
 | 
			
		||||
            int major = Integer.parseInt(parts[1]);
 | 
			
		||||
            int minor = Integer.parseInt(parts[2]);
 | 
			
		||||
            API_VERSION = new ApiVersion(human, major, minor);
 | 
			
		||||
        } catch (Exception e) {
 | 
			
		||||
            throw new RuntimeException("Invalid api version: " + VERSION, e);
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -29,6 +29,7 @@ import org.checkerframework.checker.nullness.qual.NonNull;
 | 
			
		|||
import org.checkerframework.checker.nullness.qual.Nullable;
 | 
			
		||||
import org.geysermc.api.Geyser;
 | 
			
		||||
import org.geysermc.api.GeyserApiBase;
 | 
			
		||||
import org.geysermc.api.util.ApiVersion;
 | 
			
		||||
import org.geysermc.geyser.api.command.CommandSource;
 | 
			
		||||
import org.geysermc.geyser.api.connection.GeyserConnection;
 | 
			
		||||
import org.geysermc.geyser.api.event.EventBus;
 | 
			
		||||
| 
						 | 
				
			
			@ -169,4 +170,14 @@ public interface GeyserApi extends GeyserApiBase {
 | 
			
		|||
    static GeyserApi api() {
 | 
			
		||||
        return Geyser.api(GeyserApi.class);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Returns the {@link ApiVersion} representing the current Geyser api version.
 | 
			
		||||
     * See the <a href="https://github.com/geysermc/api/blob/master/geyser-versioning.md">Geyser version outline</a>)
 | 
			
		||||
     *
 | 
			
		||||
     * @return the current geyser api version
 | 
			
		||||
     */
 | 
			
		||||
     default ApiVersion geyserApiVersion() {
 | 
			
		||||
        return BuildData.API_VERSION;
 | 
			
		||||
     }
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -59,33 +59,46 @@ public interface ExtensionDescription {
 | 
			
		|||
    String main();
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Gets the extension's major api version
 | 
			
		||||
     * Represents the human api version that the extension requires.
 | 
			
		||||
     * See the <a href="https://github.com/geysermc/api/blob/master/geyser-versioning.md">Geyser version outline</a>)
 | 
			
		||||
     * for more details on the Geyser API version.
 | 
			
		||||
     *
 | 
			
		||||
     * @return the extension's major api version
 | 
			
		||||
     * @return the extension's requested human api version
 | 
			
		||||
     */
 | 
			
		||||
    int humanApiVersion();
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Represents the major api version that the extension requires.
 | 
			
		||||
     * See the <a href="https://github.com/geysermc/api/blob/master/geyser-versioning.md">Geyser version outline</a>)
 | 
			
		||||
     * for more details on the Geyser API version.
 | 
			
		||||
     *
 | 
			
		||||
     * @return the extension's requested major api version
 | 
			
		||||
     */
 | 
			
		||||
    int majorApiVersion();
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Gets the extension's minor api version
 | 
			
		||||
     * Represents the minor api version that the extension requires.
 | 
			
		||||
     * See the <a href="https://github.com/geysermc/api/blob/master/geyser-versioning.md">Geyser version outline</a>)
 | 
			
		||||
     * for more details on the Geyser API version.
 | 
			
		||||
     *
 | 
			
		||||
     * @return the extension's minor api version
 | 
			
		||||
     * @return the extension's requested minor api version
 | 
			
		||||
     */
 | 
			
		||||
    int minorApiVersion();
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Gets the extension's patch api version
 | 
			
		||||
     *
 | 
			
		||||
     * @return the extension's patch api version
 | 
			
		||||
     * No longer in use. Geyser is now using an adaption of the romantic versioning scheme.
 | 
			
		||||
     * See <a href="https://github.com/geysermc/api/blob/master/geyser-versioning.md">here</a> for details.
 | 
			
		||||
     */
 | 
			
		||||
    int patchApiVersion();
 | 
			
		||||
    @Deprecated(forRemoval = true)
 | 
			
		||||
    default int patchApiVersion() {
 | 
			
		||||
        return minorApiVersion();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Gets the extension's api version.
 | 
			
		||||
     *
 | 
			
		||||
     * @return the extension's api version
 | 
			
		||||
     * Returns the extension's requested Geyser Api version.
 | 
			
		||||
     */
 | 
			
		||||
    default String apiVersion() {
 | 
			
		||||
        return majorApiVersion() + "." + minorApiVersion() + "." + patchApiVersion();
 | 
			
		||||
        return humanApiVersion() + "." + majorApiVersion() + "." + minorApiVersion();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -43,9 +43,9 @@ import java.util.regex.Pattern;
 | 
			
		|||
public record GeyserExtensionDescription(@NonNull String id,
 | 
			
		||||
                                         @NonNull String name,
 | 
			
		||||
                                         @NonNull String main,
 | 
			
		||||
                                         int humanApiVersion,
 | 
			
		||||
                                         int majorApiVersion,
 | 
			
		||||
                                         int minorApiVersion,
 | 
			
		||||
                                         int patchApiVersion,
 | 
			
		||||
                                         @NonNull String version,
 | 
			
		||||
                                         @NonNull List<String> authors) implements ExtensionDescription {
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -82,9 +82,9 @@ public record GeyserExtensionDescription(@NonNull String id,
 | 
			
		|||
            throw new InvalidDescriptionException(GeyserLocale.getLocaleStringLog("geyser.extensions.load.failed_api_format", name, apiVersion));
 | 
			
		||||
        }
 | 
			
		||||
        String[] api = apiVersion.split("\\.");
 | 
			
		||||
        int majorApi = Integer.parseUnsignedInt(api[0]);
 | 
			
		||||
        int minorApi = Integer.parseUnsignedInt(api[1]);
 | 
			
		||||
        int patchApi = Integer.parseUnsignedInt(api[2]);
 | 
			
		||||
        int humanApi = Integer.parseUnsignedInt(api[0]);
 | 
			
		||||
        int majorApi = Integer.parseUnsignedInt(api[1]);
 | 
			
		||||
        int minorApi = Integer.parseUnsignedInt(api[2]);
 | 
			
		||||
 | 
			
		||||
        List<String> authors = new ArrayList<>();
 | 
			
		||||
        if (source.author != null) {
 | 
			
		||||
| 
						 | 
				
			
			@ -94,7 +94,7 @@ public record GeyserExtensionDescription(@NonNull String id,
 | 
			
		|||
            authors.addAll(source.authors);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        return new GeyserExtensionDescription(id, name, main, majorApi, minorApi, patchApi, version, authors);
 | 
			
		||||
        return new GeyserExtensionDescription(id, name, main, humanApi, majorApi, minorApi, version, authors);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @NonNull
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -29,10 +29,15 @@ import it.unimi.dsi.fastutil.objects.Object2ObjectMap;
 | 
			
		|||
import it.unimi.dsi.fastutil.objects.Object2ObjectOpenHashMap;
 | 
			
		||||
import lombok.RequiredArgsConstructor;
 | 
			
		||||
import org.checkerframework.checker.nullness.qual.NonNull;
 | 
			
		||||
import org.geysermc.api.Geyser;
 | 
			
		||||
import org.geysermc.api.util.ApiVersion;
 | 
			
		||||
import org.geysermc.geyser.GeyserImpl;
 | 
			
		||||
import org.geysermc.geyser.api.GeyserApi;
 | 
			
		||||
import org.geysermc.geyser.api.event.ExtensionEventBus;
 | 
			
		||||
import org.geysermc.geyser.api.extension.*;
 | 
			
		||||
import org.geysermc.geyser.api.extension.Extension;
 | 
			
		||||
import org.geysermc.geyser.api.extension.ExtensionDescription;
 | 
			
		||||
import org.geysermc.geyser.api.extension.ExtensionLoader;
 | 
			
		||||
import org.geysermc.geyser.api.extension.ExtensionLogger;
 | 
			
		||||
import org.geysermc.geyser.api.extension.ExtensionManager;
 | 
			
		||||
import org.geysermc.geyser.api.extension.exception.InvalidDescriptionException;
 | 
			
		||||
import org.geysermc.geyser.api.extension.exception.InvalidExtensionException;
 | 
			
		||||
import org.geysermc.geyser.extension.event.GeyserExtensionEventBus;
 | 
			
		||||
| 
						 | 
				
			
			@ -40,7 +45,12 @@ import org.geysermc.geyser.text.GeyserLocale;
 | 
			
		|||
 | 
			
		||||
import java.io.IOException;
 | 
			
		||||
import java.io.Reader;
 | 
			
		||||
import java.nio.file.*;
 | 
			
		||||
import java.nio.file.FileSystem;
 | 
			
		||||
import java.nio.file.FileSystems;
 | 
			
		||||
import java.nio.file.Files;
 | 
			
		||||
import java.nio.file.NoSuchFileException;
 | 
			
		||||
import java.nio.file.Path;
 | 
			
		||||
import java.nio.file.StandardCopyOption;
 | 
			
		||||
import java.util.HashMap;
 | 
			
		||||
import java.util.LinkedHashMap;
 | 
			
		||||
import java.util.List;
 | 
			
		||||
| 
						 | 
				
			
			@ -176,16 +186,22 @@ public class GeyserExtensionLoader extends ExtensionLoader {
 | 
			
		|||
                        return;
 | 
			
		||||
                    }
 | 
			
		||||
 | 
			
		||||
                    // Completely different API version
 | 
			
		||||
                    if (description.majorApiVersion() != Geyser.api().majorApiVersion()) {
 | 
			
		||||
                        GeyserImpl.getInstance().getLogger().error(GeyserLocale.getLocaleStringLog("geyser.extensions.load.failed_api_version", name, description.apiVersion()));
 | 
			
		||||
                        return;
 | 
			
		||||
                    }
 | 
			
		||||
                    // Check whether an extensions' requested api version is compatible
 | 
			
		||||
                    ApiVersion.Compatibility compatibility = GeyserApi.api().geyserApiVersion().supportsRequestedVersion(
 | 
			
		||||
                        description.humanApiVersion(),
 | 
			
		||||
                        description.majorApiVersion(),
 | 
			
		||||
                        description.minorApiVersion()
 | 
			
		||||
                    );
 | 
			
		||||
 | 
			
		||||
                    // If the extension requires new API features, being backwards compatible
 | 
			
		||||
                    if (description.minorApiVersion() > Geyser.api().minorApiVersion()) {
 | 
			
		||||
                        GeyserImpl.getInstance().getLogger().error(GeyserLocale.getLocaleStringLog("geyser.extensions.load.failed_api_version", name, description.apiVersion()));
 | 
			
		||||
                        return;
 | 
			
		||||
                    if (compatibility != ApiVersion.Compatibility.COMPATIBLE) {
 | 
			
		||||
                        // Workaround for the switch to the Geyser API version instead of the Base API version in extensions
 | 
			
		||||
                        if (compatibility == ApiVersion.Compatibility.HUMAN_DIFFER && description.humanApiVersion() == 1) {
 | 
			
		||||
                            GeyserImpl.getInstance().getLogger().warning("The extension %s requested the Base API version %s, which is deprecated in favor of specifying the Geyser API version. Please update the extension, or contact its developer."
 | 
			
		||||
                                .formatted(name, description.apiVersion()));
 | 
			
		||||
                        } else {
 | 
			
		||||
                            GeyserImpl.getInstance().getLogger().error(GeyserLocale.getLocaleStringLog("geyser.extensions.load.failed_api_version", name, description.apiVersion()));
 | 
			
		||||
                            return;
 | 
			
		||||
                        }
 | 
			
		||||
                    }
 | 
			
		||||
 | 
			
		||||
                    GeyserExtensionContainer container = this.loadExtension(path, description);
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -7,5 +7,5 @@ org.gradle.vfs.watch=false
 | 
			
		|||
 | 
			
		||||
group=org.geysermc
 | 
			
		||||
id=geyser
 | 
			
		||||
version=2.4.0-SNAPSHOT
 | 
			
		||||
version=2.4.1-SNAPSHOT
 | 
			
		||||
description=Allows for players from Minecraft: Bedrock Edition to join Minecraft: Java Edition servers.
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -1,5 +1,5 @@
 | 
			
		|||
[versions]
 | 
			
		||||
base-api = "1.0.0-SNAPSHOT"
 | 
			
		||||
base-api = "1.0.1-SNAPSHOT"
 | 
			
		||||
cumulus = "1.1.2"
 | 
			
		||||
erosion = "1.1-20240515.191456-1"
 | 
			
		||||
events = "1.1-SNAPSHOT"
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue