1
0
mirror of https://github.com/GeyserMC/Floodgate.git synced 2026-01-04 15:31:48 +00:00

Added a way to handle packets easily. ProtocolSupport support fixed

This commit is contained in:
Tim203
2021-04-23 00:47:14 +02:00
parent 63b6e56a0d
commit c722c8e8c8
14 changed files with 561 additions and 26 deletions

View File

@@ -0,0 +1,43 @@
/*
* Copyright (c) 2019-2021 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/Floodgate
*/
package org.geysermc.floodgate.api.packet;
import io.netty.channel.ChannelHandlerContext;
/**
* For advanced users only! You shouldn't play with this unless you know what you're doing.
*/
public interface PacketHandler {
/**
* Called when a registered packet has been seen.
*
* @param ctx the channel handler context of the connection
* @param packet the packet instance
* @param serverbound if the packet is serverbound
* @return the packet it should forward. Can be null or a different packet / instance
*/
Object handle(ChannelHandlerContext ctx, Object packet, boolean serverbound);
}

View File

@@ -0,0 +1,67 @@
/*
* Copyright (c) 2019-2021 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/Floodgate
*/
package org.geysermc.floodgate.api.packet;
import io.netty.channel.ChannelHandlerContext;
import org.geysermc.floodgate.api.util.TriFunction;
public interface PacketHandlers {
/**
* Register a specific class for a specific consumer.
*
* @param handler the packet handler instance
* @param packetClass the class to start listening for
* @param consumer the consumer to call once the packet has been seen
*/
void register(
PacketHandler handler,
Class<?> packetClass,
TriFunction<ChannelHandlerContext, Object, Boolean, Object> consumer);
/**
* Register a specific class for the given packet handler's {@link
* PacketHandler#handle(ChannelHandlerContext, Object, boolean)}.
*
* @param handler the packet handler instance
* @param packetClass the class to start listening for
*/
default void register(PacketHandler handler, Class<?> packetClass) {
register(handler, packetClass, handler::handle);
}
/**
* Register every packet for the given packet handler's {@link PacketHandler#handle(ChannelHandlerContext,
* Object, boolean)}
*/
void registerAll(PacketHandler handler);
/**
* Unregisters all handlers registered under the given packet handler
*
* @param handler the packet handler instance
*/
void deregister(PacketHandler handler);
}

View File

@@ -0,0 +1,71 @@
/*
* Copyright (c) 2019-2021 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/Floodgate
*/
package org.geysermc.floodgate.api.util;
import java.util.Objects;
import java.util.function.Function;
/**
* Represents a function that accepts three arguments and produces a result. This is the three-arity
* specialization of {@link Function}.
*
* <p>This is a <a href="package-summary.html">functional interface</a>
* whose functional method is {@link #apply(Object, Object, Object)}.
*
* @param <T> the type of the first argument to the function
* @param <U> the type of the second argument to the function
* @param <V> the type of the third argument of the function
* @param <R> the type of the result of the function
* @see Function
* @since 1.8
*/
@FunctionalInterface
public interface TriFunction<T, U, V, R> {
/**
* Performs this operation on the given arguments.
*
* @param t the first input argument
* @param u the second input argument
* @param v the third input argument
*/
R apply(T t, U u, V v);
/**
* Returns a composed function that first applies this function to its input, and then applies
* the {@code after} function to the result. If evaluation of either function throws an
* exception, it is relayed to the caller of the composed function.
*
* @param <S> the type of output of the {@code after} function, and of the composed function
* @param after the function to apply after this function is applied
* @return a composed function that first applies this function and then applies the {@code
* after} function
* @throws NullPointerException if after is null
*/
default <S> TriFunction<T, U, V, S> andThen(Function<? super R, ? extends S> after) {
Objects.requireNonNull(after);
return (T t, U u, V v) -> after.apply(apply(t, u, v));
}
}

View File

