FeatherMC/src/Protocol.cpp

130 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;
}
int clientProtocolVersion = packet.ReadVarInt();
string serverIp = packet.ReadString();
uint16_t port = packet.Read<uint16_t>();
// next desired state
ProtocolState intention = packet.ReadVarInt<ProtocolState>();
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:
{
auto id = packet.ReadVarInt<ServerboundLoginPacketId>();
switch (id)
{
case ServerboundLoginPacketId::LoginStart:
{
std::string username = packet.ReadString();
std::string uuid = "ecb99913-96a8-40a7-8529-a2ca6ad95768";
uuid.resize(36);
username.resize(16);
NetworkMessage msg(VARINT_MAX_SIZE * 3 + uuid.length() + 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(username.c_str(), username.length());
msg.Finalize();
client.SendMessage(msg);
break;
}
}
break;
}
}
}
}