Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
29 changes: 29 additions & 0 deletions CMakeLists.txt
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM !

Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
cmake_minimum_required(VERSION "3.16")

set(PRODUCTION_BUILD OFF CACHE BOOL "Make this a production build" FORCE)

set(CMAKE_MSVC_RUNTIME_LIBRARY "MultiThreaded$<$<CONFIG:Debug>:Debug>")
set(CMAKE_MSVC_RUNTIME_LIBRARY "MultiThreaded$<$<CONFIG:Release>:Release>")

if(PRODUCTION_BUILD)
set(CMAKE_INTERPROCEDURAL_OPTIMIZATION TRUE)
else()
set(CMAKE_INTERPROCEDURAL_OPTIMIZATION TRUE)
endif()

project("mc-server")
set(CMAKE_CXX_STANDARD 20)

# Add external library here ->
add_subdirectory("thirdParty/asio")

file (GLOB_RECURSE MY_SOURCES CONFIGURE_DEPENDS "${CMAKE_CURRENT_SOURCE_DIR}/src/*.cpp")

add_executable(${CMAKE_PROJECT_NAME} "${MY_SOURCES}")

if(MSVC)
target_compile_definitions("${CMAKE_PROJECT_NAME}" PUBLIC _CRT_SECURE_NO_WARNINGS)
endif()

target_include_directories(${CMAKE_PROJECT_NAME} PUBLIC "${CMAKE_CURRENT_SOURCE_DIR}/include/")
target_link_libraries(${CMAKE_PROJECT_NAME} PRIVATE asio)
2 changes: 1 addition & 1 deletion external/data-generator
2 changes: 1 addition & 1 deletion include/data/RegistryData.hpp
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
#ifndef MC_CPP_SERVER_DATA_REGISTRY_HPP
#define MC_CPP_SERVER_DATA_REGISTRY_HPP

#include "nbt.hpp"
#include "lib/nbt.hpp"

#include <memory>
#include <optional>
Expand Down
102 changes: 52 additions & 50 deletions include/network/buffer.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -13,74 +13,76 @@
class Buffer {
private:
std::vector<uint8_t> _data;
size_t _pos;
size_t _pos;

public:
// ============================================================
// ========== CONSTRUCTEURS ==========
// ============================================================
Buffer();
explicit Buffer(const std::vector<uint8_t>& data);

int readVarInt();
void writeVarInt(int value);
void writeInt(int32_t value);
void writeIdentifierArray(const std::vector<std::string>& ids);
void writeUInt(uint32_t value);

// ============================================================
// ========== LECTURE ==========
// ============================================================
uint8_t readByte();
bool readBool();
int32_t readInt();
uint16_t readUShort();
uint64_t readUInt64();
int32_t readVarInt();
int64_t readVarInt64();
std::string readString(int maxLength);
std::string readString(); // Read string without max length limit
void writeString(const std::string& str);
std::string readString();
int64_t readInt64();

// Array reading methods
std::vector<std::string> readStringArray();
std::vector<int> readVarIntArray();
template <typename T> std::vector<T> readArray(std::function<T()> reader) {
std::vector<std::string> readStringArray();
std::vector<int> readVarIntArray();

template <typename T>
std::vector<T> readArray(std::function<T()> reader) {
int count = readVarInt();
if (count < 0) {
throw std::runtime_error("Negative array length");
}
if (count < 0) throw std::runtime_error("Negative array length");
std::vector<T> result;
result.reserve(count);

for (int i = 0; i < count; ++i) {
for (int i = 0; i < count; ++i)
result.push_back(reader());
}

return result;
}

// Boolean reading methods
bool readBool();

std::vector<uint8_t>& getData();
size_t remaining() const;
uint16_t readUShort();
void writeUShort(uint16_t value);
uint64_t readUInt64();
long readLong();
int32_t readInt();
void writeLong(long value);
uint8_t readByte();
void writeByte(uint8_t byte);
void writeBytes(const std::string& data);
void writeBytes(const std::vector<uint8_t>& data);
void writeUUID(const UUID& uuid);
// ============================================================
// ========== ÉCRITURE ==========
// ============================================================
void writeByte(uint8_t byte);
void writeBytes(const std::string& data);
void writeBytes(const std::vector<uint8_t>& data);

void writeBool(bool value);
void writeNBT(const std::string& nbtData);
void writePosition(int32_t x, int32_t y, int32_t z);
void writeFloat(float value);
void writeDouble(double value);
void writeIdentifier(const std::string& id);
void writeVarLong(int64_t value);
int64_t readVarLong();
void writeBool(bool value);
void writeInt(int32_t value);
void writeUInt(uint32_t value);
void writeUShort(uint16_t value);
void writeInt64(int64_t value);
void writeFloat(float value);
void writeDouble(double value);

void writeVarInt(int value);
void writeVarInt64(int64_t value);

// Known Packs packet specific methods
struct KnownPack {
std::string nameSpace;
std::string id;
std::string version;
};
std::vector<KnownPack> readKnownPacks();
void writeKnownPacks(const std::vector<KnownPack>& packs);
void writeString(const std::string& str);
void writeUUID(const UUID& uuid);
void writePosition(int32_t x, int32_t y, int32_t z);
void writeIdentifierArray(const std::vector<std::string>& ids);
void prependBytes(const std::string& data);
void prependByte(uint8_t byte);
void prependVarInt(int value);

// ============================================================
// ========== UTILITAIRES ==========
// ============================================================
std::vector<uint8_t>& getData();
size_t remaining() const;
};

#endif
49 changes: 0 additions & 49 deletions include/network/networking.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -112,53 +112,4 @@ class NetworkManager {
void handleIncomingData(int socket);
};

void packetRouter(Packet* packet, Server& server);
void handleHandshakePacket(Packet& packet, Server& server);
void handleStatusPacket(Packet& packet, Server& server);
void handlePingPacket(Packet& packet, Server& server);
void handleClientInformation(Packet& packet, Server& server);
void handleLoginStartPacket(Packet& packet, Server& server);
void handleLoginAcknowledged(Packet& packet, Server& server);
void handleCookieRequest(Packet& packet, Server& server);
void handleFinishConfiguration(Packet& packet, Server& server);
void handleAcknowledgeFinishConfiguration(Packet& packet, Server& server);
void writePlayPacket(Packet& packet, Server& server);
void writeSetCenterPacket(Packet& packet, Server& server);

// Chunk batch functions
void sendChunkBatchStart(Packet& packet, Server& server);
void sendChunkBatchFinished(Packet& packet, Server& server, int batchSize);
void sendChunkBatchSequence(Packet& packet, Server& server);

// Chunk data functions
void sendChunkData(Packet& packet, Server& server, int chunkX, int chunkZ);
void sendPlayerPositionAndLook(Packet& packet, Server& server);
void sendSpawnPosition(Packet& packet, Server& server);

// Spawn sequence functions
void sendPlayerAbilities(Packet& packet, Server& server);
void sendSetHealth(Packet& packet, Server& server);
void sendSetExperience(Packet& packet, Server& server);
void sendUpdateTime(Packet& packet, Server& server);
void sendSetHeldItem(Packet& packet, Server& server);
void handleConfirmTeleportation(Packet& packet, Server& server);
void completeSpawnSequence(Packet& packet, Server& server);
void sendDisconnectPacket(Packet* packet, const std::string& reason, Server& server);

Buffer generateEmptyChunkSections();
void writeLightData(Buffer& buf, const World::ChunkData& chunkData);
void writeActualLightData(Buffer& buf, const World::ChunkData& chunkData);
void writeEmptyLightData(Buffer& buf);

void clientboundKnownPacks(Packet& packet);
void serverboundKnownPacks(Packet& packet);

void gameEventPacket(Packet& packet, Server& server);
void levelChunkWithLight(Packet& packet, Server& server);

// Optional Packets
void changeDifficulty(Packet& packet);
void playerAbilities(Packet& packet);
void setHeldItem(Packet& packet);

#endif
1 change: 1 addition & 0 deletions include/network/packet.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@ class Packet {
int getVarintSize(int32_t value);
void setPacketSize(int32_t value);
void setPacketId(uint32_t value);
void sendPacket(int id, Buffer& data, Server& server, bool last);
};

#endif
41 changes: 41 additions & 0 deletions include/network/packetRouter.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
#ifndef PACKET_ROUTER_HPP
# define PACKET_ROUTER_HPP

# include "packet.hpp"
# include "server.hpp"

// clientbound
void changeDifficultyPacket(Packet& packet, Server& server);
void clientboundKnownPacksPacket(Packet& packet, Server& server);
void gameEventPacket(Packet& packet, Server& server);
void handleCookieRequestPacket(Packet& packet, Server& server);
void handleFinishConfigurationPacket(Packet& packet, Server& server);
void handleLoginStartPacket(Packet& packet, Server& server);
void handlePingPacket(Packet& packet, Server& server);
void handleStatusPacket(Packet& packet, Server& server);
void levelChunkWithLightPacket(Packet& packet, Server& server);
void playerAbilitiesPacket(Packet& packet, Server& server);
void sendPlayPacket(Packet& packet, Server& server);
void setHeldItemPacket(Packet& packet, Server& server);
void synchronizePlayerPositionPacket(Packet& packet, Server& server);
void setCenterPacket(Packet& packet, Server& server);

// serverbound
void handleAcknowledgeFinishConfigurationPacket(Packet& packet, Server& server);
void handleClientInformationPacket(Packet& packet, Server& server);
void handleConfirmTeleportationPacket(Packet& packet, Server& server);
void handleHandshakePacket(Packet& packet, Server& server);
void handleLoginAcknowledgedPacket(Packet& packet, Server& server);
void serverboundKnownPacksPacket(Packet& packet);

void packetRouter(Packet* packet, Server& server);

void handleHandshakeState(Packet* packet, Server& server);
void handleStatusState(Packet* packet, Server& server);
void handleLoginState(Packet* packet, Server& server);
void handleConfigurationState(Packet* packet, Server& server);
void handlePlayState(Packet* packet, Server& server);
void sendRegistryData(Packet& packet, Server& server);
void sendUpdateTags(Packet& packet, Server& server);

#endif
6 changes: 3 additions & 3 deletions src/data/RegistryData.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -48,17 +48,17 @@ std::vector<uint8_t> RegistryData::serialize() const {
Buffer buffer;

// Format MC 1.21.5: id + entries length + entries array
buffer.writeIdentifier(_registry_id);
buffer.writeString(_registry_id);
buffer.writeVarInt(static_cast<int32_t>(_entries.size()));

for (const auto& entry : _entries) {
// Chaque entrée: key (string) + value optional (anonymousNbt)
buffer.writeIdentifier(entry.entry_id);
buffer.writeString(entry.entry_id);

// Format "value optional": boolean présent + données NBT si présent
if (entry.has_data && entry.data.has_value()) {
buffer.writeBool(true); // Données présentes
buffer.writeNBT("{}"); // Données NBT (vide pour l'instant)
buffer.writeBytes("{}"); // Données NBT (vide pour l'instant)
Copy link

Copilot AI Nov 7, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Comment is in French ('Données NBT (vide pour l'instant)') and should be translated to English to maintain consistency with the rest of the codebase.

Suggested change
buffer.writeBytes("{}"); // Données NBT (vide pour l'instant)
buffer.writeBytes("{}"); // NBT data (empty for now)

Copilot uses AI. Check for mistakes.
} else {
buffer.writeBool(false); // Pas de données NBT optionnelles
}
Expand Down
8 changes: 4 additions & 4 deletions src/data/RegistryDataUtils.cpp
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
#include "RegistryDataUtils.hpp"
#include "data/RegistryDataUtils.hpp"

#include "RegistryData.hpp"
#include "RegistryIds.hpp"
#include "data/RegistryData.hpp"
#include "data/RegistryIds.hpp"
#include "logger.hpp"
#include "minecraftRegistries.hpp"
#include "data/minecraftRegistries.hpp"
#include "network/buffer.hpp"
#include "network/networking.hpp"

Expand Down
19 changes: 3 additions & 16 deletions src/data/updateTags.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -55,25 +55,12 @@ void sendUpdateTags(Packet& packet, Server& server) {
"Configuration");
}

Buffer finalBuf;
int packetId = 0x0D;
int packetIdSize = packet.getVarintSize(packetId);
int totalPayloadSize = packetIdSize + tagBuffer.getData().size();

finalBuf.writeVarInt(totalPayloadSize);
finalBuf.writeVarInt(packetId);
finalBuf.writeBytes(tagBuffer.getData());

Packet* tagsPacket = new Packet(packet);
tagsPacket->getData() = finalBuf;
tagsPacket->setPacketSize(finalBuf.getData().size());
tagsPacket->setReturnPacket(PACKET_SEND);

outgoingPackets->push(tagsPacket);
Packet* tagsPacket = new Packet(packet);
tagsPacket->sendPacket(0x0D, tagBuffer, server, true);

g_logger->logNetwork(INFO,
"Update Tags packet sent: " + std::to_string(totalRegistries) + " registries, " + std::to_string(totalTags) + " tags, " +
std::to_string(totalEntries) + " entries, packet size: " + std::to_string(finalBuf.getData().size()) + " bytes",
std::to_string(totalEntries) + " entries",
"Configuration");

packet.setReturnPacket(PACKET_OK);
Expand Down
Loading
Loading