Skip to content

Commit

Permalink
Reformatted packet handling. Moved packet snapshot in separated class
Browse files Browse the repository at this point in the history
  • Loading branch information
Nan1t committed Feb 7, 2022
1 parent 6aea039 commit 9269751
Show file tree
Hide file tree
Showing 11 changed files with 408 additions and 273 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -43,14 +43,15 @@ protected void initChannel(Channel channel) {

PacketDecoder decoder = new PacketDecoder();
PacketEncoder encoder = new PacketEncoder();
ClientConnection connection = new ClientConnection(channel, server, decoder, encoder);

pipeline.addLast("timeout", new ReadTimeoutHandler(server.getConfig().getReadTimeout(),
TimeUnit.MILLISECONDS));
pipeline.addLast("frame_decoder", new VarIntFrameDecoder());
pipeline.addLast("frame_encoder", new VarIntLengthEncoder());
pipeline.addLast("decoder", decoder);
pipeline.addLast("encoder", encoder);
pipeline.addLast("handler", new ClientConnection(channel, server, decoder, encoder));
pipeline.addLast("handler", connection);
}

}
321 changes: 50 additions & 271 deletions src/main/java/ru/nanit/limbo/connection/ClientConnection.java

Large diffs are not rendered by default.

129 changes: 129 additions & 0 deletions src/main/java/ru/nanit/limbo/connection/PacketHandler.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,129 @@
/*
* Copyright (C) 2020 Nan1t
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/

package ru.nanit.limbo.connection;

import io.netty.buffer.Unpooled;
import ru.nanit.limbo.LimboConstants;
import ru.nanit.limbo.protocol.packets.PacketHandshake;
import ru.nanit.limbo.protocol.packets.login.PacketLoginPluginRequest;
import ru.nanit.limbo.protocol.packets.login.PacketLoginPluginResponse;
import ru.nanit.limbo.protocol.packets.login.PacketLoginStart;
import ru.nanit.limbo.protocol.packets.status.PacketStatusPing;
import ru.nanit.limbo.protocol.packets.status.PacketStatusRequest;
import ru.nanit.limbo.server.LimboServer;
import ru.nanit.limbo.server.Logger;
import ru.nanit.limbo.util.UuidUtil;

import java.util.concurrent.ThreadLocalRandom;

public class PacketHandler {

private final LimboServer server;

public PacketHandler(LimboServer server) {
this.server = server;
}

public void handle(ClientConnection conn, PacketHandshake packet) {
conn.updateVersion(packet.getVersion());
conn.updateState(packet.getNextState());

Logger.debug("Pinged from %s [%s]", conn.getAddress(),
conn.getClientVersion().toString());

if (server.getConfig().getInfoForwarding().isLegacy()) {
String[] split = packet.getHost().split("\00");

if (split.length == 3 || split.length == 4) {
conn.setAddress(split[1]);
conn.getGameProfile().setUuid(UuidUtil.fromString(split[2]));
} else {
conn.disconnectLogin("You've enabled player info forwarding. You need to connect with proxy");
}
} else if (server.getConfig().getInfoForwarding().isBungeeGuard()) {
if (!conn.checkBungeeGuardHandshake(packet.getHost())) {
conn.disconnectLogin("Invalid BungeeGuard token or handshake format");
}
}
}

public void handle(ClientConnection conn, PacketStatusRequest packet) {
conn.sendPacket(PacketSnapshots.PACKET_STATUS_RESPONSE);
}

public void handle(ClientConnection conn, PacketStatusPing packet) {
conn.sendPacketAndClose(packet);
}

public void handle(ClientConnection conn, PacketLoginStart packet) {
if (server.getConfig().getMaxPlayers() > 0 &&
server.getConnections().getCount() >= server.getConfig().getMaxPlayers()) {
conn.disconnectLogin("Too many players connected");
return;
}

if (!conn.getClientVersion().isSupported()) {
conn.disconnectLogin("Unsupported client version");
return;
}

if (server.getConfig().getInfoForwarding().isModern()) {
int loginId = ThreadLocalRandom.current().nextInt(0, Integer.MAX_VALUE);
PacketLoginPluginRequest request = new PacketLoginPluginRequest();

request.setMessageId(loginId);
request.setChannel(LimboConstants.VELOCITY_INFO_CHANNEL);
request.setData(Unpooled.EMPTY_BUFFER);

conn.setVelocityLoginMessageId(loginId);
conn.sendPacket(request);
return;
}

if (!server.getConfig().getInfoForwarding().isModern()) {
conn.getGameProfile().setUsername(packet.getUsername());
conn.getGameProfile().setUuid(UuidUtil.getOfflineModeUuid(packet.getUsername()));
}

conn.fireLoginSuccess();
}

public void handle(ClientConnection conn, PacketLoginPluginResponse packet) {
if (server.getConfig().getInfoForwarding().isModern()
&& packet.getMessageId() == conn.getVelocityLoginMessageId()) {

if (!packet.isSuccessful() || packet.getData() == null) {
conn.disconnectLogin("You need to connect with Velocity");
return;
}

if (!conn.checkVelocityKeyIntegrity(packet.getData())) {
conn.disconnectLogin("Can't verify forwarded player info");
return;
}

// Order is important
conn.setAddress(packet.getData().readString());
conn.getGameProfile().setUuid(packet.getData().readUuid());
conn.getGameProfile().setUsername(packet.getData().readString());

conn.fireLoginSuccess();
}
}

}
175 changes: 175 additions & 0 deletions src/main/java/ru/nanit/limbo/connection/PacketSnapshots.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,175 @@
/*
* Copyright (C) 2020 Nan1t
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/

package ru.nanit.limbo.connection;

import ru.nanit.limbo.LimboConstants;
import ru.nanit.limbo.protocol.PacketSnapshot;
import ru.nanit.limbo.protocol.packets.login.PacketLoginSuccess;
import ru.nanit.limbo.protocol.packets.play.*;
import ru.nanit.limbo.protocol.packets.status.PacketStatusResponse;
import ru.nanit.limbo.server.LimboServer;
import ru.nanit.limbo.server.data.Title;
import ru.nanit.limbo.util.UuidUtil;

import java.util.Collections;
import java.util.UUID;
import java.util.concurrent.ThreadLocalRandom;

public final class PacketSnapshots {

public static PacketSnapshot PACKET_STATUS_RESPONSE;
public static PacketSnapshot PACKET_LOGIN_SUCCESS;
public static PacketSnapshot PACKET_JOIN_GAME;
public static PacketSnapshot PACKET_PLUGIN_MESSAGE;
public static PacketSnapshot PACKET_PLAYER_ABILITIES;
public static PacketSnapshot PACKET_PLAYER_INFO;
public static PacketSnapshot PACKET_DECLARE_COMMANDS;
public static PacketSnapshot PACKET_PLAYER_POS;
public static PacketSnapshot PACKET_JOIN_MESSAGE;
public static PacketSnapshot PACKET_BOSS_BAR;
public static PacketSnapshot PACKET_HEADER_AND_FOOTER;

public static PacketSnapshot PACKET_TITLE_TITLE;
public static PacketSnapshot PACKET_TITLE_SUBTITLE;
public static PacketSnapshot PACKET_TITLE_TIMES;

public static PacketSnapshot PACKET_TITLE_LEGACY_TITLE;
public static PacketSnapshot PACKET_TITLE_LEGACY_SUBTITLE;
public static PacketSnapshot PACKET_TITLE_LEGACY_TIMES;

private PacketSnapshots() { }

public static void initPackets(LimboServer server) {
final String username = server.getConfig().getPingData().getVersion();
final UUID uuid = UuidUtil.getOfflineModeUuid(username);

PacketLoginSuccess loginSuccess = new PacketLoginSuccess();
loginSuccess.setUsername(username);
loginSuccess.setUuid(uuid);

PacketJoinGame joinGame = new PacketJoinGame();
joinGame.setEntityId(0);
joinGame.setEnableRespawnScreen(true);
joinGame.setFlat(false);
joinGame.setGameMode(server.getConfig().getGameMode());
joinGame.setHardcore(false);
joinGame.setMaxPlayers(server.getConfig().getMaxPlayers());
joinGame.setPreviousGameMode(-1);
joinGame.setReducedDebugInfo(true);
joinGame.setDebug(false);
joinGame.setViewDistance(0);
joinGame.setWorldName("minecraft:world");
joinGame.setWorldNames("minecraft:world");
joinGame.setHashedSeed(0);
joinGame.setDimensionRegistry(server.getDimensionRegistry());

PacketPlayerAbilities playerAbilities = new PacketPlayerAbilities();
playerAbilities.setFlyingSpeed(0.0F);
playerAbilities.setFlags(0x02);
playerAbilities.setFieldOfView(0.1F);

PacketPlayerPositionAndLook positionAndLook = new PacketPlayerPositionAndLook();
positionAndLook.setX(server.getConfig().getSpawnPosition().getX());
positionAndLook.setY(server.getConfig().getSpawnPosition().getY());
positionAndLook.setZ(server.getConfig().getSpawnPosition().getZ());
positionAndLook.setYaw(server.getConfig().getSpawnPosition().getYaw());
positionAndLook.setPitch(server.getConfig().getSpawnPosition().getPitch());
positionAndLook.setTeleportId(ThreadLocalRandom.current().nextInt());

PacketDeclareCommands declareCommands = new PacketDeclareCommands();
declareCommands.setCommands(Collections.emptyList());

PacketPlayerInfo info = new PacketPlayerInfo();
info.setUsername(server.getConfig().getPlayerListUsername());
info.setGameMode(server.getConfig().getGameMode());
info.setUuid(uuid);

PACKET_STATUS_RESPONSE = PacketSnapshot.of(new PacketStatusResponse(server));
PACKET_LOGIN_SUCCESS = PacketSnapshot.of(loginSuccess);
PACKET_JOIN_GAME = PacketSnapshot.of(joinGame);
PACKET_PLAYER_ABILITIES = PacketSnapshot.of(playerAbilities);
PACKET_PLAYER_POS = PacketSnapshot.of(positionAndLook);
PACKET_PLAYER_INFO = PacketSnapshot.of(info);

PACKET_DECLARE_COMMANDS = PacketSnapshot.of(declareCommands);

if (server.getConfig().isUseHeaderAndFooter()) {
PacketPlayerListHeader header = new PacketPlayerListHeader();
header.setHeader(server.getConfig().getPlayerListHeader());
header.setFooter(server.getConfig().getPlayerListFooter());
PACKET_HEADER_AND_FOOTER = PacketSnapshot.of(header);
}

if (server.getConfig().isUseBrandName()){
PacketPluginMessage pluginMessage = new PacketPluginMessage();
pluginMessage.setChannel(LimboConstants.BRAND_CHANNEL);
pluginMessage.setMessage(server.getConfig().getBrandName());
PACKET_PLUGIN_MESSAGE = PacketSnapshot.of(pluginMessage);
}

if (server.getConfig().isUseJoinMessage()) {
PacketChatMessage joinMessage = new PacketChatMessage();
joinMessage.setJsonData(server.getConfig().getJoinMessage());
joinMessage.setPosition(PacketChatMessage.Position.CHAT);
joinMessage.setSender(UUID.randomUUID());
PACKET_JOIN_MESSAGE = PacketSnapshot.of(joinMessage);
}

if (server.getConfig().isUseBossBar()) {
PacketBossBar bossBar = new PacketBossBar();
bossBar.setBossBar(server.getConfig().getBossBar());
bossBar.setUuid(UUID.randomUUID());
PACKET_BOSS_BAR = PacketSnapshot.of(bossBar);
}

if (server.getConfig().isUseTitle()) {
Title title = server.getConfig().getTitle();

PacketTitleSetTitle packetTitle = new PacketTitleSetTitle();
PacketTitleSetSubTitle packetSubtitle = new PacketTitleSetSubTitle();
PacketTitleTimes packetTimes = new PacketTitleTimes();

PacketTitleLegacy legacyTitle = new PacketTitleLegacy();
PacketTitleLegacy legacySubtitle = new PacketTitleLegacy();
PacketTitleLegacy legacyTimes = new PacketTitleLegacy();

packetTitle.setTitle(title.getTitle());
packetSubtitle.setSubtitle(title.getSubtitle());
packetTimes.setFadeIn(title.getFadeIn());
packetTimes.setStay(title.getStay());
packetTimes.setFadeOut(title.getFadeOut());

legacyTitle.setTitle(title);
legacyTitle.setAction(PacketTitleLegacy.Action.SET_TITLE);

legacySubtitle.setTitle(title);
legacySubtitle.setAction(PacketTitleLegacy.Action.SET_SUBTITLE);

legacyTimes.setTitle(title);
legacyTimes.setAction(PacketTitleLegacy.Action.SET_TIMES_AND_DISPLAY);

PACKET_TITLE_TITLE = PacketSnapshot.of(packetTitle);
PACKET_TITLE_SUBTITLE = PacketSnapshot.of(packetSubtitle);
PACKET_TITLE_TIMES = PacketSnapshot.of(packetTimes);

PACKET_TITLE_LEGACY_TITLE = PacketSnapshot.of(legacyTitle);
PACKET_TITLE_LEGACY_SUBTITLE = PacketSnapshot.of(legacySubtitle);
PACKET_TITLE_LEGACY_TIMES = PacketSnapshot.of(legacyTimes);
}
}
}
6 changes: 6 additions & 0 deletions src/main/java/ru/nanit/limbo/protocol/Packet.java
Original file line number Diff line number Diff line change
Expand Up @@ -17,12 +17,18 @@

package ru.nanit.limbo.protocol;

import ru.nanit.limbo.connection.ClientConnection;
import ru.nanit.limbo.protocol.registry.Version;
import ru.nanit.limbo.server.LimboServer;

public interface Packet {

void encode(ByteMessage msg, Version version);

void decode(ByteMessage msg, Version version);

default void handle(ClientConnection conn, LimboServer server) {
// Ignored by default
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -17,10 +17,14 @@

package ru.nanit.limbo.protocol.packets;

import ru.nanit.limbo.connection.ClientConnection;
import ru.nanit.limbo.protocol.ByteMessage;
import ru.nanit.limbo.protocol.PacketIn;
import ru.nanit.limbo.protocol.registry.State;
import ru.nanit.limbo.protocol.registry.Version;
import ru.nanit.limbo.server.LimboServer;
import ru.nanit.limbo.server.Logger;
import ru.nanit.limbo.util.UuidUtil;

public class PacketHandshake implements PacketIn {

Expand Down Expand Up @@ -62,4 +66,9 @@ public void decode(ByteMessage msg, Version version) {
public String toString() {
return getClass().getSimpleName();
}

@Override
public void handle(ClientConnection conn, LimboServer server) {
server.getPacketHandler().handle(conn, this);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -17,9 +17,11 @@

package ru.nanit.limbo.protocol.packets.login;

import ru.nanit.limbo.connection.ClientConnection;
import ru.nanit.limbo.protocol.ByteMessage;
import ru.nanit.limbo.protocol.PacketIn;
import ru.nanit.limbo.protocol.registry.Version;
import ru.nanit.limbo.server.LimboServer;

public class PacketLoginPluginResponse implements PacketIn {

Expand Down Expand Up @@ -50,6 +52,11 @@ public void decode(ByteMessage msg, Version version) {
}
}

@Override
public void handle(ClientConnection conn, LimboServer server) {
server.getPacketHandler().handle(conn, this);
}

@Override
public String toString() {
return getClass().getSimpleName();
Expand Down
Loading

0 comments on commit 9269751

Please sign in to comment.