Update Sponge to API 8 (#2611)

This commit is contained in:
Konicai 2022-10-02 16:43:14 -04:00 committed by GitHub
parent cb864b3c98
commit 7653a626af
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
20 changed files with 293 additions and 165 deletions

View file

@ -52,10 +52,8 @@ public class GeyserBungeeDumpInfo extends BootstrapDumpInfo {
this.plugins = new ArrayList<>(); this.plugins = new ArrayList<>();
for (net.md_5.bungee.api.config.ListenerInfo listener : proxy.getConfig().getListeners()) { for (net.md_5.bungee.api.config.ListenerInfo listener : proxy.getConfig().getListeners()) {
String hostname; String hostname = listener.getHost().getHostString();
if (AsteriskSerializer.showSensitive || (listener.getHost().getHostString().equals("") || listener.getHost().getHostString().equals("0.0.0.0"))) { if (!AsteriskSerializer.showSensitive && !(hostname.equals("") || hostname.equals("0.0.0.0"))) {
hostname = listener.getHost().getHostString();
} else {
hostname = "***"; hostname = "***";
} }
this.listeners.add(new ListenerInfo(hostname, listener.getHost().getPort())); this.listeners.add(new ListenerInfo(hostname, listener.getHost().getPort()));

View file

@ -69,6 +69,9 @@ public class GeyserBungeeCommandExecutor extends Command implements TabExecutor
return; return;
} }
command.execute(session, commandSender, args.length > 1 ? Arrays.copyOfRange(args, 1, args.length) : new String[0]); command.execute(session, commandSender, args.length > 1 ? Arrays.copyOfRange(args, 1, args.length) : new String[0]);
} else {
String message = GeyserLocale.getPlayerLocaleString("geyser.bootstrap.command.not_found", commandSender.locale());
commandSender.sendMessage(ChatColor.RED + message);
} }
} else { } else {
this.commandExecutor.getCommand("help").execute(session, commandSender, new String[0]); this.commandExecutor.getCommand("help").execute(session, commandSender, new String[0]);

View file

@ -51,8 +51,9 @@ public class GeyserSpigotDumpInfo extends BootstrapDumpInfo {
this.platformVersion = Bukkit.getVersion(); this.platformVersion = Bukkit.getVersion();
this.platformAPIVersion = Bukkit.getBukkitVersion(); this.platformAPIVersion = Bukkit.getBukkitVersion();
this.onlineMode = Bukkit.getOnlineMode(); this.onlineMode = Bukkit.getOnlineMode();
if (AsteriskSerializer.showSensitive || (Bukkit.getIp().equals("") || Bukkit.getIp().equals("0.0.0.0"))) { String ip = Bukkit.getIp();
this.serverIP = Bukkit.getIp(); if (AsteriskSerializer.showSensitive || (ip.equals("") || ip.equals("0.0.0.0"))) {
this.serverIP = ip;
} else { } else {
this.serverIP = "***"; this.serverIP = "***";
} }

View file

@ -66,6 +66,9 @@ public class GeyserSpigotCommandExecutor extends GeyserCommandExecutor implement
} }
geyserCommand.execute(session, commandSender, args.length > 1 ? Arrays.copyOfRange(args, 1, args.length) : new String[0]); geyserCommand.execute(session, commandSender, args.length > 1 ? Arrays.copyOfRange(args, 1, args.length) : new String[0]);
return true; return true;
} else {
String message = GeyserLocale.getPlayerLocaleString("geyser.bootstrap.command.not_found", commandSender.locale());
commandSender.sendMessage(ChatColor.RED + message);
} }
} else { } else {
getCommand("help").execute(session, commandSender, new String[0]); getCommand("help").execute(session, commandSender, new String[0]);

View file

@ -7,13 +7,8 @@ platformRelocate("io.netty")
platformRelocate("it.unimi.dsi.fastutil") platformRelocate("it.unimi.dsi.fastutil")
platformRelocate("com.google.common") platformRelocate("com.google.common")
platformRelocate("com.google.guava") platformRelocate("com.google.guava")
platformRelocate("net.kyori") platformRelocate("net.kyori.adventure.text.serializer.gson.legacyimpl")
platformRelocate("net.kyori.adventure.nbt")
// Exclude these dependencies
exclude("com.google.code.gson:*")
exclude("org.yaml:*")
exclude("org.slf4j:*")
exclude("org.ow2.asm:*")
// These dependencies are already present on the platform // These dependencies are already present on the platform
provided(libs.sponge.api) provided(libs.sponge.api)
@ -30,5 +25,14 @@ tasks.withType<com.github.jengelman.gradle.plugins.shadow.tasks.ShadowJar> {
exclude(dependency("org.yaml:.*")) exclude(dependency("org.yaml:.*"))
exclude(dependency("org.slf4j:.*")) exclude(dependency("org.slf4j:.*"))
exclude(dependency("org.ow2.asm:.*")) exclude(dependency("org.ow2.asm:.*"))
// Exclude all Kyori dependencies except the legacy NBT serializer and NBT
exclude(dependency("net.kyori:adventure-api:.*"))
exclude(dependency("net.kyori:examination-api:.*"))
exclude(dependency("net.kyori:examination-string:.*"))
exclude(dependency("net.kyori:adventure-text-serializer-gson:.*"))
exclude(dependency("net.kyori:adventure-text-serializer-legacy:.*"))
exclude(dependency("net.kyori:adventure-text-serializer-plain:.*"))
exclude(dependency("net.kyori:adventure-key:.*"))
} }
} }

View file

@ -27,12 +27,18 @@ package org.geysermc.geyser.platform.sponge;
import lombok.Getter; import lombok.Getter;
import org.geysermc.geyser.dump.BootstrapDumpInfo; import org.geysermc.geyser.dump.BootstrapDumpInfo;
import org.geysermc.geyser.text.AsteriskSerializer;
import org.spongepowered.api.Platform; import org.spongepowered.api.Platform;
import org.spongepowered.api.Sponge; import org.spongepowered.api.Sponge;
import org.spongepowered.api.plugin.PluginContainer; import org.spongepowered.plugin.PluginContainer;
import org.spongepowered.plugin.metadata.PluginMetadata;
import org.spongepowered.plugin.metadata.model.PluginContributor;
import java.net.InetSocketAddress;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;
import java.util.Optional;
import java.util.stream.Collectors;
@Getter @Getter
public class GeyserSpongeDumpInfo extends BootstrapDumpInfo { public class GeyserSpongeDumpInfo extends BootstrapDumpInfo {
@ -44,18 +50,25 @@ public class GeyserSpongeDumpInfo extends BootstrapDumpInfo {
private final List<PluginInfo> plugins; private final List<PluginInfo> plugins;
GeyserSpongeDumpInfo() { GeyserSpongeDumpInfo() {
super(); PluginContainer container = Sponge.platform().container(Platform.Component.IMPLEMENTATION);
PluginContainer container = Sponge.getPlatform().getContainer(Platform.Component.IMPLEMENTATION); PluginMetadata platformMeta = container.metadata();
this.platformName = container.getName(); this.platformName = platformMeta.name().orElse("unknown");
this.platformVersion = container.getVersion().get(); this.platformVersion = platformMeta.version().getQualifier();
this.onlineMode = Sponge.getServer().getOnlineMode(); this.onlineMode = Sponge.server().isOnlineModeEnabled();
this.serverIP = Sponge.getServer().getBoundAddress().get().getHostString(); Optional<InetSocketAddress> socketAddress = Sponge.server().boundAddress();
this.serverPort = Sponge.getServer().getBoundAddress().get().getPort(); String hostString = socketAddress.map(InetSocketAddress::getHostString).orElse("unknown");
if (AsteriskSerializer.showSensitive || (hostString.equals("") || hostString.equals("0.0.0.0") || hostString.equals("unknown"))) {
this.serverIP = hostString;
} else {
this.serverIP = "***";
}
this.serverPort = socketAddress.map(InetSocketAddress::getPort).orElse(-1);
this.plugins = new ArrayList<>(); this.plugins = new ArrayList<>();
for (PluginContainer plugin : Sponge.getPluginManager().getPlugins()) { for (PluginContainer plugin : Sponge.pluginManager().plugins()) {
String pluginClass = plugin.getInstance().map((pl) -> pl.getClass().getName()).orElse("unknown"); PluginMetadata meta = plugin.metadata();
this.plugins.add(new PluginInfo(true, plugin.getName(), plugin.getVersion().get(), pluginClass, plugin.getAuthors())); List<String> contributors = meta.contributors().stream().map(PluginContributor::name).collect(Collectors.toList());
this.plugins.add(new PluginInfo(true, meta.name().orElse("unknown"), meta.version().toString(), meta.entrypoint(), contributors));
} }
} }
} }

View file

@ -29,7 +29,7 @@ import lombok.AllArgsConstructor;
import lombok.Getter; import lombok.Getter;
import lombok.Setter; import lombok.Setter;
import org.geysermc.geyser.GeyserLogger; import org.geysermc.geyser.GeyserLogger;
import org.slf4j.Logger; import org.apache.logging.log4j.Logger;
@AllArgsConstructor @AllArgsConstructor
public class GeyserSpongeLogger implements GeyserLogger { public class GeyserSpongeLogger implements GeyserLogger {

View file

@ -28,11 +28,12 @@ package org.geysermc.geyser.platform.sponge;
import org.geysermc.geyser.network.GameProtocol; import org.geysermc.geyser.network.GameProtocol;
import org.geysermc.geyser.ping.GeyserPingInfo; import org.geysermc.geyser.ping.GeyserPingInfo;
import org.geysermc.geyser.ping.IGeyserPingPassthrough; import org.geysermc.geyser.ping.IGeyserPingPassthrough;
import org.geysermc.geyser.translator.text.MessageTranslator;
import org.spongepowered.api.MinecraftVersion; import org.spongepowered.api.MinecraftVersion;
import org.spongepowered.api.Sponge; import org.spongepowered.api.Sponge;
import org.spongepowered.api.event.Cause;
import org.spongepowered.api.event.EventContext;
import org.spongepowered.api.event.SpongeEventFactory; import org.spongepowered.api.event.SpongeEventFactory;
import org.spongepowered.api.event.cause.Cause;
import org.spongepowered.api.event.cause.EventContext;
import org.spongepowered.api.event.server.ClientPingServerEvent; import org.spongepowered.api.event.server.ClientPingServerEvent;
import org.spongepowered.api.network.status.StatusClient; import org.spongepowered.api.network.status.StatusClient;
import org.spongepowered.api.profile.GameProfile; import org.spongepowered.api.profile.GameProfile;
@ -43,7 +44,7 @@ import java.util.Optional;
public class GeyserSpongePingPassthrough implements IGeyserPingPassthrough { public class GeyserSpongePingPassthrough implements IGeyserPingPassthrough {
private static final Cause CAUSE = Cause.of(EventContext.empty(), Sponge.getServer()); private static final Cause CAUSE = Cause.of(EventContext.empty(), Sponge.server());
private static Method SpongeStatusResponse_create; private static Method SpongeStatusResponse_create;
@ -59,50 +60,46 @@ public class GeyserSpongePingPassthrough implements IGeyserPingPassthrough {
SpongeStatusResponse_create = SpongeStatusResponse.getDeclaredMethod("create", MinecraftServer); SpongeStatusResponse_create = SpongeStatusResponse.getDeclaredMethod("create", MinecraftServer);
} }
Object response = SpongeStatusResponse_create.invoke(null, Sponge.getServer()); Object response = SpongeStatusResponse_create.invoke(null, Sponge.server());
event = SpongeEventFactory.createClientPingServerEvent(CAUSE, new GeyserStatusClient(inetSocketAddress), (ClientPingServerEvent.Response) response); event = SpongeEventFactory.createClientPingServerEvent(CAUSE, new GeyserStatusClient(inetSocketAddress), (ClientPingServerEvent.Response) response);
} catch (ReflectiveOperationException e) { } catch (ReflectiveOperationException e) {
throw new RuntimeException(e); throw new RuntimeException(e);
} }
Sponge.getEventManager().post(event); Sponge.eventManager().post(event);
GeyserPingInfo geyserPingInfo = new GeyserPingInfo( GeyserPingInfo geyserPingInfo = new GeyserPingInfo(
event.getResponse().getDescription().toPlain(), MessageTranslator.convertMessage(event.response().description()),
new GeyserPingInfo.Players( new GeyserPingInfo.Players(
event.getResponse().getPlayers().orElseThrow(IllegalStateException::new).getMax(), event.response().players().orElseThrow(IllegalStateException::new).max(),
event.getResponse().getPlayers().orElseThrow(IllegalStateException::new).getOnline() event.response().players().orElseThrow(IllegalStateException::new).online()
), ),
new GeyserPingInfo.Version( new GeyserPingInfo.Version(
event.getResponse().getVersion().getName(), event.response().version().name(),
GameProtocol.getJavaProtocolVersion()) // thanks for also not exposing this sponge GameProtocol.getJavaProtocolVersion()) // thanks for also not exposing this sponge
); );
event.getResponse().getPlayers().get().getProfiles().stream() event.response().players().ifPresent(players -> players.profiles().stream()
.map(GameProfile::getName) .map(GameProfile::name)
.map(op -> op.orElseThrow(IllegalStateException::new)) .filter(Optional::isPresent)
.forEach(geyserPingInfo.getPlayerList()::add); .map(Optional::get)
.forEach(geyserPingInfo.getPlayerList()::add)
);
return geyserPingInfo; return geyserPingInfo;
} }
@SuppressWarnings("NullableProblems") private record GeyserStatusClient(InetSocketAddress remote) implements StatusClient {
private static class GeyserStatusClient implements StatusClient {
private final InetSocketAddress remote;
public GeyserStatusClient(InetSocketAddress remote) {
this.remote = remote;
}
@Override @Override
public InetSocketAddress getAddress() { public InetSocketAddress address() {
return this.remote; return this.remote;
} }
@Override @Override
public MinecraftVersion getVersion() { public MinecraftVersion version() {
return Sponge.getPlatform().getMinecraftVersion(); return Sponge.platform().minecraftVersion();
} }
@Override @Override
public Optional<InetSocketAddress> getVirtualHost() { public Optional<InetSocketAddress> virtualHost() {
return Optional.empty(); return Optional.empty();
} }
} }

View file

@ -26,6 +26,7 @@
package org.geysermc.geyser.platform.sponge; package org.geysermc.geyser.platform.sponge;
import com.google.inject.Inject; import com.google.inject.Inject;
import org.apache.logging.log4j.Logger;
import org.geysermc.common.PlatformType; import org.geysermc.common.PlatformType;
import org.geysermc.geyser.GeyserBootstrap; import org.geysermc.geyser.GeyserBootstrap;
import org.geysermc.geyser.GeyserImpl; import org.geysermc.geyser.GeyserImpl;
@ -36,18 +37,23 @@ import org.geysermc.geyser.configuration.GeyserConfiguration;
import org.geysermc.geyser.dump.BootstrapDumpInfo; import org.geysermc.geyser.dump.BootstrapDumpInfo;
import org.geysermc.geyser.ping.GeyserLegacyPingPassthrough; import org.geysermc.geyser.ping.GeyserLegacyPingPassthrough;
import org.geysermc.geyser.ping.IGeyserPingPassthrough; import org.geysermc.geyser.ping.IGeyserPingPassthrough;
import org.geysermc.geyser.platform.sponge.command.GeyserSpongeCommandExecutor;
import org.geysermc.geyser.platform.sponge.command.GeyserSpongeCommandManager; import org.geysermc.geyser.platform.sponge.command.GeyserSpongeCommandManager;
import org.geysermc.geyser.text.GeyserLocale;
import org.geysermc.geyser.util.FileUtils; import org.geysermc.geyser.util.FileUtils;
import org.slf4j.Logger; import org.geysermc.geyser.text.GeyserLocale;
import org.geysermc.geyser.platform.sponge.command.GeyserSpongeCommandExecutor;
import org.spongepowered.api.Server;
import org.spongepowered.api.Sponge; import org.spongepowered.api.Sponge;
import org.spongepowered.api.config.ConfigDir; import org.spongepowered.api.config.ConfigDir;
import org.spongepowered.api.event.Listener; import org.spongepowered.api.event.Listener;
import org.spongepowered.api.event.game.state.GameStartedServerEvent; import org.spongepowered.api.event.lifecycle.ConstructPluginEvent;
import org.spongepowered.api.event.game.state.GameStoppedEvent; import org.spongepowered.api.event.lifecycle.RegisterCommandEvent;
import org.spongepowered.api.plugin.Plugin; import org.spongepowered.api.event.lifecycle.StartedEngineEvent;
import org.spongepowered.api.event.lifecycle.StoppingEngineEvent;
import org.spongepowered.plugin.PluginContainer;
import org.spongepowered.plugin.builtin.jvm.Plugin;
import javax.annotation.Nonnull;
import javax.annotation.Nullable;
import java.io.File; import java.io.File;
import java.io.IOException; import java.io.IOException;
import java.net.InetSocketAddress; import java.net.InetSocketAddress;
@ -55,54 +61,134 @@ import java.nio.file.Path;
import java.util.Map; import java.util.Map;
import java.util.UUID; import java.util.UUID;
@Plugin(id = "geyser", name = GeyserImpl.NAME + "-Sponge", version = GeyserImpl.VERSION, url = "https://geysermc.org", authors = "GeyserMC") @Plugin(value = "geyser")
public class GeyserSpongePlugin implements GeyserBootstrap { public class GeyserSpongePlugin implements GeyserBootstrap {
/**
* True if the plugin should be in a disabled state.
* This exists because you can't unregister or disable plugins in Sponge
*/
private boolean enabled = true;
@Inject
private PluginContainer pluginContainer;
@Inject @Inject
private Logger logger; private Logger logger;
@Inject @Inject
@ConfigDir(sharedRoot = false) @ConfigDir(sharedRoot = false)
private File configDir; private Path configPath;
private GeyserSpongeCommandManager geyserCommandManager; // Available after construction lifecycle
private GeyserSpongeConfiguration geyserConfig; private GeyserSpongeConfiguration geyserConfig;
private GeyserSpongeLogger geyserLogger; private GeyserSpongeLogger geyserLogger;
private GeyserImpl geyser;
private GeyserSpongeCommandManager geyserCommandManager; // Commands are only registered after command registration lifecycle
// Available after StartedEngine lifecycle
private IGeyserPingPassthrough geyserSpongePingPassthrough; private IGeyserPingPassthrough geyserSpongePingPassthrough;
private GeyserImpl geyser;
public void onLoad() { /**
* Only to be used for reloading
*/
@Override
public void onEnable() {
enabled = true;
onConstruction(null);
// new commands cannot be registered, and geyser's command manager does not need be reloaded
onStartedEngine(null);
}
@Override
public void onDisable() {
enabled = false;
if (geyser != null) {
geyser.shutdown();
geyser = null;
}
}
/**
* Construct the configuration, logger, and command manager. command manager will only be filled with commands once
* the connector is started, but it allows us to register events in sponge.
*
* @param event Not used.
*/
@Listener
public void onConstruction(@Nullable ConstructPluginEvent event) {
GeyserLocale.init(this); GeyserLocale.init(this);
if (!configDir.exists()) File configDir = configPath.toFile();
if (!configDir.exists()) {
configDir.mkdirs(); configDir.mkdirs();
}
File configFile; File configFile;
try { try {
configFile = FileUtils.fileOrCopiedFromResource(new File(configDir, "config.yml"), "config.yml", configFile = FileUtils.fileOrCopiedFromResource(new File(configDir, "config.yml"), "config.yml",
(file) -> file.replaceAll("generateduuid", UUID.randomUUID().toString()), this); (file) -> file.replaceAll("generateduuid", UUID.randomUUID().toString()), this);
this.geyserConfig = FileUtils.loadConfig(configFile, GeyserSpongeConfiguration.class);
} catch (IOException ex) { } catch (IOException ex) {
logger.error(GeyserLocale.getLocaleStringLog("geyser.config.failed")); logger.error(GeyserLocale.getLocaleStringLog("geyser.config.failed"));
ex.printStackTrace(); ex.printStackTrace();
onDisable();
return; return;
} }
try { GeyserConfiguration.checkGeyserConfiguration(geyserConfig, geyserLogger);
this.geyserConfig = FileUtils.loadConfig(configFile, GeyserSpongeConfiguration.class); this.geyserLogger = new GeyserSpongeLogger(logger, geyserConfig.isDebugMode());
} catch (IOException ex) {
logger.warn(GeyserLocale.getLocaleStringLog("geyser.config.failed")); this.geyser = GeyserImpl.load(PlatformType.SPONGE, this);
ex.printStackTrace();
this.geyserCommandManager = new GeyserSpongeCommandManager(geyser);
this.geyserCommandManager.init();
}
/**
* Construct the {@link GeyserSpongeCommandManager} and register the commands
*
* @param event required to register the commands
*/
@Listener
public void onRegisterCommands(@Nonnull RegisterCommandEvent<org.spongepowered.api.command.Command.Raw> event) {
if (enabled) {
event.register(this.pluginContainer, new GeyserSpongeCommandExecutor(geyser, geyserCommandManager.getCommands()), "geyser");
for (Map.Entry<Extension, Map<String, Command>> entry : this.geyserCommandManager.extensionCommands().entrySet()) {
Map<String, Command> commands = entry.getValue();
if (commands.isEmpty()) {
continue;
}
event.register(this.pluginContainer, new GeyserSpongeCommandExecutor(this.geyser, commands), entry.getKey().description().id());
}
}
}
/**
* Configure the config properly if remote address is auto. Start connector and ping passthrough, and register subcommands of /geyser
*
* @param event not required
*/
@Listener
public void onStartedEngine(@Nullable StartedEngineEvent<Server> event) {
if (!enabled) {
return; return;
} }
if (Sponge.getServer().getBoundAddress().isPresent()) { if (Sponge.server().boundAddress().isPresent()) {
InetSocketAddress javaAddr = Sponge.getServer().getBoundAddress().get(); InetSocketAddress javaAddr = Sponge.server().boundAddress().get();
// Don't change the ip if its listening on all interfaces
// By default this should be 127.0.0.1 but may need to be changed in some circumstances // By default this should be 127.0.0.1 but may need to be changed in some circumstances
if (this.geyserConfig.getRemote().address().equalsIgnoreCase("auto")) { if (this.geyserConfig.getRemote().address().equalsIgnoreCase("auto")) {
this.geyserConfig.setAutoconfiguredRemote(true); this.geyserConfig.setAutoconfiguredRemote(true);
// Don't change the ip if its listening on all interfaces
if (!javaAddr.getHostString().equals("0.0.0.0") && !javaAddr.getHostString().equals("")) {
this.geyserConfig.getRemote().setAddress(javaAddr.getHostString());
}
geyserConfig.getRemote().setPort(javaAddr.getPort()); geyserConfig.getRemote().setPort(javaAddr.getPort());
} }
} }
@ -111,14 +197,6 @@ public class GeyserSpongePlugin implements GeyserBootstrap {
geyserConfig.getBedrock().setPort(geyserConfig.getRemote().port()); geyserConfig.getBedrock().setPort(geyserConfig.getRemote().port());
} }
this.geyserLogger = new GeyserSpongeLogger(logger, geyserConfig.isDebugMode());
GeyserConfiguration.checkGeyserConfiguration(geyserConfig, geyserLogger);
this.geyser = GeyserImpl.load(PlatformType.SPONGE, this);
}
@Override
public void onEnable() {
GeyserImpl.start(); GeyserImpl.start();
if (geyserConfig.isLegacyPingPassthrough()) { if (geyserConfig.isLegacyPingPassthrough()) {
@ -126,25 +204,11 @@ public class GeyserSpongePlugin implements GeyserBootstrap {
} else { } else {
this.geyserSpongePingPassthrough = new GeyserSpongePingPassthrough(); this.geyserSpongePingPassthrough = new GeyserSpongePingPassthrough();
} }
this.geyserCommandManager = new GeyserSpongeCommandManager(Sponge.getCommandManager(), geyser);
this.geyserCommandManager.init();
Sponge.getCommandManager().register(this, new GeyserSpongeCommandExecutor(geyser, geyserCommandManager.getCommands()), "geyser");
for (Map.Entry<Extension, Map<String, Command>> entry : this.geyserCommandManager.extensionCommands().entrySet()) {
Map<String, Command> commands = entry.getValue();
if (commands.isEmpty()) {
continue;
}
Sponge.getCommandManager().register(this, new GeyserSpongeCommandExecutor(this.geyser, commands), entry.getKey().description().id());
}
} }
@Override @Listener
public void onDisable() { public void onEngineStopping(StoppingEngineEvent<Server> event) {
geyser.shutdown(); onDisable();
} }
@Override @Override
@ -159,7 +223,7 @@ public class GeyserSpongePlugin implements GeyserBootstrap {
@Override @Override
public GeyserCommandManager getGeyserCommandManager() { public GeyserCommandManager getGeyserCommandManager() {
return this.geyserCommandManager; return geyserCommandManager;
} }
@Override @Override
@ -169,22 +233,7 @@ public class GeyserSpongePlugin implements GeyserBootstrap {
@Override @Override
public Path getConfigFolder() { public Path getConfigFolder() {
return configDir.toPath(); return configPath;
}
@Listener
public void onServerStarting() {
onLoad();
}
@Listener
public void onServerStart(GameStartedServerEvent event) {
onEnable();
}
@Listener
public void onServerStop(GameStoppedEvent event) {
onDisable();
} }
@Override @Override
@ -194,6 +243,6 @@ public class GeyserSpongePlugin implements GeyserBootstrap {
@Override @Override
public String getMinecraftServerVersion() { public String getMinecraftServerVersion() {
return Sponge.getPlatform().getMinecraftVersion().getName(); return Sponge.platform().minecraftVersion().name();
} }
} }

View file

@ -25,81 +25,88 @@
package org.geysermc.geyser.platform.sponge.command; package org.geysermc.geyser.platform.sponge.command;
import net.kyori.adventure.text.Component;
import net.kyori.adventure.text.format.NamedTextColor;
import org.geysermc.geyser.GeyserImpl; import org.geysermc.geyser.GeyserImpl;
import org.geysermc.geyser.api.command.Command; import org.geysermc.geyser.api.command.Command;
import org.geysermc.geyser.command.GeyserCommand; import org.geysermc.geyser.command.GeyserCommand;
import org.geysermc.geyser.command.GeyserCommandExecutor; import org.geysermc.geyser.command.GeyserCommandExecutor;
import org.geysermc.geyser.command.GeyserCommandSource; import org.geysermc.geyser.command.GeyserCommandSource;
import org.geysermc.geyser.session.GeyserSession; import org.geysermc.geyser.session.GeyserSession;
import org.geysermc.geyser.text.ChatColor;
import org.geysermc.geyser.text.GeyserLocale; import org.geysermc.geyser.text.GeyserLocale;
import org.spongepowered.api.command.CommandCallable; import org.jetbrains.annotations.NotNull;
import org.spongepowered.api.command.CommandCause;
import org.spongepowered.api.command.CommandCompletion;
import org.spongepowered.api.command.CommandResult; import org.spongepowered.api.command.CommandResult;
import org.spongepowered.api.command.CommandSource; import org.spongepowered.api.command.parameter.ArgumentReader;
import org.spongepowered.api.text.Text;
import org.spongepowered.api.world.Location;
import org.spongepowered.api.world.World;
import javax.annotation.Nullable;
import java.util.*; import java.util.*;
import java.util.stream.Collectors;
public class GeyserSpongeCommandExecutor extends GeyserCommandExecutor implements CommandCallable { public class GeyserSpongeCommandExecutor extends GeyserCommandExecutor implements org.spongepowered.api.command.Command.Raw {
public GeyserSpongeCommandExecutor(GeyserImpl geyser, Map<String, Command> commands) { public GeyserSpongeCommandExecutor(GeyserImpl geyser, Map<String, Command> commands) {
super(geyser, commands); super(geyser, commands);
} }
@Override @Override
public CommandResult process(CommandSource source, String arguments) { public CommandResult process(CommandCause cause, ArgumentReader.Mutable arguments) {
GeyserCommandSource commandSender = new SpongeCommandSource(source); GeyserCommandSource commandSource = new SpongeCommandSource(cause);
GeyserSession session = getGeyserSession(commandSender); GeyserSession session = getGeyserSession(commandSource);
String[] args = arguments.split(" "); String[] args = arguments.input().split(" ");
if (args.length > 0) { // This split operation results in an array of length 1, containing a zero length string, if the input string is empty
if (args.length > 0 && !args[0].isEmpty()) {
GeyserCommand command = getCommand(args[0]); GeyserCommand command = getCommand(args[0]);
if (command != null) { if (command != null) {
if (!source.hasPermission(command.permission())) { if (!cause.hasPermission(command.permission())) {
// Not ideal to use log here but we dont get a session cause.audience().sendMessage(Component.text(GeyserLocale.getLocaleStringLog("geyser.bootstrap.command.permission_fail")).color(NamedTextColor.RED));
source.sendMessage(Text.of(ChatColor.RED + GeyserLocale.getLocaleStringLog("geyser.bootstrap.command.permission_fail")));
return CommandResult.success(); return CommandResult.success();
} }
if (command.isBedrockOnly() && session == null) { if (command.isBedrockOnly() && session == null) {
source.sendMessage(Text.of(ChatColor.RED + GeyserLocale.getLocaleStringLog("geyser.bootstrap.command.bedrock_only"))); cause.audience().sendMessage(Component.text(GeyserLocale.getLocaleStringLog("geyser.bootstrap.command.bedrock_only")).color(NamedTextColor.RED));
return CommandResult.success(); return CommandResult.success();
} }
getCommand(args[0]).execute(session, commandSender, args.length > 1 ? Arrays.copyOfRange(args, 1, args.length) : new String[0]); command.execute(session, commandSource, args.length > 1 ? Arrays.copyOfRange(args, 1, args.length) : new String[0]);
} else {
cause.audience().sendMessage(Component.text(GeyserLocale.getLocaleStringLog("geyser.bootstrap.command.not_found")).color(NamedTextColor.RED));
} }
} else { } else {
getCommand("help").execute(session, commandSender, new String[0]); getCommand("help").execute(session, commandSource, new String[0]);
} }
return CommandResult.success(); return CommandResult.success();
} }
@Override @Override
public List<String> getSuggestions(CommandSource source, String arguments, @Nullable Location<World> targetPosition) { public List<CommandCompletion> complete(CommandCause cause, ArgumentReader.Mutable arguments) {
if (arguments.split(" ").length == 1) { if (arguments.input().split(" ").length == 1) {
return tabComplete(new SpongeCommandSource(source)); return tabComplete(new SpongeCommandSource(cause)).stream().map(CommandCompletion::of).collect(Collectors.toList());
} }
return Collections.emptyList(); return Collections.emptyList();
} }
@Override @Override
public boolean testPermission(CommandSource source) { public boolean canExecute(CommandCause cause) {
return true; return true;
} }
@Override @Override
public Optional<Text> getShortDescription(CommandSource source) { public Optional<Component> shortDescription(CommandCause cause) {
return Optional.of(Text.of("The main command for Geyser.")); return Optional.of(Component.text("The main command for Geyser."));
} }
@Override @Override
public Optional<Text> getHelp(CommandSource source) { public Optional<Component> extendedDescription(CommandCause cause) {
return Optional.of(Text.of("/geyser help")); return shortDescription(cause);
} }
@Override @Override
public Text getUsage(CommandSource source) { public Optional<Component> help(@NotNull CommandCause cause) {
return Text.of("/geyser help"); return Optional.of(Component.text("/geyser help"));
}
@Override
public Component usage(CommandCause cause) {
return Component.text("/geyser help");
} }
} }

View file

@ -25,25 +25,37 @@
package org.geysermc.geyser.platform.sponge.command; package org.geysermc.geyser.platform.sponge.command;
import net.kyori.adventure.text.Component;
import org.geysermc.geyser.GeyserImpl; import org.geysermc.geyser.GeyserImpl;
import org.geysermc.geyser.command.GeyserCommandManager; import org.geysermc.geyser.command.GeyserCommandManager;
import org.geysermc.geyser.translator.text.MessageTranslator;
import org.spongepowered.api.Sponge; import org.spongepowered.api.Sponge;
import org.spongepowered.api.command.CommandMapping; import org.spongepowered.api.command.CommandCause;
import org.spongepowered.api.text.Text; import org.spongepowered.api.command.manager.CommandMapping;
import java.util.Optional;
public class GeyserSpongeCommandManager extends GeyserCommandManager { public class GeyserSpongeCommandManager extends GeyserCommandManager {
private final org.spongepowered.api.command.CommandManager handle;
public GeyserSpongeCommandManager(org.spongepowered.api.command.CommandManager handle, GeyserImpl geyser) { public GeyserSpongeCommandManager(GeyserImpl geyser) {
super(geyser); super(geyser);
this.handle = handle;
} }
@Override @Override
public String description(String command) { public String description(String command) {
return handle.get(command).map(CommandMapping::getCallable) if (!Sponge.isServerAvailable()) {
.map(callable -> callable.getShortDescription(Sponge.getServer().getConsole()).orElse(Text.EMPTY)) return "";
.orElse(Text.EMPTY).toPlain(); }
// Note: The command manager may be replaced at any point during the game lifecycle
return Sponge.server().commandManager().commandMapping(command)
.map(this::description)
.map(Optional::get)
.map(MessageTranslator::convertMessage)
.orElse("");
}
public Optional<Component> description(CommandMapping mapping) {
return mapping.registrar().shortDescription(CommandCause.create(), mapping);
} }
} }

View file

@ -26,29 +26,30 @@
package org.geysermc.geyser.platform.sponge.command; package org.geysermc.geyser.platform.sponge.command;
import lombok.AllArgsConstructor; import lombok.AllArgsConstructor;
import net.kyori.adventure.text.serializer.legacy.LegacyComponentSerializer;
import org.checkerframework.checker.nullness.qual.NonNull;
import org.geysermc.geyser.command.GeyserCommandSource; import org.geysermc.geyser.command.GeyserCommandSource;
import org.spongepowered.api.command.CommandSource; import org.spongepowered.api.command.CommandCause;
import org.spongepowered.api.command.source.ConsoleSource; import org.spongepowered.api.entity.living.player.server.ServerPlayer;
import org.spongepowered.api.text.Text;
@AllArgsConstructor @AllArgsConstructor
public class SpongeCommandSource implements GeyserCommandSource { public class SpongeCommandSource implements GeyserCommandSource {
private CommandSource handle; private final CommandCause handle;
@Override @Override
public String name() { public String name() {
return handle.getName(); return handle.friendlyIdentifier().orElse(handle.identifier());
} }
@Override @Override
public void sendMessage(String message) { public void sendMessage(@NonNull String message) {
handle.sendMessage(Text.of(message)); handle.audience().sendMessage(LegacyComponentSerializer.legacySection().deserialize(message));
} }
@Override @Override
public boolean isConsole() { public boolean isConsole() {
return handle instanceof ConsoleSource; return !(handle.cause().root() instanceof ServerPlayer);
} }
@Override @Override

View file

@ -0,0 +1,30 @@
{
"loader": {
"name": "java_plain",
"version": "1.0"
},
"license": "MIT",
"plugins": [
{
"id": "${id}",
"name": "${name}-Sponge",
"version": "${version}",
"entrypoint": "org.geysermc.geyser.platform.sponge.GeyserSpongePlugin",
"description": "${description}",
"links": {
"homepage": "${url}"
},
"contributors": [
{
"name": "${author}"
}
],
"dependencies": [
{
"id": "spongeapi",
"version": "8.0.0"
}
]
}
]
}

View file

@ -0,0 +1,6 @@
{
"pack": {
"description": "Geyser for Sponge",
"pack_format": 6
}
}

View file

@ -51,8 +51,9 @@ public class GeyserVelocityDumpInfo extends BootstrapDumpInfo {
this.platformVersion = proxy.getVersion().getVersion(); this.platformVersion = proxy.getVersion().getVersion();
this.platformVendor = proxy.getVersion().getVendor(); this.platformVendor = proxy.getVersion().getVendor();
this.onlineMode = proxy.getConfiguration().isOnlineMode(); this.onlineMode = proxy.getConfiguration().isOnlineMode();
if (AsteriskSerializer.showSensitive || (proxy.getBoundAddress().getHostString().equals("") || proxy.getBoundAddress().getHostString().equals("0.0.0.0"))) { String hostString = proxy.getBoundAddress().getHostString();
this.serverIP = proxy.getBoundAddress().getHostString(); if (AsteriskSerializer.showSensitive || (hostString.equals("") || hostString.equals("0.0.0.0"))) {
this.serverIP = hostString;
} else { } else {
this.serverIP = "***"; this.serverIP = "***";
} }

View file

@ -63,6 +63,9 @@ public class GeyserVelocityCommandExecutor extends GeyserCommandExecutor impleme
return; return;
} }
command.execute(session, sender, invocation.arguments().length > 1 ? Arrays.copyOfRange(invocation.arguments(), 1, invocation.arguments().length) : new String[0]); command.execute(session, sender, invocation.arguments().length > 1 ? Arrays.copyOfRange(invocation.arguments(), 1, invocation.arguments().length) : new String[0]);
} else {
String message = GeyserLocale.getPlayerLocaleString("geyser.bootstrap.command.not_found", sender.locale());
sender.sendMessage(ChatColor.RED + message);
} }
} else { } else {
getCommand("help").execute(session, sender, new String[0]); getCommand("help").execute(session, sender, new String[0]);

View file

@ -9,7 +9,7 @@ dependencies {
tasks { tasks {
processResources { processResources {
filesMatching(listOf("plugin.yml", "bungee.yml", "velocity-plugin.json")) { filesMatching(listOf("plugin.yml", "bungee.yml", "velocity-plugin.json", "META-INF/sponge_plugins.json")) {
expand( expand(
"id" to "Geyser", "id" to "Geyser",
"name" to "Geyser", "name" to "Geyser",

@ -1 +1 @@
Subproject commit 51d6f5ba7d85bfda318879dad34481d9ef4d488d Subproject commit a9cf5999af605902b18dd5c77d3562481f8d7f3d

@ -1 +1 @@
Subproject commit 2c68dab9d751f78b2f5b0298da5e338ad6bc07ca Subproject commit f1c9c2fbba0e102dc4f8c96dd9485f7ec9768174

View file

@ -25,7 +25,7 @@ adapters = "1.5-SNAPSHOT"
commodore = "2.2" commodore = "2.2"
bungeecord = "a7c6ede" bungeecord = "a7c6ede"
velocity = "3.0.0" velocity = "3.0.0"
sponge = "7.1.0" sponge = "8.0.0"
[libraries] [libraries]
jackson-annotations = { group = "com.fasterxml.jackson.core", name = "jackson-annotations", version.ref = "jackson" } jackson-annotations = { group = "com.fasterxml.jackson.core", name = "jackson-annotations", version.ref = "jackson" }