3
0
Mirror von https://github.com/GeyserMC/Geyser.git synchronisiert 2024-11-20 06:50:09 +01:00

Moved the extension into geyser-api

Dieser Commit ist enthalten in:
ImDaBigBoss 2022-01-10 20:01:36 +01:00
Ursprung bfe4c09290
Commit 6757437193
13 geänderte Dateien mit 382 neuen und 101 gelöschten Zeilen

Datei anzeigen

@ -23,9 +23,9 @@
* @link https://github.com/GeyserMC/Geyser * @link https://github.com/GeyserMC/Geyser
*/ */
package org.geysermc.geyser.extension; package org.geysermc.geyser.api.extension;
import org.geysermc.geyser.GeyserImpl; import org.geysermc.api.GeyserApiBase;
import java.io.File; import java.io.File;
import java.io.InputStream; import java.io.InputStream;
@ -37,14 +37,15 @@ public interface Extension {
boolean isEnabled(); boolean isEnabled();
boolean isDisabled(); boolean isDisabled();
File getDataFolder(); File dataFolder();
ExtensionDescription getDescription(); ExtensionDescription description();
String getName(); String name();
InputStream getResource(String filename); InputStream getResource(String filename);
void saveResource(String filename, boolean replace); void saveResource(String filename, boolean replace);
GeyserImpl getGeyser(); ClassLoader classLoader();
ClassLoader getClassLoader(); ExtensionLoader extensionLoader();
ExtensionLoader getExtensionLoader(); ExtensionLogger logger();
GeyserApiBase geyserApi();
} }

Datei anzeigen

@ -0,0 +1,36 @@
/*
* Copyright (c) 2019-2022 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.extension;
import java.util.*;
public interface ExtensionDescription {
String name();
String main();
List<String> ApiVersions();
String version();
List<String> authors();
}

Datei anzeigen

@ -0,0 +1,41 @@
/*
* Copyright (c) 2019-2022 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.extension;
import org.geysermc.geyser.api.extension.exception.InvalidDescriptionException;
import org.geysermc.geyser.api.extension.exception.InvalidExtensionException;
import java.io.File;
import java.util.regex.Pattern;
public interface ExtensionLoader {
GeyserExtension loadExtension(File file) throws InvalidExtensionException;
ExtensionDescription extensionDescription(File file) throws InvalidDescriptionException;
Pattern[] extensionFilters();
Class<?> classByName(final String name) throws ClassNotFoundException;
void enableExtension(Extension extension);
void disableExtension(Extension extension);
}

Datei anzeigen

@ -0,0 +1,90 @@
/*
* Copyright (c) 2019-2022 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.extension;
public interface ExtensionLogger {
/**
* Get the logger prefix
* @return the logger prefix
*/
String prefix();
/**
* Logs a severe message to console
*
* @param message the message to log
*/
void severe(String message);
/**
* Logs a severe message and an exception to console
*
* @param message the message to log
* @param error the error to throw
*/
void severe(String message, Throwable error);
/**
* Logs an error message to console
*
* @param message the message to log
*/
void error(String message);
/**
* Logs an error message and an exception to console
*
* @param message the message to log
* @param error the error to throw
*/
void error(String message, Throwable error);
/**
* Logs a warning message to console
*
* @param message the message to log
*/
void warning(String message);
/**
* Logs an info message to console
*
* @param message the message to log
*/
void info(String message);
/**
* Logs a debug message to console
*
* @param message the message to log
*/
void debug(String message);
/**
* If debug is enabled for this logger
*/
boolean isDebug();
}

Datei anzeigen

@ -23,9 +23,9 @@
* @link https://github.com/GeyserMC/Geyser * @link https://github.com/GeyserMC/Geyser
*/ */
package org.geysermc.geyser.extension; package org.geysermc.geyser.api.extension;
import org.geysermc.geyser.GeyserImpl; import org.geysermc.api.GeyserApiBase;
import java.io.*; import java.io.*;
import java.net.URL; import java.net.URL;
import java.net.URLConnection; import java.net.URLConnection;
@ -36,9 +36,10 @@ public class GeyserExtension implements Extension {
private File file = null; private File file = null;
private File dataFolder = null; private File dataFolder = null;
private ClassLoader classLoader = null; private ClassLoader classLoader = null;
private GeyserImpl geyser = null;
private ExtensionLoader loader; private ExtensionLoader loader;
private ExtensionLogger logger;
private ExtensionDescription description = null; private ExtensionDescription description = null;
private GeyserApiBase api = null;
@Override @Override
public void onLoad() { public void onLoad() {
@ -74,29 +75,30 @@ public class GeyserExtension implements Extension {
} }
@Override @Override
public File getDataFolder() { public File dataFolder() {
return this.dataFolder; return this.dataFolder;
} }
@Override @Override
public ExtensionDescription getDescription() { public ExtensionDescription description() {
return this.description; return this.description;
} }
@Override @Override
public String getName() { public String name() {
return this.description.getName(); return this.description.name();
} }
public void init(GeyserImpl geyser, ExtensionDescription description, File dataFolder, File file, ExtensionLoader loader) { public void init(GeyserApiBase api, ExtensionLogger logger, ExtensionLoader loader, ExtensionDescription description, File dataFolder, File file) {
if (!this.initialized) { if (!this.initialized) {
this.initialized = true; this.initialized = true;
this.file = file; this.file = file;
this.dataFolder = dataFolder; this.dataFolder = dataFolder;
this.classLoader = this.getClass().getClassLoader(); this.classLoader = this.getClass().getClassLoader();
this.geyser = geyser;
this.loader = loader; this.loader = loader;
this.logger = logger;
this.description = description; this.description = description;
this.api = api;
} }
} }
@ -152,25 +154,30 @@ public class GeyserExtension implements Extension {
out.close(); out.close();
in.close(); in.close();
} else { } else {
this.geyser.getLogger().warning("Could not save " + outFile.getName() + " to " + outFile + " because " + outFile.getName() + " already exists."); this.logger.warning("Could not save " + outFile.getName() + " to " + outFile + " because " + outFile.getName() + " already exists.");
} }
} catch (IOException ex) { } catch (IOException ex) {
this.geyser.getLogger().severe("Could not save " + outFile.getName() + " to " + outFile, ex); this.logger.severe("Could not save " + outFile.getName() + " to " + outFile, ex);
} }
} }
@Override @Override
public GeyserImpl getGeyser() { public ClassLoader classLoader() {
return this.geyser;
}
@Override
public ClassLoader getClassLoader() {
return this.classLoader; return this.classLoader;
} }
@Override @Override
public ExtensionLoader getExtensionLoader() { public ExtensionLoader extensionLoader() {
return this.loader; return this.loader;
} }
@Override
public ExtensionLogger logger() {
return this.logger;
}
@Override
public GeyserApiBase geyserApi() {
return this.api;
}
} }

Datei anzeigen

