3
0
Mirror von https://github.com/GeyserMC/Geyser.git synchronisiert 2024-12-26 08:10:11 +01:00

Tweaks to support Android (#1206)

* Downgrade reflections to 0.9.11

* Add comment explaining downgrade

* Move to pre-build reflections

* Update skins to use https and relative cache dir

* Move to https OptiFine cape url

* Add javadoc to isProduction

* Add ANDROID as a platform type

* Re-ordered PlatformType

* Change stop command to call onDisable
Dieser Commit ist enthalten in:
rtm516 2020-08-28 19:36:24 +01:00 committet von GitHub
Ursprung 1c84993853
Commit 79bf56a75c
Es konnte kein GPG-Schlüssel zu dieser Signatur gefunden werden
GPG-Schlüssel-ID: 4AEE18F83AFDEB23
13 geänderte Dateien mit 104 neuen und 18 gelöschten Zeilen

Datei anzeigen

@ -129,7 +129,12 @@
<dependency> <dependency>
<groupId>org.reflections</groupId> <groupId>org.reflections</groupId>
<artifactId>reflections</artifactId> <artifactId>reflections</artifactId>
<version>0.9.12</version> <version>0.9.11</version> <!-- This isn't the latest version to get round https://github.com/ronmamo/reflections/issues/273 -->
</dependency>
<dependency>
<groupId>org.dom4j</groupId>
<artifactId>dom4j</artifactId>
<version>2.1.3</version>
</dependency> </dependency>
<dependency> <dependency>
<groupId>net.kyori</groupId> <groupId>net.kyori</groupId>
@ -232,6 +237,52 @@
</execution> </execution>
</executions> </executions>
</plugin> </plugin>
<plugin>
<groupId>org.codehaus.gmavenplus</groupId>
<artifactId>gmavenplus-plugin</artifactId>
<version>1.9.1</version>
<executions>
<execution>
<phase>process-classes</phase>
<goals>
<goal>execute</goal>
</goals>
<configuration>
<scripts>
<script><![CDATA[
new org.reflections.Reflections("org.geysermc.connector.network.translators")
.save("${project.artifactId}/target/classes/META-INF/reflections/org.geysermc.connector.network.translators-reflections.xml")
new org.reflections.Reflections("org.geysermc.connector.network.translators.item")
.save("${project.artifactId}/target/classes/META-INF/reflections/org.geysermc.connector.network.translators.item-reflections.xml")
new org.reflections.Reflections("org.geysermc.connector.network.translators.sound")
.save("${project.artifactId}/target/classes/META-INF/reflections/org.geysermc.connector.network.translators.sound-reflections.xml")
new org.reflections.Reflections("org.geysermc.connector.network.translators.world.block.entity")
.save("${project.artifactId}/target/classes/META-INF/reflections/org.geysermc.connector.network.translators.world.block.entity-reflections.xml")
]]></script>
</scripts>
</configuration>
</execution>
</executions>
<dependencies>
<dependency>
<groupId>org.reflections</groupId>
<artifactId>reflections</artifactId>
<version>0.9.11</version>
</dependency>
<dependency>
<groupId>org.dom4j</groupId>
<artifactId>dom4j</artifactId>
<version>2.1.3</version>
</dependency>
<dependency>
<groupId>org.codehaus.groovy</groupId>
<artifactId>groovy-all</artifactId>
<version>3.0.5</version>
<scope>runtime</scope>
<type>pom</type>
</dependency>
</dependencies>
</plugin>
</plugins> </plugins>
</build> </build>
</project> </project>

Datei anzeigen

@ -163,7 +163,7 @@ public class GeyserConnector {
config.getRemote().setPort(remotePort = Integer.parseInt(record[2])); config.getRemote().setPort(remotePort = Integer.parseInt(record[2]));
logger.debug("Found SRV record \"" + remoteAddress + ":" + remotePort + "\""); 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."); logger.debug("Exception while trying to find an SRV record for the remote host.");
if (config.isDebugMode()) if (config.isDebugMode())
ex.printStackTrace(); // Otherwise we can get a stack trace for any domain that doesn't have an SRV record 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(); 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() { public static GeyserConnector getInstance() {
return instance; return instance;
} }

Datei anzeigen

@ -49,10 +49,6 @@ public class StopCommand extends GeyserCommand {
return; return;
} }
connector.shutdown(); connector.getBootstrap().onDisable();
if (connector.getPlatformType() == PlatformType.STANDALONE) {
System.exit(0);
}
} }
} }

Datei anzeigen