@@ -30,6 +30,7 @@ import com.google.inject.Singleton;
import com.google.inject.multibindings.ProvidesIntoSet;
import org.geysermc.floodgate.addon.AddonManagerAddon;
import org.geysermc.floodgate.addon.DebugAddon;
import org.geysermc.floodgate.addon.PacketHandlerAddon;
import org.geysermc.floodgate.addon.data.BungeeDataAddon;
import org.geysermc.floodgate.api.inject.InjectorAddon;
import org.geysermc.floodgate.register.AddonRegister;
@@ -57,4 +58,10 @@ public final class BungeeAddonModule extends AbstractModule {
public InjectorAddon debugAddon() {
return new DebugAddon();
}
@Singleton
@ProvidesIntoSet
public InjectorAddon packetHandlerAddon() {
return new PacketHandlerAddon();
}
}

View File

@@ -0,0 +1,78 @@
/*
* Copyright (c) 2019-2021 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/Floodgate
*/
package org.geysermc.floodgate.addon;
import com.google.inject.Inject;
import com.google.inject.name.Named;
import io.netty.channel.Channel;
import io.netty.channel.ChannelPipeline;
import org.geysermc.floodgate.addon.packethandler.ChannelInPacketHandler;
import org.geysermc.floodgate.addon.packethandler.ChannelOutPacketHandler;
import org.geysermc.floodgate.api.inject.InjectorAddon;
import org.geysermc.floodgate.packet.PacketHandlersImpl;
import org.geysermc.floodgate.util.Utils;
public class PacketHandlerAddon implements InjectorAddon {
@Inject private PacketHandlersImpl packetHandlers;
@Inject
@Named("packetEncoder")
private String packetEncoder;
@Inject
@Named("packetDecoder")
private String packetDecoder;
@Override
public void onInject(Channel channel, boolean toServer) {
channel.pipeline().addAfter(
packetEncoder, "floodgate_phaddon_out",
new ChannelOutPacketHandler(packetHandlers, toServer)
).addAfter(
packetDecoder, "floodgate_phaddon_in",
new ChannelInPacketHandler(packetHandlers, toServer)
);
}
@Override
public void onLoginDone(Channel channel) {
}
@Override
public void onRemoveInject(Channel channel) {
ChannelPipeline pipeline = channel.pipeline();
Utils.removeHandler(pipeline, "floodgate_phaddon_out");
Utils.removeHandler(pipeline, "floodgate_phaddon_in");
}
@Override
public boolean shouldInject() {
// this means that there has to be at least one PacketHandler registered to inject
return packetHandlers.hasHandlers();
}
}

View File

@@ -0,0 +1,56 @@
/*
* Copyright (c) 2019-2021 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/Floodgate
*/
package org.geysermc.floodgate.addon.packethandler;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.SimpleChannelInboundHandler;
import org.geysermc.floodgate.api.util.TriFunction;
import org.geysermc.floodgate.packet.PacketHandlersImpl;
public class ChannelInPacketHandler extends SimpleChannelInboundHandler<Object> {
private final PacketHandlersImpl packetHandlers;
private final boolean toServer;
public ChannelInPacketHandler(PacketHandlersImpl packetHandlers, boolean toServer) {
this.packetHandlers = packetHandlers;
this.toServer = toServer;
}
@Override
protected void channelRead0(ChannelHandlerContext ctx, Object msg) {
Object packet = msg;
for (TriFunction<ChannelHandlerContext, Object, Boolean, Object> consumer :
packetHandlers.getPacketHandlers(msg.getClass())) {
Object res = consumer.apply(ctx, msg, toServer);
if (!res.equals(msg)) {
packet = res;
}
}
ctx.fireChannelRead(packet);
}
}

View File

@@ -0,0 +1,57 @@
/*
* Copyright (c) 2019-2021 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/Floodgate
*/
package org.geysermc.floodgate.addon.packethandler;
import io.netty.channel.ChannelHandlerContext;
import io.netty.handler.codec.MessageToMessageEncoder;
import java.util.List;
import org.geysermc.floodgate.api.util.TriFunction;
import org.geysermc.floodgate.packet.PacketHandlersImpl;
public class ChannelOutPacketHandler extends MessageToMessageEncoder<Object> {
private final PacketHandlersImpl packetHandlers;
private final boolean toServer;
public ChannelOutPacketHandler(PacketHandlersImpl packetHandlers, boolean toServer) {
this.packetHandlers = packetHandlers;
this.toServer = toServer;
}
@Override
protected void encode(ChannelHandlerContext ctx, Object msg, List<Object> out) {
Object packet = msg;
for (TriFunction<ChannelHandlerContext, Object, Boolean, Object> consumer :
packetHandlers.getPacketHandlers(msg.getClass())) {
Object res = consumer.apply(ctx, msg, toServer);
if (!res.equals(msg)) {
packet = res;
}
}
out.add(packet);
}
}

