126 lines
4.4 KiB
C++
126 lines
4.4 KiB
C++
#include "Protocol.h"
|
|
#include "PacketReader.h"
|
|
#include "PacketTypes.h"
|
|
#include "MinecraftClient.h"
|
|
#include "DedicatedServer.h"
|
|
|
|
#include <string>
|
|
|
|
namespace Feather
|
|
{
|
|
void Protocol::HandlePacket(MinecraftClient& client, PacketReader& packet)
|
|
{
|
|
auto& context = client.GetContext();
|
|
switch (context.GetState())
|
|
{
|
|
case ProtocolState::Handholding:
|
|
{
|
|
auto id = packet.ReadVarInt<ServerboundHandholdingPacketId>();
|
|
uint8_t legacyId = packet.Peek<uint8_t>();
|
|
if (id != ServerboundHandholdingPacketId::Handshake && legacyId != LegacyServerListPing)
|
|
{
|
|
printf("[Protocol] Client sent packet with non-zero ID 0x%x while state was HANDSHAKING\n", id);
|
|
break;
|
|
}
|
|
|
|
if (id != ServerboundHandholdingPacketId::Handshake)
|
|
{
|
|
// Legacy server ping.
|
|
// TODO: Do server list ping here.
|
|
break;
|
|
}
|
|
|
|
HandshakeMessage handshake(packet);
|
|
|
|
printf("[Protocol] Client Intention Packet: version=%d, serverIp=%s, port=%u, intention=%d\n",
|
|
handshake.protocolVersion,
|
|
handshake.serverIP.c_str(),
|
|
handshake.port,
|
|
handshake.intention
|
|
);
|
|
|
|
context.SetState(handshake.intention);
|
|
|
|
break;
|
|
}
|
|
|
|
case ProtocolState::Status:
|
|
{
|
|
auto id = packet.ReadVarInt<ServerboundStatusPacketId>();
|
|
switch (id)
|
|
{
|
|
case ServerboundStatusPacketId::Request:
|
|
{
|
|
printf("[Protocol] Client sent STATUS_PING_REQUEST\n");
|
|
|
|
std::string status = m_server.GetStatus().GetServerStatusJSON();
|
|
|
|
NetworkMessage msg(VARINT_MAX_SIZE + status.length());
|
|
// Packet ID
|
|
msg.WriteVarInt(ClientBoundStatusPacketId::Response);
|
|
// JSON Contents
|
|
msg.WriteString(status.c_str(), static_cast<int32_t>(status.length()));
|
|
msg.Finalize();
|
|
client.SendMessage(msg);
|
|
|
|
break;
|
|
}
|
|
case ServerboundStatusPacketId::Ping:
|
|
{
|
|
PingMessage ping(packet);
|
|
printf("[Protocol] Client sent STATUS_PING: %lld\n", ping.timestamp);
|
|
|
|
NetworkMessage msg(VARINT_MAX_SIZE + sizeof(int64_t));
|
|
|
|
msg.WriteVarInt(ClientBoundStatusPacketId::Pong);
|
|
msg.Write<uint64_t>(ping.timestamp);
|
|
msg.Finalize();
|
|
|
|
client.SendMessage(msg);
|
|
|
|
break;
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
|
|
case ProtocolState::Login:
|
|
{
|
|
auto id = packet.ReadVarInt<ServerboundLoginPacketId>();
|
|
|
|
switch (id)
|
|
{
|
|
case ServerboundLoginPacketId::LoginStart:
|
|
{
|
|
LoginStartMessage loginStart(packet);
|
|
|
|
// 1.15.2...
|
|
//std::string uuid = "ecb99913-96a8-40a7-8529-a2ca6ad95768";
|
|
//uuid.resize(36);
|
|
//NetworkMessage msg(VARINT_MAX_SIZE * 3 + uuid.length() + loginStart.username.length());
|
|
|
|
NetworkMessage msg(VARINT_MAX_SIZE * 3 + 2 * sizeof(uint64_t) + loginStart.username.length());
|
|
|
|
msg.WriteVarInt(ClientboundLoginPacketId::LoginSuccess);
|
|
// UUID 1.16.1
|
|
msg.Write<uint64_t>(4658857991808325907LL);
|
|
msg.Write<uint64_t>(7518717155607718277LL);
|
|
|
|
// UUID 1.15.2
|
|
//msg.WriteString(uuid.c_str(), uuid.length());
|
|
|
|
msg.WriteString(loginStart.username.c_str(), loginStart.username.length());
|
|
msg.Finalize();
|
|
|
|
client.SendMessage(msg);
|
|
|
|
break;
|
|
}
|
|
}
|
|
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
}
|