@ -23,7 +23,7 @@
* @link https://github.com/GeyserMC/Geyser * @link https://github.com/GeyserMC/Geyser
*/ */
package org.geysermc.geyser.extension.exception; package org.geysermc.geyser.api.extension.exception;
public class InvalidDescriptionException extends Exception { public class InvalidDescriptionException extends Exception {
public InvalidDescriptionException(Throwable cause) { public InvalidDescriptionException(Throwable cause) {

Datei anzeigen

@ -23,7 +23,7 @@
* @link https://github.com/GeyserMC/Geyser * @link https://github.com/GeyserMC/Geyser
*/ */
package org.geysermc.geyser.extension.exception; package org.geysermc.geyser.api.extension.exception;
public class InvalidExtensionException extends Exception { public class InvalidExtensionException extends Exception {
public InvalidExtensionException(Throwable cause) { public InvalidExtensionException(Throwable cause) {

Datei anzeigen

@ -52,7 +52,7 @@ import org.geysermc.geyser.api.GeyserApi;
import org.geysermc.geyser.command.CommandManager; import org.geysermc.geyser.command.CommandManager;
import org.geysermc.geyser.configuration.GeyserConfiguration; import org.geysermc.geyser.configuration.GeyserConfiguration;
import org.geysermc.geyser.entity.EntityDefinitions; import org.geysermc.geyser.entity.EntityDefinitions;
import org.geysermc.geyser.extension.ExtensionManager; import org.geysermc.geyser.extension.GeyserExtensionManager;
import org.geysermc.geyser.level.WorldManager; import org.geysermc.geyser.level.WorldManager;
import org.geysermc.geyser.network.ConnectorServerEventHandler; import org.geysermc.geyser.network.ConnectorServerEventHandler;
import org.geysermc.geyser.pack.ResourcePack; import org.geysermc.geyser.pack.ResourcePack;
@ -155,6 +155,8 @@ public class GeyserImpl implements GeyserApi {
MessageTranslator.init(); MessageTranslator.init();
MinecraftLocale.init(); MinecraftLocale.init();
GeyserExtensionManager.init();
start(); start();
GeyserConfiguration config = bootstrap.getGeyserConfig(); GeyserConfiguration config = bootstrap.getGeyserConfig();
@ -198,8 +200,6 @@ public class GeyserImpl implements GeyserApi {
ResourcePack.loadPacks(); ResourcePack.loadPacks();
ExtensionManager.init();
if (platformType != PlatformType.STANDALONE && config.getRemote().getAddress().equals("auto")) { if (platformType != PlatformType.STANDALONE && config.getRemote().getAddress().equals("auto")) {
// Set the remote address to localhost since that is where we are always connecting // Set the remote address to localhost since that is where we are always connecting
try { try {
@ -460,7 +460,7 @@ public class GeyserImpl implements GeyserApi {
ResourcePack.PACKS.clear(); ResourcePack.PACKS.clear();
ExtensionManager.getExtensionManager().disableExtensions(); GeyserExtensionManager.getExtensionManager().disableExtensions();
bootstrap.getGeyserLogger().info(GeyserLocale.getLocaleStringLog("geyser.core.shutdown.done")); bootstrap.getGeyserLogger().info(GeyserLocale.getLocaleStringLog("geyser.core.shutdown.done"));
} }

Datei anzeigen

@ -25,7 +25,9 @@
package org.geysermc.geyser.extension; package org.geysermc.geyser.extension;
import org.geysermc.geyser.extension.exception.InvalidExtensionException; import org.geysermc.geyser.api.extension.ExtensionDescription;
import org.geysermc.geyser.api.extension.GeyserExtension;
import org.geysermc.geyser.api.extension.exception.InvalidExtensionException;
import java.io.File; import java.io.File;
import java.net.MalformedURLException; import java.net.MalformedURLException;
import java.net.URL; import java.net.URL;
@ -34,28 +36,28 @@ import java.util.HashMap;
import java.util.Map; import java.util.Map;
import java.util.Set; import java.util.Set;
public class ExtensionClassLoader extends URLClassLoader { public class GeyserExtensionClassLoader extends URLClassLoader {
private ExtensionLoader loader; private GeyserExtensionLoader loader;
private Map<String, Class> classes = new HashMap<>(); private Map<String, Class> classes = new HashMap<>();
public GeyserExtension extension; public GeyserExtension extension;
public ExtensionClassLoader(ExtensionLoader loader, ClassLoader parent, ExtensionDescription description, File file) throws InvalidExtensionException, MalformedURLException { public GeyserExtensionClassLoader(GeyserExtensionLoader loader, ClassLoader parent, ExtensionDescription description, File file) throws InvalidExtensionException, MalformedURLException {
super(new URL[] { file.toURI().toURL() }, parent); super(new URL[] { file.toURI().toURL() }, parent);
this.loader = loader; this.loader = loader;
try { try {
Class<?> jarClass; Class<?> jarClass;
try { try {
jarClass = Class.forName(description.getMain(), true, this); jarClass = Class.forName(description.main(), true, this);
} catch (ClassNotFoundException ex) { } catch (ClassNotFoundException ex) {
throw new InvalidExtensionException("Class " + description.getMain() + " not found, extension cannot be loaded", ex); throw new InvalidExtensionException("Class " + description.main() + " not found, extension cannot be loaded", ex);
} }
Class<? extends GeyserExtension> extensionClass; Class<? extends GeyserExtension> extensionClass;
try { try {
extensionClass = jarClass.asSubclass(GeyserExtension.class); extensionClass = jarClass.asSubclass(GeyserExtension.class);
} catch (ClassCastException ex) { } catch (ClassCastException ex) {
throw new InvalidExtensionException("Main class " + description.getMain() + " should extends GeyserExtension, but extends " + jarClass.getSuperclass().getSimpleName(), ex); throw new InvalidExtensionException("Main class " + description.main() + " should extends GeyserExtension, but extends " + jarClass.getSuperclass().getSimpleName(), ex);
} }
extension = extensionClass.newInstance(); extension = extensionClass.newInstance();
@ -78,7 +80,7 @@ public class ExtensionClassLoader extends URLClassLoader {
Class<?> result = classes.get(name); Class<?> result = classes.get(name);
if(result == null) { if(result == null) {
if(checkGlobal) { if(checkGlobal) {
result = loader.getClassByName(name); result = loader.classByName(name);
} }
if(result == null) { if(result == null) {
result = super.findClass(name); result = super.findClass(name);

Datei anzeigen

@ -25,20 +25,19 @@
package org.geysermc.geyser.extension; package org.geysermc.geyser.extension;
import org.geysermc.geyser.extension.exception.InvalidDescriptionException; import org.geysermc.geyser.api.extension.exception.InvalidDescriptionException;
import org.yaml.snakeyaml.DumperOptions; import org.yaml.snakeyaml.DumperOptions;
import org.yaml.snakeyaml.Yaml; import org.yaml.snakeyaml.Yaml;
import java.util.*; import java.util.*;
public class ExtensionDescription { public class GeyserExtensionDescription implements org.geysermc.geyser.api.extension.ExtensionDescription {
private String name; private String name;
private String main; private String main;
private List<String> api; private List<String> api;
private String version; private String version;
private final List<String> authors = new ArrayList<>(); private final List<String> authors = new ArrayList<>();
public ExtensionDescription(String yamlString) throws InvalidDescriptionException { public GeyserExtensionDescription(String yamlString) throws InvalidDescriptionException {
DumperOptions dumperOptions = new DumperOptions(); DumperOptions dumperOptions = new DumperOptions();
dumperOptions.setDefaultFlowStyle(DumperOptions.FlowStyle.BLOCK); dumperOptions.setDefaultFlowStyle(DumperOptions.FlowStyle.BLOCK);
Yaml yaml = new Yaml(dumperOptions); Yaml yaml = new Yaml(dumperOptions);
@ -72,23 +71,28 @@ public class ExtensionDescription {
} }
} }
public String getName() { @Override
public String name() {
return this.name; return this.name;
} }
public String getMain() { @Override
public String main() {
return this.main; return this.main;
} }
public List<String> getAPIVersions() { @Override
public List<String> ApiVersions() {
return api; return api;
} }
public String getVersion() { @Override
public String version() {
return this.version; return this.version;
} }
public List<String> getAuthors() { @Override
public List<String> authors() {
return this.authors; return this.authors;
} }
} }

Datei anzeigen

@ -25,9 +25,13 @@
package org.geysermc.geyser.extension; package org.geysermc.geyser.extension;
import org.geysermc.api.Geyser;
import org.geysermc.geyser.GeyserImpl; import org.geysermc.geyser.GeyserImpl;
import org.geysermc.geyser.extension.exception.InvalidDescriptionException; import org.geysermc.geyser.api.extension.Extension;
import org.geysermc.geyser.extension.exception.InvalidExtensionException; import org.geysermc.geyser.api.extension.ExtensionLoader;
import org.geysermc.geyser.api.extension.GeyserExtension;
import org.geysermc.geyser.api.extension.exception.InvalidDescriptionException;
import org.geysermc.geyser.api.extension.exception.InvalidExtensionException;
import java.io.*; import java.io.*;
import java.util.HashMap; import java.util.HashMap;
import java.util.Map; import java.util.Map;
@ -35,10 +39,11 @@ import java.util.jar.JarEntry;
import java.util.jar.JarFile; import java.util.jar.JarFile;
import java.util.regex.Pattern; import java.util.regex.Pattern;
public class ExtensionLoader { public class GeyserExtensionLoader implements ExtensionLoader {
private final Map<String, Class> classes = new HashMap<>(); private final Map<String, Class> classes = new HashMap<>();
private final Map<String, ExtensionClassLoader> classLoaders = new HashMap<>(); private final Map<String, GeyserExtensionClassLoader> classLoaders = new HashMap<>();
@Override
public GeyserExtension loadExtension(File file) throws InvalidExtensionException { public GeyserExtension loadExtension(File file) throws InvalidExtensionException {
if (file == null) { if (file == null) {
throw new InvalidExtensionException("File is null"); throw new InvalidExtensionException("File is null");
@ -48,37 +53,39 @@ public class ExtensionLoader {
throw new InvalidExtensionException(new FileNotFoundException(file.getPath()) + " does not exist"); throw new InvalidExtensionException(new FileNotFoundException(file.getPath()) + " does not exist");
} }
final ExtensionDescription description; final GeyserExtensionDescription description;
try { try {
description = getExtensionDescription(file); description = extensionDescription(file);
} catch (InvalidDescriptionException e) { } catch (InvalidDescriptionException e) {
throw new InvalidExtensionException(e); throw new InvalidExtensionException(e);
} }
final File parentFile = file.getParentFile(); final File parentFile = file.getParentFile();
final File dataFolder = new File(parentFile, description.getName()); final File dataFolder = new File(parentFile, description.name());
if (dataFolder.exists() && !dataFolder.isDirectory()) { if (dataFolder.exists() && !dataFolder.isDirectory()) {
throw new InvalidExtensionException("The folder " + dataFolder.getPath() + " is not a directory and is the data folder for the extension " + description.getName() + "!"); throw new InvalidExtensionException("The folder " + dataFolder.getPath() + " is not a directory and is the data folder for the extension " + description.name() + "!");
} }
final ExtensionClassLoader loader; final GeyserExtensionClassLoader loader;
try { try {
loader = new ExtensionClassLoader(this, getClass().getClassLoader(), description, file); loader = new GeyserExtensionClassLoader(this, getClass().getClassLoader(), description, file);
} catch (Throwable e) { } catch (Throwable e) {
throw new InvalidExtensionException(e); throw new InvalidExtensionException(e);
} }
classLoaders.put(description.getName(), loader); classLoaders.put(description.name(), loader);
setup(loader.extension, description, dataFolder, file); setup(loader.extension, description, dataFolder, file);
return loader.extension; return loader.extension;
} }
private void setup(GeyserExtension extension, ExtensionDescription description, File dataFolder, File file) { private void setup(GeyserExtension extension, GeyserExtensionDescription description, File dataFolder, File file) {
extension.init(GeyserImpl.getInstance(), description, dataFolder, file, this); GeyserExtensionLogger logger = new GeyserExtensionLogger(GeyserImpl.getInstance().getLogger(), description.name());
extension.init(Geyser.api(), logger, this, description, dataFolder, file);
extension.onLoad(); extension.onLoad();
} }
public ExtensionDescription getExtensionDescription(File file) throws InvalidDescriptionException { @Override
public GeyserExtensionDescription extensionDescription(File file) throws InvalidDescriptionException {
JarFile jarFile = null; JarFile jarFile = null;
InputStream stream = null; InputStream stream = null;
@ -105,7 +112,7 @@ public class ExtensionLoader {
temp = bufferedReader.readLine(); temp = bufferedReader.readLine();
} }
return new ExtensionDescription(builder.toString()); return new GeyserExtensionDescription(builder.toString());
} catch (IOException e) { } catch (IOException e) {
throw new InvalidDescriptionException(e); throw new InvalidDescriptionException(e);
} finally { } finally {
@ -124,14 +131,16 @@ public class ExtensionLoader {
} }
} }
public Pattern[] getExtensionFilters() { @Override
public Pattern[] extensionFilters() {
return new Pattern[] { Pattern.compile("^.+\\.jar$") }; return new Pattern[] { Pattern.compile("^.+\\.jar$") };
} }
public Class<?> getClassByName(final String name) throws ClassNotFoundException{ @Override
public Class<?> classByName(final String name) throws ClassNotFoundException{
Class<?> clazz = classes.get(name); Class<?> clazz = classes.get(name);
try { try {
for(ExtensionClassLoader loader : classLoaders.values()) { for(GeyserExtensionClassLoader loader : classLoaders.values()) {
try { try {
clazz = loader.findClass(name,false); clazz = loader.findClass(name,false);
} catch(NullPointerException e) { } catch(NullPointerException e) {
@ -153,19 +162,21 @@ public class ExtensionLoader {
Class<?> clazz = classes.remove(name); Class<?> clazz = classes.remove(name);
} }
@Override
public void enableExtension(Extension extension) { public void enableExtension(Extension extension) {
if (extension instanceof GeyserExtension) { if (extension instanceof GeyserExtension) {
if(!extension.isEnabled()) { if(!extension.isEnabled()) {
GeyserImpl.getInstance().getLogger().info("Enabled extension " + extension.getDescription().getName()); GeyserImpl.getInstance().getLogger().info("Enabled extension " + extension.description().name());
((GeyserExtension) extension).setEnabled(true); ((GeyserExtension) extension).setEnabled(true);
} }
} }
} }
@Override
public void disableExtension(Extension extension) { public void disableExtension(Extension extension) {
if (extension instanceof GeyserExtension) { if (extension instanceof GeyserExtension) {
if(extension.isEnabled()) { if(extension.isEnabled()) {
GeyserImpl.getInstance().getLogger().info("Disabled extension " + extension.getDescription().getName()); GeyserImpl.getInstance().getLogger().info("Disabled extension " + extension.description().name());
((GeyserExtension) extension).setEnabled(false); ((GeyserExtension) extension).setEnabled(false);
} }
} }

Datei anzeigen

@ -0,0 +1,88 @@
/*
* Copyright (c) 2019-2022 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.extension;
import org.geysermc.geyser.GeyserLogger;
import org.geysermc.geyser.api.extension.ExtensionLogger;
public class GeyserExtensionLogger implements ExtensionLogger {
private GeyserLogger logger;
private String loggerPrefix;
public GeyserExtensionLogger(GeyserLogger logger, String prefix) {
this.logger = logger;
this.loggerPrefix = prefix;
}
@Override
public String prefix() {
return this.loggerPrefix;
}
private String addPrefix(String message) {
return "[" + this.loggerPrefix + "] " + message;
}
@Override
public void severe(String message) {
this.logger.severe(this.addPrefix(message));
}
@Override
public void severe(String message, Throwable error) {
this.logger.severe(this.addPrefix(message), error);
}
@Override
public void error(String message) {
this.logger.error(this.addPrefix(message));
}
@Override
public void error(String message, Throwable error) {
this.logger.error(this.addPrefix(message), error);
}
@Override
public void warning(String message) {
this.logger.warning(this.addPrefix(message));
}
@Override
public void info(String message) {
this.logger.info(this.addPrefix(message));
}
@Override
public void debug(String message) {
this.logger.debug(this.addPrefix(message));
}
@Override
public boolean isDebug() {
return this.logger.isDebug();
}
}

Datei anzeigen

@ -26,35 +26,36 @@
package org.geysermc.geyser.extension; package org.geysermc.geyser.extension;
import org.geysermc.geyser.GeyserImpl; import org.geysermc.geyser.GeyserImpl;
import org.geysermc.geyser.api.extension.Extension;
import org.geysermc.geyser.api.extension.ExtensionDescription;
import org.geysermc.geyser.api.extension.GeyserExtension;
import java.io.File; import java.io.File;
import java.io.FilenameFilter;
import java.lang.reflect.Constructor; import java.lang.reflect.Constructor;
import java.util.*; import java.util.*;
import java.util.regex.Pattern; import java.util.regex.Pattern;
public class ExtensionManager { public class GeyserExtensionManager {
private static ExtensionManager extensionManager = null; private static GeyserExtensionManager geyserExtensionManager = null;
protected Map<String, Extension> extensions = new LinkedHashMap<>(); protected Map<String, Extension> extensions = new LinkedHashMap<>();
protected Map<Pattern, ExtensionLoader> fileAssociations = new HashMap<>(); protected Map<Pattern, GeyserExtensionLoader> fileAssociations = new HashMap<>();
public static void init() { public static void init() {
GeyserImpl.getInstance().getLogger().info("Loading extensions..."); GeyserImpl.getInstance().getLogger().info("Loading extensions...");
extensionManager = new ExtensionManager(); geyserExtensionManager = new GeyserExtensionManager();
extensionManager.registerInterface(ExtensionLoader.class); geyserExtensionManager.registerInterface(GeyserExtensionLoader.class);
extensionManager.loadExtensions(new File("extensions")); geyserExtensionManager.loadExtensions(new File("extensions"));
GeyserImpl.getInstance().getLogger().info("Loaded " + extensionManager.extensions.size() + " extensions."); GeyserImpl.getInstance().getLogger().info("Loaded " + geyserExtensionManager.extensions.size() + " extensions.");
for (Extension extension : extensionManager.getExtensions().values()) { for (Extension extension : geyserExtensionManager.getExtensions().values()) {
if (!extension.isEnabled()) { if (!extension.isEnabled()) {
extensionManager.enableExtension(extension); geyserExtensionManager.enableExtension(extension);
} }
} }
} }
public static ExtensionManager getExtensionManager() { public static GeyserExtensionManager getExtensionManager() {
return extensionManager; return geyserExtensionManager;
} }
public Extension getExtension(String name) { public Extension getExtension(String name) {
@ -68,11 +69,11 @@ public class ExtensionManager {
return this.extensions; return this.extensions;
} }
public void registerInterface(Class<? extends ExtensionLoader> loader) { public void registerInterface(Class<? extends GeyserExtensionLoader> loader) {
ExtensionLoader instance; GeyserExtensionLoader instance;
if (ExtensionLoader.class.isAssignableFrom(loader)) { if (GeyserExtensionLoader.class.isAssignableFrom(loader)) {
Constructor<? extends ExtensionLoader> constructor; Constructor<? extends GeyserExtensionLoader> constructor;
try { try {
constructor = loader.getConstructor(); constructor = loader.getConstructor();
@ -88,7 +89,7 @@ public class ExtensionManager {
throw new IllegalArgumentException("Class " + loader.getName() + " does not implement interface ExtensionLoader"); throw new IllegalArgumentException("Class " + loader.getName() + " does not implement interface ExtensionLoader");
} }
Pattern[] patterns = instance.getExtensionFilters(); Pattern[] patterns = instance.extensionFilters();
synchronized (this) { synchronized (this) {
for (Pattern pattern : patterns) { for (Pattern pattern : patterns) {
@ -97,17 +98,17 @@ public class ExtensionManager {
} }
} }
public GeyserExtension loadExtension(File file, Map<Pattern, ExtensionLoader> loaders) { public GeyserExtension loadExtension(File file, Map<Pattern, GeyserExtensionLoader> loaders) {
for (ExtensionLoader loader : (loaders == null ? this.fileAssociations : loaders).values()) { for (GeyserExtensionLoader loader : (loaders == null ? this.fileAssociations : loaders).values()) {
for (Pattern pattern : loader.getExtensionFilters()) { for (Pattern pattern : loader.extensionFilters()) {
if (pattern.matcher(file.getName()).matches()) { if (pattern.matcher(file.getName()).matches()) {
try { try {
ExtensionDescription description = loader.getExtensionDescription(file); ExtensionDescription description = loader.extensionDescription(file);
if (description != null) { if (description != null) {
GeyserExtension extension = loader.loadExtension(file); GeyserExtension extension = loader.loadExtension(file);
if (extension != null) { if (extension != null) {
this.extensions.put(extension.getDescription().getName(), extension); this.extensions.put(extension.description().name(), extension);
return extension; return extension;
} }
@ -143,9 +144,9 @@ public class ExtensionManager {
Map<String, File> extensions = new LinkedHashMap<>(); Map<String, File> extensions = new LinkedHashMap<>();
Map<String, Extension> loadedExtensions = new LinkedHashMap<>(); Map<String, Extension> loadedExtensions = new LinkedHashMap<>();
for (final ExtensionLoader loader : this.fileAssociations.values()) { for (final GeyserExtensionLoader loader : this.fileAssociations.values()) {
for (File file : dictionary.listFiles((dir, name) -> { for (File file : dictionary.listFiles((dir, name) -> {
for (Pattern pattern : loader.getExtensionFilters()) { for (Pattern pattern : loader.extensionFilters()) {
if (pattern.matcher(name).matches()) { if (pattern.matcher(name).matches()) {
return true; return true;
} }
@ -157,9 +158,9 @@ public class ExtensionManager {
} }
try { try {
ExtensionDescription description = loader.getExtensionDescription(file); ExtensionDescription description = loader.extensionDescription(file);
if (description != null) { if (description != null) {
String name = description.getName(); String name = description.name();
if (extensions.containsKey(name) || this.getExtension(name) != null) { if (extensions.containsKey(name) || this.getExtension(name) != null) {
GeyserImpl.getInstance().getLogger().warning("Found duplicate extension '" + name + "', ignoring '" + file.getName() + "'"); GeyserImpl.getInstance().getLogger().warning("Found duplicate extension '" + name + "', ignoring '" + file.getName() + "'");
@ -168,7 +169,7 @@ public class ExtensionManager {
boolean compatible = false; boolean compatible = false;
for (String version : description.getAPIVersions()) { for (String version : description.ApiVersions()) {
try { try {
//Check the format: majorVersion.minorVersion.patch //Check the format: majorVersion.minorVersion.patch
if (!Pattern.matches("^[0-9]+\\.[0-9]+\\.[0-9]+$", version)) { if (!Pattern.matches("^[0-9]+\\.[0-9]+\\.[0-9]+$", version)) {
@ -217,9 +218,9 @@ public class ExtensionManager {
public void enableExtension(Extension extension) { public void enableExtension(Extension extension) {
if (!extension.isEnabled()) { if (!extension.isEnabled()) {
try { try {
extension.getExtensionLoader().enableExtension(extension); extension.extensionLoader().enableExtension(extension);
} catch (Exception e) { } catch (Exception e) {
GeyserImpl.getInstance().getLogger().error("Error enabling extension " + extension.getName() + ": ", e); GeyserImpl.getInstance().getLogger().error("Error enabling extension " + extension.name() + ": ", e);
this.disableExtension(extension); this.disableExtension(extension);
} }
} }
@ -228,9 +229,9 @@ public class ExtensionManager {
public void disableExtension(Extension extension) { public void disableExtension(Extension extension) {
if (extension.isEnabled()) { if (extension.isEnabled()) {
try { try {
extension.getExtensionLoader().disableExtension(extension); extension.extensionLoader().disableExtension(extension);
} catch (Exception e) { } catch (Exception e) {
GeyserImpl.getInstance().getLogger().error("Error disabling extension " + extension.getName() + ": ", e); GeyserImpl.getInstance().getLogger().error("Error disabling extension " + extension.name() + ": ", e);
} }
} }
} }