View File

@@ -38,6 +38,7 @@ import org.geysermc.floodgate.api.SimpleFloodgateApi;
import org.geysermc.floodgate.api.handshake.HandshakeHandlers;
import org.geysermc.floodgate.api.inject.PlatformInjector;
import org.geysermc.floodgate.api.logger.FloodgateLogger;
import org.geysermc.floodgate.api.packet.PacketHandlers;
import org.geysermc.floodgate.api.player.FloodgatePlayer;
import org.geysermc.floodgate.config.FloodgateConfig;
import org.geysermc.floodgate.config.FloodgateConfigHolder;
@@ -51,6 +52,7 @@ import org.geysermc.floodgate.crypto.Base64Topping;
import org.geysermc.floodgate.crypto.FloodgateCipher;
import org.geysermc.floodgate.crypto.KeyProducer;
import org.geysermc.floodgate.inject.CommonPlatformInjector;
import org.geysermc.floodgate.packet.PacketHandlersImpl;
import org.geysermc.floodgate.player.FloodgateHandshakeHandler;
import org.geysermc.floodgate.pluginmessage.PluginMessageManager;
import org.geysermc.floodgate.skin.SkinApplier;
@@ -66,6 +68,9 @@ public class CommonModule extends AbstractModule {
bind(FloodgateApi.class).to(SimpleFloodgateApi.class);
bind(PlatformInjector.class).to(CommonPlatformInjector.class);
bind(HandshakeHandlers.class).to(HandshakeHandlersImpl.class);
bind(PacketHandlers.class).to(PacketHandlersImpl.class);
bind(PacketHandlersImpl.class).asEagerSingleton();
}
@Provides

View File

@@ -0,0 +1,120 @@
/*
* Copyright (c) 2019-2021 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/Floodgate
*/
package org.geysermc.floodgate.packet;
import io.netty.channel.ChannelHandlerContext;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import lombok.AllArgsConstructor;
import lombok.Getter;
import org.geysermc.floodgate.api.packet.PacketHandler;
import org.geysermc.floodgate.api.packet.PacketHandlers;
import org.geysermc.floodgate.api.util.TriFunction;
public final class PacketHandlersImpl implements PacketHandlers {
private final Map<PacketHandler, List<HandlerEntry>> handlers = new HashMap<>();
private final Set<TriFunction<ChannelHandlerContext, Object, Boolean, Object>> globalPacketHandlers = new HashSet<>();
private final Map<Class<?>, Set<TriFunction<ChannelHandlerContext, Object, Boolean, Object>>> packetHandlers = new HashMap<>();
@Override
public void register(
PacketHandler handler,
Class<?> packetClass,
TriFunction<ChannelHandlerContext, Object, Boolean, Object> consumer) {
if (handler == null || packetClass == null || consumer == null) {
return;
}
handlers.computeIfAbsent(handler, $ -> new ArrayList<>())
.add(new HandlerEntry(packetClass, consumer));
packetHandlers.computeIfAbsent(packetClass, $ -> new HashSet<>(globalPacketHandlers))
.add(consumer);
}
@Override
public void registerAll(PacketHandler handler) {
if (handler == null) {
return;
}
TriFunction<ChannelHandlerContext, Object, Boolean, Object> packetHandler = handler::handle;
handlers.computeIfAbsent(handler, $ -> new ArrayList<>())
.add(new HandlerEntry(null, packetHandler));
globalPacketHandlers.add(packetHandler);
for (Set<TriFunction<ChannelHandlerContext, Object, Boolean, Object>> handle : packetHandlers.values()) {
handle.add(packetHandler);
}
}
@Override
public void deregister(PacketHandler handler) {
if (handler == null) {
return;
}
List<HandlerEntry> values = handlers.remove(handler);
if (values != null) {
for (HandlerEntry value : values) {
Set<?> handlers = packetHandlers.get(value.getPacket());
if (handlers != null) {
handlers.removeIf(o -> o.equals(value.getHandler()));
if (handlers.isEmpty()) {
packetHandlers.remove(value.getPacket());
}
}
globalPacketHandlers.remove(value.getHandler());
}
}
}
public Collection<TriFunction<ChannelHandlerContext, Object, Boolean, Object>> getPacketHandlers(
Class<?> packet) {
return packetHandlers.getOrDefault(packet, Collections.emptySet());
}
public boolean hasHandlers() {
return !handlers.isEmpty();
}
@AllArgsConstructor
@Getter
private final static class HandlerEntry {
private final Class<?> packet;
private final TriFunction<ChannelHandlerContext, Object, Boolean, Object> handler;
}
}

