Skip to content

Commit c57f105

Browse files
committed
Chunk packet is valid but parser is shitting himself
1 parent 6b3f31d commit c57f105

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

64 files changed

+2659
-1151
lines changed

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,3 +12,4 @@ logs
1212
# Test server directory
1313
test-server
1414
include/external
15+
docs/

include/network/buffer.hpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,8 @@ class Buffer {
5555
uint16_t readUShort();
5656
void writeUShort(uint16_t value);
5757
uint64_t readUInt64();
58+
uint64_t readUnsignedLong();
59+
void writeUnsignedLong(uint64_t value);
5860
long readLong();
5961
int32_t readInt();
6062
void writeLong(long value);

include/network/networking.hpp

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -123,7 +123,7 @@ void handleCookieRequest(Packet& packet, Server& server);
123123
void handleFinishConfiguration(Packet& packet, Server& server);
124124
void handleAcknowledgeFinishConfiguration(Packet& packet, Server& server);
125125
void writePlayPacket(Packet& packet, Server& server);
126-
void writeSetCenterPacket(Packet& packet, Server& server);
126+
void writeSetCenterPacket(Packet& packet);
127127

128128
// Chunk batch functions
129129
void sendChunkBatchStart(Packet& packet, Server& server);
@@ -134,6 +134,7 @@ void sendChunkBatchSequence(Packet& packet, Server& server);
134134
void sendChunkData(Packet& packet, Server& server, int chunkX, int chunkZ);
135135
void sendPlayerPositionAndLook(Packet& packet, Server& server);
136136
void sendSpawnPosition(Packet& packet, Server& server);
137+
void synchronizePlayerPosition(Packet& packet, Server& server);
137138

138139
// Spawn sequence functions
139140
void sendPlayerAbilities(Packet& packet, Server& server);
@@ -154,7 +155,7 @@ void clientboundKnownPacks(Packet& packet);
154155
void serverboundKnownPacks(Packet& packet);
155156

156157
void gameEventPacket(Packet& packet, Server& server);
157-
void levelChunkWithLight(Packet& packet, Server& server);
158+
void levelChunkWithLight(Packet& packet, Server& server, int32_t chunkX, int32_t chunkZ);
158159

159160
// Optional Packets
160161
void changeDifficulty(Packet& packet);

include/network/server.hpp

Lines changed: 22 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
class NetworkManager;
55
#include "../config.hpp"
66
#include "../player.hpp"
7+
#include "../world/query.hpp"
78
#include "../world/world.hpp"
89
#include "id_manager.hpp"
910
#include "lib/json.hpp"
@@ -17,17 +18,17 @@ using json = nlohmann::json;
1718

1819
class Server {
1920
private:
20-
std::unordered_map<int, Player*> _playerLst;
21-
std::unordered_map<int, Player*> _tempPlayerLst;
22-
json _playerSample;
23-
std::mutex _playerLock;
24-
std::mutex _tempPlayerLock;
25-
Config _config;
26-
NetworkManager* _networkManager;
27-
IdManager _idManager;
28-
World::Manager _worldManager;
29-
World::LevelDat _worldData;
30-
World::Query _worldQuery;
21+
std::unordered_map<int, Player*> _playerLst;
22+
std::unordered_map<int, Player*> _tempPlayerLst;
23+
json _playerSample;
24+
std::mutex _playerLock;
25+
std::mutex _tempPlayerLock;
26+
Config _config;
27+
NetworkManager* _networkManager;
28+
IdManager _idManager;
29+
World::Manager _worldManager;
30+
World::LevelDat _worldData;
31+
std::unique_ptr<World::OptimizedQuery> _worldQuery;
3132

3233
public:
3334
Server();
@@ -54,9 +55,18 @@ class Server {
5455
NetworkManager& getNetworkManager() { return *_networkManager; }
5556
World::Manager& getWorldManager() { return _worldManager; }
5657
World::LevelDat& getWorldData() { return _worldData; }
57-
World::Query& getWorldQuery() { return _worldQuery; }
58+
// Accessor method
59+
World::OptimizedQuery& getWorldQuery() { return *_worldQuery; }
60+
const World::OptimizedQuery& getWorldQuery() const { return *_worldQuery; }
5861

5962
void printChunkInfo(const World::ChunkData& chunk);
63+
64+
// World query utility methods
65+
std::shared_ptr<World::ChunkData> loadChunkForPlayer(int32_t chunkX, int32_t chunkZ);
66+
std::vector<std::shared_ptr<World::ChunkData>> loadPlayerViewArea(int32_t centerChunkX, int32_t centerChunkZ, int radius = 5);
67+
void preloadSpawnArea(int radius = 8);
68+
void logWorldQueryStats();
69+
bool isChunkAvailable(int32_t chunkX, int32_t chunkZ);
6070
};
6171

6272
#endif

include/world/chunkParser.hpp

Lines changed: 113 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,113 @@
1+
2+
#ifndef WORLD_CHUNKPARSER_HPP
3+
#define WORLD_CHUNKPARSER_HPP
4+
5+
#include "fstream"
6+
#include "nbt.hpp"
7+
#include "world.hpp"
8+
9+
#include <cstdint>
10+
#include <filesystem>
11+
#include <map>
12+
#include <memory>
13+
#include <string>
14+
#include <utility>
15+
#include <vector>
16+
17+
namespace World {
18+
19+
class DirectChunkParser {
20+
public:
21+
struct ParseConfig {
22+
int worldHeight = 384;
23+
int minY = -64;
24+
bool loadLighting = true;
25+
bool optimizePalettes = true;
26+
bool validateData = true;
27+
bool loadBlockEntities = true;
28+
29+
// Performance options
30+
bool useMemoryMapping = true;
31+
size_t cacheSize = 64; // Number of chunks to cache
32+
};
33+
34+
private:
35+
ParseConfig _config;
36+
37+
// Region file handling
38+
struct RegionFile {
39+
std::filesystem::path path;
40+
std::unique_ptr<std::ifstream> stream;
41+
std::vector<uint32_t> chunkOffsets;
42+
std::vector<uint32_t> chunkTimestamps;
43+
bool isLoaded = false;
44+
};
45+
46+
mutable std::map<std::pair<int32_t, int32_t>, std::unique_ptr<RegionFile>> _regionCache;
47+
48+
public:
49+
explicit DirectChunkParser(const ParseConfig& config);
50+
~DirectChunkParser();
51+
52+
// Main parsing methods
53+
World::ChunkData parseChunkFromRegion(const std::filesystem::path& regionPath, int32_t chunkX, int32_t chunkZ);
54+
55+
World::ChunkData parseChunkFromNBT(const nbt::NBT& chunkNBT, int32_t chunkX, int32_t chunkZ);
56+
57+
// Batch operations
58+
std::vector<World::ChunkData> parseChunkBatch(const std::filesystem::path& regionPath,
59+
const std::vector<std::pair<int32_t, int32_t>>& coordinates);
60+
61+
// Utility methods
62+
bool chunkExistsInRegion(const std::filesystem::path& regionPath, int32_t chunkX, int32_t chunkZ);
63+
std::vector<std::pair<int32_t, int32_t>> getAvailableChunks(const std::filesystem::path& regionPath);
64+
65+
// Configuration
66+
void setConfig(const ParseConfig& config) { _config = config; }
67+
const ParseConfig& getConfig() const { return _config; }
68+
69+
private:
70+
// Region file operations
71+
RegionFile* loadRegionFile(const std::filesystem::path& regionPath) const;
72+
std::vector<uint8_t> readChunkData(RegionFile* region, int32_t chunkX, int32_t chunkZ) const;
73+
void parseRegionHeader(RegionFile* region) const;
74+
uint32_t getBlockIdFromName(const std::string& blockName);
75+
76+
// NBT parsing methods
77+
void parseHeightMaps(const nbt::TagCompound& heightmaps, World::ChunkData& chunk);
78+
void parseSections(const nbt::TagList& sections, World::ChunkData& chunk);
79+
void parseBlockEntities(const nbt::TagList& blockEntities, World::ChunkData& chunk);
80+
void parseChunkMetadata(const nbt::TagCompound& level, World::ChunkData& chunk);
81+
82+
// Section parsing
83+
void parseBlockStates(const nbt::TagCompound& blockStates, ChunkSection& section);
84+
void parseBiomes(const nbt::TagCompound& biomes, ChunkSection& section);
85+
void parseLighting(const nbt::TagCompound& section, ChunkSection& chunkSection);
86+
87+
// Paletted data unpacking
88+
std::vector<uint32_t>
89+
unpackPalettedData(const nbt::TagLongArray& data, const nbt::TagList* palette, size_t expectedSize, uint32_t defaultValue = 0);
90+
91+
std::vector<uint32_t> unpackDirectPalettedData(const nbt::TagLongArray& data, uint8_t bitsPerEntry, size_t expectedSize);
92+
93+
// Heightmap processing
94+
std::vector<uint16_t> unpackHeightmapData(const nbt::TagLongArray& data, int worldHeight);
95+
96+
// Validation methods
97+
void validateChunkData(const World::ChunkData& chunk) const;
98+
void validateSection(const ChunkSection& section, int sectionY) const;
99+
100+
// Utility methods
101+
std::pair<int32_t, int32_t> getRegionCoords(int32_t chunkX, int32_t chunkZ) const;
102+
size_t getChunkIndex(int32_t chunkX, int32_t chunkZ) const;
103+
uint32_t readBigEndianInt(const uint8_t* data) const;
104+
105+
// NBT helper methods
106+
template <typename T> T getTagValue(const nbt::TagCompound& compound, const std::string& key, T defaultValue = T{}) const;
107+
108+
bool hasTag(const nbt::TagCompound& compound, const std::string& key) const;
109+
};
110+
111+
}; // namespace World
112+
113+
#endif // WORLD_CHUNKPARSER_HPP

include/world/heightMap.hpp

Lines changed: 70 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,70 @@
1+
#ifndef HEIGHT_MAP_HPP
2+
#define HEIGHT_MAP_HPP
3+
4+
#include <cstddef>
5+
#include <cstdint>
6+
#include <map>
7+
#include <string>
8+
#include <vector>
9+
10+
namespace World {
11+
enum class Type : uint8_t { MOTION_BLOCKING = 1, MOTION_BLOCKING_NO_LEAVES = 2, OCEAN_FLOOR = 3, WORLD_SURFACE = 4, WORLD_SURFACE_WG = 5 };
12+
13+
class HeightMap {
14+
std::map<Type, std::vector<uint16_t>> _heightmaps;
15+
int _worldHeight;
16+
int _minY;
17+
uint8_t _bitsPerEntry;
18+
19+
static constexpr size_t CHUNK_SIZE = 16;
20+
static constexpr size_t HEIGHTMAP_SIZE = CHUNK_SIZE * CHUNK_SIZE; // 256 entries
21+
22+
public:
23+
HeightMap(int worldHeight = 384, int minY = -64);
24+
25+
// Core operations
26+
void setHeightMap(Type type, const std::vector<int64_t>& packedData);
27+
void setHeightMapDirect(Type type, const std::vector<uint16_t>& heights);
28+
void setHeight(Type type, uint8_t x, uint8_t z, uint16_t height);
29+
uint16_t getHeight(Type type, uint8_t x, uint8_t z) const;
30+
31+
// Bulk operations
32+
void generateEmpty();
33+
void generateFlat(uint16_t height = 64);
34+
void copyFrom(const HeightMap& other);
35+
36+
// Serialization
37+
std::vector<uint8_t> serializeToNBT() const;
38+
std::vector<int64_t> packHeightMap(Type type) const;
39+
void unpackHeightMap(Type type, const std::vector<int64_t>& packedData);
40+
41+
// Accessors
42+
int getWorldHeight() const { return _worldHeight; }
43+
int getMinY() const { return _minY; }
44+
uint8_t getBitsPerEntry() const { return _bitsPerEntry; }
45+
bool hasHeightMap(Type type) const;
46+
std::vector<Type> getAvailableTypes() const;
47+
48+
// Utilities
49+
static std::string getTypeName(Type type);
50+
static Type getTypeFromName(const std::string& name);
51+
52+
private:
53+
// Internal utilities
54+
size_t coordToIndex(uint8_t x, uint8_t z) const;
55+
void indexToCoord(size_t index, uint8_t& x, uint8_t& z) const;
56+
uint8_t calculateBitsPerEntry(int worldHeight) const;
57+
void validateCoordinates(uint8_t x, uint8_t z) const;
58+
void ensureHeightMapExists(Type type);
59+
60+
// Bit packing utilities
61+
void packBits(const std::vector<uint16_t>& heights, std::vector<int64_t>& packed) const;
62+
void unpackBits(const std::vector<int64_t>& packed, std::vector<uint16_t>& heights) const;
63+
64+
// NBT writing helpers
65+
void writeString(std::vector<uint8_t>& buffer, const std::string& str) const;
66+
void writeVarInt(std::vector<uint8_t>& buffer, int32_t value) const;
67+
void writeLongArray(std::vector<uint8_t>& buffer, const std::vector<int64_t>& data) const;
68+
};
69+
} // namespace World
70+
#endif
Lines changed: 68 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,68 @@
1+
#ifndef PALETTED_CONTAINER_HPP
2+
#define PALETTED_CONTAINER_HPP
3+
4+
#include <cstddef>
5+
#include <cstdint>
6+
#include <vector>
7+
8+
namespace World {
9+
enum class PalettedType {
10+
SINGLE_VALUED = 0,
11+
INDIRECT = 1,
12+
DIRECT = 2,
13+
};
14+
15+
class PalettedContainer {
16+
private:
17+
World::PalettedType _containerType;
18+
uint8_t _bitsPerEntry;
19+
std::vector<uint32_t> _palette; // Small array of unique values
20+
std::vector<uint64_t> _data; // Bit-packed indices/values
21+
size_t _size; // Number of entries (4096 for blocks)
22+
bool _isBlockContainer;
23+
24+
static constexpr uint8_t MIN_BITS_BLOCK = 4;
25+
static constexpr uint8_t MAX_BITS_BLOCK = 15;
26+
static constexpr uint8_t MIN_BITS_BIOME = 1;
27+
static constexpr uint8_t MAX_BITS_BIOME = 6;
28+
29+
public:
30+
explicit PalettedContainer(size_t size, bool isBlockContainer = true);
31+
32+
void setSingleValue(uint32_t value);
33+
void setFromArray(const std::vector<uint32_t>& values);
34+
uint32_t getValue(size_t index) const; // Get block at position
35+
void setValue(size_t index, uint32_t value);
36+
37+
std::vector<uint8_t> serialize() const; // Convert to network format
38+
39+
PalettedType getType() const { return _containerType; }
40+
uint8_t getBitsPerEntry() const { return _bitsPerEntry; }
41+
const std::vector<uint32_t>& getPalette() const { return _palette; }
42+
size_t getSize() const { return _size; }
43+
44+
private:
45+
// Internal optimization methods
46+
void optimizeEncoding(const std::vector<uint32_t>& values);
47+
void packData(const std::vector<uint32_t>& values);
48+
void unpackData(std::vector<uint32_t>& values) const;
49+
50+
// Bit manipulation utilities
51+
void setBits(size_t index, uint32_t value);
52+
uint32_t getBits(size_t index) const;
53+
54+
// Palette management
55+
uint32_t addToPalette(uint32_t value);
56+
uint32_t findInPalette(uint32_t value) const;
57+
58+
// Encoding strategy selection
59+
uint8_t calculateOptimalBits(size_t uniqueValues) const;
60+
bool shouldUseDirect(size_t uniqueValues) const;
61+
62+
// Serialization helpers
63+
void writeVarInt(std::vector<uint8_t>& buffer, int32_t value) const;
64+
void writeVarLong(std::vector<uint8_t>& buffer, int64_t value) const;
65+
};
66+
}; // namespace World
67+
68+
#endif

0 commit comments

Comments
 (0)