diff --git a/connector/pom.xml b/connector/pom.xml
index a3748044..e2c01e64 100644
--- a/connector/pom.xml
+++ b/connector/pom.xml
@@ -129,7 +129,12 @@
org.reflections
reflections
- 0.9.12
+ 0.9.11
+
+
+ org.dom4j
+ dom4j
+ 2.1.3
net.kyori
@@ -232,6 +237,52 @@
+
+ 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
+
+
+
diff --git a/connector/src/main/java/org/geysermc/connector/GeyserConnector.java b/connector/src/main/java/org/geysermc/connector/GeyserConnector.java
index ec332ed6..2593c516 100644
--- a/connector/src/main/java/org/geysermc/connector/GeyserConnector.java
+++ b/connector/src/main/java/org/geysermc/connector/GeyserConnector.java
@@ -163,7 +163,7 @@ public class GeyserConnector {
config.getRemote().setPort(remotePort = Integer.parseInt(record[2]));
logger.debug("Found SRV record \"" + remoteAddress + ":" + remotePort + "\"");
}
- } catch (Exception ex) {
+ } catch (Exception | NoClassDefFoundError ex) { // Check for a NoClassDefFoundError to prevent Android crashes
logger.debug("Exception while trying to find an SRV record for the remote host.");
if (config.isDebugMode())
ex.printStackTrace(); // Otherwise we can get a stack trace for any domain that doesn't have an SRV record
@@ -307,6 +307,18 @@ public class GeyserConnector {
return bootstrap.getWorldManager();
}
+ /**
+ * Get the production status of the current runtime.
+ * Will return true if the version number is not 'DEV'.
+ * Should only happen in compiled jars.
+ *
+ * @return If we are in a production build/environment
+ */
+ public boolean isProduction() {
+ //noinspection ConstantConditions
+ return !"DEV".equals(GeyserConnector.VERSION);
+ }
+
public static GeyserConnector getInstance() {
return instance;
}
diff --git a/connector/src/main/java/org/geysermc/connector/command/defaults/StopCommand.java b/connector/src/main/java/org/geysermc/connector/command/defaults/StopCommand.java
index 636058a0..c69a8705 100644
--- a/connector/src/main/java/org/geysermc/connector/command/defaults/StopCommand.java
+++ b/connector/src/main/java/org/geysermc/connector/command/defaults/StopCommand.java
@@ -49,10 +49,6 @@ public class StopCommand extends GeyserCommand {
return;
}
- connector.shutdown();
-
- if (connector.getPlatformType() == PlatformType.STANDALONE) {
- System.exit(0);
- }
+ connector.getBootstrap().onDisable();
}
}
diff --git a/connector/src/main/java/org/geysermc/connector/common/PlatformType.java b/connector/src/main/java/org/geysermc/connector/common/PlatformType.java
index 7c245c9b..4daa5d37 100644
--- a/connector/src/main/java/org/geysermc/connector/common/PlatformType.java
+++ b/connector/src/main/java/org/geysermc/connector/common/PlatformType.java
@@ -32,6 +32,7 @@ import lombok.Getter;
@AllArgsConstructor
public enum PlatformType {
+ ANDROID("Android"),
BUNGEECORD("BungeeCord"),
SPIGOT("Spigot"),
SPONGE("Sponge"),
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 92d2e910..c4386481 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
@@ -33,6 +33,7 @@ import com.nukkitx.protocol.bedrock.BedrockPacket;
import it.unimi.dsi.fastutil.objects.ObjectArrayList;
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;
@@ -48,7 +49,7 @@ public class PacketTranslatorRegistry {
private static final ObjectArrayList> IGNORED_PACKETS = new ObjectArrayList<>();
static {
- Reflections ref = new Reflections("org.geysermc.connector.network.translators");
+ Reflections ref = GeyserConnector.getInstance().isProduction() ? FileUtils.getReflections("org.geysermc.connector.network.translators") : new Reflections("org.geysermc.connector.network.translators");
for (Class> clazz : ref.getTypesAnnotatedWith(Translator.class)) {
Class> packet = clazz.getAnnotation(Translator.class).packet();
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 dce0f4b4..c0853120 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
@@ -41,6 +41,7 @@ import net.kyori.adventure.text.serializer.legacy.LegacyComponentSerializer;
import org.geysermc.connector.GeyserConnector;
import org.geysermc.connector.network.session.GeyserSession;
import org.geysermc.connector.network.translators.ItemRemapper;
+import org.geysermc.connector.utils.FileUtils;
import org.geysermc.connector.utils.LanguageUtils;
import org.geysermc.connector.utils.MessageUtils;
import org.reflections.Reflections;
@@ -62,7 +63,7 @@ public abstract class ItemTranslator {
static {
/* Load item translators */
- Reflections ref = new Reflections("org.geysermc.connector.network.translators.item");
+ Reflections ref = GeyserConnector.getInstance().isProduction() ? 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)) {
diff --git a/connector/src/main/java/org/geysermc/connector/network/translators/sound/SoundHandlerRegistry.java b/connector/src/main/java/org/geysermc/connector/network/translators/sound/SoundHandlerRegistry.java
index 893975e5..163c451c 100644
--- a/connector/src/main/java/org/geysermc/connector/network/translators/sound/SoundHandlerRegistry.java
+++ b/connector/src/main/java/org/geysermc/connector/network/translators/sound/SoundHandlerRegistry.java
@@ -25,6 +25,8 @@
package org.geysermc.connector.network.translators.sound;
+import org.geysermc.connector.GeyserConnector;
+import org.geysermc.connector.utils.FileUtils;
import org.reflections.Reflections;
import java.util.HashMap;
@@ -38,7 +40,7 @@ public class SoundHandlerRegistry {
static final Map> INTERACTION_HANDLERS = new HashMap<>();
static {
- Reflections ref = new Reflections("org.geysermc.connector.network.translators.sound");
+ Reflections ref = GeyserConnector.getInstance().isProduction() ? FileUtils.getReflections("org.geysermc.connector.network.translators.sound") : new Reflections("org.geysermc.connector.network.translators.sound");
for (Class> clazz : ref.getTypesAnnotatedWith(SoundHandler.class)) {
try {
SoundInteractionHandler> interactionHandler = (SoundInteractionHandler>) clazz.newInstance();
diff --git a/connector/src/main/java/org/geysermc/connector/network/translators/world/block/BlockTranslator.java b/connector/src/main/java/org/geysermc/connector/network/translators/world/block/BlockTranslator.java
index e627b845..8da09f6f 100644
--- a/connector/src/main/java/org/geysermc/connector/network/translators/world/block/BlockTranslator.java
+++ b/connector/src/main/java/org/geysermc/connector/network/translators/world/block/BlockTranslator.java
@@ -106,7 +106,7 @@ public class BlockTranslator {
addedStatesMap.defaultReturnValue(-1);
List paletteList = new ArrayList<>();
- Reflections ref = new Reflections("org.geysermc.connector.network.translators.world.block.entity");
+ Reflections ref = GeyserConnector.getInstance().isProduction() ? FileUtils.getReflections("org.geysermc.connector.network.translators.world.block.entity") : new Reflections("org.geysermc.connector.network.translators.world.block.entity");
ref.getTypesAnnotatedWith(BlockEntity.class);
int waterRuntimeId = -1;
diff --git a/connector/src/main/java/org/geysermc/connector/network/translators/world/block/entity/BlockEntityTranslator.java b/connector/src/main/java/org/geysermc/connector/network/translators/world/block/entity/BlockEntityTranslator.java
index c4401c4c..a538c2dc 100644
--- a/connector/src/main/java/org/geysermc/connector/network/translators/world/block/entity/BlockEntityTranslator.java
+++ b/connector/src/main/java/org/geysermc/connector/network/translators/world/block/entity/BlockEntityTranslator.java
@@ -34,6 +34,7 @@ import com.nukkitx.nbt.NbtMapBuilder;
import it.unimi.dsi.fastutil.objects.ObjectArrayList;
import org.geysermc.connector.GeyserConnector;
import org.geysermc.connector.utils.BlockEntityUtils;
+import org.geysermc.connector.utils.FileUtils;
import org.geysermc.connector.utils.LanguageUtils;
import org.reflections.Reflections;
@@ -66,7 +67,7 @@ public abstract class BlockEntityTranslator {
}
static {
- Reflections ref = new Reflections("org.geysermc.connector.network.translators.world.block.entity");
+ Reflections ref = GeyserConnector.getInstance().isProduction() ? FileUtils.getReflections("org.geysermc.connector.network.translators.world.block.entity") : new Reflections("org.geysermc.connector.network.translators.world.block.entity");
for (Class> clazz : ref.getTypesAnnotatedWith(BlockEntity.class)) {
GeyserConnector.getInstance().getLogger().debug("Found annotated block entity: " + clazz.getCanonicalName());
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 38369d6c..300946b3 100644
--- a/connector/src/main/java/org/geysermc/connector/utils/FileUtils.java
+++ b/connector/src/main/java/org/geysermc/connector/utils/FileUtils.java
@@ -28,11 +28,15 @@ package org.geysermc.connector.utils;
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.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
+import java.net.URL;
import java.util.function.Function;
public class FileUtils {
@@ -140,4 +144,21 @@ public class FileUtils {
}
return stream;
}
+
+ /**
+ * 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());
+ 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 e) { }
+
+ return reflections;
+ }
}
diff --git a/connector/src/main/java/org/geysermc/connector/utils/LocaleUtils.java b/connector/src/main/java/org/geysermc/connector/utils/LocaleUtils.java
index 285846a9..c09af2b7 100644
--- a/connector/src/main/java/org/geysermc/connector/utils/LocaleUtils.java
+++ b/connector/src/main/java/org/geysermc/connector/utils/LocaleUtils.java
@@ -150,7 +150,7 @@ public class LocaleUtils {
// Get the hash and download the locale
String hash = ASSET_MAP.get("minecraft/lang/" + locale + ".json").getHash();
- WebUtils.downloadFile("http://resources.download.minecraft.net/" + hash.substring(0, 2) + "/" + hash, localeFile.toString());
+ WebUtils.downloadFile("https://resources.download.minecraft.net/" + hash.substring(0, 2) + "/" + hash, localeFile.toString());
}
/**
diff --git a/connector/src/main/java/org/geysermc/connector/utils/SkinProvider.java b/connector/src/main/java/org/geysermc/connector/utils/SkinProvider.java
index 5551230b..7c30e48a 100644
--- a/connector/src/main/java/org/geysermc/connector/utils/SkinProvider.java
+++ b/connector/src/main/java/org/geysermc/connector/utils/SkinProvider.java
@@ -119,7 +119,7 @@ public class SkinProvider {
// Schedule Daily Image Expiry if we are caching them
if (GeyserConnector.getInstance().getConfig().getCacheImages() > 0) {
GeyserConnector.getInstance().getGeneralThreadPool().scheduleAtFixedRate(() -> {
- File cacheFolder = Paths.get("cache", "images").toFile();
+ File cacheFolder = GeyserConnector.getInstance().getBootstrap().getConfigFolder().resolve("cache").resolve("images").toFile();
if (!cacheFolder.exists()) {
return;
}
@@ -395,7 +395,7 @@ public class SkinProvider {
BufferedImage image = null;
// First see if we have a cached file. We also update the modification stamp so we know when the file was last used
- File imageFile = Paths.get("cache", "images", UUID.nameUUIDFromBytes(imageUrl.getBytes()).toString() + ".png").toFile();
+ File imageFile = GeyserConnector.getInstance().getBootstrap().getConfigFolder().resolve("cache").resolve("images").resolve(UUID.nameUUIDFromBytes(imageUrl.getBytes()).toString() + ".png").toFile();
if (imageFile.exists()) {
try {
GeyserConnector.getInstance().getLogger().debug("Reading cached image from file " + imageFile.getPath() + " for " + imageUrl);
@@ -600,7 +600,7 @@ public class SkinProvider {
@Getter
public enum CapeProvider {
MINECRAFT,
- OPTIFINE("http://s.optifine.net/capes/%s.png", CapeUrlType.USERNAME),
+ OPTIFINE("https://optifine.net/capes/%s.png", CapeUrlType.USERNAME),
LABYMOD("https://www.labymod.net/page/php/getCapeTexture.php?uuid=%s", CapeUrlType.UUID_DASHED),
FIVEZIG("https://textures.5zigreborn.eu/profile/%s", CapeUrlType.UUID_DASHED),
MINECRAFTCAPES("https://minecraftcapes.net/profile/%s/cape", CapeUrlType.UUID);
diff --git a/connector/src/main/java/org/geysermc/connector/utils/SkinUtils.java b/connector/src/main/java/org/geysermc/connector/utils/SkinUtils.java
index f0b88c43..e3488d6e 100644
--- a/connector/src/main/java/org/geysermc/connector/utils/SkinUtils.java
+++ b/connector/src/main/java/org/geysermc/connector/utils/SkinUtils.java
@@ -150,14 +150,14 @@ public class SkinUtils {
JsonNode textures = skinObject.get("textures");
JsonNode skinTexture = textures.get("SKIN");
- String skinUrl = skinTexture.get("url").asText();
+ String skinUrl = skinTexture.get("url").asText().replace("http://", "https://");
isAlex = skinTexture.has("metadata");
String capeUrl = null;
if (textures.has("CAPE")) {
JsonNode capeTexture = textures.get("CAPE");
- capeUrl = capeTexture.get("url").asText();
+ capeUrl = capeTexture.get("url").asText().replace("http://", "https://");
}
return new GameProfileData(skinUrl, capeUrl, isAlex);