FeatherMC/src/Protocol.cpp

101 lines
3.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;
}
int clientProtocolVersion = packet.ReadVarInt();
string serverIp = packet.ReadString();
uint16_t port = packet.Read<uint16_t>();
// next desired state
ProtocolState intention = (ProtocolState)(packet.ReadVarInt());
printf("[Protocol] Client Intention Packet: version=%d, serverIp=%s, port=%u, intention=%d\n",
clientProtocolVersion,
serverIp.c_str(),
port,
intention
);
context.SetState(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:
{
int64_t timestamp = packet.Read<int64_t>();
printf("[Protocol] Client sent STATUS_PING: %lld\n", timestamp);
NetworkMessage msg(VARINT_MAX_SIZE + sizeof(int64_t));
msg.WriteVarInt(ClientBoundStatusPacketId::Pong);
msg.Write<uint64_t>(timestamp);
msg.Finalize();
client.SendMessage(msg);
break;
}
}
break;
}
case ProtocolState::Login:
{
int id = packet.ReadVarInt();
Log_Info("Login packet ID %d", id);
break;
}
}
}
}