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:
@@ -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);
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
@@ -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));
|
||||
}
|
||||
}
|
||||
@@ -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();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
@@ -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
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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
|
||||
@@ -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();
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user