@ -32,6 +32,7 @@ import lombok.Getter;
@AllArgsConstructor @AllArgsConstructor
public enum PlatformType { public enum PlatformType {
ANDROID("Android"),
BUNGEECORD("BungeeCord"), BUNGEECORD("BungeeCord"),
SPIGOT("Spigot"), SPIGOT("Spigot"),
SPONGE("Sponge"), SPONGE("Sponge"),

Datei anzeigen

@ -33,6 +33,7 @@ import com.nukkitx.protocol.bedrock.BedrockPacket;
import it.unimi.dsi.fastutil.objects.ObjectArrayList; import it.unimi.dsi.fastutil.objects.ObjectArrayList;
import org.geysermc.connector.GeyserConnector; import org.geysermc.connector.GeyserConnector;
import org.geysermc.connector.network.session.GeyserSession; import org.geysermc.connector.network.session.GeyserSession;
import org.geysermc.connector.utils.FileUtils;
import org.geysermc.connector.utils.LanguageUtils; import org.geysermc.connector.utils.LanguageUtils;
import org.reflections.Reflections; import org.reflections.Reflections;
@ -48,7 +49,7 @@ public class PacketTranslatorRegistry<T> {
private static final ObjectArrayList<Class<?>> IGNORED_PACKETS = new ObjectArrayList<>(); private static final ObjectArrayList<Class<?>> IGNORED_PACKETS = new ObjectArrayList<>();
static { 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)) { for (Class<?> clazz : ref.getTypesAnnotatedWith(Translator.class)) {
Class<?> packet = clazz.getAnnotation(Translator.class).packet(); Class<?> packet = clazz.getAnnotation(Translator.class).packet();

Datei anzeigen

@ -41,6 +41,7 @@ import net.kyori.adventure.text.serializer.legacy.LegacyComponentSerializer;
import org.geysermc.connector.GeyserConnector; import org.geysermc.connector.GeyserConnector;
import org.geysermc.connector.network.session.GeyserSession; import org.geysermc.connector.network.session.GeyserSession;
import org.geysermc.connector.network.translators.ItemRemapper; import org.geysermc.connector.network.translators.ItemRemapper;
import org.geysermc.connector.utils.FileUtils;
import org.geysermc.connector.utils.LanguageUtils; import org.geysermc.connector.utils.LanguageUtils;
import org.geysermc.connector.utils.MessageUtils; import org.geysermc.connector.utils.MessageUtils;
import org.reflections.Reflections; import org.reflections.Reflections;
@ -62,7 +63,7 @@ public abstract class ItemTranslator {
static { static {
/* Load item translators */ /* 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<NbtItemStackTranslator, Integer> loadedNbtItemTranslators = new HashMap<>(); Map<NbtItemStackTranslator, Integer> loadedNbtItemTranslators = new HashMap<>();
for (Class<?> clazz : ref.getTypesAnnotatedWith(ItemRemapper.class)) { for (Class<?> clazz : ref.getTypesAnnotatedWith(ItemRemapper.class)) {

Datei anzeigen

@ -25,6 +25,8 @@
package org.geysermc.connector.network.translators.sound; package org.geysermc.connector.network.translators.sound;
import org.geysermc.connector.GeyserConnector;
import org.geysermc.connector.utils.FileUtils;
import org.reflections.Reflections; import org.reflections.Reflections;
import java.util.HashMap; import java.util.HashMap;
@ -38,7 +40,7 @@ public class SoundHandlerRegistry {
static final Map<SoundHandler, SoundInteractionHandler<?>> INTERACTION_HANDLERS = new HashMap<>(); static final Map<SoundHandler, SoundInteractionHandler<?>> INTERACTION_HANDLERS = new HashMap<>();
static { 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)) { for (Class<?> clazz : ref.getTypesAnnotatedWith(SoundHandler.class)) {
try { try {
SoundInteractionHandler<?> interactionHandler = (SoundInteractionHandler<?>) clazz.newInstance(); SoundInteractionHandler<?> interactionHandler = (SoundInteractionHandler<?>) clazz.newInstance();

Datei anzeigen

@ -106,7 +106,7 @@ public class BlockTranslator {
addedStatesMap.defaultReturnValue(-1); addedStatesMap.defaultReturnValue(-1);
List<NbtMap> paletteList = new ArrayList<>(); List<NbtMap> 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); ref.getTypesAnnotatedWith(BlockEntity.class);
int waterRuntimeId = -1; int waterRuntimeId = -1;

Datei anzeigen

@ -34,6 +34,7 @@ import com.nukkitx.nbt.NbtMapBuilder;
import it.unimi.dsi.fastutil.objects.ObjectArrayList; import it.unimi.dsi.fastutil.objects.ObjectArrayList;
import org.geysermc.connector.GeyserConnector; import org.geysermc.connector.GeyserConnector;
import org.geysermc.connector.utils.BlockEntityUtils; import org.geysermc.connector.utils.BlockEntityUtils;
import org.geysermc.connector.utils.FileUtils;
import org.geysermc.connector.utils.LanguageUtils; import org.geysermc.connector.utils.LanguageUtils;
import org.reflections.Reflections; import org.reflections.Reflections;
@ -66,7 +67,7 @@ public abstract class BlockEntityTranslator {
} }
static { 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)) { for (Class<?> clazz : ref.getTypesAnnotatedWith(BlockEntity.class)) {
GeyserConnector.getInstance().getLogger().debug("Found annotated block entity: " + clazz.getCanonicalName()); GeyserConnector.getInstance().getLogger().debug("Found annotated block entity: " + clazz.getCanonicalName());

Datei anzeigen

@ -28,11 +28,15 @@ package org.geysermc.connector.utils;
import com.fasterxml.jackson.databind.ObjectMapper; import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.dataformat.yaml.YAMLFactory; import com.fasterxml.jackson.dataformat.yaml.YAMLFactory;
import org.geysermc.connector.GeyserConnector; 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.File;
import java.io.FileOutputStream; import java.io.FileOutputStream;
import java.io.IOException; import java.io.IOException;
import java.io.InputStream; import java.io.InputStream;
import java.net.URL;
import java.util.function.Function; import java.util.function.Function;
public class FileUtils { public class FileUtils {
@ -140,4 +144,21 @@ public class FileUtils {
} }
return stream; 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;
}
} }

Datei anzeigen

@ -150,7 +150,7 @@ public class LocaleUtils {
// Get the hash and download the locale // Get the hash and download the locale
String hash = ASSET_MAP.get("minecraft/lang/" + locale + ".json").getHash(); 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());
} }
/** /**

Datei anzeigen

@ -119,7 +119,7 @@ public class SkinProvider {
// Schedule Daily Image Expiry if we are caching them // Schedule Daily Image Expiry if we are caching them
if (GeyserConnector.getInstance().getConfig().getCacheImages() > 0) { if (GeyserConnector.getInstance().getConfig().getCacheImages() > 0) {
GeyserConnector.getInstance().getGeneralThreadPool().scheduleAtFixedRate(() -> { 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()) { if (!cacheFolder.exists()) {
return; return;
} }
@ -395,7 +395,7 @@ public class SkinProvider {
BufferedImage image = null; 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 // 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()) { if (imageFile.exists()) {
try { try {
GeyserConnector.getInstance().getLogger().debug("Reading cached image from file " + imageFile.getPath() + " for " + imageUrl); GeyserConnector.getInstance().getLogger().debug("Reading cached image from file " + imageFile.getPath() + " for " + imageUrl);
@ -600,7 +600,7 @@ public class SkinProvider {
@Getter @Getter
public enum CapeProvider { public enum CapeProvider {
MINECRAFT, 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), LABYMOD("https://www.labymod.net/page/php/getCapeTexture.php?uuid=%s", CapeUrlType.UUID_DASHED),
FIVEZIG("https://textures.5zigreborn.eu/profile/%s", CapeUrlType.UUID_DASHED), FIVEZIG("https://textures.5zigreborn.eu/profile/%s", CapeUrlType.UUID_DASHED),
MINECRAFTCAPES("https://minecraftcapes.net/profile/%s/cape", CapeUrlType.UUID); MINECRAFTCAPES("https://minecraftcapes.net/profile/%s/cape", CapeUrlType.UUID);

Datei anzeigen

@ -150,14 +150,14 @@ public class SkinUtils {
JsonNode textures = skinObject.get("textures"); JsonNode textures = skinObject.get("textures");
JsonNode skinTexture = textures.get("SKIN"); JsonNode skinTexture = textures.get("SKIN");
String skinUrl = skinTexture.get("url").asText(); String skinUrl = skinTexture.get("url").asText().replace("http://", "https://");
isAlex = skinTexture.has("metadata"); isAlex = skinTexture.has("metadata");
String capeUrl = null; String capeUrl = null;
if (textures.has("CAPE")) { if (textures.has("CAPE")) {
JsonNode capeTexture = textures.get("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); return new GameProfileData(skinUrl, capeUrl, isAlex);