View File

@@ -28,7 +28,6 @@ package org.geysermc.floodgate;
import com.google.inject.Guice;
import com.google.inject.Injector;
import org.bukkit.plugin.java.JavaPlugin;
import org.geysermc.floodgate.api.InstanceHolder;
import org.geysermc.floodgate.api.logger.FloodgateLogger;
import org.geysermc.floodgate.module.PluginMessageModule;
import org.geysermc.floodgate.module.ServerCommonModule;
@@ -42,6 +41,7 @@ import org.geysermc.floodgate.util.SpigotProtocolSupportListener;
public final class SpigotPlugin extends JavaPlugin {
private SpigotPlatform platform;
private Injector injector;
@Override
public void onLoad() {
@@ -49,7 +49,7 @@ public final class SpigotPlugin extends JavaPlugin {
ReflectionUtils.setPrefix("net.minecraft.server." + minecraftVersion);
long ctm = System.currentTimeMillis();
Injector injector = Guice.createInjector(
injector = Guice.createInjector(
new ServerCommonModule(getDataFolder().toPath()),
new SpigotPlatformModule(this)
);
@@ -72,8 +72,7 @@ public final class SpigotPlugin extends JavaPlugin {
// add ProtocolSupport support (hack)
if (getServer().getPluginManager().getPlugin("ProtocolSupport") != null) {
InstanceHolder.getHandshakeHandlers()
.addHandshakeHandler(new SpigotProtocolSupportHandler());
injector.getInstance(SpigotProtocolSupportHandler.class);
SpigotProtocolSupportListener.registerHack(this);
}
}

View File

@@ -30,6 +30,7 @@ import com.google.inject.Singleton;
import com.google.inject.multibindings.ProvidesIntoSet;
import org.geysermc.floodgate.addon.AddonManagerAddon;
import org.geysermc.floodgate.addon.DebugAddon;
import org.geysermc.floodgate.addon.PacketHandlerAddon;
import org.geysermc.floodgate.addon.data.SpigotDataAddon;
import org.geysermc.floodgate.api.inject.InjectorAddon;
import org.geysermc.floodgate.register.AddonRegister;
@@ -57,4 +58,10 @@ public final class SpigotAddonModule extends AbstractModule {
public InjectorAddon debugAddon() {
return new DebugAddon();
}
@Singleton
@ProvidesIntoSet
public InjectorAddon packetHandlerAddon() {
return new PacketHandlerAddon();
}
}

View File

@@ -25,13 +25,18 @@
package org.geysermc.floodgate.util;
import com.google.inject.Inject;
import com.google.inject.name.Named;
import io.netty.channel.Channel;
import io.netty.channel.ChannelHandlerContext;
import io.netty.util.AttributeKey;
import java.lang.reflect.Method;
import java.util.UUID;
import org.geysermc.floodgate.api.handshake.HandshakeData;
import org.geysermc.floodgate.api.handshake.HandshakeHandler;
import org.geysermc.floodgate.api.packet.PacketHandler;
import org.geysermc.floodgate.api.packet.PacketHandlers;
import org.geysermc.floodgate.api.player.FloodgatePlayer;
public class SpigotProtocolSupportHandler implements HandshakeHandler {
public class SpigotProtocolSupportHandler implements PacketHandler {
private static final Method getFromChannel;
private static final Method getLoginProfile;
@@ -51,7 +56,8 @@ public class SpigotProtocolSupportHandler implements HandshakeHandler {
getFromChannel = ReflectionUtils.getMethod(connectionImpl, "getFromChannel", Channel.class);
getLoginProfile = ReflectionUtils.getMethod(connectionImpl, "getLoginProfile");
Class<?> profile = ReflectionUtils.getClass("protocolsupport.protocol.utils.authlib.LoginProfile");
Class<?> profile =
ReflectionUtils.getClass("protocolsupport.protocol.utils.authlib.LoginProfile");
setName = ReflectionUtils.getMethod(profile, "setName", String.class);
setOriginalName = ReflectionUtils.getMethod(profile, "setOriginalName", String.class);
@@ -69,24 +75,38 @@ public class SpigotProtocolSupportHandler implements HandshakeHandler {
Class<?> loginListener = ReflectionUtils.getClass(
"protocolsupport.protocol.packet.handler.AbstractLoginListener");
handleLoginStart = ReflectionUtils.getMethod(loginListener, "handleLoginStart", String.class);
handleLoginStart =
ReflectionUtils.getMethod(loginListener, "handleLoginStart", String.class);
}
@Inject
@Named("playerAttribute")
private AttributeKey<FloodgatePlayer> playerAttribute;
@Inject
public void register(PacketHandlers packetHandlers) {
packetHandlers.register(this, ReflectionUtils.getPrefixedClass("PacketLoginInStart"));
}
@Override
public void handle(HandshakeData data) {
if (data.isFloodgatePlayer() && !SpigotUtils.isBungeeData()) {
Object connection = ReflectionUtils.invoke(null, getFromChannel, data.getChannel());
Object profile = ReflectionUtils.invoke(connection, getLoginProfile);
// set correct uuid and name on ProtocolSupport's end, since we skip the LoginStart
ReflectionUtils.invoke(profile, setName, data.getCorrectUsername());
ReflectionUtils.invoke(profile, setOriginalName, data.getCorrectUsername());
ReflectionUtils.invoke(profile, setUuid, data.getCorrectUniqueId());
ReflectionUtils.invoke(profile, setOriginalUuid, data.getCorrectUniqueId());
Object temp = ReflectionUtils.invoke(connection, getNetworkManagerWrapper);
temp = ReflectionUtils.invoke(temp, getPacketListener);
ReflectionUtils.invoke(temp, handleLoginStart, data.getCorrectUsername());
public Object handle(ChannelHandlerContext ctx, Object packet, boolean serverbound) {
FloodgatePlayer player = ctx.channel().attr(playerAttribute).get();
if (player == null) {
return packet;
}
Object connection = ReflectionUtils.invoke(null, getFromChannel, ctx.channel());
Object profile = ReflectionUtils.invoke(connection, getLoginProfile);
// set correct uuid and name on ProtocolSupport's end, since we skip the LoginStart
ReflectionUtils.invoke(profile, setName, player.getCorrectUsername());
ReflectionUtils.invoke(profile, setOriginalName, player.getCorrectUsername());
ReflectionUtils.invoke(profile, setUuid, player.getCorrectUniqueId());
ReflectionUtils.invoke(profile, setOriginalUuid, player.getCorrectUniqueId());
Object temp = ReflectionUtils.invoke(connection, getNetworkManagerWrapper);
temp = ReflectionUtils.invoke(temp, getPacketListener);
ReflectionUtils.invoke(temp, handleLoginStart, player.getCorrectUsername());
return packet;
}
}

View File

@@ -4,6 +4,4 @@ version: ${project.version}
author: ${project.organization.name}
website: ${project.url}
main: org.geysermc.floodgate.SpigotPlugin
api-version: 1.13
softdepend:
- ProtocolSupport
api-version: 1.13

View File

@@ -30,6 +30,7 @@ import com.google.inject.Singleton;
import com.google.inject.multibindings.ProvidesIntoSet;
import org.geysermc.floodgate.addon.AddonManagerAddon;
import org.geysermc.floodgate.addon.DebugAddon;
import org.geysermc.floodgate.addon.PacketHandlerAddon;
import org.geysermc.floodgate.addon.data.VelocityDataAddon;
import org.geysermc.floodgate.api.inject.InjectorAddon;
import org.geysermc.floodgate.register.AddonRegister;
@@ -57,4 +58,10 @@ public final class VelocityAddonModule extends AbstractModule {
public InjectorAddon debugAddon() {
return new DebugAddon();
}
@Singleton
@ProvidesIntoSet
public InjectorAddon packetHandlerAddon() {
return new PacketHandlerAddon();
}
}