diff --git a/README.md b/README.md index 9878fa5a0..b8f8749b8 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,4 @@ -Geyser +Geyser [![forthebadge made-with-java](http://ForTheBadge.com/images/badges/made-with-java.svg)](https://java.com/) diff --git a/bootstrap/bukkit/src/main/java/org/geysermc/platform/bukkit/GeyserBukkitPlugin.java b/bootstrap/bukkit/src/main/java/org/geysermc/platform/bukkit/GeyserBukkitPlugin.java index 52893fc89..3a13777b4 100644 --- a/bootstrap/bukkit/src/main/java/org/geysermc/platform/bukkit/GeyserBukkitPlugin.java +++ b/bootstrap/bukkit/src/main/java/org/geysermc/platform/bukkit/GeyserBukkitPlugin.java @@ -44,6 +44,7 @@ import us.myles.ViaVersion.api.Via; import java.io.File; import java.io.IOException; +import java.nio.file.Path; import java.util.UUID; import java.util.logging.Level; @@ -154,6 +155,11 @@ public class GeyserBukkitPlugin extends JavaPlugin implements GeyserBootstrap { return this.geyserWorldManager; } + @Override + public Path getConfigFolder() { + return getDataFolder().toPath(); + } + public boolean isCompatible(String version, String whichVersion) { int[] currentVersion = parseVersion(version); int[] otherVersion = parseVersion(whichVersion); @@ -187,4 +193,5 @@ public class GeyserBukkitPlugin extends JavaPlugin implements GeyserBootstrap { } return temp; } + } diff --git a/bootstrap/bungeecord/src/main/java/org/geysermc/platform/bungeecord/GeyserBungeePlugin.java b/bootstrap/bungeecord/src/main/java/org/geysermc/platform/bungeecord/GeyserBungeePlugin.java index 24793839d..1cf519c0e 100644 --- a/bootstrap/bungeecord/src/main/java/org/geysermc/platform/bungeecord/GeyserBungeePlugin.java +++ b/bootstrap/bungeecord/src/main/java/org/geysermc/platform/bungeecord/GeyserBungeePlugin.java @@ -44,6 +44,7 @@ import org.geysermc.platform.bungeecord.command.GeyserBungeeCommandManager; import java.io.File; import java.io.IOException; import java.net.InetSocketAddress; +import java.nio.file.Path; import java.util.UUID; import java.util.logging.Level; @@ -134,4 +135,9 @@ public class GeyserBungeePlugin extends Plugin implements GeyserBootstrap { public IGeyserPingPassthrough getGeyserPingPassthrough() { return geyserBungeePingPassthrough; } + + @Override + public Path getConfigFolder() { + return getDataFolder().toPath(); + } } diff --git a/bootstrap/sponge/src/main/java/org/geysermc/platform/sponge/GeyserSpongePlugin.java b/bootstrap/sponge/src/main/java/org/geysermc/platform/sponge/GeyserSpongePlugin.java index 2288fc674..c5f13b581 100644 --- a/bootstrap/sponge/src/main/java/org/geysermc/platform/sponge/GeyserSpongePlugin.java +++ b/bootstrap/sponge/src/main/java/org/geysermc/platform/sponge/GeyserSpongePlugin.java @@ -50,6 +50,7 @@ import org.spongepowered.api.plugin.Plugin; import java.io.File; import java.io.IOException; import java.net.InetSocketAddress; +import java.nio.file.Path; import java.util.UUID; @Plugin(id = "geyser", name = GeyserConnector.NAME + "-Sponge", version = GeyserConnector.VERSION, url = "https://geysermc.org", authors = "GeyserMC") @@ -147,6 +148,11 @@ public class GeyserSpongePlugin implements GeyserBootstrap { return geyserSpongePingPassthrough; } + @Override + public Path getConfigFolder() { + return configDir.toPath(); + } + @Listener public void onServerStart(GameStartedServerEvent event) { onEnable(); diff --git a/bootstrap/standalone/src/main/java/org/geysermc/platform/standalone/GeyserStandaloneBootstrap.java b/bootstrap/standalone/src/main/java/org/geysermc/platform/standalone/GeyserStandaloneBootstrap.java index a1c472387..0fca35038 100644 --- a/bootstrap/standalone/src/main/java/org/geysermc/platform/standalone/GeyserStandaloneBootstrap.java +++ b/bootstrap/standalone/src/main/java/org/geysermc/platform/standalone/GeyserStandaloneBootstrap.java @@ -37,6 +37,8 @@ import org.geysermc.platform.standalone.command.GeyserCommandManager; import java.io.File; import java.io.IOException; +import java.nio.file.Path; +import java.nio.file.Paths; import java.util.UUID; public class GeyserStandaloneBootstrap implements GeyserBootstrap { @@ -100,4 +102,10 @@ public class GeyserStandaloneBootstrap implements GeyserBootstrap { public IGeyserPingPassthrough getGeyserPingPassthrough() { return geyserPingPassthrough; } + + @Override + public Path getConfigFolder() { + // Return the current working directory + return Paths.get(System.getProperty("user.dir")); + } } diff --git a/bootstrap/velocity/src/main/java/org/geysermc/platform/velocity/GeyserVelocityPlugin.java b/bootstrap/velocity/src/main/java/org/geysermc/platform/velocity/GeyserVelocityPlugin.java index e2a4787b4..5abf3c230 100644 --- a/bootstrap/velocity/src/main/java/org/geysermc/platform/velocity/GeyserVelocityPlugin.java +++ b/bootstrap/velocity/src/main/java/org/geysermc/platform/velocity/GeyserVelocityPlugin.java @@ -34,6 +34,7 @@ import com.velocitypowered.api.event.proxy.ProxyShutdownEvent; import com.velocitypowered.api.plugin.Plugin; import com.velocitypowered.api.proxy.ProxyServer; +import lombok.Getter; import org.geysermc.common.PlatformType; import org.geysermc.connector.configuration.GeyserConfiguration; import org.geysermc.connector.GeyserConnector; @@ -48,6 +49,8 @@ import org.slf4j.Logger; import java.io.File; import java.io.IOException; import java.net.InetSocketAddress; +import java.nio.file.Path; +import java.nio.file.Paths; import java.util.UUID; @Plugin(id = "geyser", name = GeyserConnector.NAME + "-Velocity", version = GeyserConnector.VERSION, url = "https://geysermc.org", authors = "GeyserMC") @@ -69,14 +72,16 @@ public class GeyserVelocityPlugin implements GeyserBootstrap { private GeyserConnector connector; + @Getter + private final Path configFolder = Paths.get("plugins/" + GeyserConnector.NAME + "-Velocity/"); + @Override public void onEnable() { - File configDir = new File("plugins/" + GeyserConnector.NAME + "-Velocity/"); - try { - if (!configDir.exists()) - configDir.mkdir(); - File configFile = FileUtils.fileOrCopiedFromResource(new File(configDir, "config.yml"), "config.yml", (x) -> x.replaceAll("generateduuid", UUID.randomUUID().toString())); + if (!configFolder.toFile().exists()) + //noinspection ResultOfMethodCallIgnored + configFolder.toFile().mkdirs(); + File configFile = FileUtils.fileOrCopiedFromResource(configFolder.resolve("config.yml").toFile(), "config.yml", (x) -> x.replaceAll("generateduuid", UUID.randomUUID().toString())); this.geyserConfig = FileUtils.loadConfig(configFile, GeyserVelocityConfiguration.class); } catch (IOException ex) { logger.warn("Failed to read/create config.yml! Make sure it's up to date and/or readable+writable!", ex); @@ -101,7 +106,7 @@ public class GeyserVelocityPlugin implements GeyserBootstrap { return; } - geyserConfig.loadFloodgate(this, proxyServer, configDir); + geyserConfig.loadFloodgate(this, proxyServer, configFolder.toFile()); this.connector = GeyserConnector.start(PlatformType.VELOCITY, this); diff --git a/connector/src/main/java/org/geysermc/connector/GeyserConnector.java b/connector/src/main/java/org/geysermc/connector/GeyserConnector.java index abd48bc29..d201656ad 100644 --- a/connector/src/main/java/org/geysermc/connector/GeyserConnector.java +++ b/connector/src/main/java/org/geysermc/connector/GeyserConnector.java @@ -31,6 +31,7 @@ import com.nukkitx.protocol.bedrock.BedrockPacketCodec; import com.nukkitx.protocol.bedrock.BedrockServer; import com.nukkitx.protocol.bedrock.v390.Bedrock_v390; import lombok.Getter; +import lombok.Setter; import org.geysermc.common.AuthType; import org.geysermc.common.PlatformType; import org.geysermc.connector.bootstrap.GeyserBootstrap; @@ -79,6 +80,7 @@ public class GeyserConnector { private static GeyserConnector instance; private RemoteServer remoteServer; + @Setter private AuthType authType; private boolean shuttingDown = false; diff --git a/connector/src/main/java/org/geysermc/connector/bootstrap/GeyserBootstrap.java b/connector/src/main/java/org/geysermc/connector/bootstrap/GeyserBootstrap.java index 5cc6d06f3..8683f80cd 100644 --- a/connector/src/main/java/org/geysermc/connector/bootstrap/GeyserBootstrap.java +++ b/connector/src/main/java/org/geysermc/connector/bootstrap/GeyserBootstrap.java @@ -33,6 +33,8 @@ import org.geysermc.connector.command.CommandManager; import org.geysermc.connector.network.translators.world.CachedChunkManager; import org.geysermc.connector.network.translators.world.WorldManager; +import java.nio.file.Path; + public interface GeyserBootstrap { CachedChunkManager DEFAULT_CHUNK_MANAGER = new CachedChunkManager(); @@ -83,4 +85,11 @@ public interface GeyserBootstrap { default WorldManager getWorldManager() { return DEFAULT_CHUNK_MANAGER; } + + /** + * Return the data folder where files get stored + * + * @return Path location of data folder + */ + Path getConfigFolder(); } diff --git a/connector/src/main/java/org/geysermc/connector/network/translators/bedrock/BedrockInteractTranslator.java b/connector/src/main/java/org/geysermc/connector/network/translators/bedrock/BedrockInteractTranslator.java index bfd4a90a5..84fb309e4 100644 --- a/connector/src/main/java/org/geysermc/connector/network/translators/bedrock/BedrockInteractTranslator.java +++ b/connector/src/main/java/org/geysermc/connector/network/translators/bedrock/BedrockInteractTranslator.java @@ -26,6 +26,7 @@ package org.geysermc.connector.network.translators.bedrock; import com.nukkitx.protocol.bedrock.data.EntityData; +import com.nukkitx.protocol.bedrock.data.EntityDataMap; import com.nukkitx.protocol.bedrock.data.EntityFlag; import org.geysermc.connector.entity.Entity; import org.geysermc.connector.network.session.GeyserSession; @@ -74,33 +75,43 @@ public class BedrockInteractTranslator extends PacketTranslator Entity interactEntity = session.getEntityCache().getEntityByGeyserId(packet.getRuntimeEntityId()); if (interactEntity == null) return; + EntityDataMap entityMetadata = interactEntity.getMetadata(); String interactiveTag; switch (interactEntity.getEntityType()) { - case PIG: - if (interactEntity.getMetadata().getFlags().getFlag(EntityFlag.SADDLED)) { - interactiveTag = "action.interact.mount"; - } else interactiveTag = ""; + case BOAT: + interactiveTag = "action.interact.ride.boat"; break; - case HORSE: - case SKELETON_HORSE: - case ZOMBIE_HORSE: case DONKEY: - case MULE: + case HORSE: case LLAMA: + case MULE: + case SKELETON_HORSE: case TRADER_LLAMA: - if (interactEntity.getMetadata().getFlags().getFlag(EntityFlag.TAMED)) { + case ZOMBIE_HORSE: + if (entityMetadata.getFlags().getFlag(EntityFlag.TAMED)) { interactiveTag = "action.interact.ride.horse"; } else { interactiveTag = "action.interact.mount"; } break; - case BOAT: - interactiveTag = "action.interact.ride.boat"; - break; case MINECART: interactiveTag = "action.interact.ride.minecart"; break; + case PIG: + if (entityMetadata.getFlags().getFlag(EntityFlag.SADDLED)) { + interactiveTag = "action.interact.mount"; + } else interactiveTag = ""; + break; + case VILLAGER: + if (entityMetadata.getInt(EntityData.VARIANT) != 14 && entityMetadata.getInt(EntityData.VARIANT) != 0 + && entityMetadata.getFloat(EntityData.SCALE) >= 0.75f) { // Not a nitwit, has a profession and is not a baby + interactiveTag = "action.interact.trade"; + } else interactiveTag = ""; + break; + case WANDERING_TRADER: + interactiveTag = "action.interact.trade"; // Since you can always trade with a wandering villager, presumably. + break; default: return; // No need to process any further since there is no interactive tag } 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 f55cb261e..e213fe6cc 100644 --- a/connector/src/main/java/org/geysermc/connector/utils/LocaleUtils.java +++ b/connector/src/main/java/org/geysermc/connector/utils/LocaleUtils.java @@ -33,6 +33,7 @@ import org.geysermc.connector.GeyserConnector; import java.io.*; import java.nio.file.Files; +import java.nio.file.Path; import java.nio.file.Paths; import java.util.*; import java.util.zip.ZipFile; @@ -49,7 +50,8 @@ public class LocaleUtils { static { // Create the locales folder - File localesFolder = new File("locales/"); + File localesFolder = GeyserConnector.getInstance().getBootstrap().getConfigFolder().resolve("locales").toFile(); + //noinspection ResultOfMethodCallIgnored localesFolder.mkdir(); // Download the latest asset list and cache it @@ -132,7 +134,7 @@ public class LocaleUtils { * @param locale Locale to download */ private static void downloadLocale(String locale) { - File localeFile = new File("locales/" + locale + ".json"); + File localeFile = Paths.get(GeyserConnector.getInstance().getBootstrap().getConfigFolder().toString(),"locales",locale + ".json").toFile(); // Check if we have already downloaded the locale file if (localeFile.exists()) { @@ -149,7 +151,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, "locales/" + locale + ".json"); + WebUtils.downloadFile("http://resources.download.minecraft.net/" + hash.substring(0, 2) + "/" + hash, localeFile.toString()); } /** @@ -205,10 +207,11 @@ public class LocaleUtils { GeyserConnector.getInstance().getLogger().debug("Download URL: " + smallestURL); // Download the smallest JAR (client or server) - WebUtils.downloadFile(smallestURL, "tmp_locale.jar"); + Path tmpFilePath = GeyserConnector.getInstance().getBootstrap().getConfigFolder().resolve("tmp_locale.jar"); + WebUtils.downloadFile(smallestURL, tmpFilePath.toString()); // Load in the JAR as a zip and extract the file - ZipFile localeJar = new ZipFile("tmp_locale.jar"); + ZipFile localeJar = new ZipFile(tmpFilePath.toString()); InputStream inputStream = localeJar.getInputStream(localeJar.getEntry("assets/minecraft/lang/en_us.json")); FileOutputStream outputStream = new FileOutputStream(localeFile); @@ -227,7 +230,7 @@ public class LocaleUtils { localeJar.close(); // Delete the nolonger needed client/server jar - Files.delete(Paths.get("tmp_locale.jar")); + Files.delete(tmpFilePath); } catch (Exception e) { throw new AssertionError("Unable to download and extract en_us locale!", e); } diff --git a/connector/src/main/resources/config.yml b/connector/src/main/resources/config.yml index a68f32a1c..e0e0771da 100644 --- a/connector/src/main/resources/config.yml +++ b/connector/src/main/resources/config.yml @@ -8,7 +8,8 @@ # -------------------------------- bedrock: - # The IP address that will listen for connections + # The IP address that will listen for connections. + # There is no reason to change this unless you want to limit what IPs can connect to your server. address: 0.0.0.0 # The port that will listen for connections port: 19132