130 lines
4.4 KiB
C++
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;
|
|
}
|
|
}
|
|
}
|
|
}
|