Merge remote-tracking branch 'origin/feature/floodgate-merge'

# Conflicts:
#	bootstrap/bungeecord/src/main/java/org/geysermc/geyser/platform/bungeecord/GeyserBungeePlugin.java
#	bootstrap/fabric/src/main/java/org/geysermc/geyser/platform/fabric/GeyserFabricMod.java
#	bootstrap/spigot/src/main/java/org/geysermc/geyser/platform/spigot/GeyserSpigotPlugin.java
#	bootstrap/sponge/src/main/java/org/geysermc/geyser/platform/sponge/GeyserSpongePlugin.java
#	bootstrap/standalone/src/main/java/org/geysermc/geyser/platform/standalone/GeyserStandaloneBootstrap.java
#	bootstrap/velocity/src/main/java/org/geysermc/geyser/platform/velocity/GeyserVelocityPlugin.java
#	core/build.gradle.kts
#	core/src/main/java/org/geysermc/geyser/GeyserImpl.java
#	core/src/main/java/org/geysermc/geyser/command/defaults/VersionCommand.java
#	core/src/main/java/org/geysermc/geyser/dump/DumpInfo.java
#	core/src/main/java/org/geysermc/geyser/entity/type/FireworkEntity.java
#	core/src/main/java/org/geysermc/geyser/network/netty/LocalSession.java
#	core/src/main/java/org/geysermc/geyser/session/GeyserSession.java
#	core/src/main/java/org/geysermc/geyser/translator/protocol/bedrock/BedrockCommandRequestTranslator.java
#	core/src/main/java/org/geysermc/geyser/translator/protocol/bedrock/BedrockNetworkStackLatencyTranslator.java
#	core/src/main/java/org/geysermc/geyser/translator/protocol/java/JavaCustomPayloadTranslator.java
#	core/src/main/java/org/geysermc/geyser/translator/protocol/java/level/JavaBlockUpdateTranslator.java
#	gradle/libs.versions.toml
This commit is contained in:
Tim203 2023-05-05 12:09:20 +02:00
commit 6ca53f5bf3
No known key found for this signature in database
GPG key ID: 736F3CD49EF01DBF
56 changed files with 733 additions and 315 deletions

View file

@ -21,6 +21,8 @@ dependencies {
attribute(TargetJvmVersion.TARGET_JVM_VERSION_ATTRIBUTE, 17)
}
}
implementation("org.geysermc.floodgate", "spigot", "2.2.0-SNAPSHOT")
}
platformRelocate("it.unimi.dsi.fastutil")
@ -32,6 +34,7 @@ platformRelocate("me.lucko.commodore")
// These dependencies are already present on the platform
provided(libs.viaversion)
provided("com.mojang", "authlib", "1.5.21")
application {
mainClass.set("org.geysermc.geyser.platform.spigot.GeyserSpigotMain")

View file

@ -41,6 +41,7 @@ public final class GeyserSpigotConfiguration extends GeyserJacksonConfiguration
@JsonIgnore
private Path floodgateKeyPath;
// TODO REMOVE
public void loadFloodgate(GeyserSpigotPlugin plugin) {
Plugin floodgate = Bukkit.getPluginManager().getPlugin("floodgate");
Path geyserDataFolder = plugin.getDataFolder().toPath();

View file

@ -33,6 +33,8 @@ import io.netty.channel.local.LocalAddress;
import io.netty.util.concurrent.DefaultThreadFactory;
import org.bukkit.Bukkit;
import org.geysermc.geyser.GeyserBootstrap;
import org.geysermc.geyser.GeyserImpl;
import org.geysermc.geyser.api.network.AuthType;
import org.geysermc.geyser.network.netty.GeyserInjector;
import org.geysermc.geyser.network.netty.LocalServerChannelWrapper;
import org.geysermc.geyser.network.netty.LocalSession;
@ -119,10 +121,17 @@ public class GeyserSpigotInjector extends GeyserInjector {
@Override
protected void initChannel(Channel ch) throws Exception {
initChannel.invoke(childHandler, ch);
if (bootstrap.getGeyserConfig().isDisableCompression() && GeyserSpigotCompressionDisabler.ENABLED) {
ch.pipeline().addAfter("encoder", "geyser-compression-disabler", new GeyserSpigotCompressionDisabler());
}
if (GeyserImpl.getInstance().getConfig().getRemote().authType() == AuthType.FLOODGATE) {
// we have to add the packet blocker in the data handler, otherwise ProtocolSupport breaks
ch.pipeline().addBefore(
"packet_handler", "geyser_data_handler",
new SpigotHybridChannelHandler()
);
}
}
})
// Set to MAX_PRIORITY as MultithreadEventLoopGroup#newDefaultThreadFactory which DefaultEventLoopGroup implements does by default
@ -174,7 +183,7 @@ public class GeyserSpigotInjector extends GeyserInjector {
*/
private void workAroundWeirdBug(GeyserBootstrap bootstrap) {
MinecraftProtocol protocol = new MinecraftProtocol();
LocalSession session = new LocalSession(bootstrap.getGeyserConfig().getRemote().address(),
LocalSession session = new LocalSession(null, bootstrap.getGeyserConfig().getRemote().address(),
bootstrap.getGeyserConfig().getRemote().port(), this.serverSocketAddress,
InetAddress.getLoopbackAddress().getHostAddress(), protocol, protocol.createHelper());
session.connect();

View file

@ -42,7 +42,9 @@ import org.bukkit.permissions.Permission;
import org.bukkit.permissions.PermissionDefault;
import org.bukkit.plugin.Plugin;
import org.bukkit.plugin.java.JavaPlugin;
import org.geysermc.common.PlatformType;
import org.geysermc.floodgate.pluginmessage.SpigotSkinApplier;
import org.geysermc.floodgate.skin.SkinApplier;
import org.geysermc.floodgate.util.SpigotVersionSpecificMethods;
import org.geysermc.geyser.Constants;
import org.geysermc.geyser.GeyserBootstrap;
import org.geysermc.geyser.GeyserImpl;
@ -52,6 +54,8 @@ import org.geysermc.geyser.api.extension.Extension;
import org.geysermc.geyser.command.GeyserCommandManager;
import org.geysermc.geyser.configuration.GeyserConfiguration;
import org.geysermc.geyser.dump.BootstrapDumpInfo;
import org.geysermc.geyser.hybrid.HybridProvider;
import org.geysermc.geyser.hybrid.IntegratedHybridProvider;
import org.geysermc.geyser.level.WorldManager;
import org.geysermc.geyser.network.GameProtocol;
import org.geysermc.geyser.ping.GeyserLegacyPingPassthrough;
@ -66,6 +70,7 @@ import org.geysermc.geyser.platform.spigot.world.manager.GeyserSpigotNativeWorld
import org.geysermc.geyser.platform.spigot.world.manager.GeyserSpigotWorldManager;
import org.geysermc.geyser.text.GeyserLocale;
import org.geysermc.geyser.util.FileUtils;
import org.geysermc.geyser.util.PlatformType;
import org.jetbrains.annotations.NotNull;
import java.io.File;
@ -154,7 +159,7 @@ public class GeyserSpigotPlugin extends JavaPlugin implements GeyserBootstrap {
GeyserConfiguration.checkGeyserConfiguration(geyserConfig, geyserLogger);
this.geyser = GeyserImpl.load(PlatformType.SPIGOT, this);
this.geyser = GeyserImpl.load(PlatformType.SPIGOT, this, null);
}
@Override
@ -165,11 +170,22 @@ public class GeyserSpigotPlugin extends JavaPlugin implements GeyserBootstrap {
return;
}
// Remove this in like a year
if (Bukkit.getPluginManager().getPlugin("floodgate-bukkit") != null) {
geyserLogger.severe(GeyserLocale.getLocaleStringLog("geyser.bootstrap.floodgate.outdated", Constants.FLOODGATE_DOWNLOAD_LOCATION));
this.getPluginLoader().disablePlugin(this);
return;
// By default this should be localhost but may need to be changed in some circumstances
if (this.geyserConfig.getRemote().address().equalsIgnoreCase("auto")) {
geyserConfig.setAutoconfiguredRemote(true);
// Don't use localhost if not listening on all interfaces
if (!Bukkit.getIp().equals("0.0.0.0") && !Bukkit.getIp().equals("")) {
geyserConfig.getRemote().setAddress(Bukkit.getIp());
}
geyserConfig.getRemote().setPort(Bukkit.getPort());
}
if (geyserConfig.getBedrock().isCloneRemotePort()) {
geyserConfig.getBedrock().setPort(Bukkit.getPort());
}
if (Bukkit.getPluginManager().getPlugin("floodgate") != null) {
geyserLogger.severe("WHY DO YOU HAVE FLOODGATE INSTALLED!!!!!!! REMOVE IT!!!!");
}
this.geyserCommandManager = new GeyserSpigotCommandManager(geyser);
@ -408,6 +424,16 @@ public class GeyserSpigotPlugin extends JavaPlugin implements GeyserBootstrap {
return this.geyserInjector.getServerSocketAddress();
}
@Override
public HybridProvider createHybridProvider(GeyserImpl geyser) {
return new IntegratedHybridProvider(geyser);
}
@Override
public SkinApplier createSkinApplier() {
return new SpigotSkinApplier(new SpigotVersionSpecificMethods(this), this);
}
/**
* @return the server version before ViaVersion finishes initializing
*/

View file

@ -0,0 +1,88 @@
/*
* Copyright (c) 2019-2022 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.geyser.platform.spigot;
import com.mojang.authlib.GameProfile;
import io.netty.channel.ChannelHandler;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.ChannelInboundHandlerAdapter;
import org.geysermc.floodgate.util.ClassNames;
import org.geysermc.geyser.hybrid.IntegratedHybridProvider;
import org.geysermc.geyser.session.GeyserSession;
import javax.annotation.Nonnull;
import static org.geysermc.floodgate.util.ReflectionUtils.setValue;
@ChannelHandler.Sharable
public final class SpigotHybridChannelHandler extends ChannelInboundHandlerAdapter {
@Override
public void channelRead(@Nonnull ChannelHandlerContext ctx, @Nonnull Object packet) throws Exception {
GeyserSession session = ctx.channel().attr(IntegratedHybridProvider.SESSION_KEY).get();
// TODO generify this code within Floodgate
if (ClassNames.LOGIN_START_PACKET.isInstance(packet)) {
Object networkManager = ctx.channel().pipeline().get("packet_handler");
Object packetListener = ClassNames.PACKET_LISTENER.get(networkManager);
setValue(networkManager, "spoofedUUID", session.javaUuid());
// check if the server is actually in the Login state
if (!ClassNames.LOGIN_LISTENER.isInstance(packetListener)) {
// player is not in the login state, abort
// I would've liked to close the channel for security reasons, but our big friend
// ProtocolSupport, who likes to break things, doesn't work otherwise
ctx.pipeline().remove(this);
return;
}
// set the player his GameProfile, we can't change the username without this
GameProfile gameProfile = new GameProfile(
// TODO testing only
session.javaUuid(), session.javaUsername()
);
setValue(packetListener, ClassNames.LOGIN_PROFILE, gameProfile);
// we have to fake the offline player (login) cycle
// just like on Spigot:
// LoginListener#initUUID
// new LoginHandler().fireEvents();
// and the tick of LoginListener will do the rest
ClassNames.INIT_UUID.invoke(packetListener);
Object loginHandler = ClassNames.LOGIN_HANDLER_CONSTRUCTOR.newInstance(packetListener);
ClassNames.FIRE_LOGIN_EVENTS.invoke(loginHandler);
ctx.pipeline().remove(this);
return;
}
ctx.fireChannelRead(packet);
}
}