Search in sources :

Example 1 with LanternClassLoader

use of org.lanternpowered.launch.LanternClassLoader in project LanternServer by LanternPowered.

the class AssetRepositoryJsonDeserializer method deserialize.

@Override
public AssetRepository deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context) throws JsonParseException {
    final MultiAssetRepository repository = new MultiAssetRepository();
    // The class loader asset repository will always be present,
    // this cannot be overridden, but the assets themselves can
    // be overridden like the minecraft resource pack system
    final ClassLoaderAssetRepository classLoaderAssetRepository = new ClassLoaderAssetRepository(this.pluginManager);
    repository.add(classLoaderAssetRepository);
    final LanternClassLoader classLoader = LanternClassLoader.get();
    final Consumer<URL> consumer = url -> {
        final Path path = PathUtils.toPath(url);
        if (Files.isDirectory(path) && Files.exists(path.resolve("data-packs.info"))) {
            Lantern.getLogger().debug("Registered a data pack asset repository: " + path);
            repository.add(new PacksAssetRepository(this.pluginManager, path));
        } else {
            classLoaderAssetRepository.addRepository(path);
        }
    };
    classLoader.getBaseURLs().forEach(consumer);
    classLoader.addBaseURLTracker(consumer);
    final JsonArray array = json.getAsJsonArray();
    for (int i = 0; i < array.size(); i++) {
        final JsonObject obj = array.get(i).getAsJsonObject();
        final String type = obj.get("type").getAsString().toLowerCase(Locale.ENGLISH);
        Path path;
        switch(type) {
            // Currently only directory asset repositories
            case "dir":
            case "directory":
                path = Paths.get(obj.get("path").getAsString());
                Lantern.getLogger().debug("Registered a directory asset repository: " + path);
                repository.add(new DirectoryAssetRepository(this.pluginManager, path));
                break;
            // Also support a directory with data/asset packs
            case "packs":
                path = Paths.get(obj.get("path").getAsString());
                Lantern.getLogger().debug("Registered a data pack asset repository: " + path);
                repository.add(new PacksAssetRepository(this.pluginManager, path));
                break;
            default:
                throw new JsonParseException("Unknown repository type: " + type);
        }
        if (!Files.exists(path)) {
            try {
                Files.createDirectories(path);
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }
    return repository;
}
Also used : JsonParseException(com.google.gson.JsonParseException) JsonObject(com.google.gson.JsonObject) Files(java.nio.file.Files) URL(java.net.URL) Preconditions.checkNotNull(com.google.common.base.Preconditions.checkNotNull) MultiAssetRepository(org.lanternpowered.server.asset.MultiAssetRepository) ClassLoaderAssetRepository(org.lanternpowered.server.asset.ClassLoaderAssetRepository) LanternPluginManager(org.lanternpowered.server.plugin.LanternPluginManager) AssetRepository(org.lanternpowered.server.asset.AssetRepository) IOException(java.io.IOException) PathUtils(org.lanternpowered.server.util.PathUtils) JsonDeserializationContext(com.google.gson.JsonDeserializationContext) LanternClassLoader(org.lanternpowered.launch.LanternClassLoader) JsonElement(com.google.gson.JsonElement) Consumer(java.util.function.Consumer) JsonArray(com.google.gson.JsonArray) DirectoryAssetRepository(org.lanternpowered.server.asset.DirectoryAssetRepository) Lantern(org.lanternpowered.server.game.Lantern) Type(java.lang.reflect.Type) Paths(java.nio.file.Paths) Locale(java.util.Locale) JsonDeserializer(com.google.gson.JsonDeserializer) PacksAssetRepository(org.lanternpowered.server.asset.PacksAssetRepository) Path(java.nio.file.Path) Path(java.nio.file.Path) DirectoryAssetRepository(org.lanternpowered.server.asset.DirectoryAssetRepository) LanternClassLoader(org.lanternpowered.launch.LanternClassLoader) MultiAssetRepository(org.lanternpowered.server.asset.MultiAssetRepository) JsonObject(com.google.gson.JsonObject) IOException(java.io.IOException) JsonParseException(com.google.gson.JsonParseException) URL(java.net.URL) JsonArray(com.google.gson.JsonArray) PacksAssetRepository(org.lanternpowered.server.asset.PacksAssetRepository) ClassLoaderAssetRepository(org.lanternpowered.server.asset.ClassLoaderAssetRepository)

Example 2 with LanternClassLoader

use of org.lanternpowered.launch.LanternClassLoader in project LanternServer by LanternPowered.

the class LanternServerLaunch method main.

public void main(String[] args) {
    final LanternClassLoader classLoader = LanternClassLoader.get();
    // Exclude the ASM library
    classLoader.addTransformerExclusion(Exclusion.forPackage("org.objectweb.asm"));
    classLoader.addTransformerExclusion(Exclusion.forPackage("org.lanternpowered.server.transformer"));
    classLoader.addTransformerExclusion(Exclusion.forClass("org.lanternpowered.server.util.BytecodeUtils"));
    classLoader.addTransformer(new FinalFieldClassTransformer());
    classLoader.addTransformer(new FastValueContainerClassTransformer());
    // Get the default logger
    final Logger logger = LoggerFactory.getLogger(InternalPluginsInfo.Implementation.IDENTIFIER);
    try {
        // Create the shared option parser
        final OptionParser optionParser = new OptionParser();
        optionParser.allowsUnrecognizedOptions();
        final OptionSpec<Void> version = optionParser.acceptsAll(Arrays.asList("version", "v"), "Display the Lantern version");
        if (optionParser.parse(args).has(version)) {
            final Package pack = Platform.class.getPackage();
            logger.info(pack.getImplementationTitle() + ' ' + pack.getImplementationVersion());
            logger.info(pack.getSpecificationTitle() + ' ' + pack.getSpecificationVersion());
            return;
        }
        final OptionSpec<Void> help = optionParser.acceptsAll(Arrays.asList("help", "h", "?"), "Show this help text").forHelp();
        // Initialize the injector
        final LanternModule module = new LanternModule(logger, args, optionParser);
        final Injector injector = Guice.createInjector(Stage.DEVELOPMENT, module);
        logger.info("Instantiated the Injector in {} mode.", Environment.get().name().toLowerCase());
        // Create the server instance
        final LanternServer lanternServer = injector.getInstance(LanternServer.class);
        // Initialize and start the server
        lanternServer.initialize();
        try {
            final Field field = OptionParser.class.getDeclaredField("allowsUnrecognizedOptions");
            field.setAccessible(true);
            field.set(optionParser, false);
            optionParser.parse(args);
        } catch (OptionException e) {
            logger.warn("Something went wrong while parsing options", e);
        } catch (Exception e) {
            logger.error("Unexpected error", e);
        }
        // annotations will be detected
        if (optionParser.parse(args).has(help)) {
            if (System.console() != null) {
                // Terminal is (very likely) supported, use the terminal width provided by jline
                final Terminal terminal = TerminalConsoleAppender.getTerminal();
                if (terminal != null) {
                    optionParser.formatHelpWith(new BuiltinHelpFormatter(terminal.getWidth(), 3));
                }
            }
            optionParser.printHelpOn(System.err);
            return;
        }
        lanternServer.start();
    } catch (Throwable t) {
        logger.error("Error during server startup.", t);
        System.exit(1);
    }
}
Also used : LanternClassLoader(org.lanternpowered.launch.LanternClassLoader) OptionException(joptsimple.OptionException) Logger(org.slf4j.Logger) OptionParser(joptsimple.OptionParser) Terminal(org.jline.terminal.Terminal) OptionException(joptsimple.OptionException) Field(java.lang.reflect.Field) BuiltinHelpFormatter(joptsimple.BuiltinHelpFormatter) Injector(com.google.inject.Injector) FastValueContainerClassTransformer(org.lanternpowered.server.transformer.data.FastValueContainerClassTransformer) LanternModule(org.lanternpowered.server.inject.LanternModule) FinalFieldClassTransformer(org.lanternpowered.server.transformer.FinalFieldClassTransformer)

Example 3 with LanternClassLoader

use of org.lanternpowered.launch.LanternClassLoader in project LanternServer by LanternPowered.

the class LanternPluginManager method loadPlugin.

private void loadPlugin(PluginCandidate candidate) {
    final String id = candidate.getId();
    final LanternClassLoader classLoader = LanternClassLoader.get();
    if (candidate.getSource().isPresent()) {
        try {
            classLoader.addBaseURL(candidate.getSource().get().toUri().toURL());
        } catch (MalformedURLException e) {
            throw new RuntimeException("Failed to add plugin '" + id + "' from " + candidate.getDisplaySource() + " to classpath", e);
        }
    }
    final PluginMetadata metadata = candidate.getMetadata();
    checkNotNull(metadata, "metadata");
    final String name = firstNonNull(metadata.getName(), id);
    final String version = firstNonNull(metadata.getVersion(), "unknown");
    try {
        final Class<?> pluginClass = Class.forName(candidate.getPluginClass());
        final PluginContainer container = new LanternPluginContainer(id, this.injector, pluginClass, metadata, candidate.getSource().orElse(null));
        registerPlugin(container);
        registerPluginInstance(container);
        this.eventManager.registerListeners(container, container.getInstance().get());
        this.logger.info("Loaded plugin: {} {} (from {})", name, version, candidate.getDisplaySource());
    } catch (Throwable e) {
        this.logger.error("Failed to load plugin: {} {} (from {})", name, version, candidate.getDisplaySource(), e);
    }
}
Also used : MalformedURLException(java.net.MalformedURLException) LanternClassLoader(org.lanternpowered.launch.LanternClassLoader) PluginContainer(org.spongepowered.api.plugin.PluginContainer) PluginMetadata(org.spongepowered.plugin.meta.PluginMetadata)

Example 4 with LanternClassLoader

use of org.lanternpowered.launch.LanternClassLoader in project LanternServer by LanternPowered.

the class FastValueContainerCheckerClassVisitor method isCompositeValueStore0.

private static int isCompositeValueStore0(String className) {
    // directly return true
    if (className.equals(COMPOSITE_VALUE_STORE_NAME)) {
        return 1;
    } else if (className.equals(I_COMPOSITE_VALUE_STORE_NAME)) {
        return 2;
    // Don't process java packages
    } else if (className.startsWith("java.")) {
        return 0;
    }
    final LanternClassLoader classLoader = LanternClassLoader.get();
    // If the class is already loaded, we might as well use it
    final Class<?> c = classLoader.getLoadedClass(className.replace('/', '.')).orElse(null);
    if (c != null) {
        return ICompositeValueStore.class.isAssignableFrom(c) ? 2 : CompositeValueStore.class.isAssignableFrom(c) ? 1 : 0;
    }
    try {
        // Read the bytecode of the class we need to analyze
        final byte[] byteCode = classLoader.readByteCode(className);
        // Also check for interfaces, super classes, etc.
        final ClassReader classReader = new ClassReader(byteCode);
        final FastValueContainerCheckerClassVisitor classVisitor = new FastValueContainerCheckerClassVisitor(null, false);
        classReader.accept(classVisitor, ClassReader.SKIP_CODE | ClassReader.SKIP_FRAMES | ClassReader.SKIP_DEBUG);
        return classVisitor.result;
    } catch (ClassNotFoundException e) {
        throw new RuntimeException(e);
    }
}
Also used : LanternClassLoader(org.lanternpowered.launch.LanternClassLoader) ClassReader(org.objectweb.asm.ClassReader) ICompositeValueStore(org.lanternpowered.server.data.ICompositeValueStore)

Aggregations

LanternClassLoader (org.lanternpowered.launch.LanternClassLoader)4 Preconditions.checkNotNull (com.google.common.base.Preconditions.checkNotNull)1 JsonArray (com.google.gson.JsonArray)1 JsonDeserializationContext (com.google.gson.JsonDeserializationContext)1 JsonDeserializer (com.google.gson.JsonDeserializer)1 JsonElement (com.google.gson.JsonElement)1 JsonObject (com.google.gson.JsonObject)1 JsonParseException (com.google.gson.JsonParseException)1 Injector (com.google.inject.Injector)1 IOException (java.io.IOException)1 Field (java.lang.reflect.Field)1 Type (java.lang.reflect.Type)1 MalformedURLException (java.net.MalformedURLException)1 URL (java.net.URL)1 Files (java.nio.file.Files)1 Path (java.nio.file.Path)1 Paths (java.nio.file.Paths)1 Locale (java.util.Locale)1 Consumer (java.util.function.Consumer)1 BuiltinHelpFormatter (joptsimple.BuiltinHelpFormatter)1