From ff280ef19216a5b6fdaebcc5b375b82fe418afb2 Mon Sep 17 00:00:00 2001 From: RednedEpic Date: Sat, 17 Jul 2021 13:36:04 -0500 Subject: [PATCH] Replace Reflections usage with an annotation processor Reduces jar size by about 1.5-2mb --- ap/pom.xml | 14 ++ .../processor/BlockEntityProcessor.java | 38 +++++ .../geysermc/processor/ClassProcessor.java | 151 ++++++++++++++++++ .../processor/CollisionRemapperProcessor.java | 38 +++++ .../processor/ItemRemapperProcessor.java | 38 +++++ .../processor/PacketTranslatorProcessor.java | 38 +++++ .../processor/SoundHandlerProcessor.java | 38 +++++ bootstrap/bungeecord/pom.xml | 8 - bootstrap/pom.xml | 10 ++ bootstrap/spigot/pom.xml | 8 - bootstrap/sponge/pom.xml | 8 - bootstrap/velocity/pom.xml | 8 - connector/pom.xml | 66 +------- .../geysermc/connector/GeyserConnector.java | 12 -- .../translators/PacketTranslatorRegistry.java | 5 +- .../translators/item/ItemTranslator.java | 5 +- .../connector/registry/Registries.java | 6 +- .../loader/AnnotatedRegistryLoader.java | 5 +- .../loader/CollisionRegistryLoader.java | 4 +- .../geysermc/connector/utils/FileUtils.java | 62 ++++--- .../javax.annotation.processing.Processor | 5 + pom.xml | 1 + 22 files changed, 424 insertions(+), 144 deletions(-) create mode 100644 ap/pom.xml create mode 100644 ap/src/main/java/org/geysermc/processor/BlockEntityProcessor.java create mode 100644 ap/src/main/java/org/geysermc/processor/ClassProcessor.java create mode 100644 ap/src/main/java/org/geysermc/processor/CollisionRemapperProcessor.java create mode 100644 ap/src/main/java/org/geysermc/processor/ItemRemapperProcessor.java create mode 100644 ap/src/main/java/org/geysermc/processor/PacketTranslatorProcessor.java create mode 100644 ap/src/main/java/org/geysermc/processor/SoundHandlerProcessor.java create mode 100644 connector/src/main/resources/META-INF/services/javax.annotation.processing.Processor diff --git a/ap/pom.xml b/ap/pom.xml new file mode 100644 index 000000000..7e263c0d1 --- /dev/null +++ b/ap/pom.xml @@ -0,0 +1,14 @@ + + + 4.0.0 + + org.geysermc + geyser-parent + 1.4.1-SNAPSHOT + + + ap + 1.4.1-SNAPSHOT + \ No newline at end of file diff --git a/ap/src/main/java/org/geysermc/processor/BlockEntityProcessor.java b/ap/src/main/java/org/geysermc/processor/BlockEntityProcessor.java new file mode 100644 index 000000000..52a6e3aae --- /dev/null +++ b/ap/src/main/java/org/geysermc/processor/BlockEntityProcessor.java @@ -0,0 +1,38 @@ +/* + * Copyright (c) 2019-2021 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.processor; + +import javax.annotation.processing.SupportedAnnotationTypes; +import javax.annotation.processing.SupportedSourceVersion; +import javax.lang.model.SourceVersion; + +@SupportedAnnotationTypes("org.geysermc.connector.network.translators.world.block.entity.BlockEntity") +@SupportedSourceVersion(SourceVersion.RELEASE_8) +public class BlockEntityProcessor extends ClassProcessor { + public BlockEntityProcessor() { + super("org.geysermc.connector.network.translators.world.block.entity.BlockEntity"); + } +} diff --git a/ap/src/main/java/org/geysermc/processor/ClassProcessor.java b/ap/src/main/java/org/geysermc/processor/ClassProcessor.java new file mode 100644 index 000000000..3531d8794 --- /dev/null +++ b/ap/src/main/java/org/geysermc/processor/ClassProcessor.java @@ -0,0 +1,151 @@ +/* + * Copyright (c) 2019-2021 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.processor; + +import javax.annotation.processing.AbstractProcessor; +import javax.annotation.processing.ProcessingEnvironment; +import javax.annotation.processing.RoundEnvironment; +import javax.lang.model.element.AnnotationMirror; +import javax.lang.model.element.Element; +import javax.lang.model.element.ElementKind; +import javax.lang.model.element.TypeElement; +import javax.tools.Diagnostic; +import javax.tools.FileObject; +import javax.tools.StandardLocation; +import java.io.BufferedWriter; +import java.io.IOException; +import java.nio.file.Files; +import java.nio.file.Path; +import java.nio.file.Paths; +import java.util.ArrayList; +import java.util.Collection; +import java.util.List; +import java.util.Set; + +public class ClassProcessor extends AbstractProcessor { + private final String annotationClassName; + + private Path outputPath; + + private final List locations = new ArrayList<>(); + + public ClassProcessor(String annotationClassName) { + this.annotationClassName = annotationClassName; + } + + @Override + public synchronized void init(ProcessingEnvironment processingEnv) { + super.init(processingEnv); + + this.processingEnv.getMessager().printMessage(Diagnostic.Kind.NOTE, "Initializing processor " + this.annotationClassName); + + String outputFile = processingEnv.getOptions().get("metadataOutputFile"); + if (outputFile != null && !outputFile.isEmpty()) { + this.outputPath = Paths.get(outputFile); + } + } + + @Override + public boolean process(Set annotations, RoundEnvironment roundEnv) { + if (roundEnv.processingOver()) { + if (!roundEnv.errorRaised()) { + complete(); + } + + return false; + } + + if (!contains(annotations, this.annotationClassName)) { + return false; + } + + for (Element element : roundEnv.getRootElements()) { + if (element.getKind() != ElementKind.CLASS) { + continue; + } + + if (!contains(element.getAnnotationMirrors(), this.annotationClassName)) { + continue; + } + + TypeElement typeElement = (TypeElement) element; + this.locations.add(typeElement.getQualifiedName().toString()); + } + return true; + } + + public boolean contains(Collection elements, String className) { + if (elements.isEmpty()) { + return false; + } + + for (TypeElement element : elements) { + if (element.getQualifiedName().contentEquals(className)) { + return true; + } + } + + return false; + } + + public boolean contains(List elements, String className) { + if (elements.isEmpty()) { + return false; + } + + for (AnnotationMirror element : elements) { + if (element.getAnnotationType().toString().equals(className)) { + return true; + } + } + + return false; + } + + public void complete() { + try (BufferedWriter writer = this.createWriter()) { + for (String location : this.locations) { + writer.write(location); + writer.newLine(); + } + } catch (IOException ex) { + ex.printStackTrace(); + } + + this.processingEnv.getMessager().printMessage(Diagnostic.Kind.NOTE, "Completed processing for " + this.annotationClassName); + } + + private BufferedWriter createWriter() throws IOException { + if (this.outputPath != null) { + this.processingEnv.getMessager().printMessage(Diagnostic.Kind.NOTE, "Writing " + this.annotationClassName + " to " + this.outputPath); + return Files.newBufferedWriter(this.outputPath); + } + + FileObject obj = this.processingEnv.getFiler().createResource(StandardLocation.CLASS_OUTPUT, "", this.annotationClassName); + this.processingEnv.getMessager().printMessage(Diagnostic.Kind.NOTE, "Writing " + this.annotationClassName + " to " + obj.toUri()); + return new BufferedWriter(obj.openWriter()); + } +} diff --git a/ap/src/main/java/org/geysermc/processor/CollisionRemapperProcessor.java b/ap/src/main/java/org/geysermc/processor/CollisionRemapperProcessor.java new file mode 100644 index 000000000..3f9111155 --- /dev/null +++ b/ap/src/main/java/org/geysermc/processor/CollisionRemapperProcessor.java @@ -0,0 +1,38 @@ +/* + * Copyright (c) 2019-2021 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.processor; + +import javax.annotation.processing.SupportedAnnotationTypes; +import javax.annotation.processing.SupportedSourceVersion; +import javax.lang.model.SourceVersion; + +@SupportedAnnotationTypes("org.geysermc.connector.network.translators.collision.CollisionRemapper") +@SupportedSourceVersion(SourceVersion.RELEASE_8) +public class CollisionRemapperProcessor extends ClassProcessor { + public CollisionRemapperProcessor() { + super("org.geysermc.connector.network.translators.collision.CollisionRemapper"); + } +} diff --git a/ap/src/main/java/org/geysermc/processor/ItemRemapperProcessor.java b/ap/src/main/java/org/geysermc/processor/ItemRemapperProcessor.java new file mode 100644 index 000000000..cbfd939c4 --- /dev/null +++ b/ap/src/main/java/org/geysermc/processor/ItemRemapperProcessor.java @@ -0,0 +1,38 @@ +/* + * Copyright (c) 2019-2021 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.processor; + +import javax.annotation.processing.SupportedAnnotationTypes; +import javax.annotation.processing.SupportedSourceVersion; +import javax.lang.model.SourceVersion; + +@SupportedAnnotationTypes("org.geysermc.connector.network.translators.ItemRemapper") +@SupportedSourceVersion(SourceVersion.RELEASE_8) +public class ItemRemapperProcessor extends ClassProcessor { + public ItemRemapperProcessor() { + super("org.geysermc.connector.network.translators.ItemRemapper"); + } +} diff --git a/ap/src/main/java/org/geysermc/processor/PacketTranslatorProcessor.java b/ap/src/main/java/org/geysermc/processor/PacketTranslatorProcessor.java new file mode 100644 index 000000000..cdfbcbe4a --- /dev/null +++ b/ap/src/main/java/org/geysermc/processor/PacketTranslatorProcessor.java @@ -0,0 +1,38 @@ +/* + * Copyright (c) 2019-2021 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.processor; + +import javax.annotation.processing.SupportedAnnotationTypes; +import javax.annotation.processing.SupportedSourceVersion; +import javax.lang.model.SourceVersion; + +@SupportedAnnotationTypes("org.geysermc.connector.network.translators.Translator") +@SupportedSourceVersion(SourceVersion.RELEASE_8) +public class PacketTranslatorProcessor extends ClassProcessor { + public PacketTranslatorProcessor() { + super("org.geysermc.connector.network.translators.Translator"); + } +} diff --git a/ap/src/main/java/org/geysermc/processor/SoundHandlerProcessor.java b/ap/src/main/java/org/geysermc/processor/SoundHandlerProcessor.java new file mode 100644 index 000000000..ee4b2ef45 --- /dev/null +++ b/ap/src/main/java/org/geysermc/processor/SoundHandlerProcessor.java @@ -0,0 +1,38 @@ +/* + * Copyright (c) 2019-2021 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.processor; + +import javax.annotation.processing.SupportedAnnotationTypes; +import javax.annotation.processing.SupportedSourceVersion; +import javax.lang.model.SourceVersion; + +@SupportedAnnotationTypes("org.geysermc.connector.network.translators.sound.SoundHandler") +@SupportedSourceVersion(SourceVersion.RELEASE_8) +public class SoundHandlerProcessor extends ClassProcessor { + public SoundHandlerProcessor() { + super("org.geysermc.connector.network.translators.sound.SoundHandler"); + } +} diff --git a/bootstrap/bungeecord/pom.xml b/bootstrap/bungeecord/pom.xml index 0f13390d5..839b8982c 100644 --- a/bootstrap/bungeecord/pom.xml +++ b/bootstrap/bungeecord/pom.xml @@ -71,10 +71,6 @@ io.netty.channel.kqueue org.geysermc.platform.bungeecord.shaded.io.netty.channel.kqueue - - org.reflections - org.geysermc.platform.bungeecord.shaded.reflections - com.google.common org.geysermc.platform.bungeecord.shaded.google.common @@ -83,10 +79,6 @@ com.google.guava org.geysermc.platform.bungeecord.shaded.google.guava - - org.dom4j - org.geysermc.platform.bungeecord.shaded.dom4j - net.kyori org.geysermc.platform.bungeecord.shaded.kyori diff --git a/bootstrap/pom.xml b/bootstrap/pom.xml index 98a08ee31..6bbd1a0b6 100644 --- a/bootstrap/pom.xml +++ b/bootstrap/pom.xml @@ -29,6 +29,16 @@ https://repo.velocitypowered.com/snapshots/ + + + + org.geysermc + ap + 1.4.1-SNAPSHOT + provided + + + bungeecord spigot diff --git a/bootstrap/spigot/pom.xml b/bootstrap/spigot/pom.xml index 133ea7779..4277dc235 100644 --- a/bootstrap/spigot/pom.xml +++ b/bootstrap/spigot/pom.xml @@ -83,10 +83,6 @@ com.fasterxml.jackson org.geysermc.platform.spigot.shaded.jackson - - org.reflections - org.geysermc.platform.spigot.shaded.reflections - com.google.common org.geysermc.platform.spigot.shaded.google.common @@ -95,10 +91,6 @@ com.google.guava org.geysermc.platform.spigot.shaded.google.guava - - org.dom4j - org.geysermc.platform.spigot.shaded.dom4j - net.kyori org.geysermc.platform.spigot.shaded.kyori diff --git a/bootstrap/sponge/pom.xml b/bootstrap/sponge/pom.xml index e0f019152..77f4fe78a 100644 --- a/bootstrap/sponge/pom.xml +++ b/bootstrap/sponge/pom.xml @@ -69,10 +69,6 @@ it.unimi.dsi.fastutil org.geysermc.platform.sponge.shaded.fastutil - - org.reflections - org.geysermc.platform.sponge.shaded.reflections - com.google.common org.geysermc.platform.sponge.shaded.google.common @@ -81,10 +77,6 @@ com.google.guava org.geysermc.platform.sponge.shaded.google.guava - - org.dom4j - org.geysermc.platform.sponge.shaded.dom4j - net.kyori org.geysermc.platform.sponge.shaded.kyori diff --git a/bootstrap/velocity/pom.xml b/bootstrap/velocity/pom.xml index c67f5a628..5c12b6a46 100644 --- a/bootstrap/velocity/pom.xml +++ b/bootstrap/velocity/pom.xml @@ -65,10 +65,6 @@ it.unimi.dsi.fastutil org.geysermc.platform.velocity.shaded.fastutil - - org.reflections - org.geysermc.platform.velocity.shaded.reflections - com.google.common org.geysermc.platform.velocity.shaded.google.common @@ -77,10 +73,6 @@ com.google.guava org.geysermc.platform.velocity.shaded.google.guava - - org.dom4j - org.geysermc.platform.velocity.shaded.dom4j - net.kyori.adventure.text.serializer.gson.legacyimpl org.geysermc.platform.velocity.shaded.kyori.legacyimpl diff --git a/connector/pom.xml b/connector/pom.xml index 6849066d9..e6cc1c302 100644 --- a/connector/pom.xml +++ b/connector/pom.xml @@ -18,6 +18,12 @@ + + org.geysermc + ap + 1.4.1-SNAPSHOT + provided + org.geysermc common @@ -207,18 +213,6 @@ osx-x86_64 - - org.reflections - reflections - 0.9.11 - compile - - - org.dom4j - dom4j - 2.1.3 - compile - net.kyori @@ -342,54 +336,6 @@ - - org.codehaus.gmavenplus - gmavenplus-plugin - 1.9.1 - - - process-classes - - execute - - - - - - - - - - - org.reflections - reflections - 0.9.11 - - - org.dom4j - dom4j - 2.1.3 - - - org.codehaus.groovy - groovy-all - 3.0.5 - runtime - pom - - - org.apache.maven.plugins maven-surefire-plugin diff --git a/connector/src/main/java/org/geysermc/connector/GeyserConnector.java b/connector/src/main/java/org/geysermc/connector/GeyserConnector.java index 291f2d7e5..173e41573 100644 --- a/connector/src/main/java/org/geysermc/connector/GeyserConnector.java +++ b/connector/src/main/java/org/geysermc/connector/GeyserConnector.java @@ -524,18 +524,6 @@ public class GeyserConnector { return !"DEV".equals(GeyserConnector.VERSION); } - /** - * Whether to use XML reflections in the jar or manually find the reflections. - * Will return true if in production and the platform is not Fabric. - * On Fabric - it complains about being unable to create a default XMLReader. - * On other platforms this should only be true in compiled jars. - * - * @return whether to use XML reflections - */ - public boolean useXmlReflections() { - return !this.getPlatformType().equals(PlatformType.FABRIC) && isProductionEnvironment(); - } - public static GeyserConnector getInstance() { return instance; } diff --git a/connector/src/main/java/org/geysermc/connector/network/translators/PacketTranslatorRegistry.java b/connector/src/main/java/org/geysermc/connector/network/translators/PacketTranslatorRegistry.java index 2469f65da..20c40a785 100644 --- a/connector/src/main/java/org/geysermc/connector/network/translators/PacketTranslatorRegistry.java +++ b/connector/src/main/java/org/geysermc/connector/network/translators/PacketTranslatorRegistry.java @@ -35,7 +35,6 @@ import org.geysermc.connector.GeyserConnector; import org.geysermc.connector.network.session.GeyserSession; import org.geysermc.connector.utils.FileUtils; import org.geysermc.connector.utils.LanguageUtils; -import org.reflections.Reflections; import java.util.HashMap; import java.util.Map; @@ -49,9 +48,7 @@ public class PacketTranslatorRegistry { private static final ObjectArrayList> IGNORED_PACKETS = new ObjectArrayList<>(); static { - Reflections ref = GeyserConnector.getInstance().useXmlReflections() ? FileUtils.getReflections("org.geysermc.connector.network.translators") : new Reflections("org.geysermc.connector.network.translators"); - - for (Class clazz : ref.getTypesAnnotatedWith(Translator.class)) { + for (Class clazz : FileUtils.getGeneratedClassesForAnnotation(Translator.class)) { Class packet = clazz.getAnnotation(Translator.class).packet(); GeyserConnector.getInstance().getLogger().debug("Found annotated translator: " + clazz.getCanonicalName() + " : " + packet.getSimpleName()); diff --git a/connector/src/main/java/org/geysermc/connector/network/translators/item/ItemTranslator.java b/connector/src/main/java/org/geysermc/connector/network/translators/item/ItemTranslator.java index c4d098f79..0fdfc3cc7 100644 --- a/connector/src/main/java/org/geysermc/connector/network/translators/item/ItemTranslator.java +++ b/connector/src/main/java/org/geysermc/connector/network/translators/item/ItemTranslator.java @@ -43,7 +43,6 @@ import org.geysermc.connector.registry.type.ItemMapping; import org.geysermc.connector.registry.type.ItemMappings; import org.geysermc.connector.utils.FileUtils; import org.geysermc.connector.utils.LocaleUtils; -import org.reflections.Reflections; import java.util.*; import java.util.stream.Collectors; @@ -61,10 +60,8 @@ public abstract class ItemTranslator { static { /* Load item translators */ - Reflections ref = GeyserConnector.getInstance().useXmlReflections() ? FileUtils.getReflections("org.geysermc.connector.network.translators.item") : new Reflections("org.geysermc.connector.network.translators.item"); - Map loadedNbtItemTranslators = new HashMap<>(); - for (Class clazz : ref.getTypesAnnotatedWith(ItemRemapper.class)) { + for (Class clazz : FileUtils.getGeneratedClassesForAnnotation(ItemRemapper.class)) { int priority = clazz.getAnnotation(ItemRemapper.class).priority(); GeyserConnector.getInstance().getLogger().debug("Found annotated item translator: " + clazz.getCanonicalName()); diff --git a/connector/src/main/java/org/geysermc/connector/registry/Registries.java b/connector/src/main/java/org/geysermc/connector/registry/Registries.java index 6a0498a79..bd6520b38 100644 --- a/connector/src/main/java/org/geysermc/connector/registry/Registries.java +++ b/connector/src/main/java/org/geysermc/connector/registry/Registries.java @@ -55,9 +55,9 @@ import java.util.Set; public class Registries { public static final SimpleRegistry BIOMES = SimpleRegistry.create("bedrock/biome_definitions.dat", RegistryLoaders.NBT); - public static final SimpleMappedRegistry BLOCK_ENTITIES = SimpleMappedRegistry.create("org.geysermc.connector.network.translators.world.block.entity", BlockEntityRegistryLoader::new); + public static final SimpleMappedRegistry BLOCK_ENTITIES = SimpleMappedRegistry.create("org.geysermc.connector.network.translators.world.block.entity.BlockEntity", BlockEntityRegistryLoader::new); - public static final SimpleMappedRegistry COLLISIONS = SimpleMappedRegistry.create(Pair.of("org.geysermc.connector.network.translators.collision.translators", "mappings/collision.json"), CollisionRegistryLoader::new); + public static final SimpleMappedRegistry COLLISIONS = SimpleMappedRegistry.create(Pair.of("org.geysermc.connector.network.translators.collision.translators.Translator", "mappings/collision.json"), CollisionRegistryLoader::new); public static final VersionedRegistry>> CRAFTING_DATA = VersionedRegistry.create(RegistryLoaders.empty(Int2ObjectOpenHashMap::new)); @@ -77,7 +77,7 @@ public class Registries { public static final SimpleMappedRegistry SOUND_EFFECTS = SimpleMappedRegistry.create("mappings/effects.json", SoundEffectsRegistryLoader::new); - public static final SimpleMappedRegistry> SOUND_HANDLERS = SimpleMappedRegistry.create("org.geysermc.connector.network.translators.sound", SoundHandlerRegistryLoader::new); + public static final SimpleMappedRegistry> SOUND_HANDLERS = SimpleMappedRegistry.create("org.geysermc.connector.network.translators.sound.SoundHandler", SoundHandlerRegistryLoader::new); public static void init() { // no-op diff --git a/connector/src/main/java/org/geysermc/connector/registry/loader/AnnotatedRegistryLoader.java b/connector/src/main/java/org/geysermc/connector/registry/loader/AnnotatedRegistryLoader.java index 4f6354af5..9f93b3873 100644 --- a/connector/src/main/java/org/geysermc/connector/registry/loader/AnnotatedRegistryLoader.java +++ b/connector/src/main/java/org/geysermc/connector/registry/loader/AnnotatedRegistryLoader.java @@ -26,9 +26,7 @@ package org.geysermc.connector.registry.loader; import it.unimi.dsi.fastutil.objects.Object2ObjectOpenHashMap; -import org.geysermc.connector.GeyserConnector; import org.geysermc.connector.utils.FileUtils; -import org.reflections.Reflections; import java.lang.annotation.Annotation; import java.util.Map; @@ -46,8 +44,7 @@ public class AnnotatedRegistryLoader implements Regi @Override public Map load(String input) { Map entries = new Object2ObjectOpenHashMap<>(); - Reflections ref = GeyserConnector.getInstance().useXmlReflections() ? FileUtils.getReflections(input) : new Reflections(input); - for (Class clazz : ref.getTypesAnnotatedWith(this.annotation)) { + for (Class clazz : FileUtils.getGeneratedClassesForAnnotation(input)) { try { entries.put(this.mapper.apply(clazz.getAnnotation(this.annotation)), (V) clazz.newInstance()); } catch (InstantiationException | IllegalAccessException ex) { diff --git a/connector/src/main/java/org/geysermc/connector/registry/loader/CollisionRegistryLoader.java b/connector/src/main/java/org/geysermc/connector/registry/loader/CollisionRegistryLoader.java index 70ba8b253..b20e1fe0e 100644 --- a/connector/src/main/java/org/geysermc/connector/registry/loader/CollisionRegistryLoader.java +++ b/connector/src/main/java/org/geysermc/connector/registry/loader/CollisionRegistryLoader.java @@ -40,7 +40,6 @@ import org.geysermc.connector.network.translators.collision.translators.OtherCol import org.geysermc.connector.network.translators.collision.translators.SolidCollision; import org.geysermc.connector.registry.BlockRegistries; import org.geysermc.connector.utils.FileUtils; -import org.reflections.Reflections; import java.io.InputStream; import java.lang.reflect.InvocationTargetException; @@ -55,8 +54,7 @@ public class CollisionRegistryLoader extends MultiResourceRegistryLoader collisions = new Int2ObjectOpenHashMap<>(); Map, CollisionInfo> annotationMap = new HashMap<>(); - Reflections ref = GeyserConnector.getInstance().useXmlReflections() ? FileUtils.getReflections(input.key()) : new Reflections(input.key()); - for (Class clazz : ref.getTypesAnnotatedWith(CollisionRemapper.class)) { + for (Class clazz : FileUtils.getGeneratedClassesForAnnotation(CollisionRemapper.class.getName())) { GeyserConnector.getInstance().getLogger().debug("Found annotated collision translator: " + clazz.getCanonicalName()); CollisionRemapper collisionRemapper = clazz.getAnnotation(CollisionRemapper.class); diff --git a/connector/src/main/java/org/geysermc/connector/utils/FileUtils.java b/connector/src/main/java/org/geysermc/connector/utils/FileUtils.java index 3fb5c2ebb..3369f16a5 100644 --- a/connector/src/main/java/org/geysermc/connector/utils/FileUtils.java +++ b/connector/src/main/java/org/geysermc/connector/utils/FileUtils.java @@ -30,16 +30,15 @@ import com.fasterxml.jackson.databind.DeserializationFeature; import com.fasterxml.jackson.databind.ObjectMapper; import com.fasterxml.jackson.dataformat.yaml.YAMLFactory; import org.geysermc.connector.GeyserConnector; -import org.reflections.Reflections; -import org.reflections.serializers.XmlSerializer; -import org.reflections.util.ConfigurationBuilder; import java.io.*; -import java.net.URL; +import java.lang.annotation.Annotation; import java.nio.charset.StandardCharsets; import java.nio.file.Files; import java.security.MessageDigest; +import java.util.Set; import java.util.function.Function; +import java.util.stream.Collectors; public class FileUtils { @@ -193,24 +192,6 @@ public class FileUtils { return sha1; } - /** - * Get the stored reflection data for a given path - * - * @param path The path to get the reflection data for - * @return The created Reflections object - */ - public static Reflections getReflections(String path) { - Reflections reflections = new Reflections(new ConfigurationBuilder().setScanners()); - XmlSerializer serializer = new XmlSerializer(); - URL resource = FileUtils.class.getClassLoader().getResource("META-INF/reflections/" + path + "-reflections.xml"); - try (InputStream inputStream = resource.openConnection().getInputStream()) { - reflections.merge(serializer.read(inputStream)); - } catch (IOException ignored) { - } - - return reflections; - } - /** * An android compatible version of {@link Files#readAllBytes} * @@ -242,4 +223,41 @@ public class FileUtils { throw new RuntimeException("Error while trying to read input stream!"); } } + + /** + * Returns a set of all the classes that are annotated by a given annotation. + * Keep in mind that these are from a set of generated annotations generated + * at compile time by the annotation processor, meaning that arbitrary annotations + * cannot be passed into this method and expected to have a set of classes + * returned back. + * + * @param annotationClass the annotation class + * @return a set of all the classes annotated by the given annotation + */ + public static Set> getGeneratedClassesForAnnotation(Class annotationClass) { + return getGeneratedClassesForAnnotation(annotationClass.getName()); + } + + /** + * Returns a set of all the classes that are annotated by a given annotation. + * Keep in mind that these are from a set of generated annotations generated + * at compile time by the annotation processor, meaning that arbitrary annotations + * cannot be passed into this method and expected to have a set of classes + * returned back. + * + * @param input the fully qualified name of the annotation + * @return a set of all the classes annotated by the given annotation + */ + public static Set> getGeneratedClassesForAnnotation(String input) { + InputStream annotatedClass = FileUtils.getResource(input); + BufferedReader reader = new BufferedReader(new InputStreamReader(annotatedClass)); + return reader.lines().map(className -> { + try { + return Class.forName(className); + } catch (ClassNotFoundException ex) { + GeyserConnector.getInstance().getLogger().error("Failed to find class " + className, ex); + throw new RuntimeException(ex); + } + }).collect(Collectors.toSet()); + } } diff --git a/connector/src/main/resources/META-INF/services/javax.annotation.processing.Processor b/connector/src/main/resources/META-INF/services/javax.annotation.processing.Processor new file mode 100644 index 000000000..463d1efad --- /dev/null +++ b/connector/src/main/resources/META-INF/services/javax.annotation.processing.Processor @@ -0,0 +1,5 @@ +org.geysermc.processor.BlockEntityProcessor +org.geysermc.processor.CollisionRemapperProcessor +org.geysermc.processor.ItemRemapperProcessor +org.geysermc.processor.PacketTranslatorProcessor +org.geysermc.processor.SoundHandlerProcessor \ No newline at end of file diff --git a/pom.xml b/pom.xml index c03efb782..f8ab9165f 100644 --- a/pom.xml +++ b/pom.xml @@ -31,6 +31,7 @@ + ap bootstrap common connector