mirror of
https://github.com/GeyserMC/Geyser.git
synced 2024-08-14 23:57:35 +00:00
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:
commit
6ca53f5bf3
56 changed files with 733 additions and 315 deletions
|
@ -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")
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -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
|
||||
*/
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue