From de19981582c5ea4460c4fbb3b40cb33de50c2690 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Antoine=20Mathi=C3=A9?= Date: Wed, 8 Oct 2025 14:28:02 +0200 Subject: [PATCH 01/27] aigen: chunks-spec v0.1 --- ideas/chunks-spec.md | 267 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 267 insertions(+) create mode 100644 ideas/chunks-spec.md diff --git a/ideas/chunks-spec.md b/ideas/chunks-spec.md new file mode 100644 index 0000000..a4b801f --- /dev/null +++ b/ideas/chunks-spec.md @@ -0,0 +1,267 @@ +Title: Chunk Streaming, Caching, and World-Sync Subsystem (Spec Sheet) +Version: 0.1 +Owner: Antoine (Server Runtime) +Status: Draft +Last Updated: 2025-10-08 + +1) Goals +- Stream chunks from Anvil region files on demand, decode via libnbt++, and + maintain a bounded in-memory cache. +- Keep main server loop authoritative over simulation (entities, blocks, light). +- Maintain consistency between background I/O/decoding and live world state. +- Pin spawn and simulation-radius chunks; prefetch neighbors; evict by LRU/TTL. +- Support async load and async save (writeback) without stalling the tick. +- Provide deterministic activation/eviction phases in the tick. + +2) Non-Goals +- Procedural generation (assume existing Anvil data). +- Full lighting algorithm specification (only interfaces/hooks). +- Network protocol specifics. + +3) Terminology +- ChunkPos: integer pair {x, z} in chunk coordinates (16×16 blocks each). +- Region: 32×32 chunks per .mca file (r...mca). +- Snapshot (immutable): decoded NBT data for a chunk (sections, biomes, + entities list, etc.), safe to move across threads. +- LiveChunk (mutable): runtime structures used by simulation (blocks, entities, + tile entities, light caches, pathing data). +- ActiveSet: map of ChunkPos -> LiveChunk under main-thread ownership. +- DesiredSet: union of spawn + per-player simulation radius + optional + prefetch radius. +- CacheEntry: background cache record (may hold Snapshot or nothing). + +4) Components +4.1) RegionFile (I/O) +- Responsibility: Read compressed chunk blobs from .mca files. +- Interfaces: + - static path regionPathFor(worldRoot, cx, cz) -> filesystem::path + - ctor(path) + - bool ok() + - optional> readChunk(cx, cz) + - (Future) writeChunk(cx, cz, compressedBlob) [async via Writeback] +- Behavior: + - Parse 8 KiB header (location + timestamps). + - readChunk returns [length:4][compression:1][payload...] as stored. + - Keeps file descriptor open; thread-safe via external serialization (one + RegionFile instance per region, methods may be called from thread pool). +- Errors: returns nullopt for missing chunks; throws only on fatal open errors. + +4.2) ChunkCodec (Decode/Encode) +- Responsibility: Convert between compressed blob and Snapshot. +- Interfaces: + - decodeFromCompressedNbt(ChunkPos, blob) -> Snapshot + stats + - encodeToCompressedNbt(ChunkPos, Snapshot) -> blob + stats +- Behavior: + - Supports compression types: 2=Zlib/Deflate, 1=Gzip, 3=LZ4 (if present). + - Uses libnbt++ to parse NBT tags; maps to Snapshot schema. + - Memory accounting: reports uncompressed size for budgeting. +- Errors: returns null/empty Snapshot on malformed input; logs diagnostics. + +4.3) ChunkManager (Background cache + async orchestration) +- Responsibility: Manage memory-bounded cache of Snapshots and orchestrate + background I/O and decoding/encoding. +- Interfaces: + - getChunkAsync(pos) -> future + - prefetch(pos) -> void (low-priority get) + - pin(pos), unpin(pos) -> void + - saveAsync(pos, Snapshot) -> future + - tick() -> void (eviction by LRU/TTL) + - setMemoryBudget(bytes) -> void + - metrics() -> struct { usedBytes, entries, pinned, inflightLoads, inflightSaves, p50/p95 IO+decode } +- Policies: + - Eviction: LRU with TTL; skip pinned and inflight; drop unpinned first. + - Memory budget: total bytes ~ sum of Snapshot size estimates. + - Prefetch: queued after required loads; dropped first under pressure. +- Concurrency: + - Thread pool(s) for I/O and decode/encode. + - No main-thread blocking except when caller chooses to wait on futures. +- Errors: futures resolve to empty Snapshot on failure; callers decide fallback. + +4.4) WorldState (Main-thread authoritative) +- Responsibility: Owns and mutates LiveChunks; integrates Snapshots deterministically. +- Interfaces: + - ensureActive(pos) -> schedules load if needed (non-blocking) + - deactivate(pos) -> schedules save if dirty, then unload + - getLive(pos) -> LiveChunk* or null + - iterateActive(aabb or radius) -> iterator + - markDirty(pos) -> void + - buildLiveFromSnapshot(pos, Snapshot) -> LiveChunk + - encodeSnapshot(LiveChunk) -> Snapshot (for save) +- Data: + - ActiveSet: unordered_map + - PendingLoads: map> + - PendingActivations: queue<(ChunkPos, Snapshot)> + - PendingEvictions: queue + - WritebackQueue: queue<(ChunkPos, Snapshot)> +- Policies: + - Activation rate limit per tick to bound frame spikes (e.g., 16). + - Defer cross-chunk operations until neighbors are present if required. + +4.5) EntitySystem and Subsystems +- Responsibility: Simulate only within ActiveSet. +- Interfaces: + - onTick(WorldView view) where view queries LiveChunks only. + - TransferQueue for entities crossing chunk borders pending activation. +- Guarantees: + - Never reads background Snapshots directly. + - Handles “chunk not loaded” by deferring or scheduling prefetch. + +5) Tick Phases (Deterministic Order) +- Phase 0: Input & Interest + - Compute DesiredSet from players (Rs sim radius, Rd prefetch radius) + spawn. + - For each pos in DesiredSet: + - If not active and not pending: ChunkManager.pin(pos); pendingLoads[pos] = + getChunkAsync(pos). For prefetch-only area: do not pin. + - For each pos in ActiveSet not in DesiredSet and not dirty: enqueue eviction. +- Phase 1: Drain Async (Non-blocking) + - Poll PendingLoads with wait_for(0ms). + - Move ready results to PendingActivations; remove from PendingLoads. +- Phase 2: World Sync + - Activate up to N per tick: buildLiveFromSnapshot; insert into ActiveSet. + - Process PendingEvictions: if dirty -> encode -> saveAsync; unpin; erase. + - Resolve edge dependencies (e.g., light border fix) if neighbors present. +- Phase 3: Simulation + - Run systems in fixed order on ActiveSet (blocks, tiles, AI, physics, entities). + - Process transfers across chunk borders; if target inactive, queue for next tick. +- Phase 4: Output & Maintenance + - Produce network snapshots from ActiveSet only. + - ChunkManager.tick(); flush writebacks opportunistically. + +6) Memory and Performance +- Budgets: + - Cache budget: default 512 MiB (configurable). + - Activation cap per tick: default 16 (configurable). + - Prefetch radius Rd = Rs + 2..4; disabled under pressure. +- Estimation: + - Snapshot.memoryBytes = sum(capacities) for sections, entities, biomes, light. +- Eviction Order: + - Prefetch-only unpinned -> old LRU unpinned -> TTL-expired -> never pinned. +- Backpressure: + - If usedBytes > budget: stop new prefetch; evict until under budget. + - If still high: reduce Rd; as a last resort, throttle new required loads (warn). + +7) Threading and Safety +- Background threads: I/O, decode, encode only; they never touch LiveChunks. +- Main thread: exclusive owner of ActiveSet and LiveChunks. +- Handoffs: + - Background produces Snapshot (immutable). + - Main thread consumes Snapshot and creates LiveChunk. +- Locks: + - ChunkManager internal locks around maps/LRU and region handle cache. + - WorldState is single-threaded; no locks on ActiveSet. +- Futures: + - Never block the tick loop; poll ready futures only. + +8) Error Handling and Recovery +- Missing chunk in region: Snapshot=null -> generator hook or treat as void. +- Corrupt NBT: log warning with pos and region; skip activation. +- Save failure: retry with backoff; mark chunk “savePending”; keep pinned until + persisted or max retries reached (then escalate). +- Region open failure: mark region offline; degrade gracefully; alert. + +9) Instrumentation and Metrics +- Expose counters/gauges: + - activeChunks, pendingLoads, pendingActivations, pendingEvictions + - cacheUsedBytes/currentBudget, pinnedCount, inflightLoads/saves + - IO latency p50/p95, decode time p50/p95, activation time p50/p95 +- Tracing spans: + - readChunk, decode, encode, writeChunk, activate, evict +- Logs: + - INFO on region opens/closes; WARN on decode/save errors; DEBUG on evictions. + +10) Configuration +- CacheConfig: + - memoryBudgetBytes (default 512 MiB) + - ttlSeconds (default 120) + - enableTTL (default true) +- Runtime: + - ioThreads (default 2), decodeThreads (default 2), encodeThreads (default 2) + - simRadius Rs per world or per player (default 8) + - prefetchRadius Rd relative to Rs (default +2) + - maxActivationsPerTick (default 16) + - saveBatchSize (default 8) +- Paths: + - worldRoot pointing to Anvil world directory (contains region/). + +11) Data Schemas (Abstract) +- Snapshot: + - ChunkPos pos + - int dataVersion + - vector
sections (Y-indexed; palette + blockStates bits) + - Biome data (per-column or per-section) + - Heightmap(s) + - Entities: vector (raw NBT fields or parsed minimal) + - TileEntities: vector + - Light (optional raw arrays if read) + - size_t memoryBytes +- LiveChunk: + - ChunkPos pos + - Blocks (mutable accessor over sections) + - Entities (engine-owned IDs) + - TileEntities + - Light caches + - Dirty flags: blocks/entities/tileEntities + - Aux: navigation mesh, scheduled ticks +- CacheEntry: + - optional snapshot + - future inflightLoad + - future inflightSave + - bool pinned + - time_point lastUsed + - size_t sizeBytes + +12) APIs (C++ Signatures, indicative) +- ChunkManager + - future getChunkAsync(ChunkPos pos); + - void prefetch(ChunkPos pos); + - void pin(ChunkPos pos); + - void unpin(ChunkPos pos); + - future saveAsync(ChunkPos pos, const Snapshot& s); + - void tick(); + - void setMemoryBudget(size_t bytes); + - Metrics metrics() const; +- WorldState + - void requestEnsureActive(ChunkPos pos); + - void processAsyncLoadsNonBlocking(); // moves ready into PendingActivations + - void activateSome(size_t maxCount); + - void scheduleDeactivate(ChunkPos pos); + - LiveChunk* getLive(ChunkPos pos); + - void markDirty(ChunkPos pos, DirtyMask mask); + - Snapshot encodeSnapshot(const LiveChunk& lc) const; + +13) Edge Policies +- Neighbor-dependent systems (lighting, fluid flow, redstone): + - Allow partial activation with border-deferred mode; reconcile when both + neighbors are active; maintain a “border dirty” mask per face. +- Cross-chunk entity movement: + - If target chunk inactive: queue transfer; ensure target pos in DesiredSet. +- Spawn area: + - Permanently pinned unless server config unpins during high pressure. + +14) Testing Strategy +- Unit: + - Region header parse; readChunk for known fixtures. + - Codec decode/encode roundtrip for multiple DataVersion samples. + - LRU/TTL eviction order under budget change. +- Integration: + - Simulate player walk; assert ActiveSet sliding window; no blocking. + - Memory cap adherence under synthetic pressure. + - Save/load dirty chunk with concurrent evictions. +- Soak: + - Long-running walk across regions; capture latency histograms. + +15) Migration/Compatibility +- Support multiple DataVersions by feature flags in ChunkCodec. +- Backward-compatible save: preserve unknown NBT tags when round-tripping. + +16) Security/Robustness +- Validate NBT lengths vs. header to avoid OOM. +- Cap per-chunk uncompressed size (e.g., 32 MiB) and reject if exceeded. +- Limit inflight loads and activations per tick to avoid spikes. + +17) Future Work +- Compression dictionary caching; in-memory section-level compression. +- Hotset prioritization via LFU or ARC instead of pure LRU. +- NUMA-aware thread pools and file read-ahead/batching. +- Sharded world loops for multi-core scaling (region-based ownership). +S From e89df37c7176835d4fefece75d1f9dc1128bdb57 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Antoine=20Mathi=C3=A9?= Date: Wed, 8 Oct 2025 15:15:09 +0200 Subject: [PATCH 02/27] cpp version bump to c++23 to be aligned with the nbt lib --- .clangd | 2 +- Makefile | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.clangd b/.clangd index e308436..b9e3cdd 100644 --- a/.clangd +++ b/.clangd @@ -1,6 +1,6 @@ CompileFlags: Add: - - "-std=c++17" + - "-std=c++23" - "-Wall" - "-Wextra" - "-Wpedantic" diff --git a/Makefile b/Makefile index 529131e..b1c59e1 100644 --- a/Makefile +++ b/Makefile @@ -15,7 +15,7 @@ TARGET := $(BUILD_DIR)/$(TARGET_NAME) # Compiler and flags CXX := g++ -CXXFLAGS := -std=c++17 -Wall -Wextra -Wpedantic -O2 +CXXFLAGS := -std=c++23 -Wall -Wextra -Wpedantic -O2 DEBUG_FLAGS := -g -DDEBUG -O0 RELEASE_FLAGS := -DNDEBUG -O3 INCLUDE_FLAGS := -I$(INCLUDE_DIR) From cc3dbbd009958baeacae1e5f34afb854c26dd394 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Antoine=20Mathi=C3=A9?= Date: Wed, 8 Oct 2025 15:23:57 +0200 Subject: [PATCH 03/27] updated doc --- ideas/chunks-spec.md | 302 ++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 281 insertions(+), 21 deletions(-) diff --git a/ideas/chunks-spec.md b/ideas/chunks-spec.md index a4b801f..7eb80ba 100644 --- a/ideas/chunks-spec.md +++ b/ideas/chunks-spec.md @@ -18,7 +18,68 @@ Last Updated: 2025-10-08 - Full lighting algorithm specification (only interfaces/hooks). - Network protocol specifics. -3) Terminology +3) Architecture Overview + +The system follows a layered architecture with clear separation of concerns: + +``` +┌─────────────────────────────────────────────────────────────┐ +│ Game Logic Layer │ +│ ┌─────────────────┐ ┌─────────────────┐ ┌──────────────┐ │ +│ │ EntitySystem │ │ BlockSystem │ │ Other Systems│ │ +│ └─────────────────┘ └─────────────────┘ └──────────────┘ │ +└─────────────────────────────────────────────────────────────┘ + │ + ▼ +┌─────────────────────────────────────────────────────────────┐ +│ Simulation Layer │ +│ ┌─────────────────────────────────────────────────────────┐ │ +│ │ WorldState │ │ +│ │ ActiveSet │ PendingLoads │ PendingActivations │ │ +│ └─────────────────────────────────────────────────────────┘ │ +└─────────────────────────────────────────────────────────────┘ + │ + ▼ +┌─────────────────────────────────────────────────────────────┐ +│ Orchestration Layer │ +│ ┌─────────────────────────────────────────────────────────┐ │ +│ │ ChunkManager │ │ +│ │ Cache │ LRU │ ThreadPools │ Futures │ │ +│ └─────────────────────────────────────────────────────────┘ │ +└─────────────────────────────────────────────────────────────┘ + │ + ▼ +┌─────────────────────────────────────────────────────────────┐ +│ Serialization Layer │ +│ ┌─────────────────┐ ┌──────────────────────┐ │ +│ │ ChunkCodec │ │ DataVersion │ │ +│ │ (NBT ↔ Snap) │ │ Compatibility │ │ +│ └─────────────────┘ └──────────────────────┘ │ +└─────────────────────────────────────────────────────────────┘ + │ + ▼ +┌─────────────────────────────────────────────────────────────┐ +│ I/O Layer │ +│ ┌─────────────────┐ ┌─────────────────┐ ┌──────────────┐ │ +│ │ RegionFile │ │ RegionCache │ │ FileSystem │ │ +│ │ (.mca) │ │ (FD mgmt) │ │ Backend │ │ +│ └─────────────────┘ └─────────────────┘ └──────────────┘ │ +└─────────────────────────────────────────────────────────────┘ +``` + +Key Architectural Principles: +- **Single ownership**: Each layer owns its data structures exclusively +- **Async boundaries**: Cross-layer communication via futures/queues +- **Immutable handoffs**: Data passed between threads as immutable snapshots +- **Bounded resources**: Memory and CPU usage controlled at each layer +- **Graceful degradation**: System continues operating under resource pressure + +Data Flow Patterns: +1. **Load Path**: I/O → Decode → Cache → Activate → Simulate +2. **Save Path**: Simulate → Encode → Cache → I/O +3. **Eviction Path**: Cache → Save Path (if dirty) → Release + +4) Terminology - ChunkPos: integer pair {x, z} in chunk coordinates (16×16 blocks each). - Region: 32×32 chunks per .mca file (r...mca). - Snapshot (immutable): decoded NBT data for a chunk (sections, biomes, @@ -30,8 +91,54 @@ Last Updated: 2025-10-08 prefetch radius. - CacheEntry: background cache record (may hold Snapshot or nothing). -4) Components -4.1) RegionFile (I/O) +5) Component Interactions + +5.1) Main Thread Tick Cycle +``` +WorldState.tick() { + Phase 0: computeDesiredSet() -> ChunkManager.pin/prefetch() + Phase 1: pollAsyncResults() -> queue activations + Phase 2: activateChunks() + evictChunks() -> modify ActiveSet + Phase 3: runSystems(ActiveSet) -> modify LiveChunks + Phase 4: produceNetworkUpdates() + ChunkManager.tick() +} +``` + +5.2) Background Thread Operations +``` +I/O Thread Pool: + RegionFile.readChunk() -> raw compressed data + RegionFile.writeChunk() <- compressed data + +Decode Thread Pool: + ChunkCodec.decode(raw data) -> Snapshot + +Encode Thread Pool: + ChunkCodec.encode(Snapshot) -> raw data +``` + +5.3) Cross-Thread Communication +- **Main → Background**: Requests via ChunkManager APIs (non-blocking) +- **Background → Main**: Results via std::future (polled, never blocking) +- **Thread Safety**: All cross-thread data is immutable (Snapshot) + +5.4) Memory Management Strategy +``` +Ownership Hierarchy: +├── ChunkManager owns: CacheEntry map, futures, thread pools +├── WorldState owns: ActiveSet, PendingQueues +├── LiveChunk owns: runtime simulation data (mutable) +├── Snapshot owns: decoded NBT data (immutable) +└── RegionFile owns: file descriptors, headers +``` + +5.5) Error Propagation +- **I/O Errors**: RegionFile → ChunkManager (via future) → WorldState (fallback) +- **Decode Errors**: ChunkCodec → ChunkManager → WorldState (empty chunk) +- **Memory Pressure**: ChunkManager → WorldState (throttle activations) + +6) Components +6.1) RegionFile (I/O) - Responsibility: Read compressed chunk blobs from .mca files. - Interfaces: - static path regionPathFor(worldRoot, cx, cz) -> filesystem::path @@ -46,7 +153,7 @@ Last Updated: 2025-10-08 RegionFile instance per region, methods may be called from thread pool). - Errors: returns nullopt for missing chunks; throws only on fatal open errors. -4.2) ChunkCodec (Decode/Encode) +6.2) ChunkCodec (Decode/Encode) - Responsibility: Convert between compressed blob and Snapshot. - Interfaces: - decodeFromCompressedNbt(ChunkPos, blob) -> Snapshot + stats @@ -57,7 +164,7 @@ Last Updated: 2025-10-08 - Memory accounting: reports uncompressed size for budgeting. - Errors: returns null/empty Snapshot on malformed input; logs diagnostics. -4.3) ChunkManager (Background cache + async orchestration) +6.3) ChunkManager (Background cache + async orchestration) - Responsibility: Manage memory-bounded cache of Snapshots and orchestrate background I/O and decoding/encoding. - Interfaces: @@ -77,7 +184,7 @@ Last Updated: 2025-10-08 - No main-thread blocking except when caller chooses to wait on futures. - Errors: futures resolve to empty Snapshot on failure; callers decide fallback. -4.4) WorldState (Main-thread authoritative) +6.4) WorldState (Main-thread authoritative) - Responsibility: Owns and mutates LiveChunks; integrates Snapshots deterministically. - Interfaces: - ensureActive(pos) -> schedules load if needed (non-blocking) @@ -97,7 +204,7 @@ Last Updated: 2025-10-08 - Activation rate limit per tick to bound frame spikes (e.g., 16). - Defer cross-chunk operations until neighbors are present if required. -4.5) EntitySystem and Subsystems +6.5) EntitySystem and Subsystems - Responsibility: Simulate only within ActiveSet. - Interfaces: - onTick(WorldView view) where view queries LiveChunks only. @@ -106,7 +213,7 @@ Last Updated: 2025-10-08 - Never reads background Snapshots directly. - Handles “chunk not loaded” by deferring or scheduling prefetch. -5) Tick Phases (Deterministic Order) +7) Tick Phases (Deterministic Order) - Phase 0: Input & Interest - Compute DesiredSet from players (Rs sim radius, Rd prefetch radius) + spawn. - For each pos in DesiredSet: @@ -127,7 +234,7 @@ Last Updated: 2025-10-08 - Produce network snapshots from ActiveSet only. - ChunkManager.tick(); flush writebacks opportunistically. -6) Memory and Performance +8) Memory and Performance - Budgets: - Cache budget: default 512 MiB (configurable). - Activation cap per tick: default 16 (configurable). @@ -140,7 +247,7 @@ Last Updated: 2025-10-08 - If usedBytes > budget: stop new prefetch; evict until under budget. - If still high: reduce Rd; as a last resort, throttle new required loads (warn). -7) Threading and Safety +9) Threading and Safety - Background threads: I/O, decode, encode only; they never touch LiveChunks. - Main thread: exclusive owner of ActiveSet and LiveChunks. - Handoffs: @@ -152,14 +259,14 @@ Last Updated: 2025-10-08 - Futures: - Never block the tick loop; poll ready futures only. -8) Error Handling and Recovery +10) Error Handling and Recovery - Missing chunk in region: Snapshot=null -> generator hook or treat as void. - Corrupt NBT: log warning with pos and region; skip activation. - Save failure: retry with backoff; mark chunk “savePending”; keep pinned until persisted or max retries reached (then escalate). - Region open failure: mark region offline; degrade gracefully; alert. -9) Instrumentation and Metrics +11) Instrumentation and Metrics - Expose counters/gauges: - activeChunks, pendingLoads, pendingActivations, pendingEvictions - cacheUsedBytes/currentBudget, pinnedCount, inflightLoads/saves @@ -169,7 +276,7 @@ Last Updated: 2025-10-08 - Logs: - INFO on region opens/closes; WARN on decode/save errors; DEBUG on evictions. -10) Configuration +12) Configuration - CacheConfig: - memoryBudgetBytes (default 512 MiB) - ttlSeconds (default 120) @@ -183,7 +290,7 @@ Last Updated: 2025-10-08 - Paths: - worldRoot pointing to Anvil world directory (contains region/). -11) Data Schemas (Abstract) +13) Data Schemas (Abstract) - Snapshot: - ChunkPos pos - int dataVersion @@ -210,7 +317,7 @@ Last Updated: 2025-10-08 - time_point lastUsed - size_t sizeBytes -12) APIs (C++ Signatures, indicative) +14) APIs (C++ Signatures, indicative) - ChunkManager - future getChunkAsync(ChunkPos pos); - void prefetch(ChunkPos pos); @@ -229,7 +336,7 @@ Last Updated: 2025-10-08 - void markDirty(ChunkPos pos, DirtyMask mask); - Snapshot encodeSnapshot(const LiveChunk& lc) const; -13) Edge Policies +15) Edge Policies - Neighbor-dependent systems (lighting, fluid flow, redstone): - Allow partial activation with border-deferred mode; reconcile when both neighbors are active; maintain a “border dirty” mask per face. @@ -238,7 +345,7 @@ Last Updated: 2025-10-08 - Spawn area: - Permanently pinned unless server config unpins during high pressure. -14) Testing Strategy +16) Testing Strategy - Unit: - Region header parse; readChunk for known fixtures. - Codec decode/encode roundtrip for multiple DataVersion samples. @@ -250,18 +357,171 @@ Last Updated: 2025-10-08 - Soak: - Long-running walk across regions; capture latency histograms. -15) Migration/Compatibility +17) Migration/Compatibility - Support multiple DataVersions by feature flags in ChunkCodec. - Backward-compatible save: preserve unknown NBT tags when round-tripping. -16) Security/Robustness +18) Security/Robustness - Validate NBT lengths vs. header to avoid OOM. - Cap per-chunk uncompressed size (e.g., 32 MiB) and reject if exceeded. - Limit inflight loads and activations per tick to avoid spikes. -17) Future Work +19) Future Work - Compression dictionary caching; in-memory section-level compression. - Hotset prioritization via LFU or ARC instead of pure LRU. - NUMA-aware thread pools and file read-ahead/batching. - Sharded world loops for multi-core scaling (region-based ownership). -S +20) Implementation Phases + +Phase 1: Foundation (Weeks 1-2) +- RegionFile: Basic .mca reading with header parsing +- ChunkCodec: NBT decode for basic block data only +- Unit tests for I/O and decode paths + +Phase 2: Caching (Weeks 3-4) +- ChunkManager: In-memory cache with LRU eviction +- Thread pools for async I/O and decode +- Integration tests with synthetic load + +Phase 3: World Integration (Weeks 5-6) +- WorldState: ActiveSet management and tick phases +- LiveChunk activation from Snapshots +- Basic entity and block system integration + +Phase 4: Performance (Weeks 7-8) +- Memory budgets and backpressure +- Metrics and instrumentation +- Performance testing and tuning + +Phase 5: Production (Weeks 9-10) +- Error handling and recovery +- Save/writeback implementation +- Soak testing and optimization + +21) Architectural Concerns & Design Alternatives + +21.1) Resource Lifecycle Management +Current Challenge: Complex state transitions between cached, pending, active, and dirty states +can lead to resource leaks or inconsistent states. + +Proposed Solution: State Machine Pattern +``` +ChunkState { + UNLOADED -> [load request] -> LOADING + LOADING -> [load complete] -> CACHED + CACHED -> [activation] -> ACTIVE + ACTIVE -> [modification] -> DIRTY + DIRTY -> [save request] -> SAVING + SAVING -> [save complete] -> CACHED + CACHED/ACTIVE -> [eviction] -> UNLOADED +} +``` + +Benefits: +- Clear ownership at each state +- Deterministic cleanup paths +- Easier debugging and metrics +- Prevents invalid state transitions + +21.2) Alternative Threading Models + +Current: Separate I/O, Decode, Encode thread pools +Alternative A: Single background worker pool with typed tasks +Alternative B: Actor model with mailbox queues per chunk +Alternative C: Lock-free single-producer-single-consumer queues + +Trade-offs Analysis: +- Current model: Higher parallelism, more complex synchronization +- Alternative A: Simpler, but potential head-of-line blocking +- Alternative B: Better isolation, higher memory overhead +- Alternative C: Lowest latency, limited to 1:1 producer-consumer + +Recommendation: Stick with current model but add task priorities. + +21.3) Memory Management Strategies + +Current: Global memory budget with LRU eviction +Alternative A: Per-region memory budgets +Alternative B: Hierarchical budgets (world -> region -> chunk) +Alternative C: Adaptive budgets based on access patterns + +Analysis: +- Current: Simple but can cause hot regions to evict cold regions +- Alternative A: Better locality but complex cross-region coordination +- Alternative B: Most flexible but highest complexity +- Alternative C: Optimal performance but unpredictable behavior + +Recommendation: Implement current model with per-region budget override option. + +21.4) Error Handling Architecture + +Current: Futures resolve to empty on error, caller decides fallback +Alternative A: Exception-based error propagation +Alternative B: Result types with explicit error handling +Alternative C: Error callback system with retry policies + +Considerations: +- Performance: Exceptions have overhead, Results require explicit handling +- Debuggability: Results provide better error context +- Reliability: Callbacks allow centralized retry logic + +Recommendation: Hybrid approach - Results for expected errors, exceptions for programmer errors. + +21.5) Cache Coherency Strategies + +Current: Main thread authoritative, background cache eventually consistent +Potential Issues: +- Save races: Background saves stale data while main thread modifies +- Memory visibility: Cache eviction during active modification +- Temporal coupling: Activation timing affects neighbor-dependent systems + +Proposed Improvements: +- Version stamps on snapshots to detect staleness +- Copy-on-write for active chunks being saved +- Deferred activation queue for neighbor dependencies + +21.6) Scalability Bottlenecks + +Identified Concerns: +1. Single ChunkManager instance limits parallelism +2. Main thread activation limit caps world size growth +3. Region file contention under high load +4. Memory allocator pressure from frequent Snapshot creation + +Mitigation Strategies: +1. Shard ChunkManager by region hash +2. Adaptive activation limits based on frame time budget +3. Read-ahead and batching for region operations +4. Object pooling for common Snapshot components + +21.7) Interface Design Philosophy + +Current: Procedural interfaces with explicit state management +Alternative: RAII-based interfaces with automatic cleanup + +Example Current: +```cpp +manager.pin(pos); +auto future = manager.getChunkAsync(pos); +// ... later +manager.unpin(pos); +``` + +Example Alternative: +```cpp +auto handle = manager.requestChunk(pos); // RAII pin +auto future = handle.getFuture(); +// automatic unpin on handle destruction +``` + +Benefits of RAII approach: +- Exception safety +- Prevents resource leaks +- Clearer ownership semantics + +Drawbacks: +- More complex implementation +- Potential performance overhead +- Less explicit control over timing + +Recommendation: Provide both interfaces - RAII for convenience, explicit for performance-critical paths. From 40eeeae95958b034275f318e59668a8b586a2a06 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Antoine=20Mathi=C3=A9?= Date: Wed, 8 Oct 2025 15:46:45 +0200 Subject: [PATCH 04/27] header refactor --- include/{ => lib}/MD5.hpp | 0 include/{ => lib}/UUID.hpp | 0 include/{ => lib}/json.hpp | 0 include/{ => lib}/nbt.hpp | 0 include/{ => network}/buffer.hpp | 2 +- include/{ => network}/id_manager.hpp | 0 include/{ => network}/networking.hpp | 4 ++-- include/{ => network}/packet.hpp | 2 +- include/{ => network}/server.hpp | 4 ++-- include/player.hpp | 2 +- src/MD5.cpp | 2 +- src/UUID.cpp | 6 +++--- src/buffer.cpp | 4 ++-- src/id_manager.cpp | 2 +- src/main.cpp | 2 +- src/networking/networkManager.cpp | 4 ++-- src/networking/networkQueuer.cpp | 6 +++--- src/networking/networkWorker.cpp | 6 +++--- src/networking/packet/chunkBatch.cpp | 10 +++++----- src/networking/packet/chunkDataSimple.cpp | 10 +++++----- src/networking/packet/cookieRequest.cpp | 8 ++++---- src/networking/packet/finishConfiguration.cpp | 6 +++--- src/networking/packet/handleClientInformation.cpp | 4 ++-- src/networking/packet/handshake.cpp | 4 ++-- src/networking/packet/loginAcknowledged.cpp | 6 +++--- src/networking/packet/loginStart.cpp | 10 +++++----- src/networking/packet/packetRouter.cpp | 6 +++--- src/networking/packet/ping.cpp | 8 ++++---- src/networking/packet/play.cpp | 10 +++++----- src/networking/packet/setCenterChunck.cpp | 10 +++++----- src/networking/packet/spawnSequence.cpp | 10 +++++----- src/networking/packet/status.cpp | 10 +++++----- src/packet.cpp | 8 ++++---- src/player.cpp | 4 ++-- src/server.cpp | 6 +++--- 35 files changed, 88 insertions(+), 88 deletions(-) rename include/{ => lib}/MD5.hpp (100%) rename include/{ => lib}/UUID.hpp (100%) rename include/{ => lib}/json.hpp (100%) rename include/{ => lib}/nbt.hpp (100%) rename include/{ => network}/buffer.hpp (97%) rename include/{ => network}/id_manager.hpp (100%) rename include/{ => network}/networking.hpp (98%) rename include/{ => network}/packet.hpp (97%) rename include/{ => network}/server.hpp (97%) diff --git a/include/MD5.hpp b/include/lib/MD5.hpp similarity index 100% rename from include/MD5.hpp rename to include/lib/MD5.hpp diff --git a/include/UUID.hpp b/include/lib/UUID.hpp similarity index 100% rename from include/UUID.hpp rename to include/lib/UUID.hpp diff --git a/include/json.hpp b/include/lib/json.hpp similarity index 100% rename from include/json.hpp rename to include/lib/json.hpp diff --git a/include/nbt.hpp b/include/lib/nbt.hpp similarity index 100% rename from include/nbt.hpp rename to include/lib/nbt.hpp diff --git a/include/buffer.hpp b/include/network/buffer.hpp similarity index 97% rename from include/buffer.hpp rename to include/network/buffer.hpp index 42c7d4a..fd44dd5 100644 --- a/include/buffer.hpp +++ b/include/network/buffer.hpp @@ -1,7 +1,7 @@ #ifndef BUFFER_HPP #define BUFFER_HPP -#include "UUID.hpp" +#include "lib/UUID.hpp" #include #include diff --git a/include/id_manager.hpp b/include/network/id_manager.hpp similarity index 100% rename from include/id_manager.hpp rename to include/network/id_manager.hpp diff --git a/include/networking.hpp b/include/network/networking.hpp similarity index 98% rename from include/networking.hpp rename to include/network/networking.hpp index e1e7bd9..a06f42b 100644 --- a/include/networking.hpp +++ b/include/network/networking.hpp @@ -1,9 +1,9 @@ #ifndef NETWORKING_HPP #define NETWORKING_HPP -#include "UUID.hpp" +#include "lib/UUID.hpp" #include "packet.hpp" -#include "player.hpp" +#include "../player.hpp" // Forward declaration to avoid circular dependency class Server; diff --git a/include/packet.hpp b/include/network/packet.hpp similarity index 97% rename from include/packet.hpp rename to include/network/packet.hpp index 280d68d..fb1c68d 100644 --- a/include/packet.hpp +++ b/include/network/packet.hpp @@ -2,7 +2,7 @@ #define PACKET_HPP #include "buffer.hpp" -#include "player.hpp" +#include "../player.hpp" #include "server.hpp" #include diff --git a/include/server.hpp b/include/network/server.hpp similarity index 97% rename from include/server.hpp rename to include/network/server.hpp index 41d2efc..1a048de 100644 --- a/include/server.hpp +++ b/include/network/server.hpp @@ -3,8 +3,8 @@ class NetworkManager; #include "id_manager.hpp" -#include "json.hpp" -#include "player.hpp" +#include "lib/json.hpp" +#include "../player.hpp" #include #include diff --git a/include/player.hpp b/include/player.hpp index 8e1b7ec..7c21855 100644 --- a/include/player.hpp +++ b/include/player.hpp @@ -1,7 +1,7 @@ #ifndef PLAYER_HPP #define PLAYER_HPP -#include "UUID.hpp" +#include "lib/UUID.hpp" #include #include diff --git a/src/MD5.cpp b/src/MD5.cpp index 4d3f919..b2145fc 100644 --- a/src/MD5.cpp +++ b/src/MD5.cpp @@ -1,4 +1,4 @@ -#include "MD5.hpp" +#include "lib/MD5.hpp" #include diff --git a/src/UUID.cpp b/src/UUID.cpp index 40c81a5..f84a441 100644 --- a/src/UUID.cpp +++ b/src/UUID.cpp @@ -1,6 +1,6 @@ -#include "MD5.hpp" -#include "UUID.hpp" -#include "buffer.hpp" +#include "lib/MD5.hpp" +#include "lib/UUID.hpp" +#include "network/buffer.hpp" #include #include diff --git a/src/buffer.cpp b/src/buffer.cpp index 2467363..3a46fad 100644 --- a/src/buffer.cpp +++ b/src/buffer.cpp @@ -1,5 +1,5 @@ -#include "UUID.hpp" -#include "buffer.hpp" +#include "lib/UUID.hpp" +#include "network/buffer.hpp" #include #include diff --git a/src/id_manager.cpp b/src/id_manager.cpp index 812b9bd..b264dcc 100644 --- a/src/id_manager.cpp +++ b/src/id_manager.cpp @@ -1,4 +1,4 @@ -#include "id_manager.hpp" +#include "network/id_manager.hpp" #include #include diff --git a/src/main.cpp b/src/main.cpp index a51254c..df27ea9 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -1,4 +1,4 @@ -#include "server.hpp" +#include "network/server.hpp" int main() { Server server; diff --git a/src/networking/networkManager.cpp b/src/networking/networkManager.cpp index 82be534..45c66c5 100644 --- a/src/networking/networkManager.cpp +++ b/src/networking/networkManager.cpp @@ -1,5 +1,5 @@ -#include "networking.hpp" -#include "server.hpp" +#include "network/networking.hpp" +#include "network/server.hpp" #include #include diff --git a/src/networking/networkQueuer.cpp b/src/networking/networkQueuer.cpp index 04fa202..f83afd7 100644 --- a/src/networking/networkQueuer.cpp +++ b/src/networking/networkQueuer.cpp @@ -1,7 +1,7 @@ -#include "networking.hpp" -#include "packet.hpp" +#include "network/networking.hpp" +#include "network/packet.hpp" #include "player.hpp" -#include "server.hpp" +#include "network/server.hpp" #include "logger.hpp" #include diff --git a/src/networking/networkWorker.cpp b/src/networking/networkWorker.cpp index ad7a5df..25e23af 100644 --- a/src/networking/networkWorker.cpp +++ b/src/networking/networkWorker.cpp @@ -1,8 +1,8 @@ #include "logger.hpp" -#include "networking.hpp" -#include "packet.hpp" +#include "network/networking.hpp" +#include "network/packet.hpp" #include "player.hpp" -#include "server.hpp" +#include "network/server.hpp" #include #include diff --git a/src/networking/packet/chunkBatch.cpp b/src/networking/packet/chunkBatch.cpp index 83dc2a6..d153949 100644 --- a/src/networking/packet/chunkBatch.cpp +++ b/src/networking/packet/chunkBatch.cpp @@ -1,9 +1,9 @@ -#include "UUID.hpp" -#include "buffer.hpp" -#include "networking.hpp" -#include "packet.hpp" +#include "lib/UUID.hpp" +#include "network/buffer.hpp" +#include "network/networking.hpp" +#include "network/packet.hpp" #include "player.hpp" -#include "server.hpp" +#include "network/server.hpp" #include diff --git a/src/networking/packet/chunkDataSimple.cpp b/src/networking/packet/chunkDataSimple.cpp index 75cc299..1ae0ab9 100644 --- a/src/networking/packet/chunkDataSimple.cpp +++ b/src/networking/packet/chunkDataSimple.cpp @@ -1,9 +1,9 @@ -#include "UUID.hpp" -#include "buffer.hpp" -#include "networking.hpp" -#include "packet.hpp" +#include "lib/UUID.hpp" +#include "network/buffer.hpp" +#include "network/networking.hpp" +#include "network/packet.hpp" #include "player.hpp" -#include "server.hpp" +#include "network/server.hpp" #include diff --git a/src/networking/packet/cookieRequest.cpp b/src/networking/packet/cookieRequest.cpp index 5cd75df..630c14e 100644 --- a/src/networking/packet/cookieRequest.cpp +++ b/src/networking/packet/cookieRequest.cpp @@ -1,9 +1,9 @@ -#include "networking.hpp" -#include "packet.hpp" +#include "network/networking.hpp" +#include "network/packet.hpp" #include "player.hpp" -#include "server.hpp" +#include "network/server.hpp" #include "logger.hpp" -#include "buffer.hpp" +#include "network/buffer.hpp" #include void handleCookieRequest(Packet& packet, Server& server) { diff --git a/src/networking/packet/finishConfiguration.cpp b/src/networking/packet/finishConfiguration.cpp index e75801b..e181658 100644 --- a/src/networking/packet/finishConfiguration.cpp +++ b/src/networking/packet/finishConfiguration.cpp @@ -1,7 +1,7 @@ -#include "networking.hpp" -#include "packet.hpp" +#include "network/networking.hpp" +#include "network/packet.hpp" #include "player.hpp" -#include "server.hpp" +#include "network/server.hpp" #include "logger.hpp" #include diff --git a/src/networking/packet/handleClientInformation.cpp b/src/networking/packet/handleClientInformation.cpp index 1a84fdc..4c94fa3 100644 --- a/src/networking/packet/handleClientInformation.cpp +++ b/src/networking/packet/handleClientInformation.cpp @@ -1,6 +1,6 @@ #include "logger.hpp" -#include "packet.hpp" -#include "server.hpp" +#include "network/packet.hpp" +#include "network/server.hpp" #include diff --git a/src/networking/packet/handshake.cpp b/src/networking/packet/handshake.cpp index bbe728d..580324a 100644 --- a/src/networking/packet/handshake.cpp +++ b/src/networking/packet/handshake.cpp @@ -1,6 +1,6 @@ -#include "packet.hpp" +#include "network/packet.hpp" #include "player.hpp" -#include "server.hpp" +#include "network/server.hpp" #include "logger.hpp" #include diff --git a/src/networking/packet/loginAcknowledged.cpp b/src/networking/packet/loginAcknowledged.cpp index d75a8f5..5775a3b 100644 --- a/src/networking/packet/loginAcknowledged.cpp +++ b/src/networking/packet/loginAcknowledged.cpp @@ -1,7 +1,7 @@ -#include "networking.hpp" -#include "packet.hpp" +#include "network/networking.hpp" +#include "network/packet.hpp" #include "player.hpp" -#include "server.hpp" +#include "network/server.hpp" #include "logger.hpp" #include diff --git a/src/networking/packet/loginStart.cpp b/src/networking/packet/loginStart.cpp index 0febb03..c0e3c88 100644 --- a/src/networking/packet/loginStart.cpp +++ b/src/networking/packet/loginStart.cpp @@ -1,9 +1,9 @@ -#include "UUID.hpp" -#include "buffer.hpp" -#include "networking.hpp" -#include "packet.hpp" +#include "lib/UUID.hpp" +#include "network/buffer.hpp" +#include "network/networking.hpp" +#include "network/packet.hpp" #include "player.hpp" -#include "server.hpp" +#include "network/server.hpp" #include "logger.hpp" #include diff --git a/src/networking/packet/packetRouter.cpp b/src/networking/packet/packetRouter.cpp index de0ae2d..52068f7 100644 --- a/src/networking/packet/packetRouter.cpp +++ b/src/networking/packet/packetRouter.cpp @@ -1,7 +1,7 @@ -#include "networking.hpp" -#include "packet.hpp" +#include "network/networking.hpp" +#include "network/packet.hpp" #include "player.hpp" -#include "server.hpp" +#include "network/server.hpp" #include "logger.hpp" #include diff --git a/src/networking/packet/ping.cpp b/src/networking/packet/ping.cpp index eaf7a40..2f6dc15 100644 --- a/src/networking/packet/ping.cpp +++ b/src/networking/packet/ping.cpp @@ -1,8 +1,8 @@ -#include "buffer.hpp" -#include "networking.hpp" -#include "packet.hpp" +#include "network/buffer.hpp" +#include "network/networking.hpp" +#include "network/packet.hpp" #include "player.hpp" -#include "server.hpp" +#include "network/server.hpp" #include "logger.hpp" #include diff --git a/src/networking/packet/play.cpp b/src/networking/packet/play.cpp index 8878655..73ca75f 100644 --- a/src/networking/packet/play.cpp +++ b/src/networking/packet/play.cpp @@ -1,12 +1,12 @@ -// #include "networking.hpp" -// #include "packet.hpp" +// #include "network/networking.hpp" +// #include "network/packet.hpp" // #include "player.hpp" -// #include "server.hpp" -// #include "buffer.hpp" +// #include "network/server.hpp" +// #include "network/buffer.hpp" // #include // #include // #include -// #include "nbt.hpp" +// #include "lib/nbt.hpp" // void writePlayPacket(Packet& packet, Server& server) { // Player* player = packet.getPlayer(); diff --git a/src/networking/packet/setCenterChunck.cpp b/src/networking/packet/setCenterChunck.cpp index 6b84f5b..1dcc964 100644 --- a/src/networking/packet/setCenterChunck.cpp +++ b/src/networking/packet/setCenterChunck.cpp @@ -1,9 +1,9 @@ -#include "UUID.hpp" -#include "buffer.hpp" -#include "networking.hpp" -#include "packet.hpp" +#include "lib/UUID.hpp" +#include "network/buffer.hpp" +#include "network/networking.hpp" +#include "network/packet.hpp" #include "player.hpp" -#include "server.hpp" +#include "network/server.hpp" #include diff --git a/src/networking/packet/spawnSequence.cpp b/src/networking/packet/spawnSequence.cpp index 4473443..629f117 100644 --- a/src/networking/packet/spawnSequence.cpp +++ b/src/networking/packet/spawnSequence.cpp @@ -1,9 +1,9 @@ -#include "UUID.hpp" -#include "buffer.hpp" -#include "networking.hpp" -#include "packet.hpp" +#include "lib/UUID.hpp" +#include "network/buffer.hpp" +#include "network/networking.hpp" +#include "network/packet.hpp" #include "player.hpp" -#include "server.hpp" +#include "network/server.hpp" #include diff --git a/src/networking/packet/status.cpp b/src/networking/packet/status.cpp index 45bc47d..36e1925 100644 --- a/src/networking/packet/status.cpp +++ b/src/networking/packet/status.cpp @@ -1,9 +1,9 @@ -#include "buffer.hpp" -#include "json.hpp" -#include "networking.hpp" -#include "packet.hpp" +#include "network/buffer.hpp" +#include "lib/json.hpp" +#include "network/networking.hpp" +#include "network/packet.hpp" #include "player.hpp" -#include "server.hpp" +#include "network/server.hpp" #include "logger.hpp" #include diff --git a/src/packet.cpp b/src/packet.cpp index e87f013..c2df746 100644 --- a/src/packet.cpp +++ b/src/packet.cpp @@ -1,8 +1,8 @@ -#include "buffer.hpp" -#include "json.hpp" -#include "packet.hpp" +#include "network/buffer.hpp" +#include "lib/json.hpp" +#include "network/packet.hpp" #include "player.hpp" -#include "server.hpp" +#include "network/server.hpp" #include "logger.hpp" #include diff --git a/src/player.cpp b/src/player.cpp index e3c05c0..d6b2de0 100644 --- a/src/player.cpp +++ b/src/player.cpp @@ -1,6 +1,6 @@ -#include "UUID.hpp" +#include "lib/UUID.hpp" #include "player.hpp" -#include "server.hpp" +#include "network/server.hpp" #include diff --git a/src/server.cpp b/src/server.cpp index 8c16f4a..eb0f4b3 100644 --- a/src/server.cpp +++ b/src/server.cpp @@ -1,8 +1,8 @@ -#include "json.hpp" +#include "lib/json.hpp" #include "logger.hpp" -#include "networking.hpp" +#include "network/networking.hpp" #include "player.hpp" -#include "server.hpp" +#include "network/server.hpp" #include #include From f12702686e63769f888be838586105a745f7e310 Mon Sep 17 00:00:00 2001 From: Antoine Mathie Date: Thu, 9 Oct 2025 17:00:12 +0200 Subject: [PATCH 05/27] fix import --- Makefile | 4 ---- src/networking/packet/packetRouter.cpp | 9 --------- 2 files changed, 13 deletions(-) diff --git a/Makefile b/Makefile index 72a14d3..af546ad 100644 --- a/Makefile +++ b/Makefile @@ -15,11 +15,7 @@ TARGET := $(BUILD_DIR)/$(TARGET_NAME) # Compiler and flags CXX := g++ -<<<<<<< HEAD -CXXFLAGS := -std=c++23 -Wall -Wextra -Wpedantic -O2 -======= CXXFLAGS := -std=c++20 -Wall -Wextra -Wpedantic -O2 ->>>>>>> main DEBUG_FLAGS := -g -DDEBUG -O0 RELEASE_FLAGS := -DNDEBUG -O3 INCLUDE_FLAGS := -I$(INCLUDE_DIR) diff --git a/src/networking/packet/packetRouter.cpp b/src/networking/packet/packetRouter.cpp index 3daafc0..a29304c 100644 --- a/src/networking/packet/packetRouter.cpp +++ b/src/networking/packet/packetRouter.cpp @@ -1,17 +1,8 @@ -<<<<<<< HEAD #include "network/networking.hpp" #include "network/packet.hpp" #include "player.hpp" #include "network/server.hpp" #include "logger.hpp" -======= -#include "logger.hpp" -#include "networking.hpp" -#include "packet.hpp" -#include "player.hpp" -#include "server.hpp" - ->>>>>>> main #include // Forward declarations of state handlers From 029c737cea4b1387a330d9e04216fa29df7a9ca7 Mon Sep 17 00:00:00 2001 From: Antoine Mathie Date: Thu, 9 Oct 2025 19:35:32 +0200 Subject: [PATCH 06/27] chore: project structure + pls fix my ocd issues --- include/lib/filesystem.hpp | 5 ++ include/network/networking.hpp | 10 +-- include/network/packet.hpp | 2 +- include/world/worldManager.hpp | 16 +++++ src/{ => entities}/player.cpp | 0 src/{ => lib}/MD5.cpp | 0 src/{ => lib}/UUID.cpp | 0 src/{ => lib}/buffer.cpp | 0 src/{id_manager.cpp => lib/idManager.cpp} | 0 src/{ => lib}/logger.cpp | 0 src/{ => lib}/packet.cpp | 0 src/networking/networkWorker.cpp | 2 +- src/networking/packet/chunkBatch.cpp | 3 +- src/networking/packet/handshake.cpp | 4 +- src/networking/packet/loginStart.cpp | 7 +-- src/networking/packet/packetRouter.cpp | 74 +++++++++++------------ src/networking/packet/play.cpp | 7 +-- src/networking/packet/spawnSequence.cpp | 3 +- src/world/worldManager.cpp | 40 ++++++++++++ 19 files changed, 115 insertions(+), 58 deletions(-) create mode 100644 include/lib/filesystem.hpp create mode 100644 include/world/worldManager.hpp rename src/{ => entities}/player.cpp (100%) rename src/{ => lib}/MD5.cpp (100%) rename src/{ => lib}/UUID.cpp (100%) rename src/{ => lib}/buffer.cpp (100%) rename src/{id_manager.cpp => lib/idManager.cpp} (100%) rename src/{ => lib}/logger.cpp (100%) rename src/{ => lib}/packet.cpp (100%) create mode 100644 src/world/worldManager.cpp diff --git a/include/lib/filesystem.hpp b/include/lib/filesystem.hpp new file mode 100644 index 0000000..1435f63 --- /dev/null +++ b/include/lib/filesystem.hpp @@ -0,0 +1,5 @@ +#ifndef FS_H +# define FS_H + + +#endif FS_H diff --git a/include/network/networking.hpp b/include/network/networking.hpp index a06f42b..4a2288a 100644 --- a/include/network/networking.hpp +++ b/include/network/networking.hpp @@ -97,6 +97,7 @@ class NetworkManager { void addPlayerConnection(std::shared_ptr connection); void removePlayerConnection(UUID id); + ThreadSafeQueue* getOutgoingQueue() { return &_outgoingPackets; } Server& getServer() { return _server; @@ -114,7 +115,7 @@ class NetworkManager { void handleIncomingData(int socket); }; -void packetRouter(Packet* packet, Server& server, ThreadSafeQueue* _outgoingPackets); +void packetRouter(Packet* packet, Server& server); void handleHandshakePacket(Packet& packet, Server& server); void handleStatusPacket(Packet& packet, Server& server); void handlePingPacket(Packet& packet, Server& server); @@ -124,13 +125,13 @@ 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 writePlayPacket(Packet& packet); 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, ThreadSafeQueue* outgoingPackets); +void sendChunkBatchSequence(Packet& packet, Server& server); // Chunk data functions void sendChunkData(Packet& packet, Server& server, int chunkX, int chunkZ); @@ -144,6 +145,7 @@ 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, ThreadSafeQueue* outgoingPackets); +void completeSpawnSequence(Packet& packet, Server& server); +void sendDisconnectPacket(Packet* packet, const std::string& reason, Server& server); #endif diff --git a/include/network/packet.hpp b/include/network/packet.hpp index fb1c68d..0ff47af 100644 --- a/include/network/packet.hpp +++ b/include/network/packet.hpp @@ -4,7 +4,7 @@ #include "buffer.hpp" #include "../player.hpp" #include "server.hpp" - +#include #include enum PacketResult { PACKET_OK = 0, PACKET_SEND = 1, PACKET_DISCONNECT = 2, PACKET_ERROR = -1 }; diff --git a/include/world/worldManager.hpp b/include/world/worldManager.hpp new file mode 100644 index 0000000..2f96bfc --- /dev/null +++ b/include/world/worldManager.hpp @@ -0,0 +1,16 @@ +#ifndef WORLD_MANAGER_HPP +# define WORLD_MANAGER_HPP + +#include +#include +#include + +class WorldManager { + private: + + public: + std::vector decompressGzip(const std::vector& compressed); +}; + + +#endif diff --git a/src/player.cpp b/src/entities/player.cpp similarity index 100% rename from src/player.cpp rename to src/entities/player.cpp diff --git a/src/MD5.cpp b/src/lib/MD5.cpp similarity index 100% rename from src/MD5.cpp rename to src/lib/MD5.cpp diff --git a/src/UUID.cpp b/src/lib/UUID.cpp similarity index 100% rename from src/UUID.cpp rename to src/lib/UUID.cpp diff --git a/src/buffer.cpp b/src/lib/buffer.cpp similarity index 100% rename from src/buffer.cpp rename to src/lib/buffer.cpp diff --git a/src/id_manager.cpp b/src/lib/idManager.cpp similarity index 100% rename from src/id_manager.cpp rename to src/lib/idManager.cpp diff --git a/src/logger.cpp b/src/lib/logger.cpp similarity index 100% rename from src/logger.cpp rename to src/lib/logger.cpp diff --git a/src/packet.cpp b/src/lib/packet.cpp similarity index 100% rename from src/packet.cpp rename to src/lib/packet.cpp diff --git a/src/networking/networkWorker.cpp b/src/networking/networkWorker.cpp index 25e23af..ebd0018 100644 --- a/src/networking/networkWorker.cpp +++ b/src/networking/networkWorker.cpp @@ -19,7 +19,7 @@ void NetworkManager::workerThreadLoop() { try { // g_logger->logNetwork(INFO, "Handling incoming data for player", "Worker"); - packetRouter(packet, getServer(), &_outgoingPackets); + packetRouter(packet, getServer()); if (packet->getReturnPacket() == PACKET_SEND) { _outgoingPackets.push(packet); packet = nullptr; diff --git a/src/networking/packet/chunkBatch.cpp b/src/networking/packet/chunkBatch.cpp index d153949..4204bb1 100644 --- a/src/networking/packet/chunkBatch.cpp +++ b/src/networking/packet/chunkBatch.cpp @@ -54,8 +54,9 @@ void sendChunkBatchFinished(Packet& packet, Server& server, int batchSize) { (void)server; } -void sendChunkBatchSequence(Packet& packet, Server& server, ThreadSafeQueue* outgoingPackets) { +void sendChunkBatchSequence(Packet& packet, Server& server) { Player* player = packet.getPlayer(); + ThreadSafeQueue* outgoingPackets = server.getNetworkManager().getOutgoingQueue(); if (!player || !outgoingPackets) return; // Player spawn position (you should get this from player data) diff --git a/src/networking/packet/handshake.cpp b/src/networking/packet/handshake.cpp index 580324a..8ba6d85 100644 --- a/src/networking/packet/handshake.cpp +++ b/src/networking/packet/handshake.cpp @@ -17,10 +17,10 @@ void handleHandshakePacket(Packet& packet, Server& server) { std::string serverAddr = packet.getData().readString(255); uint16_t port = packet.getData().readUShort(); int nextState = packet.getData().readVarInt(); - // g_logger->logNetwork(INFO, "Protocol=" + std::to_string(protocolVersion) + ", Addr=" + serverAddr + ", State=" + std::to_string(nextState), "Handshake"); + //g_logger->logNetwork(INFO, "Protocol=" + std::to_string(protocolVersion) + ", Addr=" + serverAddr + ", State=" + std::to_string(nextState), "Handshake"); if (nextState == 1) { packet.getPlayer()->setPlayerState(PlayerState::Status); - // g_logger->logNetwork(INFO, "Status request - keeping in temp list", "Handshake"); + //g_logger->logNetwork(INFO, "Status request - keeping in temp list", "Handshake"); } else if (nextState == 2) { packet.getPlayer()->setPlayerState(PlayerState::Login); server.promoteTempPlayer(packet.getPlayer()); diff --git a/src/networking/packet/loginStart.cpp b/src/networking/packet/loginStart.cpp index c0e3c88..5863019 100644 --- a/src/networking/packet/loginStart.cpp +++ b/src/networking/packet/loginStart.cpp @@ -6,7 +6,6 @@ #include "network/server.hpp" #include "logger.hpp" -#include #include void handleLoginStartPacket(Packet& packet, Server& server) { @@ -25,7 +24,7 @@ void handleLoginStartPacket(Packet& packet, Server& server) { payload.writeUUID(uuid); payload.writeString(username); payload.writeVarInt(0); // properties length (no properties) - + // Debug: Log the raw payload bytes std::string payloadHex = ""; for (size_t i = 0; i < payload.getData().size(); i++) { @@ -50,7 +49,7 @@ void handleLoginStartPacket(Packet& packet, Server& server) { packet.getData() = final; packet.setReturnPacket(PACKET_SEND); packet.setPacketSize(final.getData().size()); - + // Debug: Log the complete packet bytes std::string finalHex = ""; for (size_t i = 0; i < final.getData().size(); i++) { @@ -60,7 +59,7 @@ void handleLoginStartPacket(Packet& packet, Server& server) { if (i < final.getData().size() - 1) finalHex += " "; } g_logger->logNetwork(INFO, "Complete Login Success packet bytes: " + finalHex, "Login"); - + // Don't transition to Configuration yet - wait for Login Acknowledged g_logger->logNetwork(INFO, "Login Success sent for user: " + username + ", UUID: " + uuid.toString() + ", packet size: " + std::to_string(final.getData().size()), "Login"); (void)server; diff --git a/src/networking/packet/packetRouter.cpp b/src/networking/packet/packetRouter.cpp index 3a55277..ecf3f49 100644 --- a/src/networking/packet/packetRouter.cpp +++ b/src/networking/packet/packetRouter.cpp @@ -3,30 +3,29 @@ #include "player.hpp" #include "network/server.hpp" #include "logger.hpp" -#include +#include +#include "network/packet.hpp" -// Forward declarations of state handlers void handleHandshakeState(Packet* packet, - Server& server, - ThreadSafeQueue* outgoingPackets); -void handleStatusState(Packet* packet, Server& server, ThreadSafeQueue* outgoingPackets); -void handleLoginState(Packet* packet, Server& server, ThreadSafeQueue* outgoingPackets); + Server& server); +void handleStatusState(Packet* packet, Server& server); +void handleLoginState(Packet* packet, Server& server); void handleConfigurationState(Packet* packet, - Server& server, - ThreadSafeQueue* outgoingPackets); -void handlePlayState(Packet* packet, Server& server, ThreadSafeQueue* outgoingPackets); + Server& server); +void handlePlayState(Packet* packet, Server& server); void sendDisconnectPacket(Packet* packet, const std::string& reason, - ThreadSafeQueue* outgoingPackets); -void initGameSequence(Packet* packet, ThreadSafeQueue* _outgoingPackets, Server& server); + Server& server); +void initGameSequence(Packet* packet, Server& server); // ======================================== // Main Packet Router // ======================================== -void packetRouter(Packet* packet, Server& server, ThreadSafeQueue* _outgoingPackets) { +void packetRouter(Packet* packet, Server& server) { + if (packet == nullptr) return; - if (_outgoingPackets == nullptr) return; + if (server.getNetworkManager().getOutgoingQueue() == nullptr) return; Player* player = packet->getPlayer(); @@ -43,19 +42,19 @@ void packetRouter(Packet* packet, Server& server, ThreadSafeQueue* _out switch (player->getPlayerState()) { case PlayerState::Handshake: - handleHandshakeState(packet, server, _outgoingPackets); + handleHandshakeState(packet, server); break; case PlayerState::Status: - handleStatusState(packet, server, _outgoingPackets); + handleStatusState(packet, server); break; case PlayerState::Login: - handleLoginState(packet, server, _outgoingPackets); + handleLoginState(packet, server); break; case PlayerState::Configuration: - handleConfigurationState(packet, server, _outgoingPackets); + handleConfigurationState(packet, server); break; case PlayerState::Play: - handlePlayState(packet, server, _outgoingPackets); + handlePlayState(packet, server); break; default: g_logger->logNetwork(WARN, @@ -73,8 +72,7 @@ void packetRouter(Packet* packet, Server& server, ThreadSafeQueue* _out // ======================================== void handleHandshakeState(Packet* packet, - Server& server, - ThreadSafeQueue* outgoingPackets) { + Server& server) { handleHandshakePacket(*packet, server); } @@ -82,7 +80,7 @@ void handleHandshakeState(Packet* packet, // Status State Handler // ======================================== -void handleStatusState(Packet* packet, Server& server, ThreadSafeQueue* outgoingPackets) { +void handleStatusState(Packet* packet, Server& server) { if (packet->getId() == 0x00) { handleStatusPacket(*packet, server); } else if (packet->getId() == 0x01) { @@ -101,7 +99,7 @@ void handleStatusState(Packet* packet, Server& server, ThreadSafeQueue* // Login State Handler // ======================================== -void handleLoginState(Packet* packet, Server& server, ThreadSafeQueue* outgoingPackets) { +void handleLoginState(Packet* packet, Server& server) { // Add safety check for packet data integrity if (packet->getSize() > 32767) { // Max packet size g_logger->logNetwork(ERROR, @@ -144,8 +142,7 @@ void handleLoginState(Packet* packet, Server& server, ThreadSafeQueue* // ======================================== void handleConfigurationState(Packet* packet, - Server& server, - ThreadSafeQueue* outgoingPackets) { + Server& server) { if (packet->getId() == 0x00) { // Client Information (configuration) // g_logger->logNetwork(INFO, "Received Client Information in Configuration state", @@ -156,7 +153,7 @@ void handleConfigurationState(Packet* packet, // After processing client info, tell client we're done configuring Packet* finishPacket = new Packet(*packet); handleFinishConfiguration(*finishPacket, server); - outgoingPackets->push(finishPacket); + server.getNetworkManager().getOutgoingQueue()->push(finishPacket); // g_logger->logNetwork(INFO, "Sent Finish Configuration after Client Information", // "Configuration"); @@ -181,7 +178,7 @@ void handleConfigurationState(Packet* packet, "Received Acknowledge Finish Configuration - transitioning to Play state", "PacketRouter"); handleAcknowledgeFinishConfiguration(*packet, server); - initGameSequence(packet, outgoingPackets, server); + initGameSequence(packet, server); } else if (packet->getId() == 0x04) { // Keep Alive (configuration) @@ -217,7 +214,7 @@ void handleConfigurationState(Packet* packet, "Unknown packet ID in Configuration state: 0x" + std::to_string(packet->getId()), "PacketRouter"); - sendDisconnectPacket(packet, "Unknown packet in Configuration state", outgoingPackets); + sendDisconnectPacket(packet, "Unknown packet in Configuration state", server); packet->getPlayer()->setPlayerState(PlayerState::None); packet->setReturnPacket(PACKET_DISCONNECT); } @@ -227,7 +224,7 @@ void handleConfigurationState(Packet* packet, // Play State Handler // ======================================== -void handlePlayState(Packet* packet, Server& server, ThreadSafeQueue* outgoingPackets) { +void handlePlayState(Packet* packet, Server& server) { if (packet->getId() == 0x00) { // Confirm Teleportation handleConfirmTeleportation(*packet, server); @@ -248,7 +245,8 @@ void handlePlayState(Packet* packet, Server& server, ThreadSafeQueue* o void sendDisconnectPacket(Packet* packet, const std::string& reason, - ThreadSafeQueue* outgoingPackets) { + Server& server) { + ThreadSafeQueue* outgoingPackets = server.getNetworkManager().getOutgoingQueue(); if (!packet || !outgoingPackets) return; Player* player = packet->getPlayer(); @@ -290,8 +288,8 @@ void sendDisconnectPacket(Packet* packet, // Game Initialization Sequence // ======================================== -void initGameSequence(Packet* packet, ThreadSafeQueue* _outgoingPackets, Server& server) { - if (packet == nullptr || _outgoingPackets == nullptr) return; +void initGameSequence(Packet* packet, Server& server) { + if (packet == nullptr || server.getNetworkManager().getOutgoingQueue() == nullptr) return; Player* player = packet->getPlayer(); if (player == nullptr) return; @@ -304,29 +302,29 @@ void initGameSequence(Packet* packet, ThreadSafeQueue* _outgoingPackets // 1. Send Login (play) packet - 0x2B g_logger->logNetwork(INFO, "Sending Login (play) packet", "PacketRouter"); Packet* playPacket = new Packet(*packet); - writePlayPacket(*playPacket, server); - _outgoingPackets->push(playPacket); + writePlayPacket(*playPacket); + server.getNetworkManager().getOutgoingQueue()->push(playPacket); // 2. Send Set Center Chunk - 0x57 Packet* setCenterPacket = new Packet(*packet); writeSetCenterPacket(*setCenterPacket, server); - _outgoingPackets->push(setCenterPacket); + server.getNetworkManager().getOutgoingQueue()->push(setCenterPacket); // 3. Send complete chunk batch sequence (Start -> Chunks -> Finished) - sendChunkBatchSequence(*packet, server, _outgoingPackets); + sendChunkBatchSequence(*packet, server); // 4. Send player position and look - 0x41 Packet* positionPacket = new Packet(*packet); sendPlayerPositionAndLook(*positionPacket, server); - _outgoingPackets->push(positionPacket); + server.getNetworkManager().getOutgoingQueue()->push(positionPacket); // 5. Send spawn position - 0x5A Packet* spawnPacket = new Packet(*packet); sendSpawnPosition(*spawnPacket, server); - _outgoingPackets->push(spawnPacket); + server.getNetworkManager().getOutgoingQueue()->push(spawnPacket); // // 6. Complete spawn sequence (abilities, health, experience, time, held item) - completeSpawnSequence(*packet, server, _outgoingPackets); + completeSpawnSequence(*packet, server); g_logger->logNetwork(INFO, "Complete game sequence sent to player: ", "PacketRouter"); diff --git a/src/networking/packet/play.cpp b/src/networking/packet/play.cpp index 7680452..92c8979 100644 --- a/src/networking/packet/play.cpp +++ b/src/networking/packet/play.cpp @@ -1,15 +1,10 @@ -#include "network/networking.hpp" #include "network/packet.hpp" #include "player.hpp" -#include "network/server.hpp" #include "network/buffer.hpp" -#include #include -#include -#include "lib/nbt.hpp" -void writePlayPacket(Packet& packet, Server& server) { +void writePlayPacket(Packet& packet) { Player* player = packet.getPlayer(); if (!player) return; diff --git a/src/networking/packet/spawnSequence.cpp b/src/networking/packet/spawnSequence.cpp index 629f117..73eb337 100644 --- a/src/networking/packet/spawnSequence.cpp +++ b/src/networking/packet/spawnSequence.cpp @@ -175,8 +175,9 @@ void handleConfirmTeleportation(Packet& packet, Server& server) { (void)server; } -void completeSpawnSequence(Packet& packet, Server& server, ThreadSafeQueue* outgoingPackets) { +void completeSpawnSequence(Packet& packet, Server& server) { Player* player = packet.getPlayer(); + ThreadSafeQueue* outgoingPackets = server.getNetworkManager().getOutgoingQueue(); if (!player || !outgoingPackets) return; // std::cout << "=== Completing spawn sequence for player: " << player->getPlayerName() << " ===\n"; diff --git a/src/world/worldManager.cpp b/src/world/worldManager.cpp new file mode 100644 index 0000000..646e3f6 --- /dev/null +++ b/src/world/worldManager.cpp @@ -0,0 +1,40 @@ +#include "world/worldManager.hpp" + +#include +#include +#include +#include +#include + +std::vector WorldManager::decompressGzip(const std::vector& compressed) { + z_stream stream{}; + stream.avail_in = compressed.size(); + stream.next_in = reinterpret_cast(const_cast(compressed.data())); + stream.zalloc = Z_NULL; + stream.zfree = Z_NULL; + stream.opaque = Z_NULL; + + int ret = inflateInit2(&stream, 15 + 32); + if (ret != Z_OK) { + throw std::runtime_error("Failed to initialize zlib"); + } + + std::vector decompressed; + decompressed.resize(compressed.size() * 2); + + do { + stream.avail_out = decompressed.size(); + stream.next_out = reinterpret_cast(decompressed.data()); + + ret = inflate(&stream, Z_NO_FLUSH); + if (ret == Z_NEED_DICT || ret == Z_DATA_ERROR || ret == Z_MEM_ERROR) { + inflateEnd(&stream); + throw std::runtime_error("Failed to decompress data"); + } + + decompressed.resize(stream.total_out); + } while (ret == Z_OK); + + inflateEnd(&stream); + return decompressed; +} From 67df7a02528f0e443c971b6637f8fcc8ac99598b Mon Sep 17 00:00:00 2001 From: Antoine Mathie Date: Thu, 9 Oct 2025 21:17:45 +0200 Subject: [PATCH 07/27] feature: Reworking the config loader, added utils to get the executable file path --- .clang-format | 2 +- .github/workflows/format.yml | 18 ++++++++++++++++++ .github/workflows/verif-build.yml | 17 ----------------- include/config.hpp | 20 ++++++++++++++++++++ include/lib/filesystem.hpp | 5 ++++- src/lib/fs.cpp | 17 +++++++++++++++++ 6 files changed, 60 insertions(+), 19 deletions(-) create mode 100644 .github/workflows/format.yml delete mode 100644 .github/workflows/verif-build.yml create mode 100644 include/config.hpp create mode 100644 src/lib/fs.cpp diff --git a/.clang-format b/.clang-format index 4407457..7584438 100644 --- a/.clang-format +++ b/.clang-format @@ -2,7 +2,7 @@ BasedOnStyle: LLVM IndentWidth: 4 # logical indent level = 1 tab TabWidth: 4 # how wide a tab renders (adjust per team preference) -UseTab: ForIndentation # use tabs for indentation, spaces for alignment +UseTab: Always # use tabs for indentation, spaces for alignment ContinuationIndentWidth: 8 BreakBeforeBraces: Attach ColumnLimit: 100 diff --git a/.github/workflows/format.yml b/.github/workflows/format.yml new file mode 100644 index 0000000..35719cc --- /dev/null +++ b/.github/workflows/format.yml @@ -0,0 +1,18 @@ +name: clang-format + +on: + push: + pull_request: + +jobs: + clang-format: + runs-on: ubuntu-latest + + steps: + - uses: actions/checkout@v4 + + - name: Run clang-format + uses: jidicula/clang-format-action@v4.11.0 + with: + clang-format-version: "17" + check-path: "." diff --git a/.github/workflows/verif-build.yml b/.github/workflows/verif-build.yml deleted file mode 100644 index d21eb7c..0000000 --- a/.github/workflows/verif-build.yml +++ /dev/null @@ -1,17 +0,0 @@ -name: C/C++ CI - -on: - push: - branches: [ "main" ] - pull_request: - branches: [ "main" ] - -jobs: - build: - - runs-on: ubuntu-latest - - steps: - - uses: actions/checkout@v4 - - name: make - run: make diff --git a/include/config.hpp b/include/config.hpp new file mode 100644 index 0000000..f07aec3 --- /dev/null +++ b/include/config.hpp @@ -0,0 +1,20 @@ +#ifndef CONFIG_HPP +#define CONFIG_HPP + +#include + +class Config { + private: + std::string _gameVersion; + std::string _serverMotd; + std::string _serverAddress; + int _serverPort; + int _protocolVersion; + int _serverSize; + + public: + bool loadConfig(); + bool reloadConfig(); +}; + +#endif diff --git a/include/lib/filesystem.hpp b/include/lib/filesystem.hpp index 1435f63..d29646f 100644 --- a/include/lib/filesystem.hpp +++ b/include/lib/filesystem.hpp @@ -1,5 +1,8 @@ #ifndef FS_H # define FS_H +#include -#endif FS_H +std::filesystem::path getPath(); + +#endif diff --git a/src/lib/fs.cpp b/src/lib/fs.cpp new file mode 100644 index 0000000..08e7ca0 --- /dev/null +++ b/src/lib/fs.cpp @@ -0,0 +1,17 @@ +#include + +#include +#include +#include +#include +#include + +std::filesystem::path getPath() { + char buffer[PATH_MAX]; + ssize_t len = readlink("/proc/self/exe", buffer, sizeof(buffer) - 1); + if (len != -1) { + buffer[len] = '\0'; + return std::filesystem::path(buffer); + } + return {}; +} From 61452e8f02c4221ee3579a0ed88401b11f1536bb Mon Sep 17 00:00:00 2001 From: Antoine Mathie Date: Thu, 9 Oct 2025 21:18:37 +0200 Subject: [PATCH 08/27] fix: format action --- .github/workflows/format.yml | 1 - 1 file changed, 1 deletion(-) diff --git a/.github/workflows/format.yml b/.github/workflows/format.yml index 35719cc..9025181 100644 --- a/.github/workflows/format.yml +++ b/.github/workflows/format.yml @@ -2,7 +2,6 @@ name: clang-format on: push: - pull_request: jobs: clang-format: From d75c92a0c74b10e544fe6331917547371631254b Mon Sep 17 00:00:00 2001 From: Antoine Mathie Date: Thu, 9 Oct 2025 21:21:18 +0200 Subject: [PATCH 09/27] fix: formatting action --- .github/workflows/format.yml | 36 +++++++++++++++++++++++++++++++----- 1 file changed, 31 insertions(+), 5 deletions(-) diff --git a/.github/workflows/format.yml b/.github/workflows/format.yml index 9025181..166c638 100644 --- a/.github/workflows/format.yml +++ b/.github/workflows/format.yml @@ -2,16 +2,42 @@ name: clang-format on: push: + pull_request: jobs: clang-format: runs-on: ubuntu-latest + permissions: + contents: write steps: - - uses: actions/checkout@v4 + - name: Checkout code + uses: actions/checkout@v4 + with: + ref: ${{ github.head_ref || github.ref_name }} + token: ${{ secrets.GITHUB_TOKEN }} + + - name: Install clang-format + run: | + sudo apt-get update + sudo apt-get install -y clang-format - name: Run clang-format - uses: jidicula/clang-format-action@v4.11.0 - with: - clang-format-version: "17" - check-path: "." + run: | + find . -name '*.cpp' -o -name '*.h' -o -name '*.c' -o -name '*.hpp' -o -name '*.cc' -o -name '*.cxx' \ + | grep -v "include/lib/json.hpp" \ + | xargs clang-format -i --style=file + + - name: Commit and push changes + run: | + git config --local user.email "github-actions[bot]@users.noreply.github.com" + git config --local user.name "github-actions[bot]" + + if ! git diff --quiet; then + git add -A + git commit -m "Apply clang-format [skip ci]" + git push + echo "Code formatted and pushed" + else + echo "No formatting changes needed" + fi From 5a85a0cdbb4ecfe6eff61e1a456643f4b959766d Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" Date: Thu, 9 Oct 2025 19:23:37 +0000 Subject: [PATCH 10/27] Apply clang-format [skip ci] --- include/lib/filesystem.hpp | 2 +- include/lib/nbt.hpp | 76 ++--- include/logger.hpp | 9 +- include/network/buffer.hpp | 12 +- include/network/networking.hpp | 15 +- include/network/packet.hpp | 5 +- include/network/server.hpp | 26 +- include/player.hpp | 4 +- include/world/worldManager.hpp | 8 +- src/entities/player.cpp | 59 ++-- src/lib/MD5.cpp | 24 +- src/lib/UUID.cpp | 19 +- src/lib/buffer.cpp | 74 ++--- src/lib/fs.cpp | 19 +- src/lib/idManager.cpp | 4 +- src/lib/logger.cpp | 45 +-- src/lib/packet.cpp | 131 ++++---- src/networking/networkManager.cpp | 16 +- src/networking/networkQueuer.cpp | 42 ++- src/networking/networkWorker.cpp | 2 +- src/networking/packet/chunkBatch.cpp | 171 +++++----- src/networking/packet/chunkDataSimple.cpp | 274 ++++++++-------- src/networking/packet/cookieRequest.cpp | 157 +++++----- src/networking/packet/finishConfiguration.cpp | 72 +++-- .../packet/handleClientInformation.cpp | 8 +- src/networking/packet/handshake.cpp | 15 +- src/networking/packet/loginAcknowledged.cpp | 39 ++- src/networking/packet/loginStart.cpp | 21 +- src/networking/packet/packetRouter.cpp | 92 +++--- src/networking/packet/ping.cpp | 12 +- src/networking/packet/play.cpp | 108 +++---- src/networking/packet/setCenterChunck.cpp | 6 +- src/networking/packet/spawnSequence.cpp | 295 +++++++++--------- src/networking/packet/status.cpp | 22 +- src/server.cpp | 67 ++-- src/world/worldManager.cpp | 64 ++-- 36 files changed, 973 insertions(+), 1042 deletions(-) diff --git a/include/lib/filesystem.hpp b/include/lib/filesystem.hpp index d29646f..fd165e9 100644 --- a/include/lib/filesystem.hpp +++ b/include/lib/filesystem.hpp @@ -1,5 +1,5 @@ #ifndef FS_H -# define FS_H +#define FS_H #include diff --git a/include/lib/nbt.hpp b/include/lib/nbt.hpp index 4ba4a90..02560c5 100644 --- a/include/lib/nbt.hpp +++ b/include/lib/nbt.hpp @@ -14,45 +14,45 @@ Compatible with older C++ compilers #include #include #include +#include #include #include #include #include #include #include -#include // Compatibility implementations for GCC 10.5 #if __cpp_lib_byteswap < 202110L namespace std { - template - constexpr T byteswap(T value) noexcept { - static_assert(std::is_integral_v, "byteswap requires integral type"); - if constexpr (sizeof(T) == 1) { - return value; - } else if constexpr (sizeof(T) == 2) { - return __builtin_bswap16(value); - } else if constexpr (sizeof(T) == 4) { - return __builtin_bswap32(value); - } else if constexpr (sizeof(T) == 8) { - return __builtin_bswap64(value); - } - } -} + template constexpr T byteswap(T value) noexcept { + static_assert(std::is_integral_v, "byteswap requires integral type"); + if constexpr (sizeof(T) == 1) { + return value; + } else if constexpr (sizeof(T) == 2) { + return __builtin_bswap16(value); + } else if constexpr (sizeof(T) == 4) { + return __builtin_bswap32(value); + } else if constexpr (sizeof(T) == 8) { + return __builtin_bswap64(value); + } + } +} // namespace std #endif #if __cpp_lib_bit_cast < 201806L namespace std { - template - constexpr To bit_cast(const From& src) noexcept { - static_assert(sizeof(To) == sizeof(From), "bit_cast requires same size types"); - static_assert(std::is_trivially_copyable_v, "bit_cast requires trivially copyable To type"); - static_assert(std::is_trivially_copyable_v, "bit_cast requires trivially copyable From type"); - To dst; - std::memcpy(&dst, &src, sizeof(To)); - return dst; - } -} + template constexpr To bit_cast(const From& src) noexcept { + static_assert(sizeof(To) == sizeof(From), "bit_cast requires same size types"); + static_assert(std::is_trivially_copyable_v, + "bit_cast requires trivially copyable To type"); + static_assert(std::is_trivially_copyable_v, + "bit_cast requires trivially copyable From type"); + To dst; + std::memcpy(&dst, &src, sizeof(To)); + return dst; + } +} // namespace std #endif namespace nbt { @@ -78,19 +78,19 @@ namespace nbt { // Tag variant - using struct to avoid forward declaration issues struct Tag { std::variant, - std::shared_ptr, - TagIntArray, - TagLongArray> - data; + TagByte, + TagShort, + TagInt, + TagLong, + TagFloat, + TagDouble, + TagByteArray, + TagString, + std::shared_ptr, + std::shared_ptr, + TagIntArray, + TagLongArray> + data; // Constructors Tag() : data(TagEnd{}) {} diff --git a/include/logger.hpp b/include/logger.hpp index 9855387..f396fcd 100644 --- a/include/logger.hpp +++ b/include/logger.hpp @@ -1,6 +1,6 @@ #pragma once #ifndef LOGGER_HPP -# define LOGGER_HPP +#define LOGGER_HPP #include #include #include @@ -32,16 +32,15 @@ class LogManager { std::thread _writerThread; bool _running; - public: LogManager(); ~LogManager(); // Core logging methods void log(LogLevel level, - LogCategory category, - const std::string& message, - const std::string& source = ""); + LogCategory category, + const std::string& message, + const std::string& source = ""); void logNetwork(LogLevel level, const std::string& message, const std::string& source = ""); void logGameInfo(LogLevel level, const std::string& message, const std::string& source = ""); diff --git a/include/network/buffer.hpp b/include/network/buffer.hpp index fd44dd5..baa36a7 100644 --- a/include/network/buffer.hpp +++ b/include/network/buffer.hpp @@ -39,12 +39,12 @@ class Buffer { void writeUUID(const UUID& uuid); 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); + 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); }; #endif diff --git a/include/network/networking.hpp b/include/network/networking.hpp index 4a2288a..080b5e0 100644 --- a/include/network/networking.hpp +++ b/include/network/networking.hpp @@ -1,22 +1,22 @@ #ifndef NETWORKING_HPP #define NETWORKING_HPP +#include "../player.hpp" #include "lib/UUID.hpp" #include "packet.hpp" -#include "../player.hpp" // Forward declaration to avoid circular dependency class Server; #include #include #include +#include #include #include #include #include #include #include -#include template class ThreadSafeQueue { private: @@ -33,8 +33,7 @@ template class ThreadSafeQueue { bool tryPop(T& item) { std::lock_guard lock(_mutex); - if (_queue.empty()) - return false; + if (_queue.empty()) return false; item = std::move(_queue.front()); _queue.pop(); @@ -83,7 +82,7 @@ class NetworkManager { public: NetworkManager(size_t worker_count, - Server& s); // Could use std::thread::hardware_concurrency() for the worker size; + Server& s); // Could use std::thread::hardware_concurrency() for the worker size; ~NetworkManager() { if (_epollFd != -1) { close(_epollFd); @@ -99,9 +98,7 @@ class NetworkManager { void removePlayerConnection(UUID id); ThreadSafeQueue* getOutgoingQueue() { return &_outgoingPackets; } - Server& getServer() { - return _server; - } + Server& getServer() { return _server; } void enqueueOutgoingPacket(Packet* p); @@ -119,7 +116,7 @@ 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 handleClientInformation(Packet& packet, Server& server); void handleLoginStartPacket(Packet& packet, Server& server); void handleLoginAcknowledged(Packet& packet, Server& server); void handleCookieRequest(Packet& packet, Server& server); diff --git a/include/network/packet.hpp b/include/network/packet.hpp index 0ff47af..3817702 100644 --- a/include/network/packet.hpp +++ b/include/network/packet.hpp @@ -1,11 +1,12 @@ #ifndef PACKET_HPP #define PACKET_HPP -#include "buffer.hpp" #include "../player.hpp" +#include "buffer.hpp" #include "server.hpp" -#include + #include +#include enum PacketResult { PACKET_OK = 0, PACKET_SEND = 1, PACKET_DISCONNECT = 2, PACKET_ERROR = -1 }; diff --git a/include/network/server.hpp b/include/network/server.hpp index 1a048de..9413e9f 100644 --- a/include/network/server.hpp +++ b/include/network/server.hpp @@ -2,9 +2,9 @@ #define SERVER_HPP class NetworkManager; +#include "../player.hpp" #include "id_manager.hpp" #include "lib/json.hpp" -#include "../player.hpp" #include #include @@ -42,18 +42,10 @@ class Server { int getAmountOnline(); std::string getGameVersion(); std::string getServerMOTD(); - int getServerPort() { - return _serverPort; - } - std::string getServerAddr() { - return _serverAddr; - } - std::unordered_map& getPlayerLst() { - return _playerLst; - } - std::unordered_map& getTempPlayerLst() { - return _tempPlayerLst; - } + int getServerPort() { return _serverPort; } + std::string getServerAddr() { return _serverAddr; } + std::unordered_map& getPlayerLst() { return _playerLst; } + std::unordered_map& getTempPlayerLst() { return _tempPlayerLst; } void addPlayerToSample(const std::string& name); void removePlayerToSample(const std::string& name); @@ -64,13 +56,9 @@ class Server { void promoteTempPlayer(Player* player); void removePlayerFromAnyList(Player* player); json getPlayerSample(); - IdManager& getIdManager() { - return (_idManager); - } + IdManager& getIdManager() { return (_idManager); } - NetworkManager& getNetworkManager() { - return *_networkManager; - } + NetworkManager& getNetworkManager() { return *_networkManager; } }; #endif diff --git a/include/player.hpp b/include/player.hpp index 7c21855..55f0a62 100644 --- a/include/player.hpp +++ b/include/player.hpp @@ -3,11 +3,11 @@ #include "lib/UUID.hpp" -#include #include +#include class Server; -enum class PlayerState { None, Configuration ,Handshake, Status, Login, Play }; +enum class PlayerState { None, Configuration, Handshake, Status, Login, Play }; class PlayerConfig { private: diff --git a/include/world/worldManager.hpp b/include/world/worldManager.hpp index 2f96bfc..9ae1b5a 100644 --- a/include/world/worldManager.hpp +++ b/include/world/worldManager.hpp @@ -1,16 +1,14 @@ #ifndef WORLD_MANAGER_HPP -# define WORLD_MANAGER_HPP +#define WORLD_MANAGER_HPP -#include #include +#include #include class WorldManager { private: - public: - std::vector decompressGzip(const std::vector& compressed); + std::vector decompressGzip(const std::vector& compressed); }; - #endif diff --git a/src/entities/player.cpp b/src/entities/player.cpp index d6b2de0..6bed5ee 100644 --- a/src/entities/player.cpp +++ b/src/entities/player.cpp @@ -1,16 +1,18 @@ -#include "lib/UUID.hpp" #include "player.hpp" + +#include "lib/UUID.hpp" #include "network/server.hpp" #include Player::Player(Server& server) - : _name("Player_entity"), _state(PlayerState::None), _socketFd(-1), x(0), y(0), z(0), health(0), - _uuid(), _playerId(server.getIdManager().allocate()), _server(server), _config(new PlayerConfig()) {} + : _name("Player_entity"), _state(PlayerState::None), _socketFd(-1), x(0), y(0), z(0), health(0), + _uuid(), _playerId(server.getIdManager().allocate()), _server(server), + _config(new PlayerConfig()) {} Player::Player(const std::string& name, const PlayerState state, const int socket, Server& server) - : _state(state), _socketFd(socket), x(0), y(0), z(0), health(20), _uuid(), - _playerId(server.getIdManager().allocate()), _server(server), _config(new PlayerConfig()) { + : _state(state), _socketFd(socket), x(0), y(0), z(0), health(20), _uuid(), + _playerId(server.getIdManager().allocate()), _server(server), _config(new PlayerConfig()) { if (name.length() > 32) _name = name.substr(0, 31); else @@ -19,12 +21,12 @@ Player::Player(const std::string& name, const PlayerState state, const int socke Player& Player::operator=(const Player& src) { if (this != &src) { - this->_name = src._name; + this->_name = src._name; this->_socketFd = src._socketFd; - this->health = src.health; - this->x = src.x; - this->y = src.y; - this->z = src.z; + this->health = src.health; + this->x = src.x; + this->y = src.y; + this->z = src.z; } return (*this); } @@ -34,37 +36,20 @@ Player::~Player() { delete _config; } -std::string Player::getPlayerName(void) { - return (this->_name); -}; -void Player::setPlayerName(const std::string& name) { - this->_name = name; -} -PlayerState Player::getPlayerState() { - return (this->_state); -} -void Player::setPlayerState(PlayerState state) { - this->_state = state; -} -void Player::setSocketFd(int socket) { - this->_socketFd = socket; -} -int Player::getSocketFd() const { - return (this->_socketFd); -} +std::string Player::getPlayerName(void) { return (this->_name); }; +void Player::setPlayerName(const std::string& name) { this->_name = name; } +PlayerState Player::getPlayerState() { return (this->_state); } +void Player::setPlayerState(PlayerState state) { this->_state = state; } +void Player::setSocketFd(int socket) { this->_socketFd = socket; } +int Player::getSocketFd() const { return (this->_socketFd); } -void Player::setUUID(UUID uuid) { - _uuid = uuid; -} +void Player::setUUID(UUID uuid) { _uuid = uuid; } -int Player::getPlayerID() const { - return (_playerId); -} +int Player::getPlayerID() const { return (_playerId); } // PlayerConfig implementation PlayerConfig::PlayerConfig() - : _chatMode(0), _mainHand(1), _locale("en_US"), _viewDistance(10), - _displayedSkinParts(0), _chatColors(true), _enableTextFiltering(false), - _allowServerListings(true) {} + : _chatMode(0), _mainHand(1), _locale("en_US"), _viewDistance(10), _displayedSkinParts(0), + _chatColors(true), _enableTextFiltering(false), _allowServerListings(true) {} PlayerConfig::~PlayerConfig() {} diff --git a/src/lib/MD5.cpp b/src/lib/MD5.cpp index b2145fc..22cdbf1 100644 --- a/src/lib/MD5.cpp +++ b/src/lib/MD5.cpp @@ -12,22 +12,12 @@ namespace { constexpr uint32_t initC = 0x98badcfe; constexpr uint32_t initD = 0x10325476; - inline uint32_t F(uint32_t x, uint32_t y, uint32_t z) { - return (x & y) | (~x & z); - } - inline uint32_t G(uint32_t x, uint32_t y, uint32_t z) { - return (x & z) | (y & ~z); - } - inline uint32_t H(uint32_t x, uint32_t y, uint32_t z) { - return x ^ y ^ z; - } - inline uint32_t I(uint32_t x, uint32_t y, uint32_t z) { - return y ^ (x | ~z); - } + inline uint32_t F(uint32_t x, uint32_t y, uint32_t z) { return (x & y) | (~x & z); } + inline uint32_t G(uint32_t x, uint32_t y, uint32_t z) { return (x & z) | (y & ~z); } + inline uint32_t H(uint32_t x, uint32_t y, uint32_t z) { return x ^ y ^ z; } + inline uint32_t I(uint32_t x, uint32_t y, uint32_t z) { return y ^ (x | ~z); } - inline uint32_t rotate_left(uint32_t x, int n) { - return (x << n) | (x >> (32 - n)); - } + inline uint32_t rotate_left(uint32_t x, int n) { return (x << n) | (x >> (32 - n)); } } // namespace // petite implémentation brute de MD5 @@ -56,7 +46,7 @@ std::vector MD5::hash(const std::string& input) { uint32_t M[16]; for (int i = 0; i < 16; ++i) { M[i] = (data[offset + i * 4]) | (data[offset + i * 4 + 1] << 8) | - (data[offset + i * 4 + 2] << 16) | (data[offset + i * 4 + 3] << 24); + (data[offset + i * 4 + 2] << 16) | (data[offset + i * 4 + 3] << 24); } uint32_t a = A, b = B, c = C, d = D; @@ -76,7 +66,7 @@ std::vector MD5::hash(const std::string& input) { std::vector digest(16); uint32_t state[4] = {A, B, C, D}; for (int i = 0; i < 4; i++) { - digest[i * 4] = state[i] & 0xFF; + digest[i * 4] = state[i] & 0xFF; digest[i * 4 + 1] = (state[i] >> 8) & 0xFF; digest[i * 4 + 2] = (state[i] >> 16) & 0xFF; digest[i * 4 + 3] = (state[i] >> 24) & 0xFF; diff --git a/src/lib/UUID.cpp b/src/lib/UUID.cpp index f84a441..5c6732e 100644 --- a/src/lib/UUID.cpp +++ b/src/lib/UUID.cpp @@ -1,5 +1,6 @@ -#include "lib/MD5.hpp" #include "lib/UUID.hpp" + +#include "lib/MD5.hpp" #include "network/buffer.hpp" #include @@ -13,18 +14,10 @@ UUID::UUID() : _mostSigBits(0), _leastSigBits(0) {} UUID::UUID(uint64_t most, uint64_t least) : _mostSigBits(most), _leastSigBits(least) {} UUID::~UUID() {} -uint64_t UUID::getMostSigBits() const { - return _mostSigBits; -} -uint64_t UUID::getLeastSigBits() const { - return _leastSigBits; -} -void UUID::setMostSigBits(uint64_t val) { - _mostSigBits = val; -} -void UUID::setLeastSigBits(uint64_t val) { - _leastSigBits = val; -} +uint64_t UUID::getMostSigBits() const { return _mostSigBits; } +uint64_t UUID::getLeastSigBits() const { return _leastSigBits; } +void UUID::setMostSigBits(uint64_t val) { _mostSigBits = val; } +void UUID::setLeastSigBits(uint64_t val) { _leastSigBits = val; } std::string UUID::toString() const { std::stringstream ss; diff --git a/src/lib/buffer.cpp b/src/lib/buffer.cpp index 3a46fad..0453bc1 100644 --- a/src/lib/buffer.cpp +++ b/src/lib/buffer.cpp @@ -1,6 +1,7 @@ -#include "lib/UUID.hpp" #include "network/buffer.hpp" +#include "lib/UUID.hpp" + #include #include #include @@ -10,14 +11,11 @@ Buffer::Buffer() : _pos(0) {} Buffer::Buffer(const std::vector& data) : _data(data), _pos(0) {} uint8_t Buffer::readByte() { - if (_pos >= _data.size()) - throw std::runtime_error("Buffer underflow on byte"); + if (_pos >= _data.size()) throw std::runtime_error("Buffer underflow on byte"); return _data[_pos++]; } -void Buffer::writeByte(uint8_t byte) { - _data.push_back(byte); -} +void Buffer::writeByte(uint8_t byte) { _data.push_back(byte); } void Buffer::writeBytes(const std::string& data) { _data.insert(_data.end(), data.begin(), data.end()); @@ -44,8 +42,7 @@ int Buffer::readVarInt() { currentByte = readByte(); value |= (currentByte & 0x7F) << position; position += 7; - if (position >= 32) - throw std::runtime_error("VarInt too big"); + if (position >= 32) throw std::runtime_error("VarInt too big"); } while (currentByte & 0x80); return value; @@ -105,13 +102,9 @@ void Buffer::writeString(const std::string& str) { _data.insert(_data.end(), str.begin(), str.end()); } -std::vector& Buffer::getData() { - return _data; -} +std::vector& Buffer::getData() { return _data; } -size_t Buffer::remaining() const { - return _data.size() - _pos; -} +size_t Buffer::remaining() const { return _data.size() - _pos; } uint16_t Buffer::readUShort() { uint16_t val = (readByte() << 8) | readByte(); @@ -140,43 +133,44 @@ void Buffer::writeLong(long value) { } } -void Buffer::writeBool(bool value) { - writeByte(value ? 0x01 : 0x00); -} +void Buffer::writeBool(bool value) { writeByte(value ? 0x01 : 0x00); } -void Buffer::writeNBT(const std::string& nbtData) { - writeBytes(nbtData); -} +void Buffer::writeNBT(const std::string& nbtData) { writeBytes(nbtData); } void Buffer::writePosition(int32_t x, int32_t y, int32_t z) { - int64_t packed = ((int64_t)(x & 0x3FFFFFF) << 38) | ((int64_t)(y & 0xFFF) << 26) | (int64_t)(z & 0x3FFFFFF); - writeLong(packed); + int64_t packed = ((int64_t)(x & 0x3FFFFFF) << 38) | ((int64_t)(y & 0xFFF) << 26) | + (int64_t)(z & 0x3FFFFFF); + writeLong(packed); } void Buffer::writeFloat(float value) { - union { float f; uint32_t i; } u; - u.f = value; - writeUInt(u.i); + union { + float f; + uint32_t i; + } u; + u.f = value; + writeUInt(u.i); } void Buffer::writeDouble(double value) { - union { double d; uint64_t i; } u; - u.d = value; - writeLong(u.i); + union { + double d; + uint64_t i; + } u; + u.d = value; + writeLong(u.i); } void Buffer::writeVarLong(int64_t value) { - while (true) { - if ((value & ~0x7FL) == 0) { - writeByte((uint8_t)value); - return; - } else { - writeByte((uint8_t)((value & 0x7F) | 0x80)); - value >>= 7; - } - } + while (true) { + if ((value & ~0x7FL) == 0) { + writeByte((uint8_t)value); + return; + } else { + writeByte((uint8_t)((value & 0x7F) | 0x80)); + value >>= 7; + } + } } -void Buffer::writeIdentifier(const std::string& id) { - writeString(id); -} +void Buffer::writeIdentifier(const std::string& id) { writeString(id); } diff --git a/src/lib/fs.cpp b/src/lib/fs.cpp index 08e7ca0..64c3133 100644 --- a/src/lib/fs.cpp +++ b/src/lib/fs.cpp @@ -1,17 +1,16 @@ -#include - #include +#include #include #include -#include #include +#include std::filesystem::path getPath() { - char buffer[PATH_MAX]; - ssize_t len = readlink("/proc/self/exe", buffer, sizeof(buffer) - 1); - if (len != -1) { - buffer[len] = '\0'; - return std::filesystem::path(buffer); - } - return {}; + char buffer[PATH_MAX]; + ssize_t len = readlink("/proc/self/exe", buffer, sizeof(buffer) - 1); + if (len != -1) { + buffer[len] = '\0'; + return std::filesystem::path(buffer); + } + return {}; } diff --git a/src/lib/idManager.cpp b/src/lib/idManager.cpp index b264dcc..dd5633e 100644 --- a/src/lib/idManager.cpp +++ b/src/lib/idManager.cpp @@ -26,7 +26,7 @@ void IdManager::release(uint32_t id) { std::lock_guard lock(_mutex); if (id >= _nextId) { std::cerr << "[IdManager] WARNING: Trying to release invalid ID " << id - << " (nextId: " << _nextId << ")" << std::endl; + << " (nextId: " << _nextId << ")" << std::endl; return; } if (_freedIds.find(id) != _freedIds.end()) { @@ -36,7 +36,7 @@ void IdManager::release(uint32_t id) { _freedIds.insert(id); std::cout << "[IdManager] Released ID: " << id << " (freed count: " << _freedIds.size() << ")" - << std::endl; + << std::endl; } size_t IdManager::getAllocatedCount() const { diff --git a/src/lib/logger.cpp b/src/lib/logger.cpp index b4fd564..a52e47a 100644 --- a/src/lib/logger.cpp +++ b/src/lib/logger.cpp @@ -1,23 +1,23 @@ #include "logger.hpp" #include +#include #include #include #include #include +#include +#include #include +#include #include #include -#include -#include -#include -#include namespace fs = std::filesystem; LogManager::LogManager() : _running(false) { if (initializeLogDirectory()) { - _running = true; + _running = true; _writerThread = std::thread(&LogManager::writerThreadLoop, this); // Logger initialized - using console for initialization message std::cout << "Logger initialized successfully in directory: " << _logDir << std::endl; @@ -43,7 +43,7 @@ LogManager::~LogManager() { } std::string LogManager::getCurrentTimestamp() { - auto now = std::chrono::system_clock::now(); + auto now = std::chrono::system_clock::now(); auto time_t = std::chrono::system_clock::to_time_t(now); std::stringstream ss; @@ -52,7 +52,7 @@ std::string LogManager::getCurrentTimestamp() { } std::string LogManager::getDetailedTimestamp() { - auto now = std::chrono::system_clock::now(); + auto now = std::chrono::system_clock::now(); auto time_t = std::chrono::system_clock::to_time_t(now); auto ms = std::chrono::duration_cast(now.time_since_epoch()) % 1000; @@ -110,15 +110,15 @@ bool LogManager::initializeLogDirectory() { } void LogManager::log(LogLevel level, - LogCategory category, - const std::string& message, - const std::string& source) { + LogCategory category, + const std::string& message, + const std::string& source) { LogEntry entry; entry.timestamp = std::chrono::system_clock::now(); - entry.level = level; - entry.category = category; - entry.message = message; - entry.source = source; + entry.level = level; + entry.category = category; + entry.message = message; + entry.source = source; // Add to queue for file writing { @@ -126,9 +126,10 @@ void LogManager::log(LogLevel level, _logQueue.push(entry); } - if (category == GAMEINFO || category == NETWORK) { // Remove category == NETWORK on release build - std::string formattedEntry = formatLogEntry(entry); - std::cout << formattedEntry << std::endl; + if (category == GAMEINFO || + category == NETWORK) { // Remove category == NETWORK on release build + std::string formattedEntry = formatLogEntry(entry); + std::cout << formattedEntry << std::endl; } } @@ -137,8 +138,8 @@ void LogManager::logNetwork(LogLevel level, const std::string& message, const st } void LogManager::logGameInfo(LogLevel level, - const std::string& message, - const std::string& source) { + const std::string& message, + const std::string& source) { log(level, GAMEINFO, message, source); } @@ -181,9 +182,9 @@ std::string LogManager::formatLogEntry(const LogEntry& entry) { // Add timestamp auto time_t = std::chrono::system_clock::to_time_t(entry.timestamp); - auto ms = std::chrono::duration_cast( - entry.timestamp.time_since_epoch()) % - 1000; + auto ms = std::chrono::duration_cast( + entry.timestamp.time_since_epoch()) % + 1000; ss << "[" << std::put_time(std::localtime(&time_t), "%H:%M:%S"); ss << "." << std::setfill('0') << std::setw(3) << ms.count() << "] "; diff --git a/src/lib/packet.cpp b/src/lib/packet.cpp index c2df746..8f2e38e 100644 --- a/src/lib/packet.cpp +++ b/src/lib/packet.cpp @@ -1,9 +1,10 @@ -#include "network/buffer.hpp" -#include "lib/json.hpp" #include "network/packet.hpp" -#include "player.hpp" -#include "network/server.hpp" + +#include "lib/json.hpp" #include "logger.hpp" +#include "network/buffer.hpp" +#include "network/server.hpp" +#include "player.hpp" #include #include @@ -21,18 +22,18 @@ using json = nlohmann::json; Packet::~Packet() {} Packet::Packet(const Packet& other) - : _size(other._size), _id(other._id), _data(other._data), _player(other._player), - _socketFd(other._socketFd), _returnPacket(other._returnPacket) { + : _size(other._size), _id(other._id), _data(other._data), _player(other._player), + _socketFd(other._socketFd), _returnPacket(other._returnPacket) { std::cout << "[Packet] Copy constructor called" << std::endl; } Packet& Packet::operator=(const Packet& other) { if (this != &other) { - _size = other._size; - _id = other._id; - _data = other._data; - _player = other._player; - _socketFd = other._socketFd; + _size = other._size; + _id = other._id; + _data = other._data; + _player = other._player; + _socketFd = other._socketFd; _returnPacket = other._returnPacket; std::cout << "[Packet] Assignment operator called" << std::endl; } @@ -40,27 +41,25 @@ Packet& Packet::operator=(const Packet& other) { } Packet::Packet(Player* player) : _player(player), _socketFd(-1), _returnPacket(0) { - if (_player == nullptr) - throw std::runtime_error("Packet init with null player"); + if (_player == nullptr) throw std::runtime_error("Packet init with null player"); _socketFd = _player->getSocketFd(); - // g_logger->logNetwork(INFO, "Constructor: Socket FD = " + std::to_string(_socketFd), "Packet"); + // g_logger->logNetwork(INFO, "Constructor: Socket FD = " + std::to_string(_socketFd), + // "Packet"); _size = readVarint(_socketFd); - if (_size == -1) - throw std::runtime_error("Failed to read packet size"); + if (_size == -1) throw std::runtime_error("Failed to read packet size"); // g_logger->logNetwork(INFO, "Read size: " + std::to_string(_size), "Packet"); int idBytesRead = 0; - _id = readVarint(_socketFd, &idBytesRead); - if (_id == -1) - throw std::runtime_error("Failed to read packet id"); + _id = readVarint(_socketFd, &idBytesRead); + if (_id == -1) throw std::runtime_error("Failed to read packet id"); // g_logger->logNetwork(INFO, "Read ID: " + std::to_string(_id), "Packet"); int remaining = _size - idBytesRead; - // g_logger->logNetwork(INFO, "Calculated remaining: " + std::to_string(remaining) + " (size=" + std::to_string(_size) + " - idBytes=" + std::to_string(idBytesRead) + ")", "Packet"); + // g_logger->logNetwork(INFO, "Calculated remaining: " + std::to_string(remaining) + " (size=" + + // std::to_string(_size) + " - idBytes=" + std::to_string(idBytesRead) + ")", "Packet"); - if (remaining < 0) - throw std::runtime_error("Invalid packet size"); + if (remaining < 0) throw std::runtime_error("Invalid packet size"); if (remaining > 0) { std::vector tmp(remaining); ssize_t totalRead = 0; @@ -83,25 +82,24 @@ Packet::Packet(Player* player) : _player(player), _socketFd(-1), _returnPacket(0 } Packet::Packet(int socketFd, Server& server) - : _player(nullptr), _socketFd(socketFd), _returnPacket(0) { - // g_logger->logNetwork(INFO, "Constructor (socket): Socket FD = " + std::to_string(_socketFd), "Packet"); + : _player(nullptr), _socketFd(socketFd), _returnPacket(0) { + // g_logger->logNetwork(INFO, "Constructor (socket): Socket FD = " + std::to_string(_socketFd), + // "Packet"); _size = readVarint(_socketFd); - if (_size == -1) - throw std::runtime_error("Failed to read packet size"); + if (_size == -1) throw std::runtime_error("Failed to read packet size"); // g_logger->logNetwork(INFO, "Read size: " + std::to_string(_size), "Packet"); int idBytesRead = 0; - _id = readVarint(_socketFd, &idBytesRead); - if (_id == -1) - throw std::runtime_error("Failed to read packet id"); + _id = readVarint(_socketFd, &idBytesRead); + if (_id == -1) throw std::runtime_error("Failed to read packet id"); // g_logger->logNetwork(INFO, "Read ID: " + std::to_string(_id), "Packet"); int remaining = _size - idBytesRead; - // g_logger->logNetwork(INFO, "Calculated remaining: " + std::to_string(remaining) + " (size=" + std::to_string(_size) + " - idBytes=" + std::to_string(idBytesRead) + ")", "Packet"); + // g_logger->logNetwork(INFO, "Calculated remaining: " + std::to_string(remaining) + " (size=" + + // std::to_string(_size) + " - idBytes=" + std::to_string(idBytesRead) + ")", "Packet"); - if (remaining < 0) - throw std::runtime_error("Invalid packet size"); + if (remaining < 0) throw std::runtime_error("Invalid packet size"); try { _player = server.addTempPlayer("None", PlayerState::Handshake, socketFd); @@ -134,16 +132,17 @@ Packet::Packet(int socketFd, Server& server) int Packet::getVarintSize(int32_t value) { if (value < 0) { std::cerr << "[Packet] ERROR: getVarintSize called with negative value: " << value - << std::endl; + << std::endl; throw std::runtime_error("getVarintSize called with negative value"); } - int size = 0; + int size = 0; int original_value = value; do { value >>= 7; size++; } while (value != 0); - // g_logger->logNetwork(INFO, "getVarintSize(" + std::to_string(original_value) + ") = " + std::to_string(size), "Packet"); + // g_logger->logNetwork(INFO, "getVarintSize(" + std::to_string(original_value) + ") = " + + // std::to_string(size), "Packet"); return size; } @@ -159,28 +158,27 @@ int Packet::readVarint(int sock, int* bytesRead) { while (true) { ssize_t result = ::read(sock, &byte, 1); if (result <= 0) { - std::cerr << "readVarint: Failed to read byte " << localBytesRead << " from socket " << sock - << " (errno: " << errno << ")" << std::endl; + std::cerr << "readVarint: Failed to read byte " << localBytesRead << " from socket " + << sock << " (errno: " << errno << ")" << std::endl; return -1; } localBytesRead++; value |= (byte & 0x7F) << position; - if (!(byte & 0x80)) - break; // Last byte of varint + if (!(byte & 0x80)) break; // Last byte of varint position += 7; if (position >= 32) { - std::cerr << "readVarint: Varint too long (> 32 bits) after " << localBytesRead << " bytes" - << std::endl; + std::cerr << "readVarint: Varint too long (> 32 bits) after " << localBytesRead + << " bytes" << std::endl; return -1; } // Safety check to prevent infinite loops if (localBytesRead > 5) { - std::cerr << "readVarint: Too many bytes read (" << localBytesRead << "), corrupted varint" - << std::endl; + std::cerr << "readVarint: Too many bytes read (" << localBytesRead + << "), corrupted varint" << std::endl; return -1; } } @@ -189,13 +187,12 @@ int Packet::readVarint(int sock, int* bytesRead) { *bytesRead = localBytesRead; } - // g_logger->logNetwork(INFO, "readVarint: Successfully read " + std::to_string(value) + " (" + std::to_string(localBytesRead) + " bytes)", "Packet"); + // g_logger->logNetwork(INFO, "readVarint: Successfully read " + std::to_string(value) + " (" + + // std::to_string(localBytesRead) + " bytes)", "Packet"); return value; } -int Packet::readVarint(int sock) { - return readVarint(sock, nullptr); -} +int Packet::readVarint(int sock) { return readVarint(sock, nullptr); } void Packet::writeVarint(int sock, int value) { std::vector tmp; @@ -211,7 +208,7 @@ bool Packet::isSocketValid(int sock) { } struct pollfd pfd; - pfd.fd = sock; + pfd.fd = sock; pfd.events = POLLIN; int result = poll(&pfd, 1, 0); @@ -222,19 +219,15 @@ bool Packet::isSocketValid(int sock) { if (pfd.revents & (POLLHUP | POLLERR)) { std::cerr << "Socket validation: Socket " << sock << " is disconnected or has error" - << std::endl; + << std::endl; return false; } return true; } -void Packet::setReturnPacket(int value) { - this->_returnPacket = value; -} -int Packet::getReturnPacket() { - return (this->_returnPacket); -} +void Packet::setReturnPacket(int value) { this->_returnPacket = value; } +int Packet::getReturnPacket() { return (this->_returnPacket); } int Packet::varintLen(int value) { int len = 0; @@ -245,24 +238,10 @@ int Packet::varintLen(int value) { return (len); } -Player* Packet::getPlayer() const { - return (_player); -} -uint32_t Packet::getSize() { - return (_size); -} -uint32_t Packet::getId() { - return (_id); -} -Buffer& Packet::getData() { - return (_data); -} -int Packet::getSocket() const { - return (_socketFd); -}; -void Packet::setPacketSize(int32_t value) { - _size = value; -} -void Packet::setPacketId(uint32_t value) { - _id = value; -} +Player* Packet::getPlayer() const { return (_player); } +uint32_t Packet::getSize() { return (_size); } +uint32_t Packet::getId() { return (_id); } +Buffer& Packet::getData() { return (_data); } +int Packet::getSocket() const { return (_socketFd); }; +void Packet::setPacketSize(int32_t value) { _size = value; } +void Packet::setPacketId(uint32_t value) { _id = value; } diff --git a/src/networking/networkManager.cpp b/src/networking/networkManager.cpp index 45c66c5..fe87237 100644 --- a/src/networking/networkManager.cpp +++ b/src/networking/networkManager.cpp @@ -13,9 +13,9 @@ #include NetworkManager::NetworkManager(size_t workerCount, Server& s) - : _incomingPackets(), _outgoingPackets(), _workerThreads(), _shutdownFlag(false), - _receiverThread(), _senderThread(), _receiverThreadInit(0), _senderThreadInit(0), _server(s), - _epollFd(-1), _serverSocket(-1) { + : _incomingPackets(), _outgoingPackets(), _workerThreads(), _shutdownFlag(false), + _receiverThread(), _senderThread(), _receiverThreadInit(0), _senderThreadInit(0), _server(s), + _epollFd(-1), _serverSocket(-1) { _workerThreads.reserve(workerCount); setupEpoll(); @@ -34,12 +34,12 @@ void NetworkManager::startThreads() { _shutdownFlag = false; if (!_receiverThreadInit) { - _receiverThread = std::thread(&NetworkManager::receiverThreadLoop, this); + _receiverThread = std::thread(&NetworkManager::receiverThreadLoop, this); _receiverThreadInit = 1; } if (!_senderThreadInit) { - _senderThread = std::thread(&NetworkManager::senderThreadLoop, this); + _senderThread = std::thread(&NetworkManager::senderThreadLoop, this); _senderThreadInit = 1; } size_t workerCount = _workerThreads.capacity(); @@ -96,7 +96,7 @@ void NetworkManager::start() { struct sockaddr_in serverAddr; serverAddr.sin_family = AF_INET; - serverAddr.sin_port = htons(getServer().getServerPort()); + serverAddr.sin_port = htons(getServer().getServerPort()); if (strcmp(getServer().getServerAddr().c_str(), "0.0.0.0") == 0) { serverAddr.sin_addr.s_addr = INADDR_ANY; @@ -110,8 +110,8 @@ void NetworkManager::start() { if (bind(_serverSocket, (struct sockaddr*)&serverAddr, sizeof(serverAddr)) < 0) { close(_serverSocket); throw std::runtime_error("Failed to bind socket to " + - std::string(getServer().getServerAddr()) + ":" + - std::to_string(getServer().getServerPort())); + std::string(getServer().getServerAddr()) + ":" + + std::to_string(getServer().getServerPort())); } if (listen(_serverSocket, SOMAXCONN) < 0) { diff --git a/src/networking/networkQueuer.cpp b/src/networking/networkQueuer.cpp index f83afd7..8674d7b 100644 --- a/src/networking/networkQueuer.cpp +++ b/src/networking/networkQueuer.cpp @@ -1,8 +1,8 @@ +#include "logger.hpp" #include "network/networking.hpp" #include "network/packet.hpp" -#include "player.hpp" #include "network/server.hpp" -#include "logger.hpp" +#include "player.hpp" #include #include @@ -10,10 +10,10 @@ #include #include #include +#include #include #include #include -#include void NetworkManager::receiverThreadLoop() { const int MaxEvent = 256; @@ -23,46 +23,44 @@ void NetworkManager::receiverThreadLoop() { int eventCount = epoll_wait(_epollFd, events, MaxEvent, 50); if (eventCount == -1) { - if (errno == EINTR) - continue; + if (errno == EINTR) continue; break; } for (int i = 0; i < eventCount; i++) { - int fd = events[i].data.fd; + int fd = events[i].data.fd; uint32_t eventFlags = events[i].events; if (fd == _serverSocket) { sockaddr_in client_addr{}; socklen_t addr_len = sizeof(client_addr); - int client_fd = accept(_serverSocket, (sockaddr*)&client_addr, &addr_len); + int client_fd = accept(_serverSocket, (sockaddr*)&client_addr, &addr_len); if (client_fd != -1) { - // g_logger->logNetwork(INFO, "New connection accepted on socket " + std::to_string(client_fd), "Network Manager"); + // g_logger->logNetwork(INFO, "New connection accepted on socket " + + // std::to_string(client_fd), "Network Manager"); epoll_event event; event.events = EPOLLIN; event.data.fd = client_fd; if (epoll_ctl(_epollFd, EPOLL_CTL_ADD, client_fd, &event) == -1) { std::cerr << "[Network Manager] Failed to add new client socket to epoll" - << std::endl; + << std::endl; close(client_fd); } } continue; } - auto it = getServer().getPlayerLst().find(fd); + auto it = getServer().getPlayerLst().find(fd); Player* p = nullptr; if (it != getServer().getPlayerLst().end()) { p = it->second; } else { auto temp_it = getServer().getTempPlayerLst().find(fd); - if (temp_it != getServer().getTempPlayerLst().end()) - p = temp_it->second; + if (temp_it != getServer().getTempPlayerLst().end()) p = temp_it->second; } if (eventFlags & EPOLLERR || eventFlags & EPOLLHUP) { - if (p) - getServer().removePlayerFromAnyList(p); + if (p) getServer().removePlayerFromAnyList(p); epoll_ctl(_epollFd, EPOLL_CTL_DEL, fd, nullptr); close(fd); continue; @@ -75,8 +73,7 @@ void NetworkManager::receiverThreadLoop() { else handleIncomingData(fd); } catch (const std::exception& e) { - if (p) - getServer().removePlayerFromAnyList(p); + if (p) getServer().removePlayerFromAnyList(p); epoll_ctl(_epollFd, EPOLL_CTL_DEL, fd, nullptr); close(fd); } @@ -90,14 +87,14 @@ void NetworkManager::senderThreadLoop() { Packet* p = nullptr; while (_outgoingPackets.tryPop(p)) { - if (p == nullptr) - break; + if (p == nullptr) break; try { // g_logger->logNetwork(INFO, "Sending packet to player", "Network Manager"); send(p->getSocket(), p->getData().getData().data(), p->getSize(), MSG_NOSIGNAL); if (p->getPlayer() && p->getPlayer()->getPlayerState() == PlayerState::None) { - // g_logger->logNetwork(INFO, "Closing status connection after response", "Network Manager"); + // g_logger->logNetwork(INFO, "Closing status connection after response", + // "Network Manager"); getServer().removePlayerFromAnyList(p->getPlayer()); epoll_ctl(_epollFd, EPOLL_CTL_DEL, p->getSocket(), nullptr); close(p->getSocket()); @@ -113,9 +110,7 @@ void NetworkManager::senderThreadLoop() { } } -void NetworkManager::enqueueOutgoingPacket(Packet* p) { - _outgoingPackets.push(p); -} +void NetworkManager::enqueueOutgoingPacket(Packet* p) { _outgoingPackets.push(p); } void NetworkManager::handleIncomingData(Player* connection) { Packet* p; @@ -131,7 +126,8 @@ void NetworkManager::handleIncomingData(Player* connection) { void NetworkManager::handleIncomingData(int socket) { Packet* p; - // g_logger->logNetwork(INFO, "Handling incoming data for socket " + std::to_string(socket), "Network Manager"); + // g_logger->logNetwork(INFO, "Handling incoming data for socket " + std::to_string(socket), + // "Network Manager"); try { p = new Packet(socket, getServer()); _incomingPackets.push(p); diff --git a/src/networking/networkWorker.cpp b/src/networking/networkWorker.cpp index ebd0018..4909e72 100644 --- a/src/networking/networkWorker.cpp +++ b/src/networking/networkWorker.cpp @@ -1,8 +1,8 @@ #include "logger.hpp" #include "network/networking.hpp" #include "network/packet.hpp" -#include "player.hpp" #include "network/server.hpp" +#include "player.hpp" #include #include diff --git a/src/networking/packet/chunkBatch.cpp b/src/networking/packet/chunkBatch.cpp index 4204bb1..4a2be77 100644 --- a/src/networking/packet/chunkBatch.cpp +++ b/src/networking/packet/chunkBatch.cpp @@ -2,110 +2,111 @@ #include "network/buffer.hpp" #include "network/networking.hpp" #include "network/packet.hpp" -#include "player.hpp" #include "network/server.hpp" +#include "player.hpp" #include void sendChunkBatchStart(Packet& packet, Server& server) { - std::cout << "=== Sending Chunk Batch Start ===\n"; + std::cout << "=== Sending Chunk Batch Start ===\n"; - // Chunk Batch Start has no fields - just the packet ID - Buffer buf; - // No data to write for this packet + // Chunk Batch Start has no fields - just the packet ID + Buffer buf; + // No data to write for this packet - int packetId = 0x0C; // Chunk Batch Start packet ID for protocol 770 - int packetIdSize = packet.getVarintSize(packetId); - int totalPayloadSize = packetIdSize + buf.getData().size(); + int packetId = 0x0C; // Chunk Batch Start packet ID for protocol 770 + int packetIdSize = packet.getVarintSize(packetId); + int totalPayloadSize = packetIdSize + buf.getData().size(); - Buffer finalBuf; - finalBuf.writeVarInt(totalPayloadSize); - finalBuf.writeVarInt(packetId); - if (!buf.getData().empty()) { - finalBuf.writeBytes(buf.getData()); - } + Buffer finalBuf; + finalBuf.writeVarInt(totalPayloadSize); + finalBuf.writeVarInt(packetId); + if (!buf.getData().empty()) { + finalBuf.writeBytes(buf.getData()); + } - packet.getData() = finalBuf; - packet.setPacketSize(finalBuf.getData().size()); - packet.setReturnPacket(PACKET_SEND); + packet.getData() = finalBuf; + packet.setPacketSize(finalBuf.getData().size()); + packet.setReturnPacket(PACKET_SEND); - (void)server; + (void)server; } void sendChunkBatchFinished(Packet& packet, Server& server, int batchSize) { - std::cout << "=== Sending Chunk Batch Finished (batch size: " << batchSize << ") ===\n"; + std::cout << "=== Sending Chunk Batch Finished (batch size: " << batchSize << ") ===\n"; - Buffer buf; - buf.writeVarInt(batchSize); // Number of chunks in the batch + Buffer buf; + buf.writeVarInt(batchSize); // Number of chunks in the batch - int packetId = 0x0B; // Chunk Batch Finished packet ID for protocol 770 - int packetIdSize = packet.getVarintSize(packetId); - int totalPayloadSize = packetIdSize + buf.getData().size(); + int packetId = 0x0B; // Chunk Batch Finished packet ID for protocol 770 + int packetIdSize = packet.getVarintSize(packetId); + int totalPayloadSize = packetIdSize + buf.getData().size(); - Buffer finalBuf; - finalBuf.writeVarInt(totalPayloadSize); - finalBuf.writeVarInt(packetId); - finalBuf.writeBytes(buf.getData()); + Buffer finalBuf; + finalBuf.writeVarInt(totalPayloadSize); + finalBuf.writeVarInt(packetId); + finalBuf.writeBytes(buf.getData()); - packet.getData() = finalBuf; - packet.setPacketSize(finalBuf.getData().size()); - packet.setReturnPacket(PACKET_SEND); + packet.getData() = finalBuf; + packet.setPacketSize(finalBuf.getData().size()); + packet.setReturnPacket(PACKET_SEND); - (void)server; + (void)server; } void sendChunkBatchSequence(Packet& packet, Server& server) { - Player* player = packet.getPlayer(); - ThreadSafeQueue* outgoingPackets = server.getNetworkManager().getOutgoingQueue(); - if (!player || !outgoingPackets) return; - - // Player spawn position (you should get this from player data) - int playerChunkX = 0; // player->getChunkX(); - int playerChunkZ = 0; // player->getChunkZ(); - - // Get view distance from player config - int viewDistance = 5; // Default - if (player->getPlayerConfig()) { - viewDistance = player->getPlayerConfig()->getViewDistance(); - } - - std::cout << "=== Starting chunk batch sequence for player: " << player->getPlayerName() - << " (view distance: " << viewDistance << ") ===\n"; - - // 1. Send Chunk Batch Start - try { - Packet* batchStartPacket = new Packet(packet); - sendChunkBatchStart(*batchStartPacket, server); - outgoingPackets->push(batchStartPacket); - } catch (const std::exception& e) { - std::cerr << "Error sending chunk batch start: " << e.what() << std::endl; - return; - } - - // 2. Send chunks in a radius around player - int chunksCount = 0; - for (int x = playerChunkX - viewDistance; x <= playerChunkX + viewDistance; x++) { - for (int z = playerChunkZ - viewDistance; z <= playerChunkZ + viewDistance; z++) { - try { - Packet* chunkPacket = new Packet(packet); - sendChunkData(*chunkPacket, server, x, z); - outgoingPackets->push(chunkPacket); - chunksCount++; - } catch (const std::exception& e) { - std::cerr << "Error sending chunk (" << x << ", " << z << "): " << e.what() << std::endl; - } - } - } - - // 3. Send Chunk Batch Finished - try { - Packet* batchFinishedPacket = new Packet(packet); - sendChunkBatchFinished(*batchFinishedPacket, server, chunksCount); - outgoingPackets->push(batchFinishedPacket); - } catch (const std::exception& e) { - std::cerr << "Error sending chunk batch finished: " << e.what() << std::endl; - return; - } - - std::cout << "=== Chunk batch sequence completed: " << chunksCount << " chunks sent ===\n"; + Player* player = packet.getPlayer(); + ThreadSafeQueue* outgoingPackets = server.getNetworkManager().getOutgoingQueue(); + if (!player || !outgoingPackets) return; + + // Player spawn position (you should get this from player data) + int playerChunkX = 0; // player->getChunkX(); + int playerChunkZ = 0; // player->getChunkZ(); + + // Get view distance from player config + int viewDistance = 5; // Default + if (player->getPlayerConfig()) { + viewDistance = player->getPlayerConfig()->getViewDistance(); + } + + std::cout << "=== Starting chunk batch sequence for player: " << player->getPlayerName() + << " (view distance: " << viewDistance << ") ===\n"; + + // 1. Send Chunk Batch Start + try { + Packet* batchStartPacket = new Packet(packet); + sendChunkBatchStart(*batchStartPacket, server); + outgoingPackets->push(batchStartPacket); + } catch (const std::exception& e) { + std::cerr << "Error sending chunk batch start: " << e.what() << std::endl; + return; + } + + // 2. Send chunks in a radius around player + int chunksCount = 0; + for (int x = playerChunkX - viewDistance; x <= playerChunkX + viewDistance; x++) { + for (int z = playerChunkZ - viewDistance; z <= playerChunkZ + viewDistance; z++) { + try { + Packet* chunkPacket = new Packet(packet); + sendChunkData(*chunkPacket, server, x, z); + outgoingPackets->push(chunkPacket); + chunksCount++; + } catch (const std::exception& e) { + std::cerr << "Error sending chunk (" << x << ", " << z << "): " << e.what() + << std::endl; + } + } + } + + // 3. Send Chunk Batch Finished + try { + Packet* batchFinishedPacket = new Packet(packet); + sendChunkBatchFinished(*batchFinishedPacket, server, chunksCount); + outgoingPackets->push(batchFinishedPacket); + } catch (const std::exception& e) { + std::cerr << "Error sending chunk batch finished: " << e.what() << std::endl; + return; + } + + std::cout << "=== Chunk batch sequence completed: " << chunksCount << " chunks sent ===\n"; } diff --git a/src/networking/packet/chunkDataSimple.cpp b/src/networking/packet/chunkDataSimple.cpp index 1ae0ab9..b7874ff 100644 --- a/src/networking/packet/chunkDataSimple.cpp +++ b/src/networking/packet/chunkDataSimple.cpp @@ -2,170 +2,170 @@ #include "network/buffer.hpp" #include "network/networking.hpp" #include "network/packet.hpp" -#include "player.hpp" #include "network/server.hpp" +#include "player.hpp" #include void sendChunkData(Packet& packet, Server& server, int chunkX, int chunkZ) { - std::cout << "=== Sending Chunk Data (" << chunkX << ", " << chunkZ << ") ===\n"; - - Buffer buf; - - // Chunk X and Z coordinates - buf.writeInt(chunkX); - buf.writeInt(chunkZ); - - // Heightmaps (NBT) - minimal implementation using empty compound tag - buf.writeByte(0x0A); - buf.writeByte(0x00); - buf.writeByte(0x00); - buf.writeByte(0x00); - - // Chunk data array - simplified version - Buffer chunkData; - - // Number of sections (24 sections for world height -64 to 319) - const int NUM_SECTIONS = 24; - - for (int section = 0; section < NUM_SECTIONS; section++) { - // Block count (non-air blocks in this section) - write as 2 bytes for short - buf.writeByte(0x00); - buf.writeByte(0x00); - - // Block states palette - chunkData.writeByte(0); - chunkData.writeVarInt(0); - chunkData.writeVarInt(0); - - // Biomes palette - chunkData.writeByte(0); - chunkData.writeVarInt(1); - chunkData.writeVarInt(0); - } - - // Write chunk data size and data - buf.writeVarInt(chunkData.getData().size()); - buf.writeBytes(chunkData.getData()); - - // Number of block entities - buf.writeVarInt(0); - - // Light data - simplified version - // Sky Light Mask (BitSet) - all sections have sky light - buf.writeVarInt(1); - buf.writeLong(0x1FFFFFF); - - // Block Light Mask (BitSet) - no block light - buf.writeVarInt(1); - buf.writeLong(0); - - // Empty Sky Light Mask - buf.writeVarInt(1); - buf.writeLong(0); - - // Empty Block Light Mask - buf.writeVarInt(1); - buf.writeLong(0); - - // Sky Light arrays (2048 bytes each for sections with sky light) - for (int i = 0; i < 25; i++) { - buf.writeVarInt(2048); - for (int j = 0; j < 2048; j++) { - buf.writeByte(0xFF); - } - } - - // No Block Light arrays since mask is 0 - - // Create final packet - int packetId = 0x27; - int packetIdSize = packet.getVarintSize(packetId); - int totalPayloadSize = packetIdSize + buf.getData().size(); - - Buffer finalBuf; - finalBuf.writeVarInt(totalPayloadSize); - finalBuf.writeVarInt(packetId); - finalBuf.writeBytes(buf.getData()); - - packet.getData() = finalBuf; - packet.setPacketSize(finalBuf.getData().size()); - packet.setReturnPacket(PACKET_SEND); - - (void)server; + std::cout << "=== Sending Chunk Data (" << chunkX << ", " << chunkZ << ") ===\n"; + + Buffer buf; + + // Chunk X and Z coordinates + buf.writeInt(chunkX); + buf.writeInt(chunkZ); + + // Heightmaps (NBT) - minimal implementation using empty compound tag + buf.writeByte(0x0A); + buf.writeByte(0x00); + buf.writeByte(0x00); + buf.writeByte(0x00); + + // Chunk data array - simplified version + Buffer chunkData; + + // Number of sections (24 sections for world height -64 to 319) + const int NUM_SECTIONS = 24; + + for (int section = 0; section < NUM_SECTIONS; section++) { + // Block count (non-air blocks in this section) - write as 2 bytes for short + buf.writeByte(0x00); + buf.writeByte(0x00); + + // Block states palette + chunkData.writeByte(0); + chunkData.writeVarInt(0); + chunkData.writeVarInt(0); + + // Biomes palette + chunkData.writeByte(0); + chunkData.writeVarInt(1); + chunkData.writeVarInt(0); + } + + // Write chunk data size and data + buf.writeVarInt(chunkData.getData().size()); + buf.writeBytes(chunkData.getData()); + + // Number of block entities + buf.writeVarInt(0); + + // Light data - simplified version + // Sky Light Mask (BitSet) - all sections have sky light + buf.writeVarInt(1); + buf.writeLong(0x1FFFFFF); + + // Block Light Mask (BitSet) - no block light + buf.writeVarInt(1); + buf.writeLong(0); + + // Empty Sky Light Mask + buf.writeVarInt(1); + buf.writeLong(0); + + // Empty Block Light Mask + buf.writeVarInt(1); + buf.writeLong(0); + + // Sky Light arrays (2048 bytes each for sections with sky light) + for (int i = 0; i < 25; i++) { + buf.writeVarInt(2048); + for (int j = 0; j < 2048; j++) { + buf.writeByte(0xFF); + } + } + + // No Block Light arrays since mask is 0 + + // Create final packet + int packetId = 0x27; + int packetIdSize = packet.getVarintSize(packetId); + int totalPayloadSize = packetIdSize + buf.getData().size(); + + Buffer finalBuf; + finalBuf.writeVarInt(totalPayloadSize); + finalBuf.writeVarInt(packetId); + finalBuf.writeBytes(buf.getData()); + + packet.getData() = finalBuf; + packet.setPacketSize(finalBuf.getData().size()); + packet.setReturnPacket(PACKET_SEND); + + (void)server; } void sendPlayerPositionAndLook(Packet& packet, Server& server) { - std::cout << "=== Sending Player Position and Look ===\n"; + std::cout << "=== Sending Player Position and Look ===\n"; - Buffer buf; + Buffer buf; - // Teleport ID - buf.writeVarInt(1); + // Teleport ID + buf.writeVarInt(1); - // Player position (using writeLong for double precision storage) - // Note: This is a simplified approach - ideally you'd add writeDouble to Buffer - int64_t x_bits = 0x3FE0000000000000; - int64_t y_bits = 0x4050000000000000; - int64_t z_bits = 0x3FE0000000000000; + // Player position (using writeLong for double precision storage) + // Note: This is a simplified approach - ideally you'd add writeDouble to Buffer + int64_t x_bits = 0x3FE0000000000000; + int64_t y_bits = 0x4050000000000000; + int64_t z_bits = 0x3FE0000000000000; - buf.writeLong(x_bits); - buf.writeLong(y_bits); - buf.writeLong(z_bits); + buf.writeLong(x_bits); + buf.writeLong(y_bits); + buf.writeLong(z_bits); - // Velocity (all zero) - buf.writeLong(0); - buf.writeLong(0); - buf.writeLong(0); + // Velocity (all zero) + buf.writeLong(0); + buf.writeLong(0); + buf.writeLong(0); - // Rotation (using writeInt for float storage) - buf.writeInt(0); - buf.writeInt(0); + // Rotation (using writeInt for float storage) + buf.writeInt(0); + buf.writeInt(0); - // Flags (0x00 = absolute positioning) - buf.writeInt(0x00); + // Flags (0x00 = absolute positioning) + buf.writeInt(0x00); - int packetId = 0x41; - int packetIdSize = packet.getVarintSize(packetId); - int totalPayloadSize = packetIdSize + buf.getData().size(); + int packetId = 0x41; + int packetIdSize = packet.getVarintSize(packetId); + int totalPayloadSize = packetIdSize + buf.getData().size(); - Buffer finalBuf; - finalBuf.writeVarInt(totalPayloadSize); - finalBuf.writeVarInt(packetId); - finalBuf.writeBytes(buf.getData()); + Buffer finalBuf; + finalBuf.writeVarInt(totalPayloadSize); + finalBuf.writeVarInt(packetId); + finalBuf.writeBytes(buf.getData()); - packet.getData() = finalBuf; - packet.setPacketSize(finalBuf.getData().size()); - packet.setReturnPacket(PACKET_SEND); + packet.getData() = finalBuf; + packet.setPacketSize(finalBuf.getData().size()); + packet.setReturnPacket(PACKET_SEND); - (void)server; + (void)server; } void sendSpawnPosition(Packet& packet, Server& server) { - std::cout << "=== Sending Spawn Position ===\n"; + std::cout << "=== Sending Spawn Position ===\n"; - Buffer buf; + Buffer buf; - // Encode position as long (X=0, Y=64, Z=0 packed into 64 bits) - // Position format: ((x & 0x3FFFFFF) << 38) | ((z & 0x3FFFFFF) << 12) | (y & 0xFFF) - int64_t encodedPos = ((int64_t)0 << 38) | ((int64_t)0 << 12) | (64 & 0xFFF); - buf.writeLong(encodedPos); + // Encode position as long (X=0, Y=64, Z=0 packed into 64 bits) + // Position format: ((x & 0x3FFFFFF) << 38) | ((z & 0x3FFFFFF) << 12) | (y & 0xFFF) + int64_t encodedPos = ((int64_t)0 << 38) | ((int64_t)0 << 12) | (64 & 0xFFF); + buf.writeLong(encodedPos); - // Spawn angle (0.0f as int bits) - buf.writeInt(0); + // Spawn angle (0.0f as int bits) + buf.writeInt(0); - int packetId = 0x5A; // Set Default Spawn Position packet ID for protocol 770 - int packetIdSize = packet.getVarintSize(packetId); - int totalPayloadSize = packetIdSize + buf.getData().size(); + int packetId = 0x5A; // Set Default Spawn Position packet ID for protocol 770 + int packetIdSize = packet.getVarintSize(packetId); + int totalPayloadSize = packetIdSize + buf.getData().size(); - Buffer finalBuf; - finalBuf.writeVarInt(totalPayloadSize); - finalBuf.writeVarInt(packetId); - finalBuf.writeBytes(buf.getData()); + Buffer finalBuf; + finalBuf.writeVarInt(totalPayloadSize); + finalBuf.writeVarInt(packetId); + finalBuf.writeBytes(buf.getData()); - packet.getData() = finalBuf; - packet.setPacketSize(finalBuf.getData().size()); - packet.setReturnPacket(PACKET_SEND); + packet.getData() = finalBuf; + packet.setPacketSize(finalBuf.getData().size()); + packet.setReturnPacket(PACKET_SEND); - (void)server; + (void)server; } diff --git a/src/networking/packet/cookieRequest.cpp b/src/networking/packet/cookieRequest.cpp index 630c14e..4d3b78e 100644 --- a/src/networking/packet/cookieRequest.cpp +++ b/src/networking/packet/cookieRequest.cpp @@ -1,84 +1,93 @@ +#include "logger.hpp" +#include "network/buffer.hpp" #include "network/networking.hpp" #include "network/packet.hpp" -#include "player.hpp" #include "network/server.hpp" -#include "logger.hpp" -#include "network/buffer.hpp" +#include "player.hpp" + #include void handleCookieRequest(Packet& packet, Server& server) { - // g_logger->logNetwork(INFO, "Received Cookie Request in Configuration state", "Configuration"); - - Player* player = packet.getPlayer(); - if (!player) { - // g_logger->logNetwork(ERROR, "Error: No player associated with Cookie Request packet", "Configuration"); - packet.setReturnPacket(PACKET_DISCONNECT); - return; - } - - // Debug: Log raw packet data - // g_logger->logNetwork(INFO, "Cookie Request packet size: " + std::to_string(packet.getSize()) + " bytes", "Configuration"); - - // Read the cookie identifier from the request - std::string cookieIdentifier; - try { - // Create a fresh buffer from the packet data to read from beginning - Buffer cookieBuffer(packet.getData().getData()); - cookieIdentifier = cookieBuffer.readString(32767); // Max string length - // g_logger->logNetwork(INFO, "Cookie Request for identifier: '" + cookieIdentifier + "'", "Configuration"); - } catch (const std::exception& e) { - // g_logger->logNetwork(ERROR, "Failed to read cookie identifier: " + std::string(e.what()), "Configuration"); - // Send empty response instead of disconnecting - cookieIdentifier = "unknown"; - } - - // Create Cookie Response packet (0x01) - Buffer payload; - payload.writeVarInt(0x01); // Cookie Response packet ID - payload.writeString(cookieIdentifier); // Echo back the identifier - - // For now, send empty cookie data (no stored cookie) - payload.writeByte(0x00); // Has payload: false (no cookie data) - - Buffer final; - final.writeVarInt(payload.getData().size()); - final.writeBytes(payload.getData()); - - packet.getData() = final; - packet.setReturnPacket(PACKET_SEND); - packet.setPacketSize(final.getData().size()); - - // g_logger->logNetwork(INFO, "Sent Cookie Response for identifier: '" + cookieIdentifier + "' (no data), response size: " + std::to_string(final.getData().size()), "Configuration"); - - // g_logger->logNetwork(INFO, "Cookie Response sent - now sending Finish Configuration to advance sequence", "Configuration"); - - (void)server; // Suppress unused parameter warning + // g_logger->logNetwork(INFO, "Received Cookie Request in Configuration state", + // "Configuration"); + + Player* player = packet.getPlayer(); + if (!player) { + // g_logger->logNetwork(ERROR, "Error: No player associated with Cookie Request packet", + // "Configuration"); + packet.setReturnPacket(PACKET_DISCONNECT); + return; + } + + // Debug: Log raw packet data + // g_logger->logNetwork(INFO, "Cookie Request packet size: " + std::to_string(packet.getSize()) + // + " bytes", "Configuration"); + + // Read the cookie identifier from the request + std::string cookieIdentifier; + try { + // Create a fresh buffer from the packet data to read from beginning + Buffer cookieBuffer(packet.getData().getData()); + cookieIdentifier = cookieBuffer.readString(32767); // Max string length + // g_logger->logNetwork(INFO, "Cookie Request for identifier: '" + cookieIdentifier + "'", + // "Configuration"); + } catch (const std::exception& e) { + // g_logger->logNetwork(ERROR, "Failed to read cookie identifier: " + std::string(e.what()), + // "Configuration"); Send empty response instead of disconnecting + cookieIdentifier = "unknown"; + } + + // Create Cookie Response packet (0x01) + Buffer payload; + payload.writeVarInt(0x01); // Cookie Response packet ID + payload.writeString(cookieIdentifier); // Echo back the identifier + + // For now, send empty cookie data (no stored cookie) + payload.writeByte(0x00); // Has payload: false (no cookie data) + + Buffer final; + final.writeVarInt(payload.getData().size()); + final.writeBytes(payload.getData()); + + packet.getData() = final; + packet.setReturnPacket(PACKET_SEND); + packet.setPacketSize(final.getData().size()); + + // g_logger->logNetwork(INFO, "Sent Cookie Response for identifier: '" + cookieIdentifier + "' + // (no data), response size: " + std::to_string(final.getData().size()), "Configuration"); + + // g_logger->logNetwork(INFO, "Cookie Response sent - now sending Finish Configuration to + // advance sequence", "Configuration"); + + (void)server; // Suppress unused parameter warning } void sendFinishConfigurationAfterCookie(Packet& packet, Server& server) { - // g_logger->logNetwork(INFO, "Sending Finish Configuration to advance sequence", "Configuration"); - - Player* player = packet.getPlayer(); - if (!player) { - // g_logger->logNetwork(ERROR, "Error: No player for Finish Configuration", "Configuration"); - return; - } - - // Create Finish Configuration packet (0x03) - Buffer payload; - payload.writeVarInt(0x03); // Finish Configuration packet ID - - Buffer final; - final.writeVarInt(payload.getData().size()); - final.writeBytes(payload.getData()); - - // Create a new packet for Finish Configuration - Packet* finishPacket = new Packet(packet); - finishPacket->getData() = final; - finishPacket->setReturnPacket(PACKET_SEND); - finishPacket->setPacketSize(final.getData().size()); - - // g_logger->logNetwork(INFO, "Finish Configuration packet prepared", "Configuration"); - - (void)server; + // g_logger->logNetwork(INFO, "Sending Finish Configuration to advance sequence", + // "Configuration"); + + Player* player = packet.getPlayer(); + if (!player) { + // g_logger->logNetwork(ERROR, "Error: No player for Finish Configuration", + // "Configuration"); + return; + } + + // Create Finish Configuration packet (0x03) + Buffer payload; + payload.writeVarInt(0x03); // Finish Configuration packet ID + + Buffer final; + final.writeVarInt(payload.getData().size()); + final.writeBytes(payload.getData()); + + // Create a new packet for Finish Configuration + Packet* finishPacket = new Packet(packet); + finishPacket->getData() = final; + finishPacket->setReturnPacket(PACKET_SEND); + finishPacket->setPacketSize(final.getData().size()); + + // g_logger->logNetwork(INFO, "Finish Configuration packet prepared", "Configuration"); + + (void)server; } diff --git a/src/networking/packet/finishConfiguration.cpp b/src/networking/packet/finishConfiguration.cpp index e181658..6bc95b6 100644 --- a/src/networking/packet/finishConfiguration.cpp +++ b/src/networking/packet/finishConfiguration.cpp @@ -1,56 +1,60 @@ +#include "logger.hpp" #include "network/networking.hpp" #include "network/packet.hpp" -#include "player.hpp" #include "network/server.hpp" -#include "logger.hpp" +#include "player.hpp" + #include void handleFinishConfiguration(Packet& packet, Server& server) { - // g_logger->logNetwork(INFO, "Starting configuration finish sequence", "Configuration"); + // g_logger->logNetwork(INFO, "Starting configuration finish sequence", "Configuration"); - Player* player = packet.getPlayer(); - if (!player) { - // g_logger->logNetwork(ERROR, "Error: No player associated with packet", "Configuration"); - packet.setReturnPacket(PACKET_DISCONNECT); - return; - } + Player* player = packet.getPlayer(); + if (!player) { + // g_logger->logNetwork(ERROR, "Error: No player associated with packet", "Configuration"); + packet.setReturnPacket(PACKET_DISCONNECT); + return; + } - // g_logger->logNetwork(INFO, "Sending Finish Configuration packet to " + player->getPlayerName(), "Configuration"); + // g_logger->logNetwork(INFO, "Sending Finish Configuration packet to " + + // player->getPlayerName(), "Configuration"); - // Send Finish Configuration packet (0x03) - Buffer payload; - payload.writeVarInt(0x03); // Finish Configuration packet ID + // Send Finish Configuration packet (0x03) + Buffer payload; + payload.writeVarInt(0x03); // Finish Configuration packet ID - Buffer final; - final.writeVarInt(payload.getData().size()); - final.writeBytes(payload.getData()); + Buffer final; + final.writeVarInt(payload.getData().size()); + final.writeBytes(payload.getData()); - packet.getData() = final; - packet.setReturnPacket(PACKET_SEND); - packet.setPacketSize(final.getData().size()); + packet.getData() = final; + packet.setReturnPacket(PACKET_SEND); + packet.setPacketSize(final.getData().size()); - // g_logger->logNetwork(INFO, "Finish Configuration packet sent, waiting for client acknowledgment", "Configuration"); + // g_logger->logNetwork(INFO, "Finish Configuration packet sent, waiting for client + // acknowledgment", "Configuration"); - (void)server; // Suppress unused parameter warning + (void)server; // Suppress unused parameter warning } void handleAcknowledgeFinishConfiguration(Packet& packet, Server& server) { - // g_logger->logNetwork(INFO, "Received Acknowledge Finish Configuration", "Configuration"); + // g_logger->logNetwork(INFO, "Received Acknowledge Finish Configuration", "Configuration"); - Player* player = packet.getPlayer(); - if (!player) { - // g_logger->logNetwork(ERROR, "Error: No player associated with packet", "Configuration"); - packet.setReturnPacket(PACKET_DISCONNECT); - return; - } + Player* player = packet.getPlayer(); + if (!player) { + // g_logger->logNetwork(ERROR, "Error: No player associated with packet", "Configuration"); + packet.setReturnPacket(PACKET_DISCONNECT); + return; + } - // Client has acknowledged finish configuration, now transition to Play state - player->setPlayerState(PlayerState::Play); + // Client has acknowledged finish configuration, now transition to Play state + player->setPlayerState(PlayerState::Play); - // g_logger->logNetwork(INFO, "Player " + player->getPlayerName() + " transitioned to Play state - ready for game packets", "Configuration"); + // g_logger->logNetwork(INFO, "Player " + player->getPlayerName() + " transitioned to Play state + // - ready for game packets", "Configuration"); - // Just acknowledge the packet - the actual game sequence will be triggered separately - packet.setReturnPacket(PACKET_OK); + // Just acknowledge the packet - the actual game sequence will be triggered separately + packet.setReturnPacket(PACKET_OK); - (void)server; // Suppress unused parameter warning + (void)server; // Suppress unused parameter warning } diff --git a/src/networking/packet/handleClientInformation.cpp b/src/networking/packet/handleClientInformation.cpp index 4c94fa3..d00036a 100644 --- a/src/networking/packet/handleClientInformation.cpp +++ b/src/networking/packet/handleClientInformation.cpp @@ -31,11 +31,11 @@ void handleClientInformation(Packet& packet, Server& server) { // g_logger->logGameInfo( // INFO, "Main Hand: " + std::to_string(config->getMainHand()), "ClientInfo"); // g_logger->logGameInfo(INFO, - // "Enabled Text Filtering: " + std::to_string(config->getTextFiltering()), - // "ClientInfo"); + // "Enabled Text Filtering: " + + // std::to_string(config->getTextFiltering()), "ClientInfo"); // g_logger->logGameInfo(INFO, - // "Allow Server Listings: " + std::to_string(config->getServerListings()), - // "ClientInfo"); + // "Allow Server Listings: " + + // std::to_string(config->getServerListings()), "ClientInfo"); packet.setReturnPacket(PACKET_OK); (void)server; } diff --git a/src/networking/packet/handshake.cpp b/src/networking/packet/handshake.cpp index 8ba6d85..bff9ca5 100644 --- a/src/networking/packet/handshake.cpp +++ b/src/networking/packet/handshake.cpp @@ -1,7 +1,7 @@ +#include "logger.hpp" #include "network/packet.hpp" -#include "player.hpp" #include "network/server.hpp" -#include "logger.hpp" +#include "player.hpp" #include #include @@ -13,14 +13,15 @@ void handleHandshakePacket(Packet& packet, Server& server) { packet.setReturnPacket(PACKET_DISCONNECT); return; } - int protocolVersion = packet.getData().readVarInt(); + int protocolVersion = packet.getData().readVarInt(); std::string serverAddr = packet.getData().readString(255); - uint16_t port = packet.getData().readUShort(); - int nextState = packet.getData().readVarInt(); - //g_logger->logNetwork(INFO, "Protocol=" + std::to_string(protocolVersion) + ", Addr=" + serverAddr + ", State=" + std::to_string(nextState), "Handshake"); + uint16_t port = packet.getData().readUShort(); + int nextState = packet.getData().readVarInt(); + // g_logger->logNetwork(INFO, "Protocol=" + std::to_string(protocolVersion) + ", Addr=" + + // serverAddr + ", State=" + std::to_string(nextState), "Handshake"); if (nextState == 1) { packet.getPlayer()->setPlayerState(PlayerState::Status); - //g_logger->logNetwork(INFO, "Status request - keeping in temp list", "Handshake"); + // g_logger->logNetwork(INFO, "Status request - keeping in temp list", "Handshake"); } else if (nextState == 2) { packet.getPlayer()->setPlayerState(PlayerState::Login); server.promoteTempPlayer(packet.getPlayer()); diff --git a/src/networking/packet/loginAcknowledged.cpp b/src/networking/packet/loginAcknowledged.cpp index 5775a3b..47d9d0b 100644 --- a/src/networking/packet/loginAcknowledged.cpp +++ b/src/networking/packet/loginAcknowledged.cpp @@ -1,30 +1,35 @@ +#include "logger.hpp" #include "network/networking.hpp" #include "network/packet.hpp" -#include "player.hpp" #include "network/server.hpp" -#include "logger.hpp" +#include "player.hpp" + #include void handleLoginAcknowledged(Packet& packet, Server& server) { - // g_logger->logNetwork(INFO, "Login Acknowledged received - transitioning to Configuration state", "Login"); + // g_logger->logNetwork(INFO, "Login Acknowledged received - transitioning to Configuration + // state", "Login"); - Player* player = packet.getPlayer(); - if (!player) { - // g_logger->logNetwork(ERROR, "Error: No player associated with Login Acknowledged packet", "Login"); - packet.setReturnPacket(PACKET_DISCONNECT); - return; - } + Player* player = packet.getPlayer(); + if (!player) { + // g_logger->logNetwork(ERROR, "Error: No player associated with Login Acknowledged packet", + // "Login"); + packet.setReturnPacket(PACKET_DISCONNECT); + return; + } - // The Login Acknowledged packet has no payload (0 bytes), so nothing to read + // The Login Acknowledged packet has no payload (0 bytes), so nothing to read - // The client has acknowledged the login success, now we officially transition to Configuration state - player->setPlayerState(PlayerState::Configuration); + // The client has acknowledged the login success, now we officially transition to Configuration + // state + player->setPlayerState(PlayerState::Configuration); - // g_logger->logNetwork(INFO, "Player " + player->getPlayerName() + " successfully acknowledged login - transitioned to Configuration state", "Login"); + // g_logger->logNetwork(INFO, "Player " + player->getPlayerName() + " successfully acknowledged + // login - transitioned to Configuration state", "Login"); - // Just acknowledge the packet - don't send anything yet - // The client will send Client Information (packet 0x03) next in Configuration state - packet.setReturnPacket(PACKET_OK); + // Just acknowledge the packet - don't send anything yet + // The client will send Client Information (packet 0x03) next in Configuration state + packet.setReturnPacket(PACKET_OK); - (void)server; // Suppress unused parameter warning + (void)server; // Suppress unused parameter warning } diff --git a/src/networking/packet/loginStart.cpp b/src/networking/packet/loginStart.cpp index 5863019..721af5d 100644 --- a/src/networking/packet/loginStart.cpp +++ b/src/networking/packet/loginStart.cpp @@ -1,10 +1,10 @@ #include "lib/UUID.hpp" +#include "logger.hpp" #include "network/buffer.hpp" #include "network/networking.hpp" #include "network/packet.hpp" -#include "player.hpp" #include "network/server.hpp" -#include "logger.hpp" +#include "player.hpp" #include @@ -36,15 +36,15 @@ void handleLoginStartPacket(Packet& packet, Server& server) { g_logger->logNetwork(INFO, "Login Success payload bytes: " + payloadHex, "Login"); // Calculate total packet size (packet ID + payload) - int packetId = 0x02; - int payloadSize = payload.getData().size(); + int packetId = 0x02; + int payloadSize = payload.getData().size(); int packetIdVarintSize = packet.getVarintSize(packetId); - int totalPayloadSize = packetIdVarintSize + payloadSize; + int totalPayloadSize = packetIdVarintSize + payloadSize; Buffer final; - final.writeVarInt(totalPayloadSize); // Total packet size - final.writeVarInt(packetId); // Login Success packet ID (0x02) - final.writeBytes(payload.getData()); // UUID + username + properties + final.writeVarInt(totalPayloadSize); // Total packet size + final.writeVarInt(packetId); // Login Success packet ID (0x02) + final.writeBytes(payload.getData()); // UUID + username + properties packet.getData() = final; packet.setReturnPacket(PACKET_SEND); @@ -61,6 +61,9 @@ void handleLoginStartPacket(Packet& packet, Server& server) { g_logger->logNetwork(INFO, "Complete Login Success packet bytes: " + finalHex, "Login"); // Don't transition to Configuration yet - wait for Login Acknowledged - g_logger->logNetwork(INFO, "Login Success sent for user: " + username + ", UUID: " + uuid.toString() + ", packet size: " + std::to_string(final.getData().size()), "Login"); + g_logger->logNetwork(INFO, + "Login Success sent for user: " + username + ", UUID: " + uuid.toString() + + ", packet size: " + std::to_string(final.getData().size()), + "Login"); (void)server; } diff --git a/src/networking/packet/packetRouter.cpp b/src/networking/packet/packetRouter.cpp index ecf3f49..8a07356 100644 --- a/src/networking/packet/packetRouter.cpp +++ b/src/networking/packet/packetRouter.cpp @@ -1,21 +1,17 @@ +#include "logger.hpp" #include "network/networking.hpp" #include "network/packet.hpp" -#include "player.hpp" #include "network/server.hpp" -#include "logger.hpp" +#include "player.hpp" + #include -#include "network/packet.hpp" -void handleHandshakeState(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 handleConfigurationState(Packet* packet, Server& server); void handlePlayState(Packet* packet, Server& server); -void sendDisconnectPacket(Packet* packet, - const std::string& reason, - Server& server); +void sendDisconnectPacket(Packet* packet, const std::string& reason, Server& server); void initGameSequence(Packet* packet, Server& server); // ======================================== @@ -35,10 +31,10 @@ void packetRouter(Packet* packet, Server& server) { } g_logger->logNetwork(INFO, - "Routing packet ID: 0x" + std::to_string(packet->getId()) + - " (size: " + std::to_string(packet->getSize()) + ") for state: " + - std::to_string(static_cast(player->getPlayerState())), - "PacketRouter"); + "Routing packet ID: 0x" + std::to_string(packet->getId()) + + " (size: " + std::to_string(packet->getSize()) + ") for state: " + + std::to_string(static_cast(player->getPlayerState())), + "PacketRouter"); switch (player->getPlayerState()) { case PlayerState::Handshake: @@ -58,10 +54,10 @@ void packetRouter(Packet* packet, Server& server) { break; default: g_logger->logNetwork(WARN, - "Unknown player state: " + - std::to_string(static_cast(player->getPlayerState())) + - ", disconnecting", - "PacketRouter"); + "Unknown player state: " + + std::to_string(static_cast(player->getPlayerState())) + + ", disconnecting", + "PacketRouter"); packet->setReturnPacket(PACKET_DISCONNECT); break; } @@ -71,8 +67,7 @@ void packetRouter(Packet* packet, Server& server) { // Handshake State Handler // ======================================== -void handleHandshakeState(Packet* packet, - Server& server) { +void handleHandshakeState(Packet* packet, Server& server) { handleHandshakePacket(*packet, server); } @@ -87,9 +82,9 @@ void handleStatusState(Packet* packet, Server& server) { handlePingPacket(*packet, server); } else { g_logger->logNetwork(WARN, - "Unknown packet ID in Status state: 0x" + - std::to_string(packet->getId()), - "PacketRouter"); + "Unknown packet ID in Status state: 0x" + + std::to_string(packet->getId()), + "PacketRouter"); packet->getPlayer()->setPlayerState(PlayerState::None); packet->setReturnPacket(PACKET_DISCONNECT); } @@ -103,8 +98,8 @@ void handleLoginState(Packet* packet, Server& server) { // Add safety check for packet data integrity if (packet->getSize() > 32767) { // Max packet size g_logger->logNetwork(ERROR, - "Packet size too large: " + std::to_string(packet->getSize()), - "PacketRouter"); + "Packet size too large: " + std::to_string(packet->getSize()), + "PacketRouter"); packet->setReturnPacket(PACKET_DISCONNECT); return; } @@ -116,7 +111,7 @@ void handleLoginState(Packet* packet, Server& server) { } else if (packet->getId() == 0x02) { // Login Plugin Response - safe to ignore most of the time g_logger->logNetwork( - INFO, "Received Login Plugin Response (0x02) - acknowledging", "PacketRouter"); + INFO, "Received Login Plugin Response (0x02) - acknowledging", "PacketRouter"); packet->setReturnPacket(PACKET_OK); } else if (packet->getId() == 0x03) { // Login Acknowledged @@ -125,13 +120,13 @@ void handleLoginState(Packet* packet, Server& server) { } else if (packet->getId() == 0x04) { // Cookie Response (login) g_logger->logNetwork( - INFO, "Received Login Cookie Response (0x04) - acknowledging", "PacketRouter"); + INFO, "Received Login Cookie Response (0x04) - acknowledging", "PacketRouter"); packet->setReturnPacket(PACKET_OK); } else { g_logger->logNetwork(WARN, - "Unknown packet ID in Login state: 0x" + - std::to_string(packet->getId()), - "PacketRouter"); + "Unknown packet ID in Login state: 0x" + + std::to_string(packet->getId()), + "PacketRouter"); packet->getPlayer()->setPlayerState(PlayerState::None); packet->setReturnPacket(PACKET_DISCONNECT); } @@ -141,8 +136,7 @@ void handleLoginState(Packet* packet, Server& server) { // Configuration State Handler // ======================================== -void handleConfigurationState(Packet* packet, - Server& server) { +void handleConfigurationState(Packet* packet, Server& server) { if (packet->getId() == 0x00) { // Client Information (configuration) // g_logger->logNetwork(INFO, "Received Client Information in Configuration state", @@ -166,17 +160,17 @@ void handleConfigurationState(Packet* packet, } else if (packet->getId() == 0x02) { // Serverbound Plugin Message (configuration) g_logger->logNetwork(INFO, - "Received Serverbound Plugin Message (0x02), size: " + - std::to_string(packet->getSize()) + " bytes", - "PacketRouter"); + "Received Serverbound Plugin Message (0x02), size: " + + std::to_string(packet->getSize()) + " bytes", + "PacketRouter"); packet->setReturnPacket(PACKET_OK); } else if (packet->getId() == 0x03) { // Acknowledge Finish Configuration -> enter Play g_logger->logNetwork( - INFO, - "Received Acknowledge Finish Configuration - transitioning to Play state", - "PacketRouter"); + INFO, + "Received Acknowledge Finish Configuration - transitioning to Play state", + "PacketRouter"); handleAcknowledgeFinishConfiguration(*packet, server); initGameSequence(packet, server); @@ -211,9 +205,9 @@ void handleConfigurationState(Packet* packet, } else { g_logger->logNetwork(WARN, - "Unknown packet ID in Configuration state: 0x" + - std::to_string(packet->getId()), - "PacketRouter"); + "Unknown packet ID in Configuration state: 0x" + + std::to_string(packet->getId()), + "PacketRouter"); sendDisconnectPacket(packet, "Unknown packet in Configuration state", server); packet->getPlayer()->setPlayerState(PlayerState::None); packet->setReturnPacket(PACKET_DISCONNECT); @@ -243,9 +237,7 @@ void handlePlayState(Packet* packet, Server& server) { // Disconnect Packet Creation // ======================================== -void sendDisconnectPacket(Packet* packet, - const std::string& reason, - Server& server) { +void sendDisconnectPacket(Packet* packet, const std::string& reason, Server& server) { ThreadSafeQueue* outgoingPackets = server.getNetworkManager().getOutgoingQueue(); if (!packet || !outgoingPackets) return; @@ -253,7 +245,7 @@ void sendDisconnectPacket(Packet* packet, if (!player) return; g_logger->logNetwork( - INFO, "Sending disconnect packet to player with reason: " + reason, "PacketRouter"); + INFO, "Sending disconnect packet to player with reason: " + reason, "PacketRouter"); try { // Create Disconnect packet (0x02 in Configuration state) @@ -269,7 +261,7 @@ void sendDisconnectPacket(Packet* packet, final.writeBytes(payload.getData()); // Create new packet for disconnect - Packet* disconnectPacket = new Packet(*packet); + Packet* disconnectPacket = new Packet(*packet); disconnectPacket->getData() = final; disconnectPacket->setReturnPacket(PACKET_SEND); disconnectPacket->setPacketSize(final.getData().size()); @@ -279,8 +271,8 @@ void sendDisconnectPacket(Packet* packet, g_logger->logNetwork(INFO, "Disconnect packet queued for sending", "PacketRouter"); } catch (const std::exception& e) { g_logger->logNetwork(ERROR, - "Error creating disconnect packet: " + std::string(e.what()), - "PacketRouter"); + "Error creating disconnect packet: " + std::string(e.what()), + "PacketRouter"); } } @@ -296,7 +288,7 @@ void initGameSequence(Packet* packet, Server& server) { // Player should already be in Play state at this point g_logger->logNetwork( - INFO, "Starting game sequence for player: " + player->getPlayerName(), "PacketRouter"); + INFO, "Starting game sequence for player: " + player->getPlayerName(), "PacketRouter"); try { // 1. Send Login (play) packet - 0x2B @@ -331,7 +323,7 @@ void initGameSequence(Packet* packet, Server& server) { packet->setReturnPacket(PACKET_OK); } catch (const std::exception& e) { g_logger->logNetwork( - ERROR, "Error in game sequence: " + std::string(e.what()), "PacketRouter"); + ERROR, "Error in game sequence: " + std::string(e.what()), "PacketRouter"); packet->setReturnPacket(PACKET_ERROR); } } diff --git a/src/networking/packet/ping.cpp b/src/networking/packet/ping.cpp index 2f6dc15..e104535 100644 --- a/src/networking/packet/ping.cpp +++ b/src/networking/packet/ping.cpp @@ -1,9 +1,9 @@ +#include "logger.hpp" #include "network/buffer.hpp" #include "network/networking.hpp" #include "network/packet.hpp" -#include "player.hpp" #include "network/server.hpp" -#include "logger.hpp" +#include "player.hpp" #include @@ -16,9 +16,10 @@ void handlePingPacket(Packet& packet, Server& server) { long timestamp = packet.getData().readLong(); - // g_logger->logNetwork(INFO, "Received ping request with timestamp: " + std::to_string(timestamp), "Ping"); + // g_logger->logNetwork(INFO, "Received ping request with timestamp: " + + // std::to_string(timestamp), "Ping"); - int packetId = 0x01; + int packetId = 0x01; int packetIdVarintSize = packet.getVarintSize(packetId); int totalPayloadSize = packetIdVarintSize + 8; @@ -32,7 +33,8 @@ void handlePingPacket(Packet& packet, Server& server) { packet.setPacketSize(buf.getData().size()); packet.getPlayer()->setPlayerState(PlayerState::None); - // g_logger->logNetwork(INFO, "Pong response ready - echoing timestamp " + std::to_string(timestamp), "Ping"); + // g_logger->logNetwork(INFO, "Pong response ready - echoing timestamp " + + // std::to_string(timestamp), "Ping"); (void)server; } diff --git a/src/networking/packet/play.cpp b/src/networking/packet/play.cpp index 92c8979..da584f6 100644 --- a/src/networking/packet/play.cpp +++ b/src/networking/packet/play.cpp @@ -1,81 +1,81 @@ +#include "network/buffer.hpp" #include "network/packet.hpp" #include "player.hpp" -#include "network/buffer.hpp" -#include +#include void writePlayPacket(Packet& packet) { - Player* player = packet.getPlayer(); - if (!player) return; + Player* player = packet.getPlayer(); + if (!player) return; - Buffer buf; + Buffer buf; - // 1. Entity ID - buf.writeInt(player->getPlayerID()); + // 1. Entity ID + buf.writeInt(player->getPlayerID()); - // 2. Is Hardcore (false) - buf.writeBool(false); + // 2. Is Hardcore (false) + buf.writeBool(false); - // 3. Game mode (survival = 0) - buf.writeByte(0); + // 3. Game mode (survival = 0) + buf.writeByte(0); - // 4. Previous game mode (-1 = not set) - buf.writeByte(-1); + // 4. Previous game mode (-1 = not set) + buf.writeByte(-1); - // 5. World names (just overworld for now) - buf.writeVarInt(1); // Number of worlds - buf.writeString("minecraft:overworld"); + // 5. World names (just overworld for now) + buf.writeVarInt(1); // Number of worlds + buf.writeString("minecraft:overworld"); - // 6. Registry codec (empty/minimal for now) - // We'll write a minimal empty NBT structure - buf.writeByte(0x0A); // TAG_Compound - buf.writeByte(0); // Short value (high byte) - buf.writeByte(0); // Short value (low byte) - buf.writeByte(0x00); // TAG_End + // 6. Registry codec (empty/minimal for now) + // We'll write a minimal empty NBT structure + buf.writeByte(0x0A); // TAG_Compound + buf.writeByte(0); // Short value (high byte) + buf.writeByte(0); // Short value (low byte) + buf.writeByte(0x00); // TAG_End - // 7. Dimension (empty/minimal for now) - // We'll write a minimal empty NBT structure - buf.writeByte(0x0A); // TAG_Compound - buf.writeByte(0); // Short value (high byte) - buf.writeByte(0); // Short value (low byte) - buf.writeByte(0x00); // TAG_End + // 7. Dimension (empty/minimal for now) + // We'll write a minimal empty NBT structure + buf.writeByte(0x0A); // TAG_Compound + buf.writeByte(0); // Short value (high byte) + buf.writeByte(0); // Short value (low byte) + buf.writeByte(0x00); // TAG_End - // 8. World name - buf.writeString("minecraft:overworld"); + // 8. World name + buf.writeString("minecraft:overworld"); - // 9. Hashed seed - buf.writeLong(12345678L); + // 9. Hashed seed + buf.writeLong(12345678L); - // 10. Max players - buf.writeVarInt(20); + // 10. Max players + buf.writeVarInt(20); - // 11. View distance - buf.writeVarInt(10); + // 11. View distance + buf.writeVarInt(10); - // 12. Simulation distance - buf.writeVarInt(10); + // 12. Simulation distance + buf.writeVarInt(10); - // 13. Reduced debug info - buf.writeBool(false); + // 13. Reduced debug info + buf.writeBool(false); - // 14. Enable respawn screen - buf.writeBool(true); + // 14. Enable respawn screen + buf.writeBool(true); - // 15. Do limited crafting - buf.writeBool(false); + // 15. Do limited crafting + buf.writeBool(false); - // 16. Dimension type - buf.writeString("minecraft:overworld"); + // 16. Dimension type + buf.writeString("minecraft:overworld"); - // 17. Dimension name - buf.writeString("minecraft:overworld"); + // 17. Dimension name + buf.writeString("minecraft:overworld"); - // 18. Portal cooldown - buf.writeVarInt(0); + // 18. Portal cooldown + buf.writeVarInt(0); - // 19. Enforces secure chat - buf.writeBool(false); + // 19. Enforces secure chat + buf.writeBool(false); - packet.setPacketId(0x2B); // Login (play) packet ID - packet.getData() = buf; + packet.setPacketId(0x2B); // Login (play) packet ID + packet.getData() = buf; } diff --git a/src/networking/packet/setCenterChunck.cpp b/src/networking/packet/setCenterChunck.cpp index 1dcc964..5e161be 100644 --- a/src/networking/packet/setCenterChunck.cpp +++ b/src/networking/packet/setCenterChunck.cpp @@ -2,8 +2,8 @@ #include "network/buffer.hpp" #include "network/networking.hpp" #include "network/packet.hpp" -#include "player.hpp" #include "network/server.hpp" +#include "player.hpp" #include @@ -14,8 +14,8 @@ void writeSetCenterPacket(Packet& packet, Server& server) { buf.writeVarInt(0); buf.writeVarInt(0); - int packetId = 0x57; - int packetIdSize = packet.getVarintSize(packetId); + int packetId = 0x57; + int packetIdSize = packet.getVarintSize(packetId); int totalPayloadSize = packetIdSize + buf.getData().size(); Buffer finalBuf; diff --git a/src/networking/packet/spawnSequence.cpp b/src/networking/packet/spawnSequence.cpp index 73eb337..1ce86b4 100644 --- a/src/networking/packet/spawnSequence.cpp +++ b/src/networking/packet/spawnSequence.cpp @@ -2,216 +2,217 @@ #include "network/buffer.hpp" #include "network/networking.hpp" #include "network/packet.hpp" -#include "player.hpp" #include "network/server.hpp" +#include "player.hpp" #include void sendPlayerAbilities(Packet& packet, Server& server) { - std::cout << "=== Sending Player Abilities ===\n"; + std::cout << "=== Sending Player Abilities ===\n"; - Buffer buf; + Buffer buf; - // Flags (byte) - bit field for player abilities - uint8_t flags = 0x00; - // 0x01: Invulnerable - // 0x02: Flying - // 0x04: Allow Flying (creative mode) - // 0x08: Creative Mode (instant break) - buf.writeByte(flags); + // Flags (byte) - bit field for player abilities + uint8_t flags = 0x00; + // 0x01: Invulnerable + // 0x02: Flying + // 0x04: Allow Flying (creative mode) + // 0x08: Creative Mode (instant break) + buf.writeByte(flags); - // Flying Speed (float) - 0.05 by default - // Convert 0.05f to IEEE 754 bits: 0x3D4CCCCD - buf.writeInt(0x3D4CCCCD); + // Flying Speed (float) - 0.05 by default + // Convert 0.05f to IEEE 754 bits: 0x3D4CCCCD + buf.writeInt(0x3D4CCCCD); - // Field of View Modifier (float) - 0.1 by default - // Convert 0.1f to IEEE 754 bits: 0x3DCCCCCD - buf.writeInt(0x3DCCCCCD); + // Field of View Modifier (float) - 0.1 by default + // Convert 0.1f to IEEE 754 bits: 0x3DCCCCCD + buf.writeInt(0x3DCCCCCD); - int packetId = 0x39; // Player Abilities packet ID for protocol 770 - int packetIdSize = packet.getVarintSize(packetId); - int totalPayloadSize = packetIdSize + buf.getData().size(); + int packetId = 0x39; // Player Abilities packet ID for protocol 770 + int packetIdSize = packet.getVarintSize(packetId); + int totalPayloadSize = packetIdSize + buf.getData().size(); - Buffer finalBuf; - finalBuf.writeVarInt(totalPayloadSize); - finalBuf.writeVarInt(packetId); - finalBuf.writeBytes(buf.getData()); + Buffer finalBuf; + finalBuf.writeVarInt(totalPayloadSize); + finalBuf.writeVarInt(packetId); + finalBuf.writeBytes(buf.getData()); - packet.getData() = finalBuf; - packet.setPacketSize(finalBuf.getData().size()); - packet.setReturnPacket(PACKET_SEND); + packet.getData() = finalBuf; + packet.setPacketSize(finalBuf.getData().size()); + packet.setReturnPacket(PACKET_SEND); - (void)server; + (void)server; } void sendSetHealth(Packet& packet, Server& server) { - std::cout << "=== Sending Set Health ===\n"; + std::cout << "=== Sending Set Health ===\n"; - Buffer buf; + Buffer buf; - // Health (float) - 20.0 = full health - // Convert 20.0f to IEEE 754 bits: 0x41A00000 - buf.writeInt(0x41A00000); + // Health (float) - 20.0 = full health + // Convert 20.0f to IEEE 754 bits: 0x41A00000 + buf.writeInt(0x41A00000); - // Food (VarInt) - 20 = full food bar - buf.writeVarInt(20); + // Food (VarInt) - 20 = full food bar + buf.writeVarInt(20); - // Food Saturation (float) - 5.0 by default - // Convert 5.0f to IEEE 754 bits: 0x40A00000 - buf.writeInt(0x40A00000); + // Food Saturation (float) - 5.0 by default + // Convert 5.0f to IEEE 754 bits: 0x40A00000 + buf.writeInt(0x40A00000); - int packetId = 0x61; // Set Health packet ID for protocol 770 - int packetIdSize = packet.getVarintSize(packetId); - int totalPayloadSize = packetIdSize + buf.getData().size(); + int packetId = 0x61; // Set Health packet ID for protocol 770 + int packetIdSize = packet.getVarintSize(packetId); + int totalPayloadSize = packetIdSize + buf.getData().size(); - Buffer finalBuf; - finalBuf.writeVarInt(totalPayloadSize); - finalBuf.writeVarInt(packetId); - finalBuf.writeBytes(buf.getData()); + Buffer finalBuf; + finalBuf.writeVarInt(totalPayloadSize); + finalBuf.writeVarInt(packetId); + finalBuf.writeBytes(buf.getData()); - packet.getData() = finalBuf; - packet.setPacketSize(finalBuf.getData().size()); - packet.setReturnPacket(PACKET_SEND); + packet.getData() = finalBuf; + packet.setPacketSize(finalBuf.getData().size()); + packet.setReturnPacket(PACKET_SEND); - (void)server; + (void)server; } void sendSetExperience(Packet& packet, Server& server) { - std::cout << "=== Sending Set Experience ===\n"; + std::cout << "=== Sending Set Experience ===\n"; - Buffer buf; + Buffer buf; - // Experience bar (float) - 0.0 to 1.0 (progress to next level) - // Convert 0.0f to IEEE 754 bits: 0x00000000 - buf.writeInt(0x00000000); + // Experience bar (float) - 0.0 to 1.0 (progress to next level) + // Convert 0.0f to IEEE 754 bits: 0x00000000 + buf.writeInt(0x00000000); - // Level (VarInt) - current experience level - buf.writeVarInt(0); + // Level (VarInt) - current experience level + buf.writeVarInt(0); - // Total Experience (VarInt) - total experience points - buf.writeVarInt(0); + // Total Experience (VarInt) - total experience points + buf.writeVarInt(0); - int packetId = 0x60; // Set Experience packet ID for protocol 770 - int packetIdSize = packet.getVarintSize(packetId); - int totalPayloadSize = packetIdSize + buf.getData().size(); + int packetId = 0x60; // Set Experience packet ID for protocol 770 + int packetIdSize = packet.getVarintSize(packetId); + int totalPayloadSize = packetIdSize + buf.getData().size(); - Buffer finalBuf; - finalBuf.writeVarInt(totalPayloadSize); - finalBuf.writeVarInt(packetId); - finalBuf.writeBytes(buf.getData()); + Buffer finalBuf; + finalBuf.writeVarInt(totalPayloadSize); + finalBuf.writeVarInt(packetId); + finalBuf.writeBytes(buf.getData()); - packet.getData() = finalBuf; - packet.setPacketSize(finalBuf.getData().size()); - packet.setReturnPacket(PACKET_SEND); + packet.getData() = finalBuf; + packet.setPacketSize(finalBuf.getData().size()); + packet.setReturnPacket(PACKET_SEND); - (void)server; + (void)server; } void sendUpdateTime(Packet& packet, Server& server) { - std::cout << "=== Sending Update Time ===\n"; + std::cout << "=== Sending Update Time ===\n"; - Buffer buf; + Buffer buf; - // World Age (Long) - total ticks since world creation - buf.writeLong(0); + // World Age (Long) - total ticks since world creation + buf.writeLong(0); - // Time of day (Long) - 0 = sunrise, 6000 = noon, 12000 = sunset, 18000 = midnight - buf.writeLong(1000); // Morning time + // Time of day (Long) - 0 = sunrise, 6000 = noon, 12000 = sunset, 18000 = midnight + buf.writeLong(1000); // Morning time - // Time of day increasing (Boolean) - should client auto-advance time - buf.writeByte(0x01); // true + // Time of day increasing (Boolean) - should client auto-advance time + buf.writeByte(0x01); // true - int packetId = 0x6A; // Update Time packet ID for protocol 770 - int packetIdSize = packet.getVarintSize(packetId); - int totalPayloadSize = packetIdSize + buf.getData().size(); + int packetId = 0x6A; // Update Time packet ID for protocol 770 + int packetIdSize = packet.getVarintSize(packetId); + int totalPayloadSize = packetIdSize + buf.getData().size(); - Buffer finalBuf; - finalBuf.writeVarInt(totalPayloadSize); - finalBuf.writeVarInt(packetId); - finalBuf.writeBytes(buf.getData()); + Buffer finalBuf; + finalBuf.writeVarInt(totalPayloadSize); + finalBuf.writeVarInt(packetId); + finalBuf.writeBytes(buf.getData()); - packet.getData() = finalBuf; - packet.setPacketSize(finalBuf.getData().size()); - packet.setReturnPacket(PACKET_SEND); + packet.getData() = finalBuf; + packet.setPacketSize(finalBuf.getData().size()); + packet.setReturnPacket(PACKET_SEND); - (void)server; + (void)server; } void sendSetHeldItem(Packet& packet, Server& server) { - std::cout << "=== Sending Set Held Item ===\n"; + std::cout << "=== Sending Set Held Item ===\n"; - Buffer buf; + Buffer buf; - // Slot (VarInt) - hotbar slot selected (0-8) - buf.writeVarInt(0); // First slot selected + // Slot (VarInt) - hotbar slot selected (0-8) + buf.writeVarInt(0); // First slot selected - int packetId = 0x62; // Set Held Item packet ID for protocol 770 - int packetIdSize = packet.getVarintSize(packetId); - int totalPayloadSize = packetIdSize + buf.getData().size(); + int packetId = 0x62; // Set Held Item packet ID for protocol 770 + int packetIdSize = packet.getVarintSize(packetId); + int totalPayloadSize = packetIdSize + buf.getData().size(); - Buffer finalBuf; - finalBuf.writeVarInt(totalPayloadSize); - finalBuf.writeVarInt(packetId); - finalBuf.writeBytes(buf.getData()); + Buffer finalBuf; + finalBuf.writeVarInt(totalPayloadSize); + finalBuf.writeVarInt(packetId); + finalBuf.writeBytes(buf.getData()); - packet.getData() = finalBuf; - packet.setPacketSize(finalBuf.getData().size()); - packet.setReturnPacket(PACKET_SEND); + packet.getData() = finalBuf; + packet.setPacketSize(finalBuf.getData().size()); + packet.setReturnPacket(PACKET_SEND); - (void)server; + (void)server; } void handleConfirmTeleportation(Packet& packet, Server& server) { - std::cout << "=== Received Confirm Teleportation ===\n"; + std::cout << "=== Received Confirm Teleportation ===\n"; - // Read teleport ID from packet data - int teleportId = packet.getData().readVarInt(); + // Read teleport ID from packet data + int teleportId = packet.getData().readVarInt(); - std::cout << "Player confirmed teleportation with ID: " << teleportId << std::endl; + std::cout << "Player confirmed teleportation with ID: " << teleportId << std::endl; - // Mark packet as processed - packet.setReturnPacket(PACKET_OK); + // Mark packet as processed + packet.setReturnPacket(PACKET_OK); - (void)server; + (void)server; } void completeSpawnSequence(Packet& packet, Server& server) { - Player* player = packet.getPlayer(); - ThreadSafeQueue* outgoingPackets = server.getNetworkManager().getOutgoingQueue(); - if (!player || !outgoingPackets) return; - - // std::cout << "=== Completing spawn sequence for player: " << player->getPlayerName() << " ===\n"; - std::cout << "=== Completing spawn sequence for player: " << " ===\n"; - - try { - // 9. Player Abilities (0x39) - Packet* abilitiesPacket = new Packet(packet); - sendPlayerAbilities(*abilitiesPacket, server); - outgoingPackets->push(abilitiesPacket); - - // 10. Set Health (0x61) - Packet* healthPacket = new Packet(packet); - sendSetHealth(*healthPacket, server); - outgoingPackets->push(healthPacket); - - // 11. Set Experience (0x60) - Packet* experiencePacket = new Packet(packet); - sendSetExperience(*experiencePacket, server); - outgoingPackets->push(experiencePacket); - - // 12. Update Time (0x6A) - Packet* timePacket = new Packet(packet); - sendUpdateTime(*timePacket, server); - outgoingPackets->push(timePacket); - - // 13. Set Held Item (0x62) - Packet* heldItemPacket = new Packet(packet); - sendSetHeldItem(*heldItemPacket, server); - outgoingPackets->push(heldItemPacket); - - std::cout << "=== Spawn sequence completed! Player should now be fully spawned ===\n"; - - } catch (const std::exception& e) { - std::cerr << "Error completing spawn sequence: " << e.what() << std::endl; - } + Player* player = packet.getPlayer(); + ThreadSafeQueue* outgoingPackets = server.getNetworkManager().getOutgoingQueue(); + if (!player || !outgoingPackets) return; + + // std::cout << "=== Completing spawn sequence for player: " << player->getPlayerName() << " + // ===\n"; + std::cout << "=== Completing spawn sequence for player: " << " ===\n"; + + try { + // 9. Player Abilities (0x39) + Packet* abilitiesPacket = new Packet(packet); + sendPlayerAbilities(*abilitiesPacket, server); + outgoingPackets->push(abilitiesPacket); + + // 10. Set Health (0x61) + Packet* healthPacket = new Packet(packet); + sendSetHealth(*healthPacket, server); + outgoingPackets->push(healthPacket); + + // 11. Set Experience (0x60) + Packet* experiencePacket = new Packet(packet); + sendSetExperience(*experiencePacket, server); + outgoingPackets->push(experiencePacket); + + // 12. Update Time (0x6A) + Packet* timePacket = new Packet(packet); + sendUpdateTime(*timePacket, server); + outgoingPackets->push(timePacket); + + // 13. Set Held Item (0x62) + Packet* heldItemPacket = new Packet(packet); + sendSetHeldItem(*heldItemPacket, server); + outgoingPackets->push(heldItemPacket); + + std::cout << "=== Spawn sequence completed! Player should now be fully spawned ===\n"; + + } catch (const std::exception& e) { + std::cerr << "Error completing spawn sequence: " << e.what() << std::endl; + } } diff --git a/src/networking/packet/status.cpp b/src/networking/packet/status.cpp index 36e1925..3dc2ad6 100644 --- a/src/networking/packet/status.cpp +++ b/src/networking/packet/status.cpp @@ -1,10 +1,10 @@ -#include "network/buffer.hpp" #include "lib/json.hpp" +#include "logger.hpp" +#include "network/buffer.hpp" #include "network/networking.hpp" #include "network/packet.hpp" -#include "player.hpp" #include "network/server.hpp" -#include "logger.hpp" +#include "player.hpp" #include #include @@ -18,16 +18,16 @@ void handleStatusPacket(Packet& packet, Server& server) { return; } - json jres = {{"version", - {{"name", server.getGameVersion()}, {"protocol", server.getProtocolVersion()}}}, - {"players", - {{"max", server.getServerSize()}, - {"online", server.getAmountOnline()}, - {"sample", server.getPlayerSample()}}}, - {"description", {{"text", server.getServerMOTD()}}}}; + json jres = {{"version", + {{"name", server.getGameVersion()}, {"protocol", server.getProtocolVersion()}}}, + {"players", + {{"max", server.getServerSize()}, + {"online", server.getAmountOnline()}, + {"sample", server.getPlayerSample()}}}, + {"description", {{"text", server.getServerMOTD()}}}}; std::string payload = jres.dump(); - int jsonLen = payload.size(); + int jsonLen = payload.size(); int packetId = 0x00; int packetIdVarintSize = packet.getVarintSize(packetId); diff --git a/src/server.cpp b/src/server.cpp index eb0f4b3..1441b71 100644 --- a/src/server.cpp +++ b/src/server.cpp @@ -1,8 +1,9 @@ +#include "network/server.hpp" + #include "lib/json.hpp" #include "logger.hpp" #include "network/networking.hpp" #include "player.hpp" -#include "network/server.hpp" #include #include @@ -14,8 +15,8 @@ using json = nlohmann::json; Server::Server() - : _playerLst(), _protocolVersion(770), _serverSize(-100000000), _gameVersion("1.12.5"), - _serverMOTD(), _serverPort(25565), _serverAddr("0.0.0.0"), _networkManager(nullptr) {} + : _playerLst(), _protocolVersion(770), _serverSize(-100000000), _gameVersion("1.12.5"), + _serverMOTD(), _serverPort(25565), _serverAddr("0.0.0.0"), _networkManager(nullptr) {} Server::~Server() { if (_networkManager) { @@ -26,11 +27,10 @@ Server::~Server() { int Server::start_server() { try { - initializeGlobalLogger(); + initializeGlobalLogger(); Server::loadConfig(); size_t workerCount = 4; - if (workerCount == 0) - workerCount = 4; // fallback + if (workerCount == 0) workerCount = 4; // fallback // Create NetworkManager with BOTH required parameters _networkManager = new NetworkManager(workerCount, *this); @@ -61,11 +61,13 @@ int Server::loadConfig() { try { inputFile >> j; - // g_logger->logGameInfo(INFO, "Successfully parsed " + std::string(ConfigFileName) + "!", "Server"); + // g_logger->logGameInfo(INFO, "Successfully parsed " + std::string(ConfigFileName) + "!", + // "Server"); _gameVersion = j["version"]["name"]; // g_logger->logGameInfo(INFO, "Game version: " + _gameVersion, "Server"); _protocolVersion = j["version"]["protocol"]; - // g_logger->logGameInfo(INFO, "Protocol version: " + std::to_string(_protocolVersion), "Server"); + // g_logger->logGameInfo(INFO, "Protocol version: " + std::to_string(_protocolVersion), + // "Server"); _serverSize = j["server"]["max-players"]; // g_logger->logGameInfo(INFO, "Server size: " + std::to_string(_serverSize), "Server"); _serverMOTD = j["server"]["motd"]; @@ -119,7 +121,8 @@ Player* Server::addTempPlayer(const std::string& name, const PlayerState state, std::lock_guard lock(_tempPlayerLock); _tempPlayerLst[socket] = newPlayer; - // g_logger->logGameInfo(INFO, "Added temp player on socket " + std::to_string(socket), "Server"); + // g_logger->logGameInfo(INFO, "Added temp player on socket " + std::to_string(socket), + // "Server"); return (newPlayer); } @@ -131,12 +134,12 @@ void Server::removeTempPlayer(Player* player) { std::lock_guard lock(_tempPlayerLock); _tempPlayerLst.erase(socket); delete player; - // g_logger->logGameInfo(INFO, "Removed temp player from socket " + std::to_string(socket), "Server"); + // g_logger->logGameInfo(INFO, "Removed temp player from socket " + std::to_string(socket), + // "Server"); } void Server::promoteTempPlayer(Player* player) { - if (!player) - return; + if (!player) return; int socket = player->getSocketFd(); std::lock_guard lockTemp(_tempPlayerLock); @@ -145,7 +148,8 @@ void Server::promoteTempPlayer(Player* player) { std::lock_guard lockPlayer(_playerLock); _playerLst[socket] = player; - // g_logger->logGameInfo(INFO, "Promoted temp player to main list on socket " + std::to_string(socket), "Server"); + // g_logger->logGameInfo(INFO, "Promoted temp player to main list on socket " + + // std::to_string(socket), "Server"); } void Server::removePlayerFromAnyList(Player* player) { @@ -160,7 +164,8 @@ void Server::removePlayerFromAnyList(Player* player) { if (temp_it != _tempPlayerLst.end()) { _tempPlayerLst.erase(socket); delete player; - // g_logger->logGameInfo(INFO, "Removed temp player from socket " + std::to_string(socket), "Server"); + // g_logger->logGameInfo(INFO, "Removed temp player from socket " + + // std::to_string(socket), "Server"); return; } } @@ -171,17 +176,17 @@ void Server::removePlayerFromAnyList(Player* player) { if (main_it != _playerLst.end()) { _playerLst.erase(socket); delete player; - // g_logger->logGameInfo(INFO, "Removed main player from socket " + std::to_string(socket), "Server"); + // g_logger->logGameInfo(INFO, "Removed main player from socket " + + // std::to_string(socket), "Server"); return; } } delete player; - // g_logger->logGameInfo(INFO, "Deleted orphaned player from socket " + std::to_string(socket), "Server"); + // g_logger->logGameInfo(INFO, "Deleted orphaned player from socket " + std::to_string(socket), + // "Server"); } -void Server::addPlayerToSample(const std::string& name) { - _playerSample.push_back(name); -} +void Server::addPlayerToSample(const std::string& name) { _playerSample.push_back(name); } void Server::removePlayerToSample(const std::string& name) { for (size_t i = 0; i < _playerLst.size(); i++) @@ -191,21 +196,9 @@ void Server::removePlayerToSample(const std::string& name) { } } -std::string Server::getGameVersion() { - return _gameVersion; -} -std::string Server::getServerMOTD() { - return _serverMOTD; -} -int Server::getProtocolVersion() { - return _protocolVersion; -} -int Server::getServerSize() { - return _serverSize; -} -int Server::getAmountOnline() { - return _playerLst.size(); -} -json Server::getPlayerSample() { - return _playerSample; -} +std::string Server::getGameVersion() { return _gameVersion; } +std::string Server::getServerMOTD() { return _serverMOTD; } +int Server::getProtocolVersion() { return _protocolVersion; } +int Server::getServerSize() { return _serverSize; } +int Server::getAmountOnline() { return _playerLst.size(); } +json Server::getPlayerSample() { return _playerSample; } diff --git a/src/world/worldManager.cpp b/src/world/worldManager.cpp index 646e3f6..0e01375 100644 --- a/src/world/worldManager.cpp +++ b/src/world/worldManager.cpp @@ -1,40 +1,40 @@ #include "world/worldManager.hpp" -#include +#include #include #include -#include #include +#include std::vector WorldManager::decompressGzip(const std::vector& compressed) { - z_stream stream{}; - stream.avail_in = compressed.size(); - stream.next_in = reinterpret_cast(const_cast(compressed.data())); - stream.zalloc = Z_NULL; - stream.zfree = Z_NULL; - stream.opaque = Z_NULL; - - int ret = inflateInit2(&stream, 15 + 32); - if (ret != Z_OK) { - throw std::runtime_error("Failed to initialize zlib"); - } - - std::vector decompressed; - decompressed.resize(compressed.size() * 2); - - do { - stream.avail_out = decompressed.size(); - stream.next_out = reinterpret_cast(decompressed.data()); - - ret = inflate(&stream, Z_NO_FLUSH); - if (ret == Z_NEED_DICT || ret == Z_DATA_ERROR || ret == Z_MEM_ERROR) { - inflateEnd(&stream); - throw std::runtime_error("Failed to decompress data"); - } - - decompressed.resize(stream.total_out); - } while (ret == Z_OK); - - inflateEnd(&stream); - return decompressed; + z_stream stream{}; + stream.avail_in = compressed.size(); + stream.next_in = reinterpret_cast(const_cast(compressed.data())); + stream.zalloc = Z_NULL; + stream.zfree = Z_NULL; + stream.opaque = Z_NULL; + + int ret = inflateInit2(&stream, 15 + 32); + if (ret != Z_OK) { + throw std::runtime_error("Failed to initialize zlib"); + } + + std::vector decompressed; + decompressed.resize(compressed.size() * 2); + + do { + stream.avail_out = decompressed.size(); + stream.next_out = reinterpret_cast(decompressed.data()); + + ret = inflate(&stream, Z_NO_FLUSH); + if (ret == Z_NEED_DICT || ret == Z_DATA_ERROR || ret == Z_MEM_ERROR) { + inflateEnd(&stream); + throw std::runtime_error("Failed to decompress data"); + } + + decompressed.resize(stream.total_out); + } while (ret == Z_OK); + + inflateEnd(&stream); + return decompressed; } From 50dd6971d1e95eac54507fe15405c2e06a4f6794 Mon Sep 17 00:00:00 2001 From: Antoine Mathie Date: Thu, 9 Oct 2025 22:16:54 +0200 Subject: [PATCH 11/27] feature: New config class, config loader, reloader. updated the server code to use the new config --- .clang-format | 5 +- include/config.hpp | 30 ++++++++-- include/network/server.hpp | 47 ++++++---------- src/lib/config.cpp | 91 +++++++++++++++++++++++++++++++ src/networking/networkManager.cpp | 11 ++-- src/networking/packet/status.cpp | 10 ++-- src/server.cpp | 61 ++++----------------- 7 files changed, 158 insertions(+), 97 deletions(-) create mode 100644 src/lib/config.cpp diff --git a/.clang-format b/.clang-format index 7584438..edb7a86 100644 --- a/.clang-format +++ b/.clang-format @@ -10,8 +10,9 @@ AllowShortIfStatementsOnASingleLine: true AllowShortFunctionsOnASingleLine: true PointerAlignment: Left SpaceBeforeParens: ControlStatements -AlignConsecutiveAssignments: Consecutive -AlignConsecutiveDeclarations: None +AlignConsecutiveAssignments: true +AlignConsecutiveDeclarations: true +AlignConsecutiveMacros: true BinPackArguments: false BinPackParameters: false Cpp11BracedListStyle: true diff --git a/include/config.hpp b/include/config.hpp index f07aec3..bf72abc 100644 --- a/include/config.hpp +++ b/include/config.hpp @@ -1,20 +1,38 @@ #ifndef CONFIG_HPP #define CONFIG_HPP +#include #include class Config { private: - std::string _gameVersion; - std::string _serverMotd; - std::string _serverAddress; - int _serverPort; - int _protocolVersion; - int _serverSize; + std::filesystem::path _execPath; + std::string _gameVersion; + std::string _serverMotd; + std::string _serverAddress; + int _serverPort; + int _protocolVersion; + int _serverSize; public: + Config(); + ~Config(); bool loadConfig(); bool reloadConfig(); + + int getServerPort(); + int getProtocolVersion(); + int getServerSize(); + std::string getVersion(); + std::string getServerMotd(); + std::string getServerAddress(); + + void setProtocolVersion(int ProtoVersion); + void setServerSize(int ServerSize); + void setServerPort(int ServerPort); + void setServerMotd(std::string ServerMotd); + void setServerVersion(std::string ServerVersion); + void setServerAddress(std::string ServerAddress); }; #endif diff --git a/include/network/server.hpp b/include/network/server.hpp index 9413e9f..e8e32ce 100644 --- a/include/network/server.hpp +++ b/include/network/server.hpp @@ -2,6 +2,7 @@ #define SERVER_HPP class NetworkManager; +#include "../config.hpp" #include "../player.hpp" #include "id_manager.hpp" #include "lib/json.hpp" @@ -10,7 +11,6 @@ class NetworkManager; #include #include #include -#define ConfigFileName "config.json" using json = nlohmann::json; @@ -18,18 +18,12 @@ class Server { private: std::unordered_map _playerLst; std::unordered_map _tempPlayerLst; - json _playerSample; - std::mutex _playerLock; - std::mutex _tempPlayerLock; - int _protocolVersion; - int _serverSize; - int loadConfig(); - std::string _gameVersion; - std::string _serverMOTD; - int _serverPort; - std::string _serverAddr; - NetworkManager* _networkManager; - IdManager _idManager; + json _playerSample; + std::mutex _playerLock; + std::mutex _tempPlayerLock; + Config _config; + NetworkManager* _networkManager; + IdManager _idManager; public: Server(); @@ -37,25 +31,20 @@ class Server { int start_server(); - int getProtocolVersion(); - int getServerSize(); - int getAmountOnline(); - std::string getGameVersion(); - std::string getServerMOTD(); - int getServerPort() { return _serverPort; } - std::string getServerAddr() { return _serverAddr; } + int getAmountOnline(); + Config& getConfig() { return _config; } std::unordered_map& getPlayerLst() { return _playerLst; } std::unordered_map& getTempPlayerLst() { return _tempPlayerLst; } - void addPlayerToSample(const std::string& name); - void removePlayerToSample(const std::string& name); - Player* addPlayer(const std::string& name, const PlayerState state, const int socket); - void removePlayer(Player* player); - Player* addTempPlayer(const std::string& name, const PlayerState state, const int socket); - void removeTempPlayer(Player* player); - void promoteTempPlayer(Player* player); - void removePlayerFromAnyList(Player* player); - json getPlayerSample(); + void addPlayerToSample(const std::string& name); + void removePlayerToSample(const std::string& name); + Player* addPlayer(const std::string& name, const PlayerState state, const int socket); + void removePlayer(Player* player); + Player* addTempPlayer(const std::string& name, const PlayerState state, const int socket); + void removeTempPlayer(Player* player); + void promoteTempPlayer(Player* player); + void removePlayerFromAnyList(Player* player); + json getPlayerSample(); IdManager& getIdManager() { return (_idManager); } NetworkManager& getNetworkManager() { return *_networkManager; } diff --git a/src/lib/config.cpp b/src/lib/config.cpp new file mode 100644 index 0000000..95b8597 --- /dev/null +++ b/src/lib/config.cpp @@ -0,0 +1,91 @@ +#include "config.hpp" +#include "lib/filesystem.hpp" +#include "lib/json.hpp" +#include "logger.hpp" + +#include +#include + +using json = nlohmann::json; + +Config::Config() { _execPath = getPath(); } + +bool Config::loadConfig() { + std::ifstream inputFile(_execPath.root_directory() / + "config.json"); // Should change the config path later if needed + + if (!inputFile.is_open()) { + g_logger->logGameInfo(DEBUG, "Error: Could not open: config.json", "SERVER"); + return true; + } + + json config; + + try { + inputFile >> config; + Config::setServerVersion(config["version"]["name"]); + Config::setProtocolVersion(config["version"]["protocol"]); + Config::setServerSize(config["server"]["max-players"]); + Config::setServerMotd(config["server"]["motd"]); + Config::setServerAddress(config["server"]["ip-address"]); + Config::setServerPort(config["server"]["port"]); + } catch (json::parse_error& e) { + g_logger->logGameInfo( + ERROR, "Error parsing config.json: " + std::string(e.what()), "SERVER"); + inputFile.close(); + return true; + } + inputFile.close(); + return false; +} + +bool Config::reloadConfig() { + std::ifstream inputFile(_execPath.root_directory() / + "config.json"); // Should change the config path later if needed + + if (!inputFile.is_open()) { + g_logger->logGameInfo(DEBUG, "Error: Could not open: config.json", "SERVER"); + return true; + } + + json config; + + try { + Config::setServerSize(config["server"]["max-players"]); + Config::setServerMotd(config["server"]["motd"]); + } catch (json::parse_error& e) { + g_logger->logGameInfo( + ERROR, "Error parsing config.json: " + std::string(e.what()), "SERVER"); + inputFile.close(); + return true; + } + return false; +} + +Config::~Config() {} + +// Getter methods +int Config::getServerPort() { return _serverPort; } + +int Config::getProtocolVersion() { return _protocolVersion; } + +int Config::getServerSize() { return _serverSize; } + +std::string Config::getVersion() { return _gameVersion; } + +std::string Config::getServerMotd() { return _serverMotd; } + +std::string Config::getServerAddress() { return _serverAddress; } + +// Setter methods +void Config::setProtocolVersion(int ProtoVersion) { _protocolVersion = ProtoVersion; } + +void Config::setServerSize(int ServerSize) { _serverSize = ServerSize; } + +void Config::setServerPort(int ServerPort) { _serverPort = ServerPort; } + +void Config::setServerMotd(std::string ServerMotd) { _serverMotd = ServerMotd; } + +void Config::setServerVersion(std::string ServerVersion) { _gameVersion = ServerVersion; } + +void Config::setServerAddress(std::string ServerAddress) { _serverAddress = ServerAddress; } diff --git a/src/networking/networkManager.cpp b/src/networking/networkManager.cpp index fe87237..2110cce 100644 --- a/src/networking/networkManager.cpp +++ b/src/networking/networkManager.cpp @@ -96,12 +96,13 @@ void NetworkManager::start() { struct sockaddr_in serverAddr; serverAddr.sin_family = AF_INET; - serverAddr.sin_port = htons(getServer().getServerPort()); + serverAddr.sin_port = htons(getServer().getConfig().getServerPort()); - if (strcmp(getServer().getServerAddr().c_str(), "0.0.0.0") == 0) { + if (strcmp(getServer().getConfig().getServerAddress().c_str(), "0.0.0.0") == 0) { serverAddr.sin_addr.s_addr = INADDR_ANY; } else { - if (inet_aton(getServer().getServerAddr().c_str(), &serverAddr.sin_addr) == 0) { + if (inet_aton(getServer().getConfig().getServerAddress().c_str(), &serverAddr.sin_addr) == + 0) { close(_serverSocket); throw std::runtime_error("Invalid IP address"); } @@ -110,8 +111,8 @@ void NetworkManager::start() { if (bind(_serverSocket, (struct sockaddr*)&serverAddr, sizeof(serverAddr)) < 0) { close(_serverSocket); throw std::runtime_error("Failed to bind socket to " + - std::string(getServer().getServerAddr()) + ":" + - std::to_string(getServer().getServerPort())); + std::string(getServer().getConfig().getServerAddress()) + ":" + + std::to_string(getServer().getConfig().getServerPort())); } if (listen(_serverSocket, SOMAXCONN) < 0) { diff --git a/src/networking/packet/status.cpp b/src/networking/packet/status.cpp index 3dc2ad6..31e88a1 100644 --- a/src/networking/packet/status.cpp +++ b/src/networking/packet/status.cpp @@ -1,5 +1,4 @@ #include "lib/json.hpp" -#include "logger.hpp" #include "network/buffer.hpp" #include "network/networking.hpp" #include "network/packet.hpp" @@ -18,13 +17,14 @@ void handleStatusPacket(Packet& packet, Server& server) { return; } - json jres = {{"version", - {{"name", server.getGameVersion()}, {"protocol", server.getProtocolVersion()}}}, + json jres = {{"version", + {{"name", server.getConfig().getVersion()}, + {"protocol", server.getConfig().getProtocolVersion()}}}, {"players", - {{"max", server.getServerSize()}, + {{"max", server.getConfig().getServerSize()}, {"online", server.getAmountOnline()}, {"sample", server.getPlayerSample()}}}, - {"description", {{"text", server.getServerMOTD()}}}}; + {"description", {{"text", server.getConfig().getServerMotd()}}}}; std::string payload = jres.dump(); int jsonLen = payload.size(); diff --git a/src/server.cpp b/src/server.cpp index 1441b71..ba51e6e 100644 --- a/src/server.cpp +++ b/src/server.cpp @@ -1,22 +1,19 @@ -#include "network/server.hpp" - +#include "config.hpp" #include "lib/json.hpp" #include "logger.hpp" #include "network/networking.hpp" +#include "network/server.hpp" #include "player.hpp" #include #include -#include #include #include #include using json = nlohmann::json; -Server::Server() - : _playerLst(), _protocolVersion(770), _serverSize(-100000000), _gameVersion("1.12.5"), - _serverMOTD(), _serverPort(25565), _serverAddr("0.0.0.0"), _networkManager(nullptr) {} +Server::Server() : _playerLst(), _config(), _networkManager(nullptr) {} Server::~Server() { if (_networkManager) { @@ -28,7 +25,10 @@ Server::~Server() { int Server::start_server() { try { initializeGlobalLogger(); - Server::loadConfig(); + if (_config.loadConfig()) { + g_logger->logGameInfo(ERROR, "Failed to load config", "SERVER"); + return 1; + } size_t workerCount = 4; if (workerCount == 0) workerCount = 4; // fallback @@ -48,41 +48,6 @@ int Server::start_server() { return (0); } -int Server::loadConfig() { - std::ifstream inputFile(ConfigFileName); - - if (!inputFile.is_open()) { - std::cerr << "[Server] Error: Could not open " << ConfigFileName << std::endl; - return 1; - } - - json j; - - try { - inputFile >> j; - - // g_logger->logGameInfo(INFO, "Successfully parsed " + std::string(ConfigFileName) + "!", - // "Server"); - _gameVersion = j["version"]["name"]; - // g_logger->logGameInfo(INFO, "Game version: " + _gameVersion, "Server"); - _protocolVersion = j["version"]["protocol"]; - // g_logger->logGameInfo(INFO, "Protocol version: " + std::to_string(_protocolVersion), - // "Server"); - _serverSize = j["server"]["max-players"]; - // g_logger->logGameInfo(INFO, "Server size: " + std::to_string(_serverSize), "Server"); - _serverMOTD = j["server"]["motd"]; - // g_logger->logGameInfo(INFO, "Server MOTD: " + _serverMOTD, "Server"); - _serverAddr = j["server"]["ip-address"]; - // g_logger->logGameInfo(INFO, "Server IP address : " + _serverAddr, "Server"); - _serverPort = j["server"]["port"]; - // g_logger->logGameInfo(INFO, "Server port: " + std::to_string(_serverPort), "Server"); - } catch (json::parse_error& e) { - std::cerr << "[Server]: Json parse error: " << e.what() << std::endl; - return (1); - } - return (0); -} - Player* Server::addPlayer(const std::string& name, const PlayerState state, const int socket) { Player* newPlayer = nullptr; try { @@ -130,7 +95,7 @@ void Server::removeTempPlayer(Player* player) { if (!player) { return; } - int socket = player->getSocketFd(); + int socket = player->getSocketFd(); std::lock_guard lock(_tempPlayerLock); _tempPlayerLst.erase(socket); delete player; @@ -160,7 +125,7 @@ void Server::removePlayerFromAnyList(Player* player) { { std::lock_guard lock(_tempPlayerLock); - auto temp_it = _tempPlayerLst.find(socket); + auto temp_it = _tempPlayerLst.find(socket); if (temp_it != _tempPlayerLst.end()) { _tempPlayerLst.erase(socket); delete player; @@ -172,7 +137,7 @@ void Server::removePlayerFromAnyList(Player* player) { { std::lock_guard lock(_playerLock); - auto main_it = _playerLst.find(socket); + auto main_it = _playerLst.find(socket); if (main_it != _playerLst.end()) { _playerLst.erase(socket); delete player; @@ -196,9 +161,5 @@ void Server::removePlayerToSample(const std::string& name) { } } -std::string Server::getGameVersion() { return _gameVersion; } -std::string Server::getServerMOTD() { return _serverMOTD; } -int Server::getProtocolVersion() { return _protocolVersion; } -int Server::getServerSize() { return _serverSize; } -int Server::getAmountOnline() { return _playerLst.size(); } +int Server::getAmountOnline() { return _playerLst.size(); } json Server::getPlayerSample() { return _playerSample; } From fec5b0d8fd30e80061f9f6e214f843ac4322462c Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" Date: Thu, 9 Oct 2025 20:17:38 +0000 Subject: [PATCH 12/27] Apply clang-format [skip ci] --- include/lib/UUID.hpp | 8 ++-- include/lib/nbt.hpp | 32 +++++++------- include/logger.hpp | 32 +++++++------- include/network/buffer.hpp | 26 ++++++------ include/network/id_manager.hpp | 10 ++--- include/network/networking.hpp | 26 ++++++------ include/network/packet.hpp | 32 +++++++------- include/player.hpp | 56 ++++++++++++------------- src/entities/player.cpp | 8 ++-- src/lib/MD5.cpp | 2 +- src/lib/UUID.cpp | 4 +- src/lib/buffer.cpp | 6 +-- src/lib/config.cpp | 1 + src/lib/fs.cpp | 2 +- src/lib/logger.cpp | 10 ++--- src/lib/packet.cpp | 22 +++++----- src/networking/networkQueuer.cpp | 12 +++--- src/networking/packet/chunkBatch.cpp | 2 +- src/networking/packet/handshake.cpp | 8 ++-- src/networking/packet/spawnSequence.cpp | 2 +- src/server.cpp | 3 +- 21 files changed, 153 insertions(+), 151 deletions(-) diff --git a/include/lib/UUID.hpp b/include/lib/UUID.hpp index e5599e1..cd8f823 100644 --- a/include/lib/UUID.hpp +++ b/include/lib/UUID.hpp @@ -19,13 +19,13 @@ class UUID { uint64_t getMostSigBits() const; uint64_t getLeastSigBits() const; - void setMostSigBits(uint64_t val); - void setLeastSigBits(uint64_t val); + void setMostSigBits(uint64_t val); + void setLeastSigBits(uint64_t val); std::string toString() const; - void readFromBuffer(Buffer& buf); - void writeToBuffer(Buffer& buf) const; + void readFromBuffer(Buffer& buf); + void writeToBuffer(Buffer& buf) const; static UUID fromOfflinePlayer(const std::string& name); }; diff --git a/include/lib/nbt.hpp b/include/lib/nbt.hpp index 02560c5..29c9180 100644 --- a/include/lib/nbt.hpp +++ b/include/lib/nbt.hpp @@ -58,16 +58,16 @@ namespace std { namespace nbt { // Basic NBT types - typedef std::nullptr_t TagEnd; - typedef std::int8_t TagByte; - typedef std::int16_t TagShort; - typedef std::int32_t TagInt; - typedef std::int64_t TagLong; - typedef float TagFloat; - typedef double TagDouble; - typedef std::string TagString; + typedef std::nullptr_t TagEnd; + typedef std::int8_t TagByte; + typedef std::int16_t TagShort; + typedef std::int32_t TagInt; + typedef std::int64_t TagLong; + typedef float TagFloat; + typedef double TagDouble; + typedef std::string TagString; typedef std::vector TagByteArray; - typedef std::vector TagIntArray; + typedef std::vector TagIntArray; typedef std::vector TagLongArray; // Forward declaration for recursive types @@ -166,11 +166,11 @@ namespace nbt { }; // Helper functions for creating tags - inline TagByte createByte(std::int8_t value) { return value; } - inline TagShort createShort(std::int16_t value) { return value; } - inline TagInt createInt(std::int32_t value) { return value; } - inline TagLong createLong(std::int64_t value) { return value; } - inline TagFloat createFloat(float value) { return value; } + inline TagByte createByte(std::int8_t value) { return value; } + inline TagShort createShort(std::int16_t value) { return value; } + inline TagInt createInt(std::int32_t value) { return value; } + inline TagLong createLong(std::int64_t value) { return value; } + inline TagFloat createFloat(float value) { return value; } inline TagDouble createDouble(double value) { return value; } inline TagString createString(const std::string& value) { return value; } @@ -185,10 +185,10 @@ namespace nbt { NBT(const std::string& name) : name(name) {} NBT(const std::string& name, const TagCompound& tags) : name(name), root(tags) {} - void setName(const std::string& n) { name = n; } + void setName(const std::string& n) { name = n; } std::string getName() const { return name; } - TagCompound& getRoot() { return root; } + TagCompound& getRoot() { return root; } const TagCompound& getRoot() const { return root; } void encode(std::ostream& os) const { root.encode(os); } diff --git a/include/logger.hpp b/include/logger.hpp index f396fcd..b39a3f0 100644 --- a/include/logger.hpp +++ b/include/logger.hpp @@ -15,38 +15,38 @@ enum LogCategory { NETWORK, GAMEINFO }; struct LogEntry { std::chrono::system_clock::time_point timestamp; - LogLevel level; - LogCategory category; - std::string message; - std::string source; + LogLevel level; + LogCategory category; + std::string message; + std::string source; }; class LogManager { private: std::filesystem::path _logDir; - std::ofstream _networkFile; - std::ofstream _gameInfoFile; - std::queue _logQueue; - std::mutex _queueMutex; - std::mutex _fileMutex; - std::thread _writerThread; - bool _running; + std::ofstream _networkFile; + std::ofstream _gameInfoFile; + std::queue _logQueue; + std::mutex _queueMutex; + std::mutex _fileMutex; + std::thread _writerThread; + bool _running; public: LogManager(); ~LogManager(); // Core logging methods - void log(LogLevel level, - LogCategory category, + void log(LogLevel level, + LogCategory category, const std::string& message, const std::string& source = ""); void logNetwork(LogLevel level, const std::string& message, const std::string& source = ""); void logGameInfo(LogLevel level, const std::string& message, const std::string& source = ""); private: - bool initializeLogDirectory(); - void writerThreadLoop(); + bool initializeLogDirectory(); + void writerThreadLoop(); std::string formatLogEntry(const LogEntry& entry); std::string getCurrentTimestamp(); std::string getDetailedTimestamp(); @@ -54,5 +54,5 @@ class LogManager { // Global logger instance extern std::unique_ptr g_logger; -void initializeGlobalLogger(); +void initializeGlobalLogger(); #endif diff --git a/include/network/buffer.hpp b/include/network/buffer.hpp index baa36a7..c55a28c 100644 --- a/include/network/buffer.hpp +++ b/include/network/buffer.hpp @@ -11,32 +11,32 @@ class Buffer { private: std::vector _data; - size_t _pos; + size_t _pos; public: Buffer(); explicit Buffer(const std::vector& data); - int readVarInt(); + int readVarInt(); void writeVarInt(int value); void writeInt(int32_t value); void writeIdentifierArray(const std::vector& ids); void writeUInt(uint32_t value); std::string readString(int maxLength); - void writeString(const std::string& str); + void writeString(const std::string& str); std::vector& getData(); - size_t remaining() const; - uint16_t readUShort(); - uint64_t readUInt64(); - long readLong(); - void writeLong(long value); - uint8_t readByte(); - void writeByte(uint8_t byte); - void writeBytes(const std::string& data); - void writeBytes(const std::vector& data); - void writeUUID(const UUID& uuid); + size_t remaining() const; + uint16_t readUShort(); + uint64_t readUInt64(); + long readLong(); + void writeLong(long value); + uint8_t readByte(); + void writeByte(uint8_t byte); + void writeBytes(const std::string& data); + void writeBytes(const std::vector& data); + void writeUUID(const UUID& uuid); void writeBool(bool value); void writeNBT(const std::string& nbtData); diff --git a/include/network/id_manager.hpp b/include/network/id_manager.hpp index 912ceef..39ade0b 100644 --- a/include/network/id_manager.hpp +++ b/include/network/id_manager.hpp @@ -8,7 +8,7 @@ class IdManager { private: - uint32_t _nextId; + uint32_t _nextId; std::set _freedIds; mutable std::mutex _mutex; @@ -17,10 +17,10 @@ class IdManager { ~IdManager(); uint32_t allocate(); - void release(uint32_t id); - size_t getAllocatedCount() const; - size_t getFreedCount() const; - void reset(); + void release(uint32_t id); + size_t getAllocatedCount() const; + size_t getFreedCount() const; + void reset(); }; #endif diff --git a/include/network/networking.hpp b/include/network/networking.hpp index 080b5e0..0d17eb7 100644 --- a/include/network/networking.hpp +++ b/include/network/networking.hpp @@ -20,8 +20,8 @@ class Server; template class ThreadSafeQueue { private: - std::queue _queue; - mutable std::mutex _mutex; + std::queue _queue; + mutable std::mutex _mutex; std::condition_variable _condition; public: @@ -71,17 +71,17 @@ class NetworkManager { ThreadSafeQueue _outgoingPackets; std::vector _workerThreads; - std::atomic _shutdownFlag; - std::thread _receiverThread; - std::thread _senderThread; - char _receiverThreadInit; - char _senderThreadInit; - Server& _server; - int _epollFd; - int _serverSocket; + std::atomic _shutdownFlag; + std::thread _receiverThread; + std::thread _senderThread; + char _receiverThreadInit; + char _senderThreadInit; + Server& _server; + int _epollFd; + int _serverSocket; public: - NetworkManager(size_t worker_count, + NetworkManager(size_t worker_count, Server& s); // Could use std::thread::hardware_concurrency() for the worker size; ~NetworkManager() { if (_epollFd != -1) { @@ -94,8 +94,8 @@ class NetworkManager { void stopThreads(); void shutdown(); - void addPlayerConnection(std::shared_ptr connection); - void removePlayerConnection(UUID id); + void addPlayerConnection(std::shared_ptr connection); + void removePlayerConnection(UUID id); ThreadSafeQueue* getOutgoingQueue() { return &_outgoingPackets; } Server& getServer() { return _server; } diff --git a/include/network/packet.hpp b/include/network/packet.hpp index 3817702..b344acd 100644 --- a/include/network/packet.hpp +++ b/include/network/packet.hpp @@ -14,10 +14,10 @@ class Packet { private: int32_t _size; int32_t _id; - Buffer _data; + Buffer _data; Player* _player; - int _socketFd; - int _returnPacket; + int _socketFd; + int _returnPacket; public: Packet(Player* player); @@ -25,21 +25,21 @@ class Packet { Packet(const Packet& other); Packet& operator=(const Packet& other); ~Packet(); - static int readVarint(int sock); - static int readVarint(int sock, int* bytesRead); + static int readVarint(int sock); + static int readVarint(int sock, int* bytesRead); static void writeVarint(int sock, int value); - static int varintLen(int value); + static int varintLen(int value); static bool isSocketValid(int sock); - Player* getPlayer() const; - uint32_t getSize(); - uint32_t getId(); - Buffer& getData(); - int getSocket() const; - void setReturnPacket(int value); - int getReturnPacket(); - int getVarintSize(int32_t value); - void setPacketSize(int32_t value); - void setPacketId(uint32_t value); + Player* getPlayer() const; + uint32_t getSize(); + uint32_t getId(); + Buffer& getData(); + int getSocket() const; + void setReturnPacket(int value); + int getReturnPacket(); + int getVarintSize(int32_t value); + void setPacketSize(int32_t value); + void setPacketId(uint32_t value); }; #endif diff --git a/include/player.hpp b/include/player.hpp index 55f0a62..a868e13 100644 --- a/include/player.hpp +++ b/include/player.hpp @@ -11,28 +11,28 @@ enum class PlayerState { None, Configuration, Handshake, Status, Login, Play }; class PlayerConfig { private: - int _chatMode; - int _mainHand; + int _chatMode; + int _mainHand; std::string _locale; - uint8_t _viewDistance; - uint8_t _displayedSkinParts; - bool _chatColors; - bool _enableTextFiltering; - bool _allowServerListings; + uint8_t _viewDistance; + uint8_t _displayedSkinParts; + bool _chatColors; + bool _enableTextFiltering; + bool _allowServerListings; public: PlayerConfig(); ~PlayerConfig(); // Getters - int getChatMode() const { return _chatMode; } - int getMainHand() const { return _mainHand; } + int getChatMode() const { return _chatMode; } + int getMainHand() const { return _mainHand; } std::string getLocale() const { return _locale; } - uint8_t getViewDistance() const { return _viewDistance; } - uint8_t getDisplayedSkinParts() const { return _displayedSkinParts; } - bool getChatColors() const { return _chatColors; } - bool getTextFiltering() const { return _enableTextFiltering; } - bool getServerListings() const { return _allowServerListings; } + uint8_t getViewDistance() const { return _viewDistance; } + uint8_t getDisplayedSkinParts() const { return _displayedSkinParts; } + bool getChatColors() const { return _chatColors; } + bool getTextFiltering() const { return _enableTextFiltering; } + bool getServerListings() const { return _allowServerListings; } // Setters void setChatMode(int mode) { _chatMode = mode; } @@ -47,14 +47,14 @@ class PlayerConfig { class Player { private: - std::string _name; - PlayerState _state; - int _socketFd; - int x, y, z; - int health; - UUID _uuid; - int _playerId; - Server& _server; + std::string _name; + PlayerState _state; + int _socketFd; + int x, y, z; + int health; + UUID _uuid; + int _playerId; + Server& _server; PlayerConfig* _config; public: @@ -64,16 +64,16 @@ class Player { ~Player(); std::string getPlayerName(void); - void setPlayerName(const std::string& name); + void setPlayerName(const std::string& name); PlayerState getPlayerState(); - void setPlayerState(PlayerState state); - void setSocketFd(int socket); - int getSocketFd() const; + void setPlayerState(PlayerState state); + void setSocketFd(int socket); + int getSocketFd() const; // Get PlayerConfig instance PlayerConfig* getPlayerConfig() { return _config; } - int getPlayerID() const; - void setUUID(UUID uuid); + int getPlayerID() const; + void setUUID(UUID uuid); }; #endif diff --git a/src/entities/player.cpp b/src/entities/player.cpp index 6bed5ee..6c9518f 100644 --- a/src/entities/player.cpp +++ b/src/entities/player.cpp @@ -37,11 +37,11 @@ Player::~Player() { } std::string Player::getPlayerName(void) { return (this->_name); }; -void Player::setPlayerName(const std::string& name) { this->_name = name; } +void Player::setPlayerName(const std::string& name) { this->_name = name; } PlayerState Player::getPlayerState() { return (this->_state); } -void Player::setPlayerState(PlayerState state) { this->_state = state; } -void Player::setSocketFd(int socket) { this->_socketFd = socket; } -int Player::getSocketFd() const { return (this->_socketFd); } +void Player::setPlayerState(PlayerState state) { this->_state = state; } +void Player::setSocketFd(int socket) { this->_socketFd = socket; } +int Player::getSocketFd() const { return (this->_socketFd); } void Player::setUUID(UUID uuid) { _uuid = uuid; } diff --git a/src/lib/MD5.cpp b/src/lib/MD5.cpp index 22cdbf1..c352fad 100644 --- a/src/lib/MD5.cpp +++ b/src/lib/MD5.cpp @@ -64,7 +64,7 @@ std::vector MD5::hash(const std::string& input) { // résultat en octets (little-endian) std::vector digest(16); - uint32_t state[4] = {A, B, C, D}; + uint32_t state[4] = {A, B, C, D}; for (int i = 0; i < 4; i++) { digest[i * 4] = state[i] & 0xFF; digest[i * 4 + 1] = (state[i] >> 8) & 0xFF; diff --git a/src/lib/UUID.cpp b/src/lib/UUID.cpp index 5c6732e..0ff6b1f 100644 --- a/src/lib/UUID.cpp +++ b/src/lib/UUID.cpp @@ -16,8 +16,8 @@ UUID::~UUID() {} uint64_t UUID::getMostSigBits() const { return _mostSigBits; } uint64_t UUID::getLeastSigBits() const { return _leastSigBits; } -void UUID::setMostSigBits(uint64_t val) { _mostSigBits = val; } -void UUID::setLeastSigBits(uint64_t val) { _leastSigBits = val; } +void UUID::setMostSigBits(uint64_t val) { _mostSigBits = val; } +void UUID::setLeastSigBits(uint64_t val) { _leastSigBits = val; } std::string UUID::toString() const { std::stringstream ss; diff --git a/src/lib/buffer.cpp b/src/lib/buffer.cpp index 0453bc1..6b0f645 100644 --- a/src/lib/buffer.cpp +++ b/src/lib/buffer.cpp @@ -35,7 +35,7 @@ void Buffer::writeUUID(const UUID& uuid) { } int Buffer::readVarInt() { - int value = 0, position = 0; + int value = 0, position = 0; uint8_t currentByte; do { @@ -145,7 +145,7 @@ void Buffer::writePosition(int32_t x, int32_t y, int32_t z) { void Buffer::writeFloat(float value) { union { - float f; + float f; uint32_t i; } u; u.f = value; @@ -154,7 +154,7 @@ void Buffer::writeFloat(float value) { void Buffer::writeDouble(double value) { union { - double d; + double d; uint64_t i; } u; u.d = value; diff --git a/src/lib/config.cpp b/src/lib/config.cpp index 95b8597..06deaaf 100644 --- a/src/lib/config.cpp +++ b/src/lib/config.cpp @@ -1,4 +1,5 @@ #include "config.hpp" + #include "lib/filesystem.hpp" #include "lib/json.hpp" #include "logger.hpp" diff --git a/src/lib/fs.cpp b/src/lib/fs.cpp index 64c3133..ea6f364 100644 --- a/src/lib/fs.cpp +++ b/src/lib/fs.cpp @@ -6,7 +6,7 @@ #include std::filesystem::path getPath() { - char buffer[PATH_MAX]; + char buffer[PATH_MAX]; ssize_t len = readlink("/proc/self/exe", buffer, sizeof(buffer) - 1); if (len != -1) { buffer[len] = '\0'; diff --git a/src/lib/logger.cpp b/src/lib/logger.cpp index a52e47a..08b6cb2 100644 --- a/src/lib/logger.cpp +++ b/src/lib/logger.cpp @@ -109,8 +109,8 @@ bool LogManager::initializeLogDirectory() { return true; } -void LogManager::log(LogLevel level, - LogCategory category, +void LogManager::log(LogLevel level, + LogCategory category, const std::string& message, const std::string& source) { LogEntry entry; @@ -137,7 +137,7 @@ void LogManager::logNetwork(LogLevel level, const std::string& message, const st log(level, NETWORK, message, source); } -void LogManager::logGameInfo(LogLevel level, +void LogManager::logGameInfo(LogLevel level, const std::string& message, const std::string& source) { log(level, GAMEINFO, message, source); @@ -146,7 +146,7 @@ void LogManager::logGameInfo(LogLevel level, void LogManager::writerThreadLoop() { while (_running || !_logQueue.empty()) { LogEntry entry; - bool hasEntry = false; + bool hasEntry = false; // Get entry from queue { @@ -161,7 +161,7 @@ void LogManager::writerThreadLoop() { if (hasEntry) { // Write to appropriate file std::lock_guard fileLock(_fileMutex); - std::string formattedEntry = formatLogEntry(entry); + std::string formattedEntry = formatLogEntry(entry); if (entry.category == NETWORK && _networkFile.is_open()) { _networkFile << formattedEntry << std::endl; diff --git a/src/lib/packet.cpp b/src/lib/packet.cpp index 8f2e38e..10d7541 100644 --- a/src/lib/packet.cpp +++ b/src/lib/packet.cpp @@ -62,7 +62,7 @@ Packet::Packet(Player* player) : _player(player), _socketFd(-1), _returnPacket(0 if (remaining < 0) throw std::runtime_error("Invalid packet size"); if (remaining > 0) { std::vector tmp(remaining); - ssize_t totalRead = 0; + ssize_t totalRead = 0; while (totalRead < remaining) { ssize_t bytesRead = ::read(_socketFd, tmp.data() + totalRead, remaining - totalRead); @@ -110,7 +110,7 @@ Packet::Packet(int socketFd, Server& server) if (remaining > 0) { std::vector tmp(remaining); - ssize_t totalRead = 0; + ssize_t totalRead = 0; while (totalRead < remaining) { ssize_t bytesRead = ::read(_socketFd, tmp.data() + totalRead, remaining - totalRead); @@ -151,9 +151,9 @@ int Packet::readVarint(int sock, int* bytesRead) { return -1; } - int value = 0, position = 0; + int value = 0, position = 0; uint8_t byte; - int localBytesRead = 0; + int localBytesRead = 0; while (true) { ssize_t result = ::read(sock, &byte, 1); @@ -196,7 +196,7 @@ int Packet::readVarint(int sock) { return readVarint(sock, nullptr); } void Packet::writeVarint(int sock, int value) { std::vector tmp; - Buffer buf(tmp); + Buffer buf(tmp); buf.writeVarInt(value); (void)!::write(sock, buf.getData().data(), buf.getData().size()); } @@ -227,7 +227,7 @@ bool Packet::isSocketValid(int sock) { } void Packet::setReturnPacket(int value) { this->_returnPacket = value; } -int Packet::getReturnPacket() { return (this->_returnPacket); } +int Packet::getReturnPacket() { return (this->_returnPacket); } int Packet::varintLen(int value) { int len = 0; @@ -238,10 +238,10 @@ int Packet::varintLen(int value) { return (len); } -Player* Packet::getPlayer() const { return (_player); } +Player* Packet::getPlayer() const { return (_player); } uint32_t Packet::getSize() { return (_size); } uint32_t Packet::getId() { return (_id); } -Buffer& Packet::getData() { return (_data); } -int Packet::getSocket() const { return (_socketFd); }; -void Packet::setPacketSize(int32_t value) { _size = value; } -void Packet::setPacketId(uint32_t value) { _id = value; } +Buffer& Packet::getData() { return (_data); } +int Packet::getSocket() const { return (_socketFd); }; +void Packet::setPacketSize(int32_t value) { _size = value; } +void Packet::setPacketId(uint32_t value) { _id = value; } diff --git a/src/networking/networkQueuer.cpp b/src/networking/networkQueuer.cpp index 8674d7b..6ae7d5a 100644 --- a/src/networking/networkQueuer.cpp +++ b/src/networking/networkQueuer.cpp @@ -16,7 +16,7 @@ #include void NetworkManager::receiverThreadLoop() { - const int MaxEvent = 256; + const int MaxEvent = 256; epoll_event events[MaxEvent]; while (!_shutdownFlag.load()) { @@ -28,13 +28,13 @@ void NetworkManager::receiverThreadLoop() { } for (int i = 0; i < eventCount; i++) { - int fd = events[i].data.fd; + int fd = events[i].data.fd; uint32_t eventFlags = events[i].events; if (fd == _serverSocket) { sockaddr_in client_addr{}; - socklen_t addr_len = sizeof(client_addr); - int client_fd = accept(_serverSocket, (sockaddr*)&client_addr, &addr_len); + socklen_t addr_len = sizeof(client_addr); + int client_fd = accept(_serverSocket, (sockaddr*)&client_addr, &addr_len); if (client_fd != -1) { // g_logger->logNetwork(INFO, "New connection accepted on socket " + // std::to_string(client_fd), "Network Manager"); @@ -50,8 +50,8 @@ void NetworkManager::receiverThreadLoop() { continue; } - auto it = getServer().getPlayerLst().find(fd); - Player* p = nullptr; + auto it = getServer().getPlayerLst().find(fd); + Player* p = nullptr; if (it != getServer().getPlayerLst().end()) { p = it->second; } else { diff --git a/src/networking/packet/chunkBatch.cpp b/src/networking/packet/chunkBatch.cpp index 4a2be77..cce29ad 100644 --- a/src/networking/packet/chunkBatch.cpp +++ b/src/networking/packet/chunkBatch.cpp @@ -55,7 +55,7 @@ void sendChunkBatchFinished(Packet& packet, Server& server, int batchSize) { } void sendChunkBatchSequence(Packet& packet, Server& server) { - Player* player = packet.getPlayer(); + Player* player = packet.getPlayer(); ThreadSafeQueue* outgoingPackets = server.getNetworkManager().getOutgoingQueue(); if (!player || !outgoingPackets) return; diff --git a/src/networking/packet/handshake.cpp b/src/networking/packet/handshake.cpp index bff9ca5..f44ab58 100644 --- a/src/networking/packet/handshake.cpp +++ b/src/networking/packet/handshake.cpp @@ -13,10 +13,10 @@ void handleHandshakePacket(Packet& packet, Server& server) { packet.setReturnPacket(PACKET_DISCONNECT); return; } - int protocolVersion = packet.getData().readVarInt(); - std::string serverAddr = packet.getData().readString(255); - uint16_t port = packet.getData().readUShort(); - int nextState = packet.getData().readVarInt(); + int protocolVersion = packet.getData().readVarInt(); + std::string serverAddr = packet.getData().readString(255); + uint16_t port = packet.getData().readUShort(); + int nextState = packet.getData().readVarInt(); // g_logger->logNetwork(INFO, "Protocol=" + std::to_string(protocolVersion) + ", Addr=" + // serverAddr + ", State=" + std::to_string(nextState), "Handshake"); if (nextState == 1) { diff --git a/src/networking/packet/spawnSequence.cpp b/src/networking/packet/spawnSequence.cpp index 1ce86b4..ca9044a 100644 --- a/src/networking/packet/spawnSequence.cpp +++ b/src/networking/packet/spawnSequence.cpp @@ -176,7 +176,7 @@ void handleConfirmTeleportation(Packet& packet, Server& server) { } void completeSpawnSequence(Packet& packet, Server& server) { - Player* player = packet.getPlayer(); + Player* player = packet.getPlayer(); ThreadSafeQueue* outgoingPackets = server.getNetworkManager().getOutgoingQueue(); if (!player || !outgoingPackets) return; diff --git a/src/server.cpp b/src/server.cpp index ba51e6e..3ecdadd 100644 --- a/src/server.cpp +++ b/src/server.cpp @@ -1,8 +1,9 @@ +#include "network/server.hpp" + #include "config.hpp" #include "lib/json.hpp" #include "logger.hpp" #include "network/networking.hpp" -#include "network/server.hpp" #include "player.hpp" #include From ef75fff62bdfce33d02c6084f38b3912cc8fb69f Mon Sep 17 00:00:00 2001 From: Antoine Mathie Date: Fri, 10 Oct 2025 00:07:30 +0200 Subject: [PATCH 13/27] feat: configuration changes --- config.json | 25 +++++++++++++++---------- include/config.hpp | 27 +++++++++++++++++++++------ src/lib/config.cpp | 27 +++++++++++++++++++++++++-- src/server.cpp | 13 +++++++++---- 4 files changed, 70 insertions(+), 22 deletions(-) diff --git a/config.json b/config.json index 27204e7..6e2b30b 100644 --- a/config.json +++ b/config.json @@ -1,12 +1,17 @@ { - "version": { - "name": "1.21.5", - "protocol": 770 - }, - "server": { - "ip-address": "127.0.0.1", - "port": 25565, - "motd": "§aServeur Minecraft en C!", - "max-players": 20 - } + "version": { + "name": "1.21.5", + "protocol": 770 + }, + "server": { + "ip-address": "127.0.0.1", + "port": 25565, + "motd": "§aServeur Minecraft en C!", + "max-players": 20 + }, + "world": { + "name": "world", + "gamemode": "survival", + "difficulty": "normal" + } } diff --git a/include/config.hpp b/include/config.hpp index bf72abc..5b022a7 100644 --- a/include/config.hpp +++ b/include/config.hpp @@ -7,12 +7,21 @@ class Config { private: std::filesystem::path _execPath; - std::string _gameVersion; - std::string _serverMotd; - std::string _serverAddress; - int _serverPort; - int _protocolVersion; - int _serverSize; + + // Version Config + std::string _gameVersion; + int _protocolVersion; + + // Server Config + std::string _serverMotd; + std::string _serverAddress; + int _serverPort; + int _serverSize; + + // World Config + std::string _worldName; + std::string _gamemode; + std::string _difficulty; public: Config(); @@ -26,6 +35,9 @@ class Config { std::string getVersion(); std::string getServerMotd(); std::string getServerAddress(); + std::string getWorldName(); + std::string getGamemode(); + std::string getDifficulty(); void setProtocolVersion(int ProtoVersion); void setServerSize(int ServerSize); @@ -33,6 +45,9 @@ class Config { void setServerMotd(std::string ServerMotd); void setServerVersion(std::string ServerVersion); void setServerAddress(std::string ServerAddress); + void setWorldName(std::string WorldName); + void setGamemode(std::string Gamemode); + void setDifficulty(std::string Difficulty); }; #endif diff --git a/src/lib/config.cpp b/src/lib/config.cpp index 06deaaf..8378761 100644 --- a/src/lib/config.cpp +++ b/src/lib/config.cpp @@ -1,5 +1,4 @@ #include "config.hpp" - #include "lib/filesystem.hpp" #include "lib/json.hpp" #include "logger.hpp" @@ -9,7 +8,10 @@ using json = nlohmann::json; -Config::Config() { _execPath = getPath(); } +Config::Config() + : _execPath(getPath()), _gameVersion("1.21.5"), _protocolVersion(770), + _serverMotd("A Minecraft Server"), _serverAddress("127.0.0.1"), _serverPort(25565), + _serverSize(20), _worldName("world"), _gamemode("survival"), _difficulty("normal") {} bool Config::loadConfig() { std::ifstream inputFile(_execPath.root_directory() / @@ -30,6 +32,9 @@ bool Config::loadConfig() { Config::setServerMotd(config["server"]["motd"]); Config::setServerAddress(config["server"]["ip-address"]); Config::setServerPort(config["server"]["port"]); + Config::setWorldName(config["world"]["name"]); + Config::setGamemode(config["world"]["gamemode"]); + Config::setDifficulty(config["world"]["difficulty"]); } catch (json::parse_error& e) { g_logger->logGameInfo( ERROR, "Error parsing config.json: " + std::string(e.what()), "SERVER"); @@ -52,8 +57,14 @@ bool Config::reloadConfig() { json config; try { + inputFile >> config; + // Reload server settings that can be changed at runtime Config::setServerSize(config["server"]["max-players"]); Config::setServerMotd(config["server"]["motd"]); + + // Reload world settings that can be changed at runtime + Config::setGamemode(config["world"]["gamemode"]); + Config::setDifficulty(config["world"]["difficulty"]); } catch (json::parse_error& e) { g_logger->logGameInfo( ERROR, "Error parsing config.json: " + std::string(e.what()), "SERVER"); @@ -78,6 +89,12 @@ std::string Config::getServerMotd() { return _serverMotd; } std::string Config::getServerAddress() { return _serverAddress; } +std::string Config::getWorldName() { return _worldName; } + +std::string Config::getGamemode() { return _gamemode; } + +std::string Config::getDifficulty() { return _difficulty; } + // Setter methods void Config::setProtocolVersion(int ProtoVersion) { _protocolVersion = ProtoVersion; } @@ -90,3 +107,9 @@ void Config::setServerMotd(std::string ServerMotd) { _serverMotd = ServerMotd; } void Config::setServerVersion(std::string ServerVersion) { _gameVersion = ServerVersion; } void Config::setServerAddress(std::string ServerAddress) { _serverAddress = ServerAddress; } + +void Config::setWorldName(std::string WorldName) { _worldName = WorldName; } + +void Config::setGamemode(std::string Gamemode) { _gamemode = Gamemode; } + +void Config::setDifficulty(std::string Difficulty) { _difficulty = Difficulty; } diff --git a/src/server.cpp b/src/server.cpp index 3ecdadd..ba4fa7a 100644 --- a/src/server.cpp +++ b/src/server.cpp @@ -1,9 +1,8 @@ -#include "network/server.hpp" - #include "config.hpp" #include "lib/json.hpp" #include "logger.hpp" #include "network/networking.hpp" +#include "network/server.hpp" #include "player.hpp" #include @@ -162,5 +161,11 @@ void Server::removePlayerToSample(const std::string& name) { } } -int Server::getAmountOnline() { return _playerLst.size(); } -json Server::getPlayerSample() { return _playerSample; } +std::string Server::getGameVersion() { return _config.getVersion(); } +std::string Server::getServerMOTD() { return _config.getServerMotd(); } +std::string Server::getServerAddr() { return _config.getServerAddress(); } +int Server::getServerPort() { return _config.getServerPort(); } +int Server::getProtocolVersion() { return _config.getProtocolVersion(); } +int Server::getServerSize() { return _config.getServerSize(); } +int Server::getAmountOnline() { return _playerLst.size(); } +json Server::getPlayerSample() { return _playerSample; } From 5971b48953ade43ee318ac751de1ab7ed75c02cb Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" Date: Thu, 9 Oct 2025 22:09:14 +0000 Subject: [PATCH 14/27] Apply clang-format [skip ci] --- src/lib/config.cpp | 1 + src/server.cpp | 3 ++- 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/src/lib/config.cpp b/src/lib/config.cpp index 8378761..717dfb9 100644 --- a/src/lib/config.cpp +++ b/src/lib/config.cpp @@ -1,4 +1,5 @@ #include "config.hpp" + #include "lib/filesystem.hpp" #include "lib/json.hpp" #include "logger.hpp" diff --git a/src/server.cpp b/src/server.cpp index ba4fa7a..4d020a5 100644 --- a/src/server.cpp +++ b/src/server.cpp @@ -1,8 +1,9 @@ +#include "network/server.hpp" + #include "config.hpp" #include "lib/json.hpp" #include "logger.hpp" #include "network/networking.hpp" -#include "network/server.hpp" #include "player.hpp" #include From f026f64ee91563de498cc2d8c8b2c205df118221 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Antoine=20Mathi=C3=A9?= Date: Fri, 10 Oct 2025 14:38:37 +0200 Subject: [PATCH 15/27] fix: Now using getPath() to get the executable parent path --- Makefile | 19 +++++++--- include/world/core.hpp | 20 +++++++++++ include/world/worldManager.hpp | 3 +- src/lib/config.cpp | 3 +- src/lib/logger.cpp | 3 +- src/server.cpp | 13 ++----- src/world/worldManager.cpp | 63 +++++++++++++++++++++------------- 7 files changed, 83 insertions(+), 41 deletions(-) create mode 100644 include/world/core.hpp diff --git a/Makefile b/Makefile index af546ad..069aaa4 100644 --- a/Makefile +++ b/Makefile @@ -22,7 +22,7 @@ INCLUDE_FLAGS := -I$(INCLUDE_DIR) # Linker flags (add your libraries here) LDFLAGS := -LIBS := +LIBS := -lz # ================================ COLOR SETUP =============================== # ANSI color codes for beautiful output @@ -82,7 +82,7 @@ else endif # ================================= TARGETS ================================== -.PHONY: all clean debug release info help run install uninstall compile_commands +.PHONY: all clean distclean debug release info help run install uninstall compile_commands # Default target all: info $(TARGET) @@ -129,8 +129,18 @@ $(DEPS_DIR): # Clean build artifacts clean: @printf "$(BOLD)$(BRIGHT_RED)🧹 Cleaning build artifacts...$(RESET)\n" + @find $(BUILD_DIR) -type f -name "*.o" -delete 2>/dev/null || true + @find $(BUILD_DIR) -name "$(TARGET_NAME)" -delete 2>/dev/null || true + @find $(BUILD_DIR) -type d -empty -delete 2>/dev/null || true + @find $(DEPS_DIR) -type f -name "*.d" -delete 2>/dev/null || true + @find $(DEPS_DIR) -type d -empty -delete 2>/dev/null || true + @printf "$(BOLD)$(BRIGHT_GREEN)✨ Clean completed! (Preserved directories and config.json)$(RESET)\n" + +# Complete clean - removes everything including directories +distclean: + @printf "$(BOLD)$(BRIGHT_RED)🧹 Complete cleanup (removing all build artifacts and directories)...$(RESET)\n" @rm -rf $(BUILD_DIR) $(DEPS_DIR) - @printf "$(BOLD)$(BRIGHT_GREEN)✨ Clean completed!$(RESET)\n" + @printf "$(BOLD)$(BRIGHT_GREEN)✨ Complete cleanup finished!$(RESET)\n" # Run the executable run: $(TARGET) @@ -190,7 +200,8 @@ help: @printf "$(BOLD)$(BRIGHT_CYAN)║$(RESET) $(BRIGHT_GREEN)%-10s$(RESET) %-39s $(BOLD)$(BRIGHT_CYAN) ║$(RESET)\n" "all" "Build the project (default: release mode)" @printf "$(BOLD)$(BRIGHT_CYAN)║$(RESET) $(BRIGHT_GREEN)%-10s$(RESET) %-39s $(BOLD)$(BRIGHT_CYAN) ║$(RESET)\n" "debug" "Build in debug mode" @printf "$(BOLD)$(BRIGHT_CYAN)║$(RESET) $(BRIGHT_GREEN)%-10s$(RESET) %-39s $(BOLD)$(BRIGHT_CYAN) ║$(RESET)\n" "release" "Build in release mode" - @printf "$(BOLD)$(BRIGHT_CYAN)║$(RESET) $(BRIGHT_GREEN)%-10s$(RESET) %-39s $(BOLD)$(BRIGHT_CYAN) ║$(RESET)\n" "clean" "Remove all build artifacts" + @printf "$(BOLD)$(BRIGHT_CYAN)║$(RESET) $(BRIGHT_GREEN)%-10s$(RESET) %-39s $(BOLD)$(BRIGHT_CYAN) ║$(RESET)\n" "clean" "Remove build artifacts (preserve dirs)" + @printf "$(BOLD)$(BRIGHT_CYAN)║$(RESET) $(BRIGHT_GREEN)%-10s$(RESET) %-39s $(BOLD)$(BRIGHT_CYAN) ║$(RESET)\n" "distclean" "Remove all build artifacts and dirs" @printf "$(BOLD)$(BRIGHT_CYAN)║$(RESET) $(BRIGHT_GREEN)%-10s$(RESET) %-39s $(BOLD)$(BRIGHT_CYAN) ║$(RESET)\n" "run" "Build and run the executable" @printf "$(BOLD)$(BRIGHT_CYAN)║$(RESET) $(BRIGHT_GREEN)%-10s$(RESET) %-39s $(BOLD)$(BRIGHT_CYAN) ║$(RESET)\n" "compile_commands" "Generate compile_commands.json for LSP" @printf "$(BOLD)$(BRIGHT_CYAN)║$(RESET) $(BRIGHT_GREEN)%-10s$(RESET) %-39s $(BOLD)$(BRIGHT_CYAN) ║$(RESET)\n" "install" "Install the executable to system" diff --git a/include/world/core.hpp b/include/world/core.hpp new file mode 100644 index 0000000..7226fd7 --- /dev/null +++ b/include/world/core.hpp @@ -0,0 +1,20 @@ +#ifndef CORE_HPP +#define CORE_HPP + +#include +// ============================================================================ +// CORE DATA TYPES +// ============================================================================ + +enum class ChunkState : uint8_t { + UNLOADED = 0, // Not in memory + LOADING, // Background I/O in progress + CACHED, // In cache but no active in simulation + ACTIVATING, // Being conveted to LiveChunk + ACTIVE, // Active in simulation + DIRTY, // Active and modified + SAVING, // Being saved to disk + EVICTING // Being removed from memory +}; + +#endif diff --git a/include/world/worldManager.hpp b/include/world/worldManager.hpp index 9ae1b5a..fae1fc6 100644 --- a/include/world/worldManager.hpp +++ b/include/world/worldManager.hpp @@ -2,13 +2,14 @@ #define WORLD_MANAGER_HPP #include +#include #include #include class WorldManager { private: public: - std::vector decompressGzip(const std::vector& compressed); + std::vector decompressGzip(std::filesystem::path compressedFilePath); }; #endif diff --git a/src/lib/config.cpp b/src/lib/config.cpp index 717dfb9..493d0d1 100644 --- a/src/lib/config.cpp +++ b/src/lib/config.cpp @@ -1,5 +1,4 @@ #include "config.hpp" - #include "lib/filesystem.hpp" #include "lib/json.hpp" #include "logger.hpp" @@ -15,7 +14,7 @@ Config::Config() _serverSize(20), _worldName("world"), _gamemode("survival"), _difficulty("normal") {} bool Config::loadConfig() { - std::ifstream inputFile(_execPath.root_directory() / + std::ifstream inputFile(_execPath.parent_path() / "config.json"); // Should change the config path later if needed if (!inputFile.is_open()) { diff --git a/src/lib/logger.cpp b/src/lib/logger.cpp index 08b6cb2..d78d081 100644 --- a/src/lib/logger.cpp +++ b/src/lib/logger.cpp @@ -1,3 +1,4 @@ +#include "lib/filesystem.hpp" #include "logger.hpp" #include @@ -66,7 +67,7 @@ bool LogManager::initializeLogDirectory() { std::string timestamp = getCurrentTimestamp(); // Create base logs directory - fs::path baseLogsDir = "logs"; + fs::path baseLogsDir = getPath().parent_path() / "logs"; if (!fs::exists(baseLogsDir)) { if (!fs::create_directories(baseLogsDir)) { std::cerr << "Failed to create base logs directory: " << baseLogsDir << std::endl; diff --git a/src/server.cpp b/src/server.cpp index 4d020a5..ba51e6e 100644 --- a/src/server.cpp +++ b/src/server.cpp @@ -1,9 +1,8 @@ -#include "network/server.hpp" - #include "config.hpp" #include "lib/json.hpp" #include "logger.hpp" #include "network/networking.hpp" +#include "network/server.hpp" #include "player.hpp" #include @@ -162,11 +161,5 @@ void Server::removePlayerToSample(const std::string& name) { } } -std::string Server::getGameVersion() { return _config.getVersion(); } -std::string Server::getServerMOTD() { return _config.getServerMotd(); } -std::string Server::getServerAddr() { return _config.getServerAddress(); } -int Server::getServerPort() { return _config.getServerPort(); } -int Server::getProtocolVersion() { return _config.getProtocolVersion(); } -int Server::getServerSize() { return _config.getServerSize(); } -int Server::getAmountOnline() { return _playerLst.size(); } -json Server::getPlayerSample() { return _playerSample; } +int Server::getAmountOnline() { return _playerLst.size(); } +json Server::getPlayerSample() { return _playerSample; } diff --git a/src/world/worldManager.cpp b/src/world/worldManager.cpp index 0e01375..5c226b4 100644 --- a/src/world/worldManager.cpp +++ b/src/world/worldManager.cpp @@ -1,40 +1,57 @@ #include "world/worldManager.hpp" +#include #include +#include +#include +#include +#include +#include +#include #include +#include #include #include #include -std::vector WorldManager::decompressGzip(const std::vector& compressed) { - z_stream stream{}; - stream.avail_in = compressed.size(); - stream.next_in = reinterpret_cast(const_cast(compressed.data())); - stream.zalloc = Z_NULL; - stream.zfree = Z_NULL; - stream.opaque = Z_NULL; - - int ret = inflateInit2(&stream, 15 + 32); - if (ret != Z_OK) { - throw std::runtime_error("Failed to initialize zlib"); +std::vector WorldManager::decompressGzip(std::filesystem::path compressedFilePath) { + // Read file into memory + std::ifstream file(compressedFilePath, std::ios::binary); + if (!file) { + throw std::runtime_error("Could not open file: " + compressedFilePath.string()); } - std::vector decompressed; - decompressed.resize(compressed.size() * 2); + std::vector compressed((std::istreambuf_iterator(file)), + std::istreambuf_iterator()); + file.close(); - do { - stream.avail_out = decompressed.size(); - stream.next_out = reinterpret_cast(decompressed.data()); + // Initialize zlib stream + z_stream stream; + std::memset(&stream, 0, sizeof(stream)); - ret = inflate(&stream, Z_NO_FLUSH); - if (ret == Z_NEED_DICT || ret == Z_DATA_ERROR || ret == Z_MEM_ERROR) { - inflateEnd(&stream); - throw std::runtime_error("Failed to decompress data"); - } + // 16 + MAX_WBITS tells zlib to decode gzip format + if (inflateInit2(&stream, 16 + MAX_WBITS) != Z_OK) { + throw std::runtime_error("Failed to initialize gzip decompression"); + } + + // Allocate output buffer (level.dat is usually < 10MB) + std::vector decompressed(10 * 1024 * 1024); + + stream.avail_in = compressed.size(); + stream.next_in = compressed.data(); + stream.avail_out = decompressed.size(); + stream.next_out = decompressed.data(); - decompressed.resize(stream.total_out); - } while (ret == Z_OK); + int ret = inflate(&stream, Z_FINISH); + if (ret != Z_STREAM_END) { + inflateEnd(&stream); + throw std::runtime_error("Decompression failed: " + std::to_string(ret)); + } + + // Resize to actual decompressed size + decompressed.resize(stream.total_out); inflateEnd(&stream); + return decompressed; } From fb7e0fa3386c0b65ee652ebd67bbfddaea53464b Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" Date: Fri, 10 Oct 2025 12:40:03 +0000 Subject: [PATCH 16/27] Apply clang-format [skip ci] --- include/world/core.hpp | 16 ++++++++-------- src/lib/config.cpp | 1 + src/lib/logger.cpp | 3 ++- src/server.cpp | 3 ++- 4 files changed, 13 insertions(+), 10 deletions(-) diff --git a/include/world/core.hpp b/include/world/core.hpp index 7226fd7..8d660d9 100644 --- a/include/world/core.hpp +++ b/include/world/core.hpp @@ -7,14 +7,14 @@ // ============================================================================ enum class ChunkState : uint8_t { - UNLOADED = 0, // Not in memory - LOADING, // Background I/O in progress - CACHED, // In cache but no active in simulation - ACTIVATING, // Being conveted to LiveChunk - ACTIVE, // Active in simulation - DIRTY, // Active and modified - SAVING, // Being saved to disk - EVICTING // Being removed from memory + UNLOADED = 0, // Not in memory + LOADING, // Background I/O in progress + CACHED, // In cache but no active in simulation + ACTIVATING, // Being conveted to LiveChunk + ACTIVE, // Active in simulation + DIRTY, // Active and modified + SAVING, // Being saved to disk + EVICTING // Being removed from memory }; #endif diff --git a/src/lib/config.cpp b/src/lib/config.cpp index 493d0d1..a81c821 100644 --- a/src/lib/config.cpp +++ b/src/lib/config.cpp @@ -1,4 +1,5 @@ #include "config.hpp" + #include "lib/filesystem.hpp" #include "lib/json.hpp" #include "logger.hpp" diff --git a/src/lib/logger.cpp b/src/lib/logger.cpp index d78d081..26e8b82 100644 --- a/src/lib/logger.cpp +++ b/src/lib/logger.cpp @@ -1,6 +1,7 @@ -#include "lib/filesystem.hpp" #include "logger.hpp" +#include "lib/filesystem.hpp" + #include #include #include diff --git a/src/server.cpp b/src/server.cpp index ba51e6e..3ecdadd 100644 --- a/src/server.cpp +++ b/src/server.cpp @@ -1,8 +1,9 @@ +#include "network/server.hpp" + #include "config.hpp" #include "lib/json.hpp" #include "logger.hpp" #include "network/networking.hpp" -#include "network/server.hpp" #include "player.hpp" #include From e10f463cd9c262bba4f2a77304c8dcea2b125b86 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Antoine=20Mathi=C3=A9?= Date: Fri, 10 Oct 2025 17:14:15 +0200 Subject: [PATCH 17/27] feat: Gzip decompress, can now load level.dat --- include/lib/nbt.hpp | 1 - include/world/core.hpp | 20 --- include/world/worldManager.hpp | 61 +++++++++- src/world/worldManager.cpp | 216 +++++++++++++++++++++++++++++++++ 4 files changed, 275 insertions(+), 23 deletions(-) delete mode 100644 include/world/core.hpp diff --git a/include/lib/nbt.hpp b/include/lib/nbt.hpp index 29c9180..93388a8 100644 --- a/include/lib/nbt.hpp +++ b/include/lib/nbt.hpp @@ -12,7 +12,6 @@ Compatible with older C++ compilers #endif #include -#include #include #include #include diff --git a/include/world/core.hpp b/include/world/core.hpp deleted file mode 100644 index 7226fd7..0000000 --- a/include/world/core.hpp +++ /dev/null @@ -1,20 +0,0 @@ -#ifndef CORE_HPP -#define CORE_HPP - -#include -// ============================================================================ -// CORE DATA TYPES -// ============================================================================ - -enum class ChunkState : uint8_t { - UNLOADED = 0, // Not in memory - LOADING, // Background I/O in progress - CACHED, // In cache but no active in simulation - ACTIVATING, // Being conveted to LiveChunk - ACTIVE, // Active in simulation - DIRTY, // Active and modified - SAVING, // Being saved to disk - EVICTING // Being removed from memory -}; - -#endif diff --git a/include/world/worldManager.hpp b/include/world/worldManager.hpp index fae1fc6..249edb7 100644 --- a/include/world/worldManager.hpp +++ b/include/world/worldManager.hpp @@ -1,15 +1,72 @@ #ifndef WORLD_MANAGER_HPP #define WORLD_MANAGER_HPP +#include "lib/nbt.hpp" + +#include #include #include +#include #include -#include + +struct Data { // see https://minecraft.wiki/w/Java_Edition_level_format#level.dat_format + // Existing fields + bool allowCommands; + double BorderCenterX; + double BorderCenterY; + double BorderDamagePerBlock; + double BorderSafeZone; + long BorderSizeLerpTarget; + double BorderWarningBlocks; + double BorderWarningTime; + int clearWeatherTime; + int DataVersion; + long DayTime; + std::byte Difficulty; + bool DifficultyLocked; + int GameType; + std::string generatorName; + int generatorVersiona; + bool hardcore; + bool initialized; + long LastPlayed; + std::string LevelName; + bool MapFeatures; + bool raining; + int rainTime; + long RandomSeed; + long SizeOnDisk; + int SpawnX; + int SpawnY; + int SpawnZ; + bool thundering; + int thunderTime; + long Time; + int version; + int WanderingTraderSpawnChange; + int WanderingTraderSpawnDelay; + bool WasModded; + + // The full NBT data, for accessing less common or custom tags + nbt::NBT nbtData; +}; class WorldManager { - private: public: + // Decompresses a Gzip file into a byte vector std::vector decompressGzip(std::filesystem::path compressedFilePath); + + // Loads and parses the level.dat file + Data loadLevelDat(std::filesystem::path levelDatPath); + + private: + // NBT parsing helper functions + nbt::Tag parseTag(const std::vector& data, size_t& cursor, uint8_t type); + std::string parseTagName(const std::vector& data, size_t& cursor); + nbt::TagCompound parseCompound(const std::vector& data, size_t& cursor); + nbt::TagList parseList(const std::vector& data, size_t& cursor); + + template T read(const std::vector& data, size_t& cursor); }; #endif diff --git a/src/world/worldManager.cpp b/src/world/worldManager.cpp index 5c226b4..eb848a0 100644 --- a/src/world/worldManager.cpp +++ b/src/world/worldManager.cpp @@ -1,19 +1,38 @@ #include "world/worldManager.hpp" +#include +#include #include #include #include #include #include +#include #include #include #include +#include #include #include #include #include #include +// --- NBT Tag Type IDs --- +const uint8_t TAG_END = 0; +const uint8_t TAG_BYTE = 1; +const uint8_t TAG_SHORT = 2; +const uint8_t TAG_INT = 3; +const uint8_t TAG_LONG = 4; +const uint8_t TAG_FLOAT = 5; +const uint8_t TAG_DOUBLE = 6; +const uint8_t TAG_BYTE_ARRAY = 7; +const uint8_t TAG_STRING = 8; +const uint8_t TAG_LIST = 9; +const uint8_t TAG_COMPOUND = 10; +const uint8_t TAG_INT_ARRAY = 11; +const uint8_t TAG_LONG_ARRAY = 12; + std::vector WorldManager::decompressGzip(std::filesystem::path compressedFilePath) { // Read file into memory std::ifstream file(compressedFilePath, std::ios::binary); @@ -55,3 +74,200 @@ std::vector WorldManager::decompressGzip(std::filesystem::path compress return decompressed; } + +Data WorldManager::loadLevelDat(std::filesystem::path levelDatPath) { + std::vector decompressedData = decompressGzip(levelDatPath); + if (decompressedData.empty()) { + throw std::runtime_error("Decompressed level.dat data is empty."); + } + + size_t cursor = 0; + + uint8_t rootType = read(decompressedData, cursor); + if (rootType != TAG_COMPOUND) { + throw std::runtime_error("level.dat must start with a TAG_Compound."); + } + + std::string rootName = parseTagName(decompressedData, cursor); + nbt::TagCompound rootCompound = parseCompound(decompressedData, cursor); + + Data dataStruct; + dataStruct.nbtData = nbt::NBT(rootName, rootCompound); + + // --- Populate the Data struct for easy access --- + const auto& dataCompound = + dataStruct.nbtData.getRoot().at("Data").get>(); + + // Helper to safely get a value from a compound tag + auto getTagValue = [&](const std::string& key, auto& member) { + using MemberType = std::remove_reference_t; + if (dataCompound->contains(key)) { + try { + if constexpr (std::is_same_v) { + // NBT uses TagByte for booleans + member = (dataCompound->at(key).get() != 0); + } else if constexpr (std::is_same_v) { + member = std::byte(dataCompound->at(key).get()); + } else { + member = dataCompound->at(key).get(); + } + } catch (const std::bad_variant_access&) { + // Type mismatch, leave member as default + } + } + }; + + getTagValue("allowCommands", dataStruct.allowCommands); + getTagValue("BorderCenterX", dataStruct.BorderCenterX); + getTagValue("BorderCenterY", dataStruct.BorderCenterY); + getTagValue("BorderDamagePerBlock", dataStruct.BorderDamagePerBlock); + getTagValue("BorderSafeZone", dataStruct.BorderSafeZone); + getTagValue("BorderSizeLerpTarget", dataStruct.BorderSizeLerpTarget); + getTagValue("BorderWarningBlocks", dataStruct.BorderWarningBlocks); + getTagValue("BorderWarningTime", dataStruct.BorderWarningTime); + getTagValue("clearWeatherTime", dataStruct.clearWeatherTime); + getTagValue("DataVersion", dataStruct.DataVersion); + getTagValue("DayTime", dataStruct.DayTime); + getTagValue("Difficulty", dataStruct.Difficulty); + getTagValue("DifficultyLocked", dataStruct.DifficultyLocked); + getTagValue("GameType", dataStruct.GameType); + getTagValue("generatorName", dataStruct.generatorName); + getTagValue("generatorVersion", dataStruct.generatorVersiona); + getTagValue("hardcore", dataStruct.hardcore); + getTagValue("initialized", dataStruct.initialized); + getTagValue("LastPlayed", dataStruct.LastPlayed); + getTagValue("LevelName", dataStruct.LevelName); + getTagValue("MapFeatures", dataStruct.MapFeatures); + getTagValue("raining", dataStruct.raining); + getTagValue("rainTime", dataStruct.rainTime); + getTagValue("RandomSeed", dataStruct.RandomSeed); + getTagValue("SizeOnDisk", dataStruct.SizeOnDisk); + getTagValue("SpawnX", dataStruct.SpawnX); + getTagValue("SpawnY", dataStruct.SpawnY); + getTagValue("SpawnZ", dataStruct.SpawnZ); + getTagValue("thundering", dataStruct.thundering); + getTagValue("thunderTime", dataStruct.thunderTime); + getTagValue("Time", dataStruct.Time); + getTagValue("version", dataStruct.version); + getTagValue("WanderingTraderSpawnChance", dataStruct.WanderingTraderSpawnChange); + getTagValue("WanderingTraderSpawnDelay", dataStruct.WanderingTraderSpawnDelay); + getTagValue("WasModded", dataStruct.WasModded); + + return dataStruct; +} + +// --- NBT Parsing Implementation --- + +template T WorldManager::read(const std::vector& data, size_t& cursor) { + if (cursor + sizeof(T) > data.size()) { + throw std::runtime_error("NBT parsing error: unexpected end of data."); + } + T value; + std::memcpy(&value, &data[cursor], sizeof(T)); + cursor += sizeof(T); + + if constexpr (sizeof(T) > 1) { + if (std::endian::native == std::endian::little) { + return std::byteswap(value); + } + } + return value; +} + +std::string WorldManager::parseTagName(const std::vector& data, size_t& cursor) { + uint16_t length = read(data, cursor); + if (length == 0) { + return ""; + } + if (cursor + length > data.size()) { + throw std::runtime_error("NBT parsing error: invalid tag name length."); + } + std::string name(data.begin() + cursor, data.begin() + cursor + length); + cursor += length; + return name; +} + +nbt::TagCompound WorldManager::parseCompound(const std::vector& data, size_t& cursor) { + nbt::TagCompound compound; + while (cursor < data.size()) { + uint8_t tagType = read(data, cursor); + if (tagType == TAG_END) { + break; + } + + std::string tagName = parseTagName(data, cursor); + compound[tagName] = parseTag(data, cursor, tagType); + } + return compound; +} + +nbt::TagList WorldManager::parseList(const std::vector& data, size_t& cursor) { + nbt::TagList list; + uint8_t listType = read(data, cursor); + int32_t length = read(data, cursor); + + for (int32_t i = 0; i < length; ++i) { + list.push_back(parseTag(data, cursor, listType)); + } + return list; +} + +nbt::Tag WorldManager::parseTag(const std::vector& data, size_t& cursor, uint8_t tagType) { + switch (tagType) { + case TAG_BYTE: + return nbt::Tag(read(data, cursor)); + case TAG_SHORT: + return nbt::Tag(read(data, cursor)); + case TAG_INT: + return nbt::Tag(read(data, cursor)); + case TAG_LONG: + return nbt::Tag(read(data, cursor)); + case TAG_FLOAT: + return nbt::Tag(std::bit_cast(read(data, cursor))); + case TAG_DOUBLE: + return nbt::Tag(std::bit_cast(read(data, cursor))); + case TAG_STRING: { + uint16_t length = read(data, cursor); + if (cursor + length > data.size()) { + throw std::runtime_error("NBT parsing error: invalid string length."); + } + std::string str(data.begin() + cursor, data.begin() + cursor + length); + cursor += length; + return nbt::Tag(str); + } + case TAG_BYTE_ARRAY: { + int32_t length = read(data, cursor); + nbt::TagByteArray array; + if (length > 0) { + array.resize(length); + std::memcpy(array.data(), &data[cursor], length); + cursor += length; + } + return nbt::Tag(array); + } + case TAG_INT_ARRAY: { + int32_t length = read(data, cursor); + nbt::TagIntArray array; + array.reserve(length); + for (int32_t i = 0; i < length; ++i) { + array.push_back(read(data, cursor)); + } + return nbt::Tag(array); + } + case TAG_LONG_ARRAY: { + int32_t length = read(data, cursor); + nbt::TagLongArray array; + array.reserve(length); + for (int32_t i = 0; i < length; ++i) { + array.push_back(read(data, cursor)); + } + return nbt::Tag(array); + } + case TAG_LIST: + return nbt::Tag(std::make_shared(parseList(data, cursor))); + case TAG_COMPOUND: + return nbt::Tag(std::make_shared(parseCompound(data, cursor))); + default: + throw std::runtime_error("Unsupported NBT tag type: " + std::to_string(tagType)); + } +} From 4a76b85a4e4f5d30e3ed6b40775fe73f5fc9bcfe Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Antoine=20Mathi=C3=A9?= Date: Fri, 10 Oct 2025 17:31:38 +0200 Subject: [PATCH 18/27] feat: debug load level --- include/network/server.hpp | 5 +++ include/world/worldManager.hpp | 4 ++- src/server.cpp | 61 ++++++++++++++++++++++++++++++++-- src/world/worldManager.cpp | 2 -- 4 files changed, 67 insertions(+), 5 deletions(-) diff --git a/include/network/server.hpp b/include/network/server.hpp index e8e32ce..b07dd79 100644 --- a/include/network/server.hpp +++ b/include/network/server.hpp @@ -4,6 +4,7 @@ class NetworkManager; #include "../config.hpp" #include "../player.hpp" +#include "../world/worldManager.hpp" #include "id_manager.hpp" #include "lib/json.hpp" @@ -24,6 +25,8 @@ class Server { Config _config; NetworkManager* _networkManager; IdManager _idManager; + WorldManager _worldManager; + Data _worldData; public: Server(); @@ -48,6 +51,8 @@ class Server { IdManager& getIdManager() { return (_idManager); } NetworkManager& getNetworkManager() { return *_networkManager; } + WorldManager& getWorldManager() { return _worldManager; } + Data& getWorldData() { return _worldData; } }; #endif diff --git a/include/world/worldManager.hpp b/include/world/worldManager.hpp index 249edb7..2baa995 100644 --- a/include/world/worldManager.hpp +++ b/include/world/worldManager.hpp @@ -55,7 +55,6 @@ class WorldManager { public: // Decompresses a Gzip file into a byte vector std::vector decompressGzip(std::filesystem::path compressedFilePath); - // Loads and parses the level.dat file Data loadLevelDat(std::filesystem::path levelDatPath); @@ -67,6 +66,9 @@ class WorldManager { nbt::TagList parseList(const std::vector& data, size_t& cursor); template T read(const std::vector& data, size_t& cursor); + + private: + Data _LevelDat; }; #endif diff --git a/src/server.cpp b/src/server.cpp index 3ecdadd..fd63fca 100644 --- a/src/server.cpp +++ b/src/server.cpp @@ -1,13 +1,15 @@ -#include "network/server.hpp" - #include "config.hpp" +#include "lib/filesystem.hpp" #include "lib/json.hpp" #include "logger.hpp" #include "network/networking.hpp" +#include "network/server.hpp" #include "player.hpp" +#include "world/worldManager.hpp" #include #include +#include #include #include #include @@ -30,6 +32,61 @@ int Server::start_server() { g_logger->logGameInfo(ERROR, "Failed to load config", "SERVER"); return 1; } + + // Load world data + g_logger->logGameInfo(INFO, "Loading world...", "SERVER"); + try { + std::string worldName = _config.getWorldName(); + std::filesystem::path levelDatPath = getPath().parent_path() / worldName / "level.dat"; + + if (!std::filesystem::exists(levelDatPath)) { + g_logger->logGameInfo( + ERROR, "level.dat not found at: " + levelDatPath.string(), "SERVER"); + return 1; + } + + _worldData = _worldManager.loadLevelDat(levelDatPath); + + // Log world information + g_logger->logGameInfo( + INFO, "World loaded successfully: " + _worldData.LevelName, "SERVER"); + g_logger->logGameInfo(INFO, + "Spawn Point: X=" + std::to_string(_worldData.SpawnX) + + " Y=" + std::to_string(_worldData.SpawnY) + + " Z=" + std::to_string(_worldData.SpawnZ), + "SERVER"); + g_logger->logGameInfo( + INFO, "Random Seed: " + std::to_string(_worldData.RandomSeed), "SERVER"); + g_logger->logGameInfo( + INFO, "Game Type: " + std::to_string(_worldData.GameType), "SERVER"); + g_logger->logGameInfo( + INFO, "Data Version: " + std::to_string(_worldData.DataVersion), "SERVER"); + g_logger->logGameInfo(INFO, + "Difficulty: " + + std::to_string(static_cast(_worldData.Difficulty)), + "SERVER"); + g_logger->logGameInfo(INFO, + "Hardcore: " + + std::string(_worldData.hardcore ? "true" : "false"), + "SERVER"); + g_logger->logGameInfo(INFO, "Time: " + std::to_string(_worldData.Time), "SERVER"); + g_logger->logGameInfo( + INFO, "Day Time: " + std::to_string(_worldData.DayTime), "SERVER"); + g_logger->logGameInfo(INFO, "Generator: " + _worldData.generatorName, "SERVER"); + g_logger->logGameInfo(INFO, + "Raining: " + std::string(_worldData.raining ? "true" : "false"), + "SERVER"); + g_logger->logGameInfo(INFO, + "Thundering: " + + std::string(_worldData.thundering ? "true" : "false"), + "SERVER"); + + } catch (const std::exception& e) { + g_logger->logGameInfo( + ERROR, "Failed to load world: " + std::string(e.what()), "SERVER"); + return 1; + } + size_t workerCount = 4; if (workerCount == 0) workerCount = 4; // fallback diff --git a/src/world/worldManager.cpp b/src/world/worldManager.cpp index eb848a0..db1b8a8 100644 --- a/src/world/worldManager.cpp +++ b/src/world/worldManager.cpp @@ -1,13 +1,11 @@ #include "world/worldManager.hpp" -#include #include #include #include #include #include #include -#include #include #include #include From 4ab9e6fad676941ddd2b69498d4956b94be5ffe7 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" Date: Fri, 10 Oct 2025 15:33:46 +0000 Subject: [PATCH 19/27] Apply clang-format [skip ci] --- src/server.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/server.cpp b/src/server.cpp index fd63fca..40fbaf1 100644 --- a/src/server.cpp +++ b/src/server.cpp @@ -1,9 +1,10 @@ +#include "network/server.hpp" + #include "config.hpp" #include "lib/filesystem.hpp" #include "lib/json.hpp" #include "logger.hpp" #include "network/networking.hpp" -#include "network/server.hpp" #include "player.hpp" #include "world/worldManager.hpp" From 8eaa45b5515bd16b996ee769b9c8a81096d1a570 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Antoine=20Mathi=C3=A9?= Date: Fri, 10 Oct 2025 17:42:13 +0200 Subject: [PATCH 20/27] feat: now make run cmd create a test-server folder --- .gitignore | 3 ++ Makefile | 27 ++++++++++++++++-- world/DIM-1/data/chunks.dat | Bin 0 -> 48 bytes world/DIM-1/data/raids.dat | Bin 0 -> 73 bytes world/DIM1/data/chunks.dat | Bin 0 -> 48 bytes world/DIM1/data/raids_end.dat | Bin 0 -> 73 bytes .../4572e510-ac24-44b0-a915-5ed21da4028c.json | 15 ++++++++++ world/data/chunks.dat | Bin 0 -> 48 bytes world/data/raids.dat | Bin 0 -> 73 bytes world/data/random_sequences.dat | Bin 0 -> 71 bytes world/data/scoreboard.dat | Bin 0 -> 48 bytes world/entities/r.-1.-1.mca | Bin 0 -> 20480 bytes world/entities/r.-1.0.mca | Bin 0 -> 28672 bytes world/entities/r.0.-1.mca | Bin 0 -> 36864 bytes world/entities/r.0.0.mca | 0 world/icon.png | Bin 0 -> 5191 bytes world/level.dat | Bin 0 -> 2407 bytes world/level.dat_old | Bin 0 -> 2406 bytes .../4572e510-ac24-44b0-a915-5ed21da4028c.dat | Bin 0 -> 866 bytes ...72e510-ac24-44b0-a915-5ed21da4028c.dat_old | Bin 0 -> 866 bytes world/poi/r.-1.-1.mca | 0 world/poi/r.-1.0.mca | 0 world/poi/r.0.-1.mca | 0 world/poi/r.0.0.mca | 0 world/region/r.-1.-1.mca | Bin 0 -> 1728512 bytes world/region/r.-1.0.mca | Bin 0 -> 1646592 bytes world/region/r.0.-1.mca | Bin 0 -> 1814528 bytes world/region/r.0.0.mca | Bin 0 -> 1728512 bytes world/session.lock | 1 + .../4572e510-ac24-44b0-a915-5ed21da4028c.json | 1 + 30 files changed, 44 insertions(+), 3 deletions(-) create mode 100644 world/DIM-1/data/chunks.dat create mode 100644 world/DIM-1/data/raids.dat create mode 100644 world/DIM1/data/chunks.dat create mode 100644 world/DIM1/data/raids_end.dat create mode 100644 world/advancements/4572e510-ac24-44b0-a915-5ed21da4028c.json create mode 100644 world/data/chunks.dat create mode 100644 world/data/raids.dat create mode 100644 world/data/random_sequences.dat create mode 100644 world/data/scoreboard.dat create mode 100644 world/entities/r.-1.-1.mca create mode 100644 world/entities/r.-1.0.mca create mode 100644 world/entities/r.0.-1.mca create mode 100644 world/entities/r.0.0.mca create mode 100644 world/icon.png create mode 100644 world/level.dat create mode 100644 world/level.dat_old create mode 100644 world/playerdata/4572e510-ac24-44b0-a915-5ed21da4028c.dat create mode 100644 world/playerdata/4572e510-ac24-44b0-a915-5ed21da4028c.dat_old create mode 100644 world/poi/r.-1.-1.mca create mode 100644 world/poi/r.-1.0.mca create mode 100644 world/poi/r.0.-1.mca create mode 100644 world/poi/r.0.0.mca create mode 100644 world/region/r.-1.-1.mca create mode 100644 world/region/r.-1.0.mca create mode 100644 world/region/r.0.-1.mca create mode 100644 world/region/r.0.0.mca create mode 100644 world/session.lock create mode 100644 world/stats/4572e510-ac24-44b0-a915-5ed21da4028c.json diff --git a/.gitignore b/.gitignore index a92ec07..bb837ff 100644 --- a/.gitignore +++ b/.gitignore @@ -8,3 +8,6 @@ compile_commands.json .cache .vscode logs + +# Test server directory +test-server diff --git a/Makefile b/Makefile index 069aaa4..24ed34c 100644 --- a/Makefile +++ b/Makefile @@ -82,7 +82,7 @@ else endif # ================================= TARGETS ================================== -.PHONY: all clean distclean debug release info help run install uninstall compile_commands +.PHONY: all clean distclean clean-test debug release info help run install uninstall compile_commands # Default target all: info $(TARGET) @@ -142,11 +142,31 @@ distclean: @rm -rf $(BUILD_DIR) $(DEPS_DIR) @printf "$(BOLD)$(BRIGHT_GREEN)✨ Complete cleanup finished!$(RESET)\n" +# Clean test-server directory +clean-test: + @printf "$(BOLD)$(BRIGHT_RED)🧹 Cleaning test-server directory...$(RESET)\n" + @rm -rf test-server + @printf "$(BOLD)$(BRIGHT_GREEN)✨ Test-server cleanup finished!$(RESET)\n" + # Run the executable run: $(TARGET) + @printf "$(BOLD)$(BRIGHT_MAGENTA)🚀 Setting up test-server environment...$(RESET)\n" + @mkdir -p test-server + @printf "$(BOLD)$(BRIGHT_BLUE)📦 Copying executable to test-server...$(RESET)\n" + @cp $(TARGET) test-server/$(TARGET_NAME) + @printf "$(BOLD)$(BRIGHT_BLUE)📦 Copying config.json to test-server...$(RESET)\n" + @cp -f config.json test-server/ 2>/dev/null || printf "$(YELLOW)⚠️ config.json not found, skipping...$(RESET)\n" + @printf "$(BOLD)$(BRIGHT_BLUE)📦 Copying world folder to test-server...$(RESET)\n" + @if [ -d "world" ]; then \ + cp -r world test-server/; \ + printf "$(BOLD)$(BRIGHT_GREEN)✅ World folder copied successfully!$(RESET)\n"; \ + else \ + printf "$(YELLOW)⚠️ World folder not found, skipping...$(RESET)\n"; \ + fi + @printf "$(BOLD)$(BRIGHT_GREEN)✅ Test environment ready!$(RESET)\n" @printf "$(BOLD)$(BRIGHT_MAGENTA)🚀 Running $(TARGET_NAME)...$(RESET)\n" @printf "$(DIM)$(WHITE)" && echo "================================================" && printf "$(RESET)" - @./$(TARGET) + @cd test-server && ./$(TARGET_NAME) @printf "$(DIM)$(WHITE)" && echo "================================================" && printf "$(RESET)" # Display project information @@ -202,7 +222,8 @@ help: @printf "$(BOLD)$(BRIGHT_CYAN)║$(RESET) $(BRIGHT_GREEN)%-10s$(RESET) %-39s $(BOLD)$(BRIGHT_CYAN) ║$(RESET)\n" "release" "Build in release mode" @printf "$(BOLD)$(BRIGHT_CYAN)║$(RESET) $(BRIGHT_GREEN)%-10s$(RESET) %-39s $(BOLD)$(BRIGHT_CYAN) ║$(RESET)\n" "clean" "Remove build artifacts (preserve dirs)" @printf "$(BOLD)$(BRIGHT_CYAN)║$(RESET) $(BRIGHT_GREEN)%-10s$(RESET) %-39s $(BOLD)$(BRIGHT_CYAN) ║$(RESET)\n" "distclean" "Remove all build artifacts and dirs" - @printf "$(BOLD)$(BRIGHT_CYAN)║$(RESET) $(BRIGHT_GREEN)%-10s$(RESET) %-39s $(BOLD)$(BRIGHT_CYAN) ║$(RESET)\n" "run" "Build and run the executable" + @printf "$(BOLD)$(BRIGHT_CYAN)║$(RESET) $(BRIGHT_GREEN)%-10s$(RESET) %-39s $(BOLD)$(BRIGHT_CYAN) ║$(RESET)\n" "clean-test" "Remove test-server directory" + @printf "$(BOLD)$(BRIGHT_CYAN)║$(RESET) $(BRIGHT_GREEN)%-10s$(RESET) %-39s $(BOLD)$(BRIGHT_CYAN) ║$(RESET)\n" "run" "Setup test-server and run executable" @printf "$(BOLD)$(BRIGHT_CYAN)║$(RESET) $(BRIGHT_GREEN)%-10s$(RESET) %-39s $(BOLD)$(BRIGHT_CYAN) ║$(RESET)\n" "compile_commands" "Generate compile_commands.json for LSP" @printf "$(BOLD)$(BRIGHT_CYAN)║$(RESET) $(BRIGHT_GREEN)%-10s$(RESET) %-39s $(BOLD)$(BRIGHT_CYAN) ║$(RESET)\n" "install" "Install the executable to system" @printf "$(BOLD)$(BRIGHT_CYAN)║$(RESET) $(BRIGHT_GREEN)%-10s$(RESET) %-39s $(BOLD)$(BRIGHT_CYAN) ║$(RESET)\n" "uninstall" "Remove the executable from system" diff --git a/world/DIM-1/data/chunks.dat b/world/DIM-1/data/chunks.dat new file mode 100644 index 0000000000000000000000000000000000000000..4089fbca8fc3193e65516144369cda83dfcca31f GIT binary patch literal 48 zcmb2|=3oGW|BsUr9wa4rdg^$lB&0nkW4x5O()H-fpOrj3O#YG#u8eb<<$wwShN};E literal 0 HcmV?d00001 diff --git a/world/DIM-1/data/raids.dat b/world/DIM-1/data/raids.dat new file mode 100644 index 0000000000000000000000000000000000000000..82c846306b24c6763f6ca80102b0626c93d60e78 GIT binary patch literal 73 zcmb2|=3oGW|BsUr9wa4rdg^$lq$Oyc^f{N7kgy>&E#bWPT8+;0K8&9vBxgwOh;86H a6x7{i{Q0wl1j{@l28REeZl;+7O#lGn{~N0S literal 0 HcmV?d00001 diff --git a/world/DIM1/data/chunks.dat b/world/DIM1/data/chunks.dat new file mode 100644 index 0000000000000000000000000000000000000000..4089fbca8fc3193e65516144369cda83dfcca31f GIT binary patch literal 48 zcmb2|=3oGW|BsUr9wa4rdg^$lB&0nkW4x5O()H-fpOrj3O#YG#u8eb<<$wwShN};E literal 0 HcmV?d00001 diff --git a/world/DIM1/data/raids_end.dat b/world/DIM1/data/raids_end.dat new file mode 100644 index 0000000000000000000000000000000000000000..82c846306b24c6763f6ca80102b0626c93d60e78 GIT binary patch literal 73 zcmb2|=3oGW|BsUr9wa4rdg^$lq$Oyc^f{N7kgy>&E#bWPT8+;0K8&9vBxgwOh;86H a6x7{i{Q0wl1j{@l28REeZl;+7O#lGn{~N0S literal 0 HcmV?d00001 diff --git a/world/advancements/4572e510-ac24-44b0-a915-5ed21da4028c.json b/world/advancements/4572e510-ac24-44b0-a915-5ed21da4028c.json new file mode 100644 index 0000000..5e01b24 --- /dev/null +++ b/world/advancements/4572e510-ac24-44b0-a915-5ed21da4028c.json @@ -0,0 +1,15 @@ +{ + "minecraft:recipes/decorations/crafting_table": { + "criteria": { + "unlock_right_away": "2025-10-10 17:26:39 +0200" + }, + "done": true + }, + "minecraft:adventure/adventuring_time": { + "criteria": { + "minecraft:plains": "2025-10-10 17:26:40 +0200" + }, + "done": false + }, + "DataVersion": 4325 +} \ No newline at end of file diff --git a/world/data/chunks.dat b/world/data/chunks.dat new file mode 100644 index 0000000000000000000000000000000000000000..4089fbca8fc3193e65516144369cda83dfcca31f GIT binary patch literal 48 zcmb2|=3oGW|BsUr9wa4rdg^$lB&0nkW4x5O()H-fpOrj3O#YG#u8eb<<$wwShN};E literal 0 HcmV?d00001 diff --git a/world/data/raids.dat b/world/data/raids.dat new file mode 100644 index 0000000000000000000000000000000000000000..82c846306b24c6763f6ca80102b0626c93d60e78 GIT binary patch literal 73 zcmb2|=3oGW|BsUr9wa4rdg^$lq$Oyc^f{N7kgy>&E#bWPT8+;0K8&9vBxgwOh;86H a6x7{i{Q0wl1j{@l28REeZl;+7O#lGn{~N0S literal 0 HcmV?d00001 diff --git a/world/data/random_sequences.dat b/world/data/random_sequences.dat new file mode 100644 index 0000000000000000000000000000000000000000..ce54a5fa17fefe8541c2e633345f66dfdd4dc956 GIT binary patch literal 71 zcmb2|=3oGW|BsUr9wa4rdg^$lq$OzjozYB8VCXCmTP`+j*)!GUV#Wpr#s#|>o*oYB X?lS)TSwezko)H5B*EzFdGoXF|Uy&F4 literal 0 HcmV?d00001 diff --git a/world/data/scoreboard.dat b/world/data/scoreboard.dat new file mode 100644 index 0000000000000000000000000000000000000000..4089fbca8fc3193e65516144369cda83dfcca31f GIT binary patch literal 48 zcmb2|=3oGW|BsUr9wa4rdg^$lB&0nkW4x5O()H-fpOrj3O#YG#u8eb<<$wwShN};E literal 0 HcmV?d00001 diff --git a/world/entities/r.-1.-1.mca b/world/entities/r.-1.-1.mca new file mode 100644 index 0000000000000000000000000000000000000000..37abe1d23f39a3a98bb0b276aa443ee18e59d1fe GIT binary patch literal 20480 zcmeI%`8O159{_NmtjLkR>zLk*ix2Guei5$r4w#Y?TVv zFt)~4_Q?`ivV>8uY~3OBzVA8je{gT-bkF-dzdzsS`+T0|obUN^aDV{>fB+Bx0zd!= z00AHX1b_e#00KbZdka7geD4*0-1waT$9w;APX%NK1b_e#00KY&2mk>f00e*l5C8&y zzku)Z@tVIs>OUjmkF$49G$%3FA+6URYAD$;{maRQoDptS^qYj))>sm;S~a_bteGlq ztixsX8ji%o^!Z_@_ex}tWDH*R#Hv03U1cL2MGiki0#Cg6K5*1CqjBu9f%uj z=DSV-cmDj1h&tJk#}aPPrs;Q)E5_a^nCdV1v+r%CY6?6Gq*dt8_HG4>`7yrYP8fyX zYKxjpPD^c}94N(#FzE}Wmr|RoB1pwz8b3pGM4=`H5(?-KKZ{&BRBM46eatExwW%6PuZ{$~9ki~7WjXZ2?C^-ELV`VgOvx1N9&MSWq7 zn9__6Nu@wF+>IU@P8{jI>52`+Zkzg}E~n-}^1@*l&D?o=O0AJh^n=$HZR7#NF(t@( z%Jl+@c#~lKlgdoKo4d!326EBQ464v_b2>B)H;`{a(Vvny6q0H4l(=t8P$W%3iW+MG z8$2#cbnzT7@W#(-5?Txi*BcPw{nPBH->%5(BdJGZGTymx3YrY0$@9B@_L|lW(oIj` zox63>oOz)T!ZRXp^af3LEB#h`oXoH_bfd?A-p0$e-L695xf={w?E{+(7>(J&4kR-j zGW+uYH)FDFxwJeeh-;0!?K&|Ma&SzM0|nDKDDx zZLj_AyKIy61{@Du#I{05&}_@Gyv8Ge8*Z!2+iHJjmjhMD7F6*}hVfi_AXlKGz5yl%q7n77!h z-c$v1zB-#buLfqJc~n?g$(8&|*jbVDa5wQV0*qSV%g%474VK|nWNam8j22cF@ z%)N2_3$w0lci!c3m?LCI%(sP}JVWq`RWRCX?6y`{NTkbo--}BW`zVFL&n(aO*zsrN zc-t$WHjzPT4b_&1`YY9Yqfq9ZdGP@abT^%>$1_z(VW+u4qQT zrnV&~D_+Fw#^_H_u0mqQ?|;EXStIMRwwohY_ZB-h4zLX|*6|ufCpqv{=_6LB*@dKn zkg@Q4r*B87Dl47rxI4B+D89^9pKwpZ>ErK>-p4*|_D$A@;=)#c3Syuc>$g2UspGoN zk5=ZKa!~6&WU@?LPa*|7(+?}1ICqsN)YpZ}>-uzsscB)J(kG>Rq$O%? zhFWxc4jadbBG(x#XoF?0H^FP!kw=O(v}?)a>-Q}F?B}44k0+m$$uMwwy%;CM=ZExq zVdJ-?t@M!t0cpd;k4p{uj?Eh>Cf6U~JtX_L{4-yvGg{8bP2r8l4cI2c31+4f4;+FC^&%(S{5EnTkA(+OV6S+5qK zvgcbQoYRSfD*If+_+6FZvd?}$eff?SDbyADoLfOE7Uv4BY1t8i^D08hgI=go-NWKf#C*FvfC~RY<&OK|;9MB|$cq+;^irx6ciJ~~|9A*1}{{LTmh+sMp Y00KY&2mk>f00e*l5C8%|;JXU^8*u#y1^@s6 literal 0 HcmV?d00001 diff --git a/world/entities/r.-1.0.mca b/world/entities/r.-1.0.mca new file mode 100644 index 0000000000000000000000000000000000000000..1363904cca278bc6fd342c71ed71f52464e68a5a GIT binary patch literal 28672 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 literal 0 HcmV?d00001 diff --git a/world/entities/r.0.-1.mca b/world/entities/r.0.-1.mca new file mode 100644 index 0000000000000000000000000000000000000000..8cbb0216c8a08bb103e18b805c76a30a1823caa0 GIT binary patch literal 36864 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 N00e*l5ct~(`~#Tz)HnbD literal 0 HcmV?d00001 diff --git a/world/entities/r.0.0.mca b/world/entities/r.0.0.mca new file mode 100644 index 0000000..e69de29 diff --git a/world/icon.png b/world/icon.png new file mode 100644 index 0000000000000000000000000000000000000000..bdd5dd7aa94b155718475ec4c3f2bbb4d780fe1a GIT binary patch literal 5191 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 L^^uptQO*AWrcsN{ literal 0 HcmV?d00001 diff --git a/world/level.dat b/world/level.dat new file mode 100644 index 0000000000000000000000000000000000000000..8741cbad3c54aa01c13f80bb18d316a09af8353a GIT binary patch literal 2407 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 Z{OXdi#U4qGF(}8D{{zS<)wHw{000njsObOz literal 0 HcmV?d00001 diff --git a/world/level.dat_old b/world/level.dat_old new file mode 100644 index 0000000000000000000000000000000000000000..4a8682f68fdb3a0df258c0d7cf29fbc5fbe31c90 GIT binary patch literal 2406 zcmV-s37PgEiwFP!00000|Ako1ZyZS#ukm;$GvlxEM<5AA1eOCUL9|Ioc7<3Hd&YJQ zj$?VeNr-?}O?S;qt*g6QRn>N8`4?8=Y(7K|a9D{02QCPqT_G+=Sq}UU%ZdLX{Hm&Z zdYm}gkvdLSz4z+X`}n>0xpo~p+`V!KSGhdgE_=>>Ur z)o(wh%BtWt^}RLE+#>DAQi*7rB|T;g_H~8K^<|RjARIAmtj3zLD7w}-{^JjS|4D@` z4_U$#H7pn~YBI%irA1m1Zk1>*6Wt=KF;7^i=)n9y;xZ@pfEH=yd{VVYLr)HC6jDfo z)cRb)IPH=@6)>D`lDeQ{rXZV;s-?4+Aj>6PpG68wRZ<@@J{%cmxe4K7Nf>curm1F1 zs*5GnP*JS|w|rJ)ldNi^ve0TA*vly%G3Th6X@1biWH^!{(qyGvKDK@w!eFE(=n<}r z!)J|k{*;CTLCs|SJX6AHYvr;Tu^?giS52F^QJQ$#oCV>$GjyP3rb5;r^%VAJ=5@+K zjj5}}h<6?&l4~~6a%qb1%*MHTLjUEn>nw@hr2Ilj>8M`O+#mD0xGz`j93Gnvb6rJ; zGTE{ouaK2Jgud<>M0+o!iOru%)8?#UCv>c^+XTth@u$h_C#Cx{jnL3n##v12YXEynp;ne-F9p=!v?`p3V0 z*QfP`M@Sc>BeI~E&{U744XQfeg(L1}W29A;%?!a-iwO$WH_~cIoGl$ z7)x;uYElUE0QyMv#ye2(D>{)U>tUDyO`y9>?t6%>+-Q)mI@mqO$%S6}yWfJQviWab7|<_C(gkJ#CBS2ZFxkHRgS(5Gd9wj+t! z9ic+M;?ULr{y8hBtyq+WEb6j;Hrz=Da$=f`C$N`#EgW;c%c+tdve0nkUxy|e2&p6A zDHIfIfIsA8$kwA{+Z)BxX}O5%>r{J18|{0kEIG<8P`L>MUVJVV8Dq&;i4A(O7?!+bj1E#etxy8<0BoA@PGwuZ_>?B&o38#}dI6~y^ zBo=$5D)FUAd!GmAr~PsycX`YWi#oQtSbr5;bGXbl0C+Iv#H%?D08Kf%Nf)xt@=ge; z-Mabio%dW2OkwF1e_P1mdW38)@VD5wq*FN5)>FNmcWllRdMd8=DH;{=s>sz65x1l| z>cH(L$3p;h-Cw>%Y8$qzMKc$(Sh});!nbrkQ)a^z4{d0i5?2;m4hig{vej}Pmd%9K z3AVJI^cE6vON^}!RkE1Fnne4As3NYAw%7Yws?=I%J$4GYGS{SiE>M_kPc_faO0CCq zJP>0mA3da@{fwh|s*&ai6+VyOfAQjT6iCo**ge#>`oL>ZLtiS!o@n>Q=QydQSjbbh zA>~mM{k(h0JM>FsD-q@{4~$i!Lf+zfLr`s(wlbB_kZo~cTxoRCk*m7IbuX4jOl@cU zVagILt#N%0X_G7%xxuOs5 zR#?_ucFe@R=T`RHe3(e|_O>(xkwdd!fXWwynNrC0fE8eb9&Eu=aRis27Ksn{>N;1I z?;^4uCfmw3F%^`bZZRR9+tj10Jb*>4HnwY=`O)d=?>_zSVB~D&^z)YcPN4^n(+r>z zgc8%>GZVNDKEU7-vcTl68wQ0FS2+R)!~t5B5bmmyg%dvv2BMUF$=FICXpXA{*5yG? zgx&AK6Jef@fukdysn!c&EkC((zy-ci7V-)Xah86SP43DN`JkD_!w?ahK$!wo$cK5HRr_ZebPyWrR+0deC!0pgX zLu=pw<$TC;zI!XV+dSX5rsoaY2)voGkuz2?G*CnHhTAsORnoKpR=8~~54g=|BZ|hi z2sj_iSG{ZCLPdj=Dp(gaIKW{xxa@pt5w*yoc8>|5I*Y8qdO{j+vSwMTyhaQ5Jln72 znClkn4(NaS^5x5aR!PHxw-YmW>hO$hjJjQhxW?g=LY` z1@RMqP8&C%DzE0n7y%T{kMQ`~avbOz1;6UEu`Bz?CXHgSnOMk+&VH^zLU(<$;5MrH3=Id{)Kz&1YqAC$!!VREi!3mX YUtKb`*dwVi2IbiDe-R2x2DB0Y0MLA~zyJUM literal 0 HcmV?d00001 diff --git a/world/playerdata/4572e510-ac24-44b0-a915-5ed21da4028c.dat b/world/playerdata/4572e510-ac24-44b0-a915-5ed21da4028c.dat new file mode 100644 index 0000000000000000000000000000000000000000..33d13927e1f09c6efee91f02bb3adabbb5ec1d5b GIT binary patch literal 866 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

;; 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�pm$5E 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 G7WiM5%M-@{ literal 0 HcmV?d00001 diff --git a/world/region/r.-1.0.mca b/world/region/r.-1.0.mca new file mode 100644 index 0000000000000000000000000000000000000000..4e8b5ac0e8560ca32103ca7fd7fd75c49213a0a8 GIT binary patch literal 1646592 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

Uu6III4yWYusi2I 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

8&;PveSdCS{(tFT2Ygo`00e*l5C8%| z00;m9AOHk_z#mG0+~V8(zdxV<-_`k)*GlcTpRLUDLX6?lQ;uf!i`6w53Q5P4E^ME> zs^+_2w}*;)*|8rlKlX)=i8tKgX$m%^d|!e2(arXU_l?WN^$v^mlwX~RFjgR&<@lTN z|Mh>4|7YcIk z3~h7kqq?O&yie%1Bag=N#RC=$^YwDKPS?!Pchu_ESIPvIi9eRO^ik&(S;7(isxs|S zlijxf{OL9?$=e%_eh^d%FFmB3;{P;e!v=RH$_=sOXFy-+Y&^}CKgy?aVepz&ak^`U z^4sujpr~w+(>tzuEvm{cZ!G*%{;WH#Pu< zl1XJhQW&cNM~Y)fuLs2AR%b=#n-HCCmxOY>-*BUiqd;U{9OCo za%|Im7u{cvDQtM}shDk7=WF-PVC(W!Q?#yKPmbB&sI6*d#!deE%RTk3u7v_dD$t=>t75ACit|b*mzfU|!H1vVhoUFCx9{IrGO+Q-vus+R(xJW6A zFJf3Lz?vc;0hm;Vsv>N4AVwv2Y!rn+AT46)0x{aLaeUjzaaVOgHYTc>Z;wxcP`fO4?_!#EJ)fJ*BcX2SYOv&KX zu?Z{aw7e^k<&U%oz`X(iAOHk_01yBIKmZ5;0U!VbfWUvf0J-_M{{LQ5{vU*9Wyf-H zd?}ioJ?Ao|5Cadd%&LH&n$^7b;CQvJ4PCJP)P*C4EM`MEdd%e87he^RD^jvN`B?VI z50g4>cy{<^|9pdJ*9YdNeo-18eW`SIv*r+9Y=-P*o*CAuaJ7kAd*({cxy^@m!h!+w zeCmW3a*Fb)Sv!yN1+3uplKo7_%u^%sX=l$=nfv!v2M^5EA_Ah`H$;6J7kgGJn^tmO zJ4vD2$^s`()dx>#conWCnC56$dI=*kxxu1Q*Bx|tIj5-lBqlG6AfZgRwY_s&g4F)s z5!!Fhglcxda6=1INbUdY-`f8rNeBMB?f*S6%H7U?W2j&<3Ju49Yx`&2J^fGb{@(t7 zaHCe4=oF9YsO*!U7)uyCX zdfL~7?Em_O1HK>-00KY&2mk>f00e*l5C8%|00{h{1b*!QkN^Aq|FJMtqTIeqlCY)w zkEN%5LNhsN2gCkR0Dw-+pt#tx54Rv^MxNVHG|%+1KM!o8W11H2FqpHEx_vxN>h&~o zUU|twH5K`G!fE~V9@-m|n3N2U!ma$ix|e#N&SZXF46D$Qw8$!b#;dj<>|)Eoy*KMA zM=f@X6aeto{r?7f=aoyUPfE8T*|#DiUOabd6cd*&xV9FQowiSd^!7i&8eQzd(Fr>Y zC8(emyI~h0{=&Q40nNK90Nf@Lw)KUca0FkJ0lPQei?*GYQqmbMy1u&Do-#RPcRG#-hed#jih% z%eh;MICI90;?_=&&y2D5s7A5%S?%F_zjW9sOj zIc>y~+i^ac_v$_t8Uak>2eW2)LvpWv910~>C|CVB+=pPg2QWA@341&XL&IpeDXy~E?4uOeda4m@rDT_{DbRZxwLI_Mz@6&~mSE5+=!~Ert7T z00;m9AOHk_01yBIKmZ5;f&WW^AJ6~)LH=JF%>8Ad>IxOEDKLnzt>?o^$s5X8_UN2K zf6eXZB~Hg2dTz5g zOH8nO9@uQtLbt1wN?5>iLYs$M8xMp~Ky|?Bal>BwP@Q3`rSPC~O^n2eE zNnIxw(nOEAdfFZ1y>x8OMC&oP+4!Awhr+AjEhoI*N=+R|O@D^ldfeAT&4*8etR2NZ zhm#`yu0#AuQvh5rDrm)9s8Bf49!=+h(MHF)U@k(WZ=p2dNIvYLE|?RPV2M^tLg{BV zz3>0Tff}eR8~U&zx+=Dt|ChEq0Kk(?>GRN{qi=!b@#MhBu{}8M$Tug=7q_N5H_2&^ kfb;+V%T)^g77zdeKmZ5;0U!VbfB+Bx0zd!={Cfib4-|3+;Q#;t literal 0 HcmV?d00001 diff --git a/world/region/r.0.-1.mca b/world/region/r.0.-1.mca new file mode 100644 index 0000000000000000000000000000000000000000..1c4760a76ea47298a3e424f63c264aa0942e9d65 GIT binary patch literal 1814528 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 z zIyqcvy-}lwLMSrd1fMu7O9Yp1RYj|^B|?QxZm+abbt~Pl(Lo^;v+p>j|KA_m|L?*> z#uP#noTKDzl)rJ~djHKX(50 zzR{Dfh)ZyNgx3!J%6Auj3j{y_1V8`;KmY_l00ck)1VG@&1-|G1{m}XUZ~gy&t^aMu z)dq&g{=@Zu*7pGb|33}@q;Q4zmxT2m1{k z=U*#k9LjKNK&Um!`3a8b8Osvpg%`AaedN)eAU(gz*O=EpD^B?E_<0HLSRvh)Bd@&a zEhzsq0l;*M2GapB`Mm?6@!{spMOhz7iA3JM!rP9`JArzx;f_og>s1Y6ABk#C5O9Ta-9EG$}MQghiLRtv5(>K8@&f!6v zgTA;{Y#M_PzSo$f!KZdcRI1LLP3(X|@N_+5MAl1x3KdxWZAHg5mF?7+yYbDkcrxQ1 zEz9QS4rJVKmYX;$EV7N(=zsjxgDXJ*1V8`;KmY_l00ck)1V8`;exbmh_y3i-nz`&q z{U7uHXIjo&E+CPWiKBn=!V_=)kow2PkJraDP`pbxbgT;}+H43ql4R_edSpsy8b^f) zm+S;p>c>9cC+avIc`ooV%Vnc73jHu5%48yQ(^=<)g-X*J#C-}2vDu)Id70*8YU5A- zy8e%SbNyfC0$0IR)o&)45dc!;M<=c-HOD%`7sT;TdQ5D~l_YjK8mP>&}14slc8X%^9?d*k%ttoztJ9% zw5qz6cA|L?K_6~m1=2=E=Zig_cu<0^Yhe=Mr$I#-Ge<-^dmBxtM#aP_?PHUn1n;Fe zRM*8n^oSU7gkKsq6SkJn(oo<(g8Oi2frUr{J(k%N*liKAb@S7@hu^ZPp-qml@8Ni! ziuU}T05HE-)Nv~TK;7=+>Td}Em~jAX0zfV{0f575D*=G;2ND3^d`|!*r)yN2pWI`& zcJ&YY{~pE=b(p`fRZG~fCd;JP6)C#f{B3jp9}6<;!k_m4k($%E;Jpi7WB7$HFZ>h; zfB*=900@8p2!H?xfB*=9zz+-jC;I=RS}*~CYb1eRE{oz2%ARRlkUV{xi;VufKr1(k zw-A@>Mo!F&4wJ=-e@XzTUnEcyuoqWa6{Y2G)NN!Z6^$Qbd`natyuv#~&gDQBZb>RD z%b(OJDbQX}dyIB>WA*iGF63H#*aW}{`X2}YZ2GSW0Nn2J|Ciqb0Af&>R)NF2oNuOx zxO~;?co{cN@9RMD%ad3f5IIhU7KjVoRnudjt&=VwTseSgNXbFbqt zt%Om@%+i2o(cy)YsoqVGKj&Sb_nRK`&wO=Z$%NtF-8*C?&4h`mH}6}&x;Cq7*Q93ySX{E~V zr~dnW6YjVLI$&F5c~;@9{dlbHaS7*?6i?R+>Q8pyCEywPsRT85h3)> zqS;3b*@L&7EGo43twwd8y)NVM?wFtSm(MaieaD<~{K`rtcHf`4*QQ!{CcjVo){tAA z{j;;Eu)P#R-S?&(^#lr&#tkj98+SI~aC8ec;!X5KJ781y=$N>I_$h5t9kf}yNxH=h zQOV;8)wFXj5%GBMkp0Hrsw7R?;v8;=8)}a4jlnw`{46F^F)~AauJ1{8#FHd_S&y!< znoqW7{EhDTtoQgMIX7O1)}K@u$(OS$>fX$$?l0-g*yH~lF^7_UW4>X=0iLgT#Ays0;YjNZ8_^FL?GZXiE3NdV zHOLZSK=4z?@6`Vn!c-!;dJOvQarEd32WCoJ2|Y4AqLAI<#$Llq#nDBj z*|WI;(6j+@|3tbdX8hkjaGmGeK zcx&`K+aN!lsJM4W23A5+AK(7>~FRHa{g6*^3ER)-~T zA4qKFc<)7d*^)qb+-+>tjh$9BhV6Frqww*J@nFK}x7Pb7J>J*R5ih%6h?Zjh9{>ON zkMaLf6WHnh2n*kTx&H4@>Hp1!|33ZySFQh(^BZ3@Kv{(gI+Gkw32@Ptv?{+=X>pI< z!Yv_yjY2#0=&QDzMg%$86XGVz+=Y2`U;@oV-2HKEvaX-i~Ma1ksM}Z~8QsyXvzAns`LXVw(*KeNsk%2$|0~0cNp5I646$*B`fJOkHI%t3A`Q}<2?=4$3<86McUodUalhTohdAOrOUl*LmvH<|C#7?Ky{px!?TZ{0*ZR8 zuMWkySIn0gC-=v`GmANCS$0wMEu&n6=N`+Cr|pV(Bl?wXvIKh#@eFY&KSqq-oi}ZM zjm_L6A)~4z`ho6$uHTpcr9atR{`YUD|5v_G{|El-?tjYvY5M=`=JY?gbl|V<{*T}6 z{wKIYw|4Z`zPs>iAOHd&00JNY0w4eaAOHd&00KWQ@ORGt`Rz3-Cj+!P9})75TMccH z{QCUA`E=%`LsV@S#IA?GkUVB|>vGX-JE_~<@Z08PueuayedR_6t3^Fl)IC@j+_KDD zhz6HWuibw2Mc^Yr?4Yrht!GfR)@OTLZp`*StxUBwYU1@kOM7u4vz(Jbg`fVk{ZH(9 zn&6+d|J`mAwT%80PK902cX~upSdX_0HR0j*$+cfEA>YK@@%4U&3rZrTjqOoO797u- z3e$>_{9N;%&3B*5zHPq1DzBchY}PU=*P_f9UyinZf3qMr+)#2yP#H~Ah|56zSQLv@ zcM9g?!h?Hn?!A?HW|Jn+A*+2ry`{T-@Au_@Z4~dEwwC{C*nM34ZTX+?*7Cob*yVpI zmRrmJNG%ZrbdMgzv5gqX3ZeLXtIAsQgbtEQE0wh>TOm%+$sLlmagQ?|GC~QV?hB!$ z$J;2TR?B1_t8*!L%5y&LS*4Jmn%YpFEJhwp3zA7l6LwgS`9{!<+Mz5TW=N%Z+@Bfe z(ad-V%bcXo%samIoz{ofD1ZFLgDXJ*1V8`;KmY_l00ck)1V8`;eyP9?g&#lvH{<7* zntLC*_}BX17L)%sJXUmxwDj&WNf`dUU`qN{g4C7R@1-mr`nf7oV3 z`B{pHGtZ6Arp)?wS@7QI<{x*GasGn^Noxa=ozCUQ6d1F<4*>Z8aR4Bt z>DISvHw6bdvi{`<0GB_006_iw4*&0DKP=X+8bZ2Y>^GpY#a1gdR#?e&%)l zIZidba+g<+zEY!{dA8gRLuP~WVqrvpsL&g+B6r7{vZItU$+3evc zp;Exz_JI9ZK++9)`fn3=aB~xIg2@wl2ts9_?LIYHm_K&@^}f-QuZT-g=E*DBVA);g zFKYQ5KHm|T6Xub^BhahW9-yR?+uU;Dasi2~OdS1_7oK?YhtxkVe!M=Of#O}l1OP6a zXtN>cNWumH%9PMFjtUVj*$JxDkA1#R)NwlUT;OAt%SL4s`e8(r$wcO+v(5<%m8La_ z`xF*pm;k_endW0^<4>xkw*mkUd=CK34rCYDhazpRT;LM9vXP7l06fX_aweZzXOb-< zi7&{_Fu8R%W&yy5@JThy0)Q`1$2S)MWQIR7u>Z;{WI-4;+f9mM=#9$CAa{33w(6Nu zqJLF8Ivgi@X(_i>drYZiUZMQ!*_rHC(~Hvr&4==aSm}-ZnGMen2z`F?x;L!R{6&5b ztyvZ>KMv7Nx!cVS`Fh&qn7Z4^i>Q*uJHJzu{eUUqM-u)hFt*Q))vFDo)TIw zqHwK5gKYEWgdTTg5;aqkgHtdI0CLl44Yx)BngwS+Y%KuP?Rbg)Z2=(WW5DJDz)RQ# zfN!=I0MZQ^Sz{Lf1Xg1g0iONG0s!|owo#+wLa5`uU={!<7bd;c+FStOgINIZ0lNTzSC};lvj89;y8yrhvjD(vB%fM553>NE z++~gWM_)X+4g^2|1V8`;KmY_l00ck)1VG@I3jCM$|6Ba){{KH6|401$IyZkG8mW@R#ZN}>ae?Vw>L$}UdPwFQL+ij_FBI0PWa;>%D{MU_`+Y?{JwQ;p?{x+?<+Ee&w)E;Y{|u{mlf^D&Tf_ zw&&&4@`|5IwJ%CX2u0z$(-J}HJC5s{;2QVR3RC#Y?Uq)mY84VXNF_ZwyjA!oc*Z4- z8u?lx_R`6bOV96+V&GHe&6Ox zaIPr1*6nWl=yu`QTl^<;{qH_AX+M~Yy5c!FmAXdrOW$4iF%SR&5C8!X009sH0T2KI z5CDN67x+8%KfC>9nE!|Q|9_tUKX1K8@#8NZTnPdo00JNY0w4eaAOHd&00JQJO9lSU z{QqC;f0+M=`G3s(zf~+G0RGbdUidK(009sH0T2KI5C8!X009vAae==z|DWEX1oQte z|Nocy|L_*b|NHTOJ-8ACKmY_l00ck)1V8`;KmY`Oslb0}|3A$C|L>dsFZ%}Rf4}s9 z7k&%`KmY_l00ck)1V8`;KmY``Bk+Hz|L3ntg{WMM$G_QSZ{o?9K`z_ZKzvbj#bDz= z+K6o}7rF|MdR}POh0ycnDrWtk?q}^J!l6^f&%?D@pEsW^KU&MYI;OwBnjoWONh#-Y zs!N_CL!~i-$l<96rRHhh{HyuJLv=fwugk_<*GmviaTvRsn5`-0cqE^X5KnwKfW?3J zmnY8~=G;g9wxUPaQTn zfl2@0$R6HI|IZ5dQ?dViLFx>HlYg zpT&eKMrNqb^*yPMc#?!k|L+>B`DAOxk4^u-#~;bL@jA5rq{2vs#(qp|0ihRRyuZwZ zrrC?&*O>JGmr1mlVO~<!$IMRBOByjU5kiUhj_;CgD{VzsAxNzdehrxP z|HaMp|K}-Dm!+~6G3o#9Ye{c!Z>IkvG3o!y*!2Gs1kWQe>Hm4y)Bl5*^nZmB59+~u zO!|K!#TwIgUOl)L1V8`;KmY_l00ck)1V8`;K;Rb&>_G0YkNkvE@OyjeK&ejrsViSO zjF6oXymRFCf2sd37<#fsuV=b=cZg`cGw8R+(W56Em?>?MA6&0Hi5y^G#BBfDd!p?E z!D2pk`=3-vB*$nT&Qh1li%gC}>saxJZAO%zrHDB5+~{n|roIpe*o!NzI`bN$Do|?l z_OkT`&q4#(ZFq*rxg5yCElFi%`I8zY1=Aa|_;~yq@7yfXV+80Ts!IGE1m<7vQ4q(!-v5NEc<$cPn)!@bH<4sXTfqln zHowC6b04(n*_;aX)0cRumsy5qoh^G!Zn56#n;_A&Jm8ltL!K48gU(4&%c8+hu;bmw zN4Y(&G_C||2@XS|ef->*qWi(UHy)qeDm8CJQ|-ycyXhA`{vv;J?wm7++$4^m(yiW- zmydfFjI?zUh`8oGo9{lAecQ~=DzBchY}PU=*P_f9UyinZf3qMr+)#2yP#H~=s>?wA zSQLv@w?3x&e{*`|v@z3LVYLX8W88Z8j{}{33Er8Lx98bscpTE(@hqPp z+L7D`+9w!?{q@N=tTP{s?&#K8OS+t@Dxvw@Zv=tz5N(wtN;_PwnW3p;X>f0XKfXDO zw~emz_2*Kh%Up~_k2S;Z;l^0j2G+PcDPBUIH>1pq?Udu{kuee%C!de_;JnCfXgA*| z@NyB6=tk3^S!#0?8JM8!oey_Tj2zlo3cG*llKUD+3DcTan{inMp8 zu;`U8_pS|j^i%$4qSFD@aZV1;K7I-)>aD&y6yshoUuK-#AN$TM=A>oWMbWp6at)q) zEI*#ME8>mlSGLI#>@~zQ#G(8cF@AU6wD~o5>mCUiRUM6Yey1q+0aL<{^!$w~Hf^Ji zmeo;jam^E^v+w8~$(d|@U5w=a{R_Z_|JxUUkl(%lq-=d&xc64(nN6BNhphGi^_K4T zy&C_+7l7uiF97AODV7M#-aktOsU?Dd?$M(-wh<#)Arzl)RatAE&_PmZrLtCKE5r#p zxkJ)6?s3LLMkpcFeIbY#mJ*+K{5$x!Vc>( z-w3)7a|MLO>vYfSp+j{xnVh{iU5C8!X009sH0T2KI5CDN+Ch&Lq|H%v~ z5-;4;5Tq{+tG@f?Bu{pmV995az%R05IE1oi8W$u_-{vBtKQGYA&EhS@<+_m*^PMJi=q~ z;q8V;XifUx2Rw2gALZvQ@oG~0c1=}qP?LPk*LyNPIt!^1OO|~yRoi}wu&fj*@oK0K zow&C;VQxk*y3skMJdm_ZL-2!##rl(t;yx$ZCAXHDY%Y;Ab)#Gkq6MMSbpu>I$+wAj zemyTF$`F~`d#J8|DIbrDuJS17+c&1qajNN+yJ)j|`*eW*iW!R0zdC9VE#sBXV8^D)4rgZ!@m$Z4}jR<3Arc*SL!={rHMVbQ+WcM2% zVm>Yi$%wK(k`kFPQA&M(_AbFAx&FtMNT#~TEOD)}qKQLyD1|#iRH}>boWM>Z>|6e* zZnwT({X$Q=k(;h@k2IdpK_cmS9BHM})@~sbqi=$H9NVZ79o-}ExH(G%1)Us)v{FTD zyA?uO2({BU!7I+;L7aoWxK?Z$gAcyfn54m{c1BdH&YVr`fI{$eJz_-GOMeO#Sp989 z$2FDh)R?>R&9Znh;~g!_=H?D$+;5hfI4dk%uCE>aW$!Kg5D0((2!H?xfB*=900@8p z2!O!$1pZ6U|5J@10N{UJ0D#E*HQMdHeQ-4hfB*=900@8p2!H?xfB*=9z^@YcZ>|6J zq5l70SO4pguhIRg_ZEH!1V8`;KmY_l00ck)1V8`;Kwx_Uf2aN@*8YD#|9=AJ|Nl7w z@c;SzKfc!5;qASBa5V^k00@8p2!H?xfB*=900@A^*;$c)c=tG_t*SCPNKCV zzv{h(-vI#-009sH0T2KI5C8!X009u#p1|L!|MxK`3u$H67tG;QiITh?yc-);yb^pX z?6ukyu8`tElLV?gQ#SsyGMQd3!WwU^a6hJRD5t6>GjO#_TODkaj5dlTPR9H!cSlN2l_Io++7mwT4^rP->MyLEfT%7bhB3blOE5kLizB@Phzu zM=nn8nHHN_&Z>Etn?dE4xi|9YN@ zB!U7H>TmVfUh$xpZBs|WxQq()0VI=WCn`B()@{cazn7)b%EvMO-NvnUE}sIo=;?{3e*Jw*3T) z-?#Y^oGVJMb-UX>x?MQ-7XQgy|GUpj+7ITUu6Pc5ORgRIRqrkQ4hVn%2!H?xfB*=9 z00@8p2!O!$1pZ6w|3+Sz|Nmb%|DR>GM!&tc53U9Q5C8!X009sH0T2KI5C8!X_*DY` zt@S_T|LOg&tN;6+tTFtm_ZEH!1V8`;KmY_l00ck)1V8`;Kwx_UxR-a>M^<(=%9o$o zM>s2SDVCFAq`GXGm0r}L%@>7@Rq1`Efv z>QfJz@YuNyaq*e4zBDNd^)(B(G&Y`6*SKkhKQsDHMP-pjSLnjLzSyw})CuACYO2>K z2qJLiqO8}I8z{(8HWWv{Moq5QyHo1dG8K!ROFZq0bMH#lCH_Xlo%WvG!sxG4iED}c zgHC50^GA>rB>N?$ccb4e$Cf(yxMW4f)Vyc3B?>0v@6fq&#La0ek>sYti|n&SWypyh zm)q)HdfDt8m*OAI-%1VLD;35~Gk(Q0NuRoghm&Ufl&5h$&s}00)(Ttwury-wIv#&w z@_HUIngs3&V*RjKVjHFkAN?>rnsF&l;Z&Qxm}TnNu8fqx#U+yuM;ZLgrq4WWGo{@*#okkk@#&pwYw{2`ULL#!7sKBr-S`g}g2qCv)52OJBdF(QkZ5h@?89dqMtb#Z5906Q$!k_KNeCZr z7U{EFo18H(a4N7Yy7erSy-C@4|B>vV3@&TI19?8J79lp|;im59NtdoMf6Jj@v{yEt zy810nmUelsVL=TE`izcWYjFlLxGA;pMv>X!a_4%UD>Mlqx`!*W^}~+RByd*X^EJFA zZu8eI;6t)jNbw;#Di-v^ii!Cj>w5AvcoFjl=*k;}@zadIo5+=z96c#lW_buzoPP$fmXR-H=VZfocj2Y*#Zmkd4^97ho}@6UT^aAyzz0T2KI z5C8!X009sH0T2KI5ZI=`_xitiv;LnYO=_Wh_?&7q&VKg&X>z>>-^diO<-gIZ#%aXG z!LGn`*G{v8_&QhLDHTSA4=yZKo_a8V$DT&lWMjsfV^T)tYZh#6uzCEig+CKm-eI>v zql>72XuEa%kH8%N=U|WjQ!&T?O%&w4HZ)tu|6-gq0q1W!`DlCN;0DlsKmK3IEezj0 z{(tjDJ5W1KNG<-1d&|YT0v;DuOG>?Nt_c>t{9PND4Bj9cyW}4X$*&~UPD=;p8VQ6= zG7hGbMmYN1@-Rrqw)&bjpLuuJ{ILqmCx9GcJeq`~6?8Q`S~Sd$bx91uqKVr=btP$- z19Y#^7#^-5HVBjQq^aeR=4(**6b{jq*AHuBezoD{w|^&Ry@-}Y`Z@8>b8jfcnMBM& zE|SmADkOTB1z%f4cCKXX_K{ex^G|R`+v^(548U;ZMFYvPW0$*w*Pbg*8b1=PwoFQ z-`oE={%!j|BewltiN=tlBC;d@lY+BP%MJC;TEkl>7X1BK1il<;HO_iC<$C{)h}l9K zMe_B`ru%YN7lzfe6XLb$QhXTvYtVE*@1en+K>!3m00ck)1V8`;KmY_l00cl_n*!UL z|34G<#4ciI85Q-HcJu4wf<+s8hovU&QiPIFg$o3!=L}t_&PC>BBkWQ*3I*K0SWUlp zvFgJU8Sju89iZEYqMI5e8bGN%dinOhR*P^HIR%AOHd&00JNY0w4eaAOHd&00JQJ(*(9x|Kr(9L;l|n z<^N4)qM3f$LxUTG00@8p2!H?xfB*=900@8p2!Oyg1-4iJAGJRN_5Tmm|CA@ttlNAP za5)Ho00@8p2!H?xfB*=900@8p2>djG?bZM6_L5Nl|4{vZdF$jPF2!H?x zfB*=900@8p2!H?xY*XMb`G1tp|Fil3N5T!x7Hp0GqcG$Dz1Z=8Rm}MR#KYa6@_jbP z|Hq;!^=qFMi=9h9>xvWi_w)bb`u&cZwVLv@oh{a35Ll$1*;9`+9$nX(Fu>bCe!+7k zMAw97Cm&MUQ}{7<>)+uDx;h>)ngs3&cRnOj#T&kcQ=T++JV$Am{dIly!!Wb|nDDPb7 zjn#~#YI`;Hgx>c}gLc{i`*e%-!z^eLLUa#f6aO(w0NE?>`5I!0+X8i0`H-v?QhYuE zx|_j&nB{+%%Acvi#~@6PW?afs*vz^wW|>;ICDSxuaq0LHCjLKn_DE~EGtCKH(r>l} z)SAYf&H7QK5v9u&>91wj`3JAiNQic$5B$7m26qMl5C8!X009sH0T2KI5C8!X0DBHBd| ze~xpxJTpltZLb_Bdqpm`{_jmN7C-7^s1cr)sGMOaNBK2xv;IF^tP&FQBLAAC6PMnb z68==D{6qqpYmUZ0ty0|U1wi2y)YU@ z2B@sRomSs5eW8+KhoPFPOkQb5a8dM1iIw2)eMg+HR_0VXq!GzJx;*P)pp>Xdi@L1p zX+~AH_AFbj&AE!YF_TYAA?a!(ieuf1z{0GI`IL1shlGkvrTda5vy96>&i|tio9;hc zI-8)L6mE!;m~!s>)TX0VaL2Z&>scs!lZwIqqnSaOTtrlRB9BpLSL91E)5fVK`GnQp z`6RV#I_ScoX%}VVQT~c>uKA7Cnl8Q9>?wTlMCfS|ZrTStI(!YUh}&v-9_xzmHDG!G zf^~P$j4NUb|LEV({%_M59dek6 zBzk`hzP5<0Dlov5|9SpY8mSXbM@I?YMxpm?^FhGnAOHd&00JNY0w4eaAOHd&00JQJ z69u-H|9{f{6y*Q^Q2xK551RcaJ~p^D2!H?xfB*=900@8p2!H?xfB*<=OW-g4{~;1? z|H%J)%Dk2TXCBdS{IocoMF%&v53#GbG%xYyN&b?_Pu_R;MX|AS9pd6MV|{5-8|rHo zZfR^huC8&@41Xr@or=mLjjoWwygvWY3e*YV_G+rvCkXm*=Ax|El{pTOqiiUSevO)3 zugBx84LI-YIIOdEaDMK-U(am1FL!leSWP=2UYjn( zhvEKlH0`#Y16&LOAOHd&00JNY0w4eaAOHd&00KW#V0-8P84VO03w!cyg_2LpKQX>?6CW~@0TWmLXq!PW-GQ<(FAEzJ3Ud57Hw&5>|} zvjx!sx{WA0)F{zFubZ6fvZ}Dl@rj4KKjr)E|JG#tbu5}vzxG+N*tztxt~hbDS-<7~ z7lwbGN?c1U{h}SHohGCff5yG#VqF1`3pW41n`?rFFMrp@B~1Q*W0(AcA^DZ0xPHIm zX04_?ZD)&h7z7rnXZF-1jYrqDCJgZQk6-Xy3DGs7*~y2L_7r}sTfm1rTtQd2b>#2P zhh(aF!`E=ilctX6C=Ii}uJ7jIKSxDm4Nsz+`5HOHQR2%Xb_E04$HYI+y`dCm5-|(8 zNWK{WP=*Zv=v>Lz?IW>X=biF)z9@JOZ-W9&vYp2O*Ma~DfB*=900@8p2!H?xfB*=9 zz)uy}-uZv68qEKH_@VRvM0_;;PknH3a}WRl5C8!X009sH0T2KI5C8!X*oMIN>VKsN ze?I^B!_5B^s%na8>h~&M>u}>f)W&%}!b9bJ4!%$elzxM10%HzijUzFrZ;(w`AIP?*-0l?ewUU*a1#%e}dwUL_o zGg;b+najU#08pyMYyh~txd9+#YXiV!4UZNLbC5104ReU@<}yH<8lE%QgaDdao@%}Z zFJha^6S)#|yprj<8Z78f9WB!0^nLH{OC>h)y}+aYI+@*CsG1U8E5aafxAne`gMWx) z@hd(T9Q9E&*ESvlTnYjp00JNY0w4eaAOHd&00JNY0zXyY`~JUL`3fG){=X7L_W1(E z5WJC#LY5;qWRfZxO!C1I@>i03^c9$fZaa8OW>Co16A_CaYie)~>|?+?B0`#ymzh^% zEAMrYs5sm7g**EhrTV%Iv!nJ5RJmzrIrm`>&Va=r>&}$gat5{8C8d3bihiBi z+N523Q-WFl7vADVJmz)7uhn?p;nE=iovrnMrhT6hOA02ZCmR+A9%I`7mEzC3w_GYO zsOeW65CyOZCB!c7D=5Z2SL^VAv#MUpnb+v2%sxd@3TZrqdQP z@9vsst8lL6$sxw0NjO$PSHojQ!~9s6#30NUy9!W}hB-j@8chOA#ezZDU1I(qZ2LcE z3*c7!zxb;SFTeecd+S9sEYdx>KF@U@;9|NQ#eI|k+y4J(AZK&`AEy0Z{9T=Q_GbJ4 zUVR)i_fLInaB~m<0T2KI5C8!X009sH0T2KI5ZIQ$f5H5J%YWhgKT9NVqA z{0EOne!2E9c4O>M>`*()sHmG?h((246s+kTmYTS`H_xjGD;i`1X?bS1sa4=wDh-+8}&LRo~^HY|k1=1E1i zUD&Dn!tJ^uB1pCSyY0ec?t9sVMU%93>FyM1P`oevR`;Ap!%GsIrxlT%zwQ6atu=8v z5mZyHrzRt_AfO{}8HACe+7E%;-+j6kINv>_L z`5vO4Lu8A$#a8yHXiA!(iF};g3=CZ=KE>edFUQRP3r9}$Dw<&C|LOXUkJW9?{}=2U zVDU&suku$Jg-}dx&Ho$uV&?ye1aJecVCMfL*_pE^_)dSu&i^}Ietax&bqQbB8wb}@ z&~R)1f8OjC|3-(x7lqiFBIY7Zt2EjB)c$cncDn1B`oHXnR+EChHLqiQ-GgvcdepA6 zsLx9G3mH^;pY~i$@OCZ{H<{ucpa=tFU5!Cs9@ql>UeGr{~Iz@(ADzj(TuBm3j6EIN4#5N5wH62iUVz1RCI8q zrkec9^5YNL8dY-G`k!l6?O_MM#zX}(&(~RY?o8R{FRE3fWLMGqw)Gs~Vh{iU5C8!X z009sH0T2KI5C8!X_?ZIR%m3?Of&Bj;%m1&rftpUD0kT41jmH_voZe^Y~n<68Bp2TgeFT!*;$%vfKVl!f}5g%6eV7fr1=mLvi$L)Z}`-JEeXtQ?b~&#M7=g z_pW4J;%`LUY46D`jQ%>6xR%I2=yb+0e*{TEvR_hqH~QUjY^j5fOIBn|&3i^$qF^%q z4xKAU+?>V|Np4EK$Ua+ChMeeexvk!%m(9*`DgM#?t<=!HQeoUQ<5xVB^r>rjIBCXD zc^cRA+$FYQt+3S(OCu()n@y|yL6jSeN4bL2TJIvVTNtPVq zJlP$xJ2b@5H`t)-+^l%5mWoQue$RP?f&f2Xibmj>+sZn9T&Avmi<7<5PTOD?eW>%komkacIipIi(48*F z9!d9=0NrAPFj>#L#BBlCc>i2t@*2#3KcuwhWF1c|F?lV|OX9Xb-BrGZQ=T++JV$8^ zx6=Rl8Z@H%zP_p6Rpe<9WqMQX48w~3H5&%9D1qeXB=*aRZRch#zjS0qJ9pz(F}REw zT%M{dt6Rpknnu(7%*O`z1_2NN0T2KI5C8!X009sH0T2LzZ3+BS{r|irMB=HokKagH zAfcSkk*CbjHJ5gFx0pxt8$T^hXVJk;?L+J;F3n54d6K_m@{{-7ef?~|AOF{WKmH%b z9RDA}p9$PL{zoXx>+>J|$MJt3&K&mmpX0zkj{osEYXi z(z+$KIsb2lJ^s%b|MT(x>8<1cg*|^f{{OOd{I5CDql-QMf6e{d@jvIEkN*=mvB&A-Yw34PL}H$15T`w(|ch)H`bpZ=Lw; z@5dtW*25{+`*%bREu>Q+oO7bF!WXkH(M{JNUoZ|4&!X!@}2))NFQVM9;^iK2yG{FWKMQS(G=P$V-)~zMD{V zy>0Tzop^Pzz?WR6J4Q)geP&Evbha>9$LT+bCfd$pfNMbj1V8`;KmY_l00ck)1V8`; zK;Wkee6Roej^?pbRc+!2@|dtrj6R{lu z4S<+00l!TEcoFjl=*k;}@zadIo5+=z96c#lW_buzoP zP$fmXR-H=VZfocj2Y*#Zmkd4^9E(F}o}c>M;N~Cz0w4eaAOHd&00JNY0w4eaAg~>Q zf13YKYN34ooN6@Ae)j!oa=i!N$P}>UztOA4X~f0BuE2EHPP2pfI#=H*6-I>*E-Y1^ zdN6>;o<`SXW5$|eQby%#7Hn;>8UL?^ng1{Eu-l+H5^iv|AUZ&|5k-d@CBmNnyDqB= zyBwdup8xyo|JG#t6?^_)`wSERpMKUACyw@e{QpXBVfbeJf6W)|Kf$yD*?_vk-ne{4eFOJbX?2tYaWHFAcd z#Fs#(;5j@#5j6RB z9s^tp0w4eaAOHd&00JNY0w4eaAOHeCRbYGb|Bccx|Nmq2|CvY73_tb3!OcMc1V8`; zKmY_l00ck)1V8`;KwujJ+pGU+?WNEHd)>Hsrjz=c8Y~>ws!u&=!ux#zK-u>N08^L+ z0A~0zqgx9Agf7hMiyiyN0)U9E1po~c|5yOvj%fg3!ZZLRo_58#cjbEnKu>OA^kxG9 zKXw5?{>Yyf0Jv-|0I((c;{t%2TMGb?6Fn~21pwLXzbydR`{xA!v`@H+puC6 z0i+R=*YWrhlhHg;Q<%VwS06yE0M&7ne+ato|pWMzd_= zF~FrD00JNY0w4eaAOHd&00JNY0wC~H1-4iJU!cx5Z#%raV>B8Q0I;6$>JG8{2hog? zx5JEWo@B|C&Xe6CyF)_~e1i?T&drK9X{o5h?Dxz3f8PQquOHSX@@m7& zZ@=T-dJzqabWh9xK==680Kg&a0KlVxoZkij#4!T^+3lMH0CH7m&Y$|=;N~Cz0w4ea zAOHd&00JNY0w4eaAg~PqT=gCHk(Hf|*!(}jS&2)roQfB@tEA_KYVR>u?JL=u|No$N zGtq0cINF&YdphCtEJ2l6PG9(noW(clU9C=6D|0Fx(uiaqU7qzYP)gLKMO{|)G@~k8 zdzLNN=6p`ZP$N7oQ8~j6z(r5Y<2tpF#dn=?~MP8Z&v?1IqOBVEYiuSR_w3IQjw){h4_=& zFDJHD4#~cBWY*K_#;;;9A3LjxUKyxc#{GN?y>}ZA0WJjr5C8!X009sH0T2KI5C8!X z0D+$@fUCM$|JTcxD}K-a_qNxdW~lUFr$SMmd3`LcCYIPz(n9z;>iG=%$`c{EdqYG% zStbe-4TAj}y!)Qc*Lbq~c{hv)3Gq){Xik&OvqsFB(ya-&`B@DMUfS>3mMx=7Ue}X( z%&*|taFMY(;e#2Ui3w}Nu$FcepXFN#p`nDRz&KHVG_T0s9r)Dm#xL;aAhTE^%q+Uv z2K5U>qiXwUGrf;pPgr=c&r!CUGM|{BNpB%yOrJ5(uZ2@iwn6!hna8f_N614TUE0;} zJKjs;%-r~zF zYK8FyCjCFD_k$L#0QdXX?s8Wb*w~xf>YA2Rt4KZ6(0o7nvBB*@00ck)1V8`;KmY_l z00ck)1VCV00^95V@1cVHzaN|bZ?i`;ZtFq7#UKCzAOHd&00JNY0w4eaAOHd&@Dl~L zSO4?dpN9OuqYQp#(`TNx8Pas%l76$r^Z>A{HtR=`MwEW2NPjJJL2U2}jRc1U`uI-f{(t8zX;KU2^XF8farU$CPm}9C z__j6wZ}h5h8gX&3D=^)))9fI=&eeBHg;C*y3rm%!9t_~Ir_nXpn6c)Vlu`Mb1zQ^! zW8?p|@Mi+cJM1=Sj)WVWEr<@#ZA8)iANKA%5bCx6A3w>KNu)3#S)#0CNGMB^&{!f{ z*1;%B6e>#;HIgaGHbZn|FS`&z46zDZdh5TaD=lK7)waZ^1Ve?uf}?~D=E?Pemxi{?yce0 zBNi{zKX6Bf!(X&&jFdKwW#jan59csV9QG0&q}Sg>VgIIefDeNJ2!H?xfB*=900@8p z2!H?xfWTiV@Q3<;XLE$|T}wjntMX8KZ35q2q1YOIx~}F^(JvhCmSzfDQK$FHFqA%i zn0$7RblK>5&?S}^JAWJhSNqHOzo9SV|3bfv|C7<3wv!h4+xWlUFXR8jHvMhi<%N^i3@Om*oFybVDG*RfK%Iy>MLD zo6ziR(ot)FZr8hzU}4!gz7~hvYhxD!d=;E#GB@8pmeUlVZM`^PY?+j3$(=^vrLUlD z_$!wUz8eHU00ck)1V8`;KmY_l00ck)1ine&5A}cQYW;8iE%krQ|6lzt_s`e=IxF=* z-B*^Tm66Ap2G7@>i{1H0T2KI5C8!X009sH z0T2KI5CDO{Qs9^Re~%7%rT@SGWu;*L^fncLxplOgX*C!QJQBQjd=PWXaItm5WX(i9 z^$3l9c1Gm$0Kk2hCv^%_$uELMocebYN6{}c zgS{22iz`G7in1mo&UdR^UbuxV#SzuH?v>ru+ zwBNB>`3oTJ#mLeJN;00f`<9G%YI`yoNzd!-VY0*yH8yXf~WwvGPen`ojK znk{j1&ESTDcl`Hfy`6E3RJ`*P*1vMu;JZNp1V8`;KmY_l00ck)1V8`;K;WAMzCQmi z8>^b%v30LUb0sIgV;?`PiESzRJOI$ku|Rq{y04Uzp@o$5s&#Q zN6xp?vs?9-`d@3M{%^a5ykI zHK=5CgK13fa^(|-5ml>%SY|LoWPJpXU^lMXoZfRcdB3K4dQQ!J1 z|F3e+GSo6d&Ny-Z<>te6MJS&gF6_2l62rpiLWU)MTqUNlQ|D^G&O&PK#KG|VqCE-cuHcd$oL{h+%+f*q|i+)GmaRGXp6+EB86^Y zZIJfc$Os%!4Ueov9Yi;*g#Sfgb?k_3LIq2K!K`%R^$Hfwnd(aKrYhN$1Qnbj4zo>8 z>Lv%3huh3zIu^1R3CfFgL20eiCE-&vj|-sw|0}mGd^ZSy00@8p2!H?xfB*=900@A< zHwyex|JUnO=&khs^RC?g4@%)0jDP6zMs+3szo2rnd>FOP$d%jD+Rx@@8K2*EkD@E* z;Cy;dF^1$^^wD;k+VG|Ikz0pJjXO`aED|fH9b~sF z?zXtuyOiKfk9K{o|ECro#3F@chSBPad)n&j6&q_0$7*;HKHvY}z0isgZ~M8$zIVd& z!+lI-a>$HjsD+rk^od}Gxa7-DA@wWy|LSF?Izs3Lh8KC7fuym_^p*VokW~K{!CNSL z&ZxWt`BuCgvz+7WI#aU?Ba1ug=|mbLnWxjqM-&il#0X~BpU4l~i7El|&#(##7~=p& zccMl>pgS>^xvdjRr_i7mAm55rS7^v)cD+l!-SO-F|NL40KHB*X~B)|HhSokAnaRfB*=900@8p2!H?xfB*=9 zz+Wfu)%kyfGXJ0E{|EQ4|0@6g|Ly$0l@x$q^Z&mo|Bq^cBJ|fS8hkSdfB*=900@8p z2!H?xfB*=900?}ez_*>ij=u5c2=OaVNsZK>!3m00ck)1V8`;KmY_l z00jO@fv?X0|Iz*b0MtH;?0P>*)I{owrUqxvk2c%X-d@^l%sgBu8+LRh|Nlw8R$-2e zdzx6Wgx{Rzz*x~T0TqQiP!xL$+Ze?iHORD@|9^4bNZvS)xd zP+_5;RMw9Z*E=j(eQ>J3)?cWarEH_F-AaO`bFa`w)l0&*vP?SNt1y`sDWc!GHNKNySPbK6 zSceYb7b37*kaVkw|MEAnMQF@6GIt$H5t$@OzKq5Qk}H2p{uc^a9T1R>a9!#BUzq@) z^!xa~jT|fGzZS>Fbcu+N4Sy^DZ7o*g|4+R+U_|*`{)=!>Hh$AGz=uHq1V8`;KmY_l z00ck)1V8`;K;SPG`0D&WLfP+6@Bd3;oBspz|K9(L^Z(TUjro7V=mrfuvi_Uq|Ed3O z{-5~I6p_Dl-QdeX00ck)1V8`;KmY_l00ck)1VG?h1l9Vusjj2)N~q- z*JRZnxP0^cnp4~?eA*6|1LG6KU)eeRtXXu=_FysFKCf3e4~7I)6Sl;p&Gh_+ZTpwX zPCm-bEvw~Lm!_=g(&GvJDG`6nm1Lb#8D?3pc574iqsna&xzZy3?(&#f$Gi^%Dy|!o z2Rtq^lJ=+Yh042RE4kn`KLH9JnukF0}b!v0l62CQ^{t z@tII*sgTPp*|(h^<@T0E^)^a&&TqxCx0;K&@i_VvbRyRV#J&wCEZ`VROD^=~q}wdb zMd75)D3deszR&0A%lABe>oc;UkDf+((le&5?_tfLtjF_`@F)CUy>^*XwY(nm<@0uK zU8C=>Jzw&jcuZ|(tAWUqjTn`d%S%UPmy(CaN<@yN=*6jS z&}aTxOpTyM+_f%ZeTNEh;9ksAFE&D$1CO<><4}@@2wFO7&ymqJhO(30dM%nC-mDQZ zU_J5ZtmmygjbY6S^KCcGqqz!AHE6q^?+zK|cHbJi-n6*2Zi9pkADh#Atvi|hM*gnT zR^by2)1ma!LG-z=%BeOaRr-5W`tO{!7Tb!sLT~V<{O3vQlUoU7|I;3*U0X3R^lkm+ zG9IYny+rm6Nsa#9gXMdhED5Lf_UzF!v(>~8N2d>=+U=rBSn?uj8>FH?o||WX5MHOZ zhec55umeemD*dg{YllZ+EmnMFXT(*ytZ&&=@L3Q50T2KI5C8!X009sH0T2Lz?@r+F zod4f7Cj`GL52e>8@ZA-PtUY)eNpi?%RnJYsbQ*}5t|-bLxrUmJ_VoRL&TuJ;O*h-f=Ibyl;E?!fh_>VV_xR{pR6&IagVZ zYMDk};aX>2$(dhY7>JQoEz?Izg?{Q`WZk=C_pa_wDXnxq{v?TM@`vV5+eeaV=tL&U zgn~2IRn$v#gAv}rjOr2)23@4bpxGS#Y)SUp@p| zjc!OqxC)VPe|-L4SV^7pff&WDq}9!vh1Tr+1GYMCKtoVfpT^WnN8 zl+O+qcH1tAVPSM3!;(I(64ThJbG2V*AvOL*u!vL3NmSc`l>k85SM;(3i@ys1 zbo^HW0JTqjWaAY;9F1@<>a*Og^lqw>T}e>EDdI5O`VgD}I8y*S-KmY_l00ck)1V8`;KmY_l;KvmBL;au99HD&oPxJpa^z(ex z|NmmAs05D$+G$6&V{POOCz6YU!_Z3o&$CkhKQ}a-MPg-ir|qN#$WgoGpFQDtw2QWv zYAWW;;t{b;Y*DV81(st*7wc)nYj0_Kdl63gQ&Hm!?9+#$9HvroEzT(}wd>C5I=%GT z@0mA*+04wUdXSOwd_L~62Vr0C?K?HE`DfOJZS_moI5J6`>}E$)!OP!T9R#3@XT%XT@PW9MUVzUd z09QKzB33&90uinv`$PXf&rIg8{r`)9>;D&tfB^tM=07NSYY+ed z5C8!X009sH0T2KI5cp07{!ss?HvgmZ|J{>U{{!d$mH&n3|Mi9xzVCF!;jusf1V8`; zKmY_l00ck)1V8`;enf$<>i>T<|L+{{kCp$I{rmI(6JO5%|GE6X(qhWCA8|XuJA(iS zfB*=900@8p2!H?xfB*=5rvks^|2@^IP+_5)+>pB3|Np1?|IU{>oJ9O2Q4^^zni`xv zKiX_lJ63n?P(TodODpZ@yF^pg&e3qID{)dnP5jWK>myA|IVg16p8P2z2UJy00ck)1V8`;KmY_l z00ck)1b$3`Z#w@E?qC1a{r{N1fB)aNrFYCE^7u;5>^2b4rjmrs=td?qaN~3*7uT0phG`73dt{<9Z^ zxY|(Y1k9DLo-1*WPv4mGDMTH<`b48*Bi+bA=`P=XPoJlrEvW{{Ix$-l(A>L{_*t*1 z^J#`W+Ffq_JWJt_$b~Fsxr8LAdk-w{PMgdZ@$qWwUZXDl&`V1vY9M8?Tk%A6M<43W za-KlvsAjZm$HCpw<~^SKpJzn!_k^38bseczV9xG~JhW)*a;og!xr4-)3PfcEVhl5# z0x_0(D1ok6``)Ss@dp$kx zs_P!EnHaEA`!4qrJQN6k00@8p2!H?xfB*=900@A<_bKp)^Z%XyF#rGH%dhYM|4IJ; z-_HO4?fie9zjp)R-^&00_58mrhwSVoJDHQ0z55>_FvFaIfH)b3gNh0F>mm@ZI9GJkbiIn=#c;*y;==ElCL#>9_W%;UWgX^?; zxP6W|(3F*%b9A4+FhY@1+7yx6TIhZ*y+UQ-0JkdaI69v zWBl9nzgR?DB$f`{pod4+qHI?$|I0^WCA?34WaAZ>*%INN(`~ih;`LzQPIHY13RVY{ z`UmdlaFv)ypEBfdB}A00@8p2!H?xfB*=900{hm z0$?tW6gYoAlU+-hHz4~dRuH8hx>3gW*+PCXX?ZO9V{+-+5}^|F(-~R;3~}*c z?$|}WezEE-izZ#WGprvH>#mZbGGkcEW8N7YEao-rx!Y}>6y#l|baG6pZ*v5xwR)kr zsh*C%Ardhy{-p!p2Euh4+3j-&Kp55&jj{Tz1K<)uIt;6h#_*H5KX(9_;N?TGI?>PH z3oEH}J`kh0m6T|CuXF&2duzD$h{X%7b^vhri&l-1(xz8C0OrFvOcRH_RyqKz(kL81 z;BJCf1_2NN0T2KI5C8!X009sH0TB3J1=i@S=Kn?M2DhqgdTf=bVzw-H9McgkHN|#* z+FC8b&?a&1+0OHhcytz)ZqkPyfA+(WaUb@bWh#BY zibD#?a!1P30~G?bLLX-BSf9{lmCYIC9Zk=$NC|!=6Ln>8iz-vbwkPIU=2k8^|6%FG zr@2yX+#Qdm9vd8$;4ispPV%R|<5C-1bJ;O~y>OVVFi>Wov;UAttK6sLEGK*2mv`E2$aZt=g>_9u`y{=G z>Boa#^nJ|Yxa^bc-h$NMdaib`#ec8<`?Ix{xf*y<1> zWWS$Q?)^_ieZ$dKFJD*#Vou8)ge(64=-!=xn$H$)B8|+jz;@RVvaau-{dwu_LG44hIZf)v=wu8s7 z$wh6vkwl0;?II&_qng}u#6`xCTYLRMgC{NA1IM?>MG4&)lDaVzxZrlB$OE-eFoG#O z&mib{zE9QDE1t@RMUrh-MYrEdJ)yJp)37gfeiBtUTT(Y|q*el>%3yNg8_h>7gI)!Q zGU_9wkGsCteGbnB0w4eaAOHd&00JNY0w4eaKf1s-o&N`*_EBWl`$?iEQeQMRID3Ay z*{1gP(q?1k;X>K4qj~*IPx7@2b7b7p#EK>S<}?S!ik1mC8*=z9bZfKhwV4~IXq}zP zg;c!nb1R3tR$YE?UVYW~n8K$sx=cBC`Y*S}ck-)TY`JclO0thq9`o*ff$^PfTQYd% zm8mIdeEWVYpX$gCoCT-yCb=M~labSGB=gHYsc4&|p%cPtF3F3}S|$#L=O33Pj`F|E z+z{nxrjfwBuVmR zG)9nIiEdEABkNECNTCqy4Lf2s!c~lXy9Sl4{W$>;aWulcsLyh{(z~fjb|patr-;LB zlasp1LFM5#vzU&BEJlLzVqH*L>vT!@6peB#Wz%=G%J3*400JNY0w4eaAOHd&00JNY z0zbOIH`V{Sk{AC2_y3#!3+w+QEEM)1eQUw{g8&GC00@8p2!H?xfB*=900?|X0@TH; z_y38FI=y-dIZsR+*Waf8NsW+(Yzub}^T@p!Oq$|&T^KatX!OoLw@?!m%Yi%V zqotE(V)JYrZDg-sFT-dycERY4I)m8-t&p5~ccBxy+&-nvetQeW9wd+Ca!O+LF1Lj2 zk#-dg^Ub?&aZYi`n7Fm{L)_fWpWk7Ol57O8lF-?SO#3e_Z6c4K!QN%rz`B%|&Yqnz;w4z6r4t7y+Tw+r(hiPa7|J(i-A$=V8Lvy&nYPZB zC%|O*iTJXVT(DKU2Y-VzPXjMcgE~D859T2Kv=)6^d%2ndF_t+g)4#i|yi$RvMjtw6 zO{YMNW42H5M^daUDb_*?#8l>?>&!z=7oVtknNi9rZdDdMtGPyesqnf>O8!;~%=bQC-RZFR0usA4aV+a^<$P_OrQJ z@y80<{{2jZW9_j`4ZB|~NwM6WuEZY-u5TC$lan46eVT!J=q59DlKZ2q-_z3r_wV(n zbLzD5n`-YkRv)ora-?mNVV!1`B zj6uDOSAKU!aqO~0+ZzYLk^(!9Lro1m0;(fBv1YH)n;u?magGQL#3-qrbJDj-`fx&2 zZPMCq%=%M&wZbzlj8h0tM}WJc`o{`)$CDFpGG_BHt;=o4mbw$Q0xmJPwPJ6$5%ZbZ zMo>=_Fb4xh$53(1Y@?`b=C(HM2ZaWe0OS}-SfN29K)xN@39Zy z^NiF83Tj9eF4#((M;{VkWDPrIEy2I0f00@8p z2!H?xfB*=900@8p2>e(AztsPGbjT_z^}lkZT>kVn6@R&Pw3}%)7!EuVymx#MbIWkC zb;4xLL_KW^jlHpv#>2;1;U%#PWv6#DvhaCZSLIcCWH4!6KRS5@XOL{p6?N1I@5E95 zG2wxBn|C#5V-DIvH`Tf^N^J4;m;Apo_r;VAKj;4mY4}K|dle?rB1QB&W4E1T-S&7g z$>i7kzwtIJiy~jQlFo!k(I!J2t3Xazjsz3Oy4%}1ACL>xgt+33QwhXc-*GjDiLgUF z6Fx^A2Bpa)iRq;eHJ!GPMAOiTOq2-)Nv^9XD|ABvqOAsX6RUu3xP)j6$F4yR>8%d_ zi$$>2qOw;r|1SI%0O%@6Cg6y+$RRbn{H#~+omnaMGMs5LWxTy6-FvT8qS?lDiHK~g z&)5H#SFit97vWaM|2+)hFiju!5*Vc4c8z84;z4g^2|1V8`;KmY_l00ck)1VG@268NS5|KT4rYpL;{s7{?1SHy4{8OuUI@w@cBm@bWtqM8${S zU8U71)3$hcxc8LuQoHs!-Aj}bp%U}c86rWPA&Ft`rVryDoBHi5z8zg-XFDSj&MLi- zx$p9%PGKr}HUGbVH*pmGGBem)vAVcI#Goi^LgIY4%H@Sy*isx(9e)YIR)eBn9Rjd& z_P-yQBubvKBWmCSaYQxzXg!JsX}^O^upbLb=D0aX26h{y0!JUO&%ig4uR5l}uId866-`W%Gkaei^b}|3KG1VC<@stco z=GyA%G>zSvBi-5i{e%PuO0>JwttZ5$3<|Rd&DG)5`?>Fh-M=U(x#3~uMWygFG>SG{ zCR+}mie^vjIY$U0)t_tEp4&Ytp}Rk|WM9Ei*Hef5*4k8rSqvoZe0=2+cF%1$yM(nL z5*u$KqcdYT?|O+^9Q;Tz<@ky8Q^}B$@~L+lKJ6!&4r?|kNSf)bUj66gN$S9=1dNWL z4k}=b0|MQMwmeD6v z4F9tz>gKtQdo$>;!%kCh*jO{Szg+nM2VG~xxHR1@9GmsKodS}%b>htGcq;|Xq4@86 z)#2$t00ck)1V8`;KmY_l00ck)1b#FD>VnVt|Ju%NDlGVyEW&v)8#c1&KV76f#VvRG zC;cn@rGh%`)v*cp74q|>cRu)3@ae8zwOXp#DUJ3SJ>_J(W5;5r#@mxr2m{AX=inN4 zmnMik41d&UE|>iHf?8zIHRrIkZMeg@W5P$Sap)50N?fvwU3mBu&x%=5o-<;f6mQyj zsLMWQedUK?w)7o(BnPi+d_hci{rNFB>I@2IR2MkPy3g%y^Br?r+SS^(;dN(n&goqO z`x?RmGqrfuaVK%Ujc5y0-K(B(NbaYAC-%#g9!oWkMn_iuJAX@1F2!OW|FgBL+5asL zj~}wRM}*N|XYPtja@sk!PbN7bNUwcUR5P3HW8CcE8vk%n;;CrMJZ(xpQFpmIr1xEd z_#WP7yE}=QvX$eWQc(}lCnP(rOmC-{zWumsnNe=8?B1M8l$C7MOW7zcuJtEn6uBCu zxwK!ZvvnV*lZ}eIKJ-|ft@rpwE^WtnWcTrE*{Hzl_Kxu$r{YQ7$A@I2IAo(D8-rR( z0`9Mkk1_H-o39)tA;P}i3n}&SOw7o@08J_F62}EX-=5PicVuO1S)WZ5&AgWW^lchJ znRwai=#REh;e9~>1V8`;KmY_l00ck)1V8`;{w;y8?*B)WjaAL>*t*xFxssFL@l~K0 z?&A9K{O%Z`v5y~EgpR*R+BZpCt(ezKTF`d3LR=ofn4TVW331pTXn3g9?PUGsLx-fF z)a9HIIDhAL#=Uz_8OR<{!qG@%M_O&1QfYts&MvyEZ^H(YZQ_W{x9@XKy~PY$Z9T3T zfqB(y>$YVr1M1mk=6cxhxl{pEB*iON~`_>`rCSFru;Du`OwM(B{Ez$pZ6R1@J7UIa4nP1J zqq}SRFI> z67=w>*zV~@3QKMlkc~||yf)seK-RVXA+g)Wil@j|hY__95fbU)#Bor7ESY*@DE)tTk>J}v00ck) z1V8`;KmY_l00ck)1VG^56j*a;HUBS4H@H=0(_^bd6|-fr}sixtamYejU$DjQ$WZZ{+XPHXhui}tGvfPpK z^gx9`t^q7{Foo$kQn#bU! zg!YKp?N5(3&kkw!_LdkbXjvGuY8)GiK4J6HRjQ=b zH6m5yh~L@dcBZF`+c=4%k?h{SA0G{L$t+)J$R!0Eo_{YT_m-|?vT{QYZ&ArPtR%yd z4kbrAVeiDPC-L+i2|thDD(OkK?!SX42bG)Ne-ZcG>CPUP^22*u`L!GH>s)@`=UyTe z{o;sg?(QCY8ha}CpQDE^P1`(u#LwWjjd>$S9Wtn}W3S|M#dtA7(Ce7Y-b<-4!?SNgYVB)DeCwrg2#GHLF5w%)Ws?QVlSWqQ}%^LYJu;_Ss@ZOPY(!#rSL&nP3+gTJG!D<9EI~t|b?RzENG? z@=$KehJyy>Ek{nv?BdquIp}&h-l6|^lw8ykxhUbGw#{QhQ$6&uz`1$*cJtlq@Dn0&*h^3AV#}N-CXVZGQ~#t!NJF-T zyN7w?-rPW%GJahcG%}p_y3u}mPx*Pvu4qcL?X=J2@+L zpzc*CDNXV8{DLaeyVp6*v3H-^Ji5G(RsG3CMMJvYa(l+v7qc_GSkI-+p20N|l6E)| zbwA=xHnSqsCOHkM=Mo%3>!w%^n^aKo>@7%=G=Cdw`qnJZvHf0q&=J3qx=n(rd55ps zsNK;jpl6X>Cn3L$bN%XlBDRnywSiGTVtOxb!Y6lq>o7j+HI{|L(^qv zUn?m(wpM#S>pOO;e)H*EOF~ZuCaU5ds^j!k_tF>ry#CYkhB3kwi!J5P$E;-)I7h4% z6o|$O#0+Mk*76xQ)CHb~SZ1M)azO>+5qjz7a)didfTzKPJ~z{!G-92kKZUYo#oS17hdpRTL5Qa-D z?dZEiTQec^qfzok5f)tK9|g}D8afFeh8<#0+S{4r3I%+a_ba&LM>Q35X7PyFCblTo z%>v6Yql@)4;#R%U#DUT>0_-z(pHaG<2ze7GBX!KBmnfuxvz;`Qls z>5<}UL|x?2A$+PGXAMdmIi!Jis7GBwxQdb8J_iBTp+XRB^(aMTk|Y^nM~p+b@{Et<;kd3hq4|VKN3H$2T{9uU!m@LGEe^TY#x4fmR|`-Vf9v^wa5K+;==^_v z%jG_SoO&ix(zTFn_H~sJ5(rvmeMCY1l|a?KYMUZZD)dj&N0~Z{k9B-BN~fN3)N*)Wgl7GeBLN$ZEhrMu6w=U+6}Rj>@!wlHZI32Z-*Q+Q?Py~ zn)YZ%hpcZFdV=a%u$A6__0EHb2LTWO0T2KI5C8!X009sH0TB4V6reW!?ZcUj>TcF0LQX?~V}~`}hH2*<7UU-_Jzwax9RZj_xbvWN0DfylNfbZ^LiA zAK^XP6~P!8VSghW*Qq|KRBK^qc!w1~Eu$+djZQNS-G9Nm+{_?rJ zny&M%yZvNjcl|;jMnbhfZ>N;OQr>3%hsHi*)}P|F%${*IxX1Ez1h^|!f2`m)?2+^B z^z2r>yl@L!iX&>_FCp4)VQ<(G^H=BpJwam*;z#R#o&VPsiv56YP{AYXPy$GMG4kyi zR5H53G^TgC@(Du;9v5@+tnq%{h4VJ9yc=U=@24=IpHFU6e|t3BQ;6c-wYHkq=MC=Y zSXFu5JoTIwW&8i-GQ!^l0w4eaAOHd&00JNY0w4eaAOHgYP~fZjpFJgoV=(^w5Ut=6EB(Q#J za$9~A%WhYjP^ze&dEg>dJXfy1bfb*#vxWR(((+jH$K;wh%TUVs!T27+c4wPE)%Fc4WU008B7+ka%#?i2@ zwEr(eU>%Wkt0lkuO>7YwvyIGM_oeCoG8!XDuKca^7YbSZg-;R4S8dJ;Ypg) ziwi2E>t0WHokH1V?|b#r+R%dK28kHGsTL>Z7mYJ-PkSz+v**?q&XP`^Y^=G7e)CF% zH(<>Zy1}J0r|+@^hg5DCYbIYfvHW;;F?RN@L9$Maf}#da?w*q-|1-`jf(PF9sr#QM zkBOx+v?%o7jLJ`~pbb>25>quaIF8Z1M*VTDmzGY{3~jMn@kDe-Ir`3WoVjGeCb&g#pY#dWZEB)Z4irp>+C_=)p&Z|2ww)}aFCpy11OD)iFN%DG3a^?5K!{!$9W5N7+dUt<5BC=f}^_8I;jcl|wj%n7G>GSGzgCZ`t` z_+%`Oh_(Furt;@Sg`o1mJ&$OYB0q4JQShYX)UKo|l9^;rHsb%bcp>^`I}Gw{zV!M+Slc=dC8Zv*vzIxSa%+>J>}0oI%jtLHYeb}39Uh(bjM&o{-mEa+ zcH=pbtI$+~w)^?+klHowTVvOo7Pr=IND8@`E$fw-Y3!0*UbvL0HFtTT%D-@^JncN{ zvH#8~>)1)_y1kr1^acavM?6q__Hstk4^CQ}Z^c}vHyAFLIgirb+90tZsmkAB+WP%@ zlx{9Zyjk#j=4Txyw+0sM@5^IkNcNIy>A1b;8itk?OKF`F(a)II1{xeWDkP;sNoMq5 z7k@L8d2?WQz%jbK|L$E5PY(hh00JNY0w4eaAOHd&00JODZS?v6e~AuR1wmyUiI>&% z-H|mZhQJ`U@g3Q>&qlTLnUk)zL`!$b#kn_(CQRkYDUKf0gF6emmc2>0*Hkup*^zgZ zCuA{8J4blS7vL^EyE0;XRKHEeijgqvL2|Ne$;Jh(uHqiHFz5n-$2q);}b6+Zgi{m1&;yxR&sqZrri)N-D#~ ztBlh5iJ?hU96J%c0|^2G+nX~nHySug&)Qs_xbDU?o_Q=S0JYDn@q!QcyA7ZAhjURh zniM3>^suGwL|&ex7OYCZ=m_ed0>(HX(2Z!zlax%JaVMGtXu1)P1RzIN;`!_o$OLyH z8;|{6^6fFyF@*+?uHNOeV8)f^f2aIzp6j?bgQ=1@O+kv0rpaXgox4o_C&)uc#o8Q3 z)IwNDq=yp+y#QIVM|>y>b`}VL00@8p2!H?xfB*=900@8p2z*Zh)JHzo|BX6i)Jpvy z9G*Vz!|5_$`lb1w4I!wrgYroHXtYtbDD~TVGsLxcw9})DQ>ofczB;-()HWlEIRjDF z`X&LS-G@qV_vWaKsm@4=r#eJAtr_&Nw2wA+JK4>@k3sYNC+(}-N~9}w+bdA2T*f;S zDodLlzSns7?&6`D5%f;oxPvG69*SpBFF55i6meQAw<<%y%{O%7olIB{*Ms}JIFk4^ zwh1+KMd(DWF;7693<$kJ2vaFT%cE`Qdjk22cDK4eD2vVBTCsL~*WAMC8s)_ehNsd5 z%`jd2(@7KdF+28BivVd^rbtn zI&Q>3X4iY<+oPyqtnfz-Et_;f}4O)4wV|Z|2?fRJPQbb00@8p2!H?xfB*=900@8p2vAXdmH!u^eAk>1 z{Hi>ZUYo#oS17hdpRTL%s#uUC$y4}i*&(G^kGV^=odk+qjl$#HCV=tI=+CGpJ(@(rU zeJ(vxT#YD+95TbF+HuyP#F0Z9c!zq_rPY8xH#=emf~^h}f?%uv5(bE{BgP?I`N;%3 zq5*OUgGY82j_Z08nopQ?)Y_lhH4_pnEIY^7;*fi7>|%hgg40aK=KIHTngX<~X9kQd zlM*et(+Ip&o)jV2ULXJhAOHd&00JNY0w4eaAOHd&@ZAV}Rsa8^{Qq3Z|3vDv;a z67$m;S^*4k@nP=RMZJEp>MV;UUAr@^9}?@XlADQ)c=3XiVFJw|Ed1}njQ+@ zceBRuARqt&AOHd&00JNY0w4eaAOHd&KyC6l|8LJq{yz&{zjCEq{`58#f4OzEn`t!| z4m=XPcYF|Y%W$!E!eq_Fp+?#@_QpmU4Sga_Jf-qoCqIcN*rRO`klvBlH0&Q9e*DrfGCDI2<0U4Cyaq~Rl- z?p2sfixkoCjNNvUb=%{~B$HHG`#;F8it?#%R!$jC2o(Z2L4ujHUlEn1Vhnh~?N1|!yL?+6Ff+W{floh(6 z0MS;1x`|alH(Wxrg=5zshxAq(|6>tswWw@FXbtKD(taBmfg^?>Tm{Jl9C76WfEr$Y z)~olaLy;myHY-74aM7GuBq;7K1a=6Vbrn(5X(*FN2gu^s_*h^rL z{u3*O8TJ+kfB*=900@8p2!H?xfB*=900?|P0$-p1myK1;@7TK6qq&lk-|p|OviGwYj+wEg>;2wsi_($mp>rJM{cq?}i+1N?3HjrSwGN4p{zBO~l@gyTBZ zCzWa~3=QwF;-_VFWu?(+rlI>Uc$b?QWUXg;x$}u`m8w*nys^})m!zh$z0J48NRd01Ka6SXR?@-gUR1jO?yo2*gOJ z7U=DiGFZyn%>U5XXUzIjyq4KBt_Js5o{j)_#p;h0{DwVpzMY=ks+SjTVM}pDE&NLD ze+zrVj+l>Nt3f?MV-Dg+>rioDegkL=#eP6HsNj)xC;_Cs82NS$DjD5i8q>R6`Glba zkBd2Z)_6bf!g(84-i{y*B&u zL%)K2Yqo8rh7ot}722qJN!V7F{q6jJYkVia%EcD#Y<=lQ8Q*6M`MtWn?rlqJJ3jtJ48ie*sV` zSPBegr4z4LuyD@Y$gxuXYjLce|A%Z?E&r?fwN}c1TZ`55|J0iUMwErVmGYnAF=fLK zzqJ4W1V8`;KmY_l00ck)1V8`;K;SzP`1<@`ncwoy=Ko3dBY&{_|Epa9?f=63zn7sD zf$wOQ;ZZ;U1V8`;KmY_l00ck)1V8`;esqDqQ~&$@Y5jlj<&TyBx6%V3@~_qZF?JN5 zAAM`V`-1=ofB*=900@8p2!H?xfB*=5M*@GS|5KV*^8f#|{x`n!b^ZThr>F#v1lnmw zwqtGN4JVR|gTs)C=~DY+Ks6qnj{=X9N3dhPej8^Ua6W>r1N zNO?XV_t=B5FZcGHn%Dd@>%uomw_BO<`FXubW}Z{N_uxQDx%qH6_JYYu0-&Ure&Y4% zbLo-dYD7uokQqMJj?PqW@cWA!k9dmeGYO{k993wFP;v4)x-7R{;thQ>wem{o){v|vzzu|GwNi(;El`s z_LZUKH)0oiH2Dg5KX-pn7Ms2G)!Ol0a|;d)%8MHePo*(=cX)LBF-(h-7i&=05j3A~ z|9>v}`N`b%UvB>=pb59I4}Posk@YBHbi+#Ue>k?ujyV0WV9AtsGva8($^34f>mG07 zQzbn#5gqAA%qRQr+-34Vv4048p&!R){jOF(a=J%?Ssib+L4W8D>?{xf0T2KI5C8!X z009sH0T2KI5cr-1{&4=E+RUDk!Z8?se)9D`HruP8zU2QMFKC>QIsCHIc=B?G)0VYX z*3S)!V@NM&-dCwy?V}OR;BInt+L7m2&T+#j{0z=vY~}plV&(k5qTPK7$w$H+D2ly> zZH(fM8f5D0@zcIIZzS&{GJK73ypX{9smX2mO)R@zZ9=J{dgg(PRPkK7zvllHla|Ml zKPFesS%z9>$QdW@zubJdt_bC`!-d_pOJZ0UUC6MckE_HqcIsU1*I7u7e-SL=)N&Hl zc3>p{Pk8PQyzitGQxYgEF?TjejjA&RqYKK#66zFW_!bxhqn8)q*leq3W{uIflx835>q zv-cs7-=Siypf@s?zdhWe=h*Hi$=xgRrmpo_cFxa541K~^?o&QUS09hqJnE^1-*w{5 z@f(uoPcX?+-!gkMpL$zV=)o|0-@83+3z1$&Z*C9$@O~{eXr=#uw|%00l*4k$w9`51 z&;9>#Z@&xx&ok2h`uVK&KZtJ8V z?=mIFF{!@I5v11Yh2o}qI{t=8#7Y;yGc>}Ecmv_OjqHY7?f(zMsv?tw$!chf7+DaF zvBD#3Q2UYgf@JPmlr3_|1TPvj+5F9s2d359kIBk0 z5+97OwM&~0lZ8;rlcJJ2T2JSUsy8S-qip)&_Z9$v00@8p2!H?xfB*=900@8p2z);R z-*o<;D|zuhaQ^?d`kx{0*ZRLY>vR3j`r()QpJlcFKluCl|KvYc|9h@h{lDJ-zl4wu z!>Xe(E0+WQSpTbYKKNY!Yk9x^|Jb|paH{vUf8ZoTtc)2}kx(*QSyDu#3~3o6Q^u89 zG#HX0GDIRJVHry@W*$R?Wu78a$WY3(B0`3w-%{;!_OpBT`R((Z{hZTt?fb8NU3+Ks zU9Zn~|8e`=_xm0V6!uVd>K97n9eH(6jn!AMb}A}k9?Qh$wH(f>pET|+I7;bxov{7q zIb?Ve5C8!X009sH0T2KI5C8!X0D-@}0IA;h`Ty#T`+r%@1kS6!>i;(h+?#ioRAND} ztn=6v6VA#*r(HUCEpHl)@1Jg2OD^_8_)W;m_U=sV z<(9kpN;UVF{{I1WFXzrdt=DeZ$3=BxA2o5yTk~5Ov7FoJ|8Ex==N0Rt`m93i|6f15 z_t=G$mtC)Bl)@!uceFS~z3&aE*g0y14d*w~bLn;Mlk;1-gRQW@Df)XOIzzFv=C~{b zQv)hsBm8f&8I^!wYDDEC!WvLyNJ~C^usMzgN!%_j+yS_s~K=g)rUS zpl~=I_x#$iM?n^E$abzzI)xhY>pU~hpoytm#%Dfhu$37$K+4|OP1y05f3*Mr1V8`; zKmY_l00ck)1V8`;K;S15Al3a^|36bB*8dc4AIEJu)Fu3}|d>N;mN zcA)&qKKchsl{W+f<_&kKWS*YAW@eCNs2?q*6Jf+!_37aSXQT7n#PUBhE5%$dpEqD^ z*{ArP56N66G5x=dnW^6q`7QllM!4b5@hk4Z#>DRbJOA_P|3+f93~_Y<8lJPHVa00@8p z2!H?xfB*=900@8p2>ho1pZ_23{}UZSW)6r`Ra8DsxpWBqbaFb#oBnt9|Jna}`~Nup z^!ho0 zPb1d<+{VGTURQ-tss?jC;Eiw4qhtDk9(?qE$*y|VC;Q0*nRIjBB{Nd^7)}&9X5gP@&enhuM*dR&I||{QzK#Mkp+XT%-}eC$ z69N+uj@%nl09qSU0I}UA)9N0S}

    I^$^CPRg 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 literal 0 HcmV?d00001 diff --git a/world/region/r.0.0.mca b/world/region/r.0.0.mca new file mode 100644 index 0000000000000000000000000000000000000000..3b35084dabbe40b7160c23ec66c2070c9700d5f3 GIT binary patch literal 1728512 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

    stwaRR)7U5m+0WHt5#oy1pv?RP<(+ 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 K00{h71pXK4;YEW0 literal 0 HcmV?d00001 diff --git a/world/session.lock b/world/session.lock new file mode 100644 index 0000000..0d7e5f8 --- /dev/null +++ b/world/session.lock @@ -0,0 +1 @@ +☃ \ No newline at end of file diff --git a/world/stats/4572e510-ac24-44b0-a915-5ed21da4028c.json b/world/stats/4572e510-ac24-44b0-a915-5ed21da4028c.json new file mode 100644 index 0000000..758ac4b --- /dev/null +++ b/world/stats/4572e510-ac24-44b0-a915-5ed21da4028c.json @@ -0,0 +1 @@ +{"stats":{"minecraft:custom":{"minecraft:time_since_rest":45,"minecraft:total_world_time":53,"minecraft:leave_game":1,"minecraft:play_time":45,"minecraft:time_since_death":45}},"DataVersion":4325} \ No newline at end of file From cd6550caa3b3632a58b6b8fea0f899a08bcb0d56 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Antoine=20Mathi=C3=A9?= Date: Fri, 10 Oct 2025 18:26:34 +0200 Subject: [PATCH 21/27] refactor: now nbt related parsing now reside inside nbt namespace --- include/lib/nbtParser.hpp | 34 ++++++ include/world/worldManager.hpp | 9 -- src/lib/nbtParser.cpp | 185 +++++++++++++++++++++++++++++++++ src/world/worldManager.cpp | 156 ++------------------------- 4 files changed, 228 insertions(+), 156 deletions(-) create mode 100644 include/lib/nbtParser.hpp create mode 100644 src/lib/nbtParser.cpp diff --git a/include/lib/nbtParser.hpp b/include/lib/nbtParser.hpp new file mode 100644 index 0000000..03196a3 --- /dev/null +++ b/include/lib/nbtParser.hpp @@ -0,0 +1,34 @@ +#ifndef NBT_PARSER_HPP +#define NBT_PARSER_HPP + +#include "lib/nbt.hpp" + +#include +#include +#include +#include + +namespace nbt { + + // NBT binary parser for Minecraft's Named Binary Tag format. + // This class parses a binary NBT buffer into the simplified NBT model in lib/nbt.hpp. + class Parser { + public: + Parser() = default; + + // Parse an NBT payload (binary) into an NBT object. + // Expects the data to start with a root tag type and name. + NBT parse(const std::vector& data); + + private: + // Helper utilities for decoding the binary stream (big-endian). + template T read(const std::vector& data, size_t& cursor); + std::string parseTagName(const std::vector& data, size_t& cursor); + TagCompound parseCompound(const std::vector& data, size_t& cursor); + TagList parseList(const std::vector& data, size_t& cursor); + Tag parseTag(const std::vector& data, size_t& cursor, uint8_t tagType); + }; + +} // namespace nbt + +#endif // NBT_PARSER_HPP diff --git a/include/world/worldManager.hpp b/include/world/worldManager.hpp index 2baa995..512057b 100644 --- a/include/world/worldManager.hpp +++ b/include/world/worldManager.hpp @@ -58,15 +58,6 @@ class WorldManager { // Loads and parses the level.dat file Data loadLevelDat(std::filesystem::path levelDatPath); - private: - // NBT parsing helper functions - nbt::Tag parseTag(const std::vector& data, size_t& cursor, uint8_t type); - std::string parseTagName(const std::vector& data, size_t& cursor); - nbt::TagCompound parseCompound(const std::vector& data, size_t& cursor); - nbt::TagList parseList(const std::vector& data, size_t& cursor); - - template T read(const std::vector& data, size_t& cursor); - private: Data _LevelDat; }; diff --git a/src/lib/nbtParser.cpp b/src/lib/nbtParser.cpp new file mode 100644 index 0000000..f5f0950 --- /dev/null +++ b/src/lib/nbtParser.cpp @@ -0,0 +1,185 @@ +#include "lib/nbtParser.hpp" + +#include +#include +#include +#include +#include +#include +#include + +namespace { + constexpr uint8_t TAG_END = 0; + constexpr uint8_t TAG_BYTE = 1; + constexpr uint8_t TAG_SHORT = 2; + constexpr uint8_t TAG_INT = 3; + constexpr uint8_t TAG_LONG = 4; + constexpr uint8_t TAG_FLOAT = 5; + constexpr uint8_t TAG_DOUBLE = 6; + constexpr uint8_t TAG_BYTE_ARRAY = 7; + constexpr uint8_t TAG_STRING = 8; + constexpr uint8_t TAG_LIST = 9; + constexpr uint8_t TAG_COMPOUND = 10; + constexpr uint8_t TAG_INT_ARRAY = 11; + constexpr uint8_t TAG_LONG_ARRAY = 12; +} // namespace + +namespace nbt { + + NBT Parser::parse(const std::vector& data) { + if (data.empty()) { + throw std::runtime_error("NBT parsing error: empty data."); + } + + size_t cursor = 0; + + uint8_t rootType = read(data, cursor); + if (rootType != TAG_COMPOUND) { + throw std::runtime_error("NBT parsing error: root must be a TAG_Compound."); + } + + std::string rootName = parseTagName(data, cursor); + TagCompound rootComp = parseCompound(data, cursor); + + return NBT(rootName, rootComp); + } + + template T Parser::read(const std::vector& data, size_t& cursor) { + if (cursor + sizeof(T) > data.size()) { + throw std::runtime_error("NBT parsing error: unexpected end of data."); + } + T value; + std::memcpy(&value, &data[cursor], sizeof(T)); + cursor += sizeof(T); + + if constexpr (sizeof(T) > 1) { + if (std::endian::native == std::endian::little) { + return std::byteswap(value); + } + } + return value; + } + + // Explicit instantiations for the types we use + template int8_t Parser::read(const std::vector&, size_t&); + template uint8_t Parser::read(const std::vector&, size_t&); + template int16_t Parser::read(const std::vector&, size_t&); + template uint16_t Parser::read(const std::vector&, size_t&); + template int32_t Parser::read(const std::vector&, size_t&); + template uint32_t Parser::read(const std::vector&, size_t&); + template int64_t Parser::read(const std::vector&, size_t&); + template uint64_t Parser::read(const std::vector&, size_t&); + + std::string Parser::parseTagName(const std::vector& data, size_t& cursor) { + uint16_t length = read(data, cursor); + if (length == 0) { + return ""; + } + if (cursor + length > data.size()) { + throw std::runtime_error("NBT parsing error: invalid tag name length."); + } + std::string name(data.begin() + cursor, data.begin() + cursor + length); + cursor += length; + return name; + } + + TagCompound Parser::parseCompound(const std::vector& data, size_t& cursor) { + TagCompound compound; + while (cursor < data.size()) { + uint8_t tagType = read(data, cursor); + if (tagType == TAG_END) { + break; + } + + std::string tagName = parseTagName(data, cursor); + compound[tagName] = parseTag(data, cursor, tagType); + } + return compound; + } + + TagList Parser::parseList(const std::vector& data, size_t& cursor) { + TagList list; + uint8_t listType = read(data, cursor); + int32_t length = read(data, cursor); + + if (length < 0) { + throw std::runtime_error("NBT parsing error: negative TAG_List length."); + } + + for (int32_t i = 0; i < length; ++i) { + list.push_back(parseTag(data, cursor, listType)); + } + return list; + } + + Tag Parser::parseTag(const std::vector& data, size_t& cursor, uint8_t tagType) { + switch (tagType) { + case TAG_BYTE: + return Tag(read(data, cursor)); + case TAG_SHORT: + return Tag(read(data, cursor)); + case TAG_INT: + return Tag(read(data, cursor)); + case TAG_LONG: + return Tag(read(data, cursor)); + case TAG_FLOAT: + return Tag(std::bit_cast(read(data, cursor))); + case TAG_DOUBLE: + return Tag(std::bit_cast(read(data, cursor))); + case TAG_STRING: { + uint16_t length = read(data, cursor); + if (cursor + length > data.size()) { + throw std::runtime_error("NBT parsing error: invalid string length."); + } + std::string str(data.begin() + cursor, data.begin() + cursor + length); + cursor += length; + return Tag(str); + } + case TAG_BYTE_ARRAY: { + int32_t length = read(data, cursor); + if (length < 0) { + throw std::runtime_error("NBT parsing error: negative TAG_Byte_Array length."); + } + TagByteArray array; + if (length > 0) { + array.resize(static_cast(length)); + std::memcpy(array.data(), &data[cursor], static_cast(length)); + cursor += static_cast(length); + } + return Tag(array); + } + case TAG_INT_ARRAY: { + int32_t length = read(data, cursor); + if (length < 0) { + throw std::runtime_error("NBT parsing error: negative TAG_Int_Array length."); + } + TagIntArray array; + array.reserve(static_cast(length)); + for (int32_t i = 0; i < length; ++i) { + array.push_back(read(data, cursor)); + } + return Tag(array); + } + case TAG_LONG_ARRAY: { + int32_t length = read(data, cursor); + if (length < 0) { + throw std::runtime_error("NBT parsing error: negative TAG_Long_Array length."); + } + TagLongArray array; + array.reserve(static_cast(length)); + for (int32_t i = 0; i < length; ++i) { + array.push_back(read(data, cursor)); + } + return Tag(array); + } + case TAG_LIST: + return Tag(std::make_shared(parseList(data, cursor))); + case TAG_COMPOUND: + return Tag(std::make_shared(parseCompound(data, cursor))); + default: + throw std::runtime_error("NBT parsing error: unsupported tag type: " + + std::to_string(tagType)); + } + } + +} // namespace nbt diff --git a/src/world/worldManager.cpp b/src/world/worldManager.cpp index db1b8a8..f586dcd 100644 --- a/src/world/worldManager.cpp +++ b/src/world/worldManager.cpp @@ -1,36 +1,20 @@ +#include "lib/nbtParser.hpp" #include "world/worldManager.hpp" -#include -#include #include #include #include #include #include -#include #include -#include #include #include +#include +#include #include #include #include -// --- NBT Tag Type IDs --- -const uint8_t TAG_END = 0; -const uint8_t TAG_BYTE = 1; -const uint8_t TAG_SHORT = 2; -const uint8_t TAG_INT = 3; -const uint8_t TAG_LONG = 4; -const uint8_t TAG_FLOAT = 5; -const uint8_t TAG_DOUBLE = 6; -const uint8_t TAG_BYTE_ARRAY = 7; -const uint8_t TAG_STRING = 8; -const uint8_t TAG_LIST = 9; -const uint8_t TAG_COMPOUND = 10; -const uint8_t TAG_INT_ARRAY = 11; -const uint8_t TAG_LONG_ARRAY = 12; - std::vector WorldManager::decompressGzip(std::filesystem::path compressedFilePath) { // Read file into memory std::ifstream file(compressedFilePath, std::ios::binary); @@ -54,9 +38,9 @@ std::vector WorldManager::decompressGzip(std::filesystem::path compress // Allocate output buffer (level.dat is usually < 10MB) std::vector decompressed(10 * 1024 * 1024); - stream.avail_in = compressed.size(); + stream.avail_in = static_cast(compressed.size()); stream.next_in = compressed.data(); - stream.avail_out = decompressed.size(); + stream.avail_out = static_cast(decompressed.size()); stream.next_out = decompressed.data(); int ret = inflate(&stream, Z_FINISH); @@ -79,18 +63,12 @@ Data WorldManager::loadLevelDat(std::filesystem::path levelDatPath) { throw std::runtime_error("Decompressed level.dat data is empty."); } - size_t cursor = 0; - - uint8_t rootType = read(decompressedData, cursor); - if (rootType != TAG_COMPOUND) { - throw std::runtime_error("level.dat must start with a TAG_Compound."); - } - - std::string rootName = parseTagName(decompressedData, cursor); - nbt::TagCompound rootCompound = parseCompound(decompressedData, cursor); + // Parse NBT using the dedicated parser + nbt::Parser parser; + nbt::NBT n = parser.parse(decompressedData); Data dataStruct; - dataStruct.nbtData = nbt::NBT(rootName, rootCompound); + dataStruct.nbtData = std::move(n); // --- Populate the Data struct for easy access --- const auto& dataCompound = @@ -153,119 +131,3 @@ Data WorldManager::loadLevelDat(std::filesystem::path levelDatPath) { return dataStruct; } - -// --- NBT Parsing Implementation --- - -template T WorldManager::read(const std::vector& data, size_t& cursor) { - if (cursor + sizeof(T) > data.size()) { - throw std::runtime_error("NBT parsing error: unexpected end of data."); - } - T value; - std::memcpy(&value, &data[cursor], sizeof(T)); - cursor += sizeof(T); - - if constexpr (sizeof(T) > 1) { - if (std::endian::native == std::endian::little) { - return std::byteswap(value); - } - } - return value; -} - -std::string WorldManager::parseTagName(const std::vector& data, size_t& cursor) { - uint16_t length = read(data, cursor); - if (length == 0) { - return ""; - } - if (cursor + length > data.size()) { - throw std::runtime_error("NBT parsing error: invalid tag name length."); - } - std::string name(data.begin() + cursor, data.begin() + cursor + length); - cursor += length; - return name; -} - -nbt::TagCompound WorldManager::parseCompound(const std::vector& data, size_t& cursor) { - nbt::TagCompound compound; - while (cursor < data.size()) { - uint8_t tagType = read(data, cursor); - if (tagType == TAG_END) { - break; - } - - std::string tagName = parseTagName(data, cursor); - compound[tagName] = parseTag(data, cursor, tagType); - } - return compound; -} - -nbt::TagList WorldManager::parseList(const std::vector& data, size_t& cursor) { - nbt::TagList list; - uint8_t listType = read(data, cursor); - int32_t length = read(data, cursor); - - for (int32_t i = 0; i < length; ++i) { - list.push_back(parseTag(data, cursor, listType)); - } - return list; -} - -nbt::Tag WorldManager::parseTag(const std::vector& data, size_t& cursor, uint8_t tagType) { - switch (tagType) { - case TAG_BYTE: - return nbt::Tag(read(data, cursor)); - case TAG_SHORT: - return nbt::Tag(read(data, cursor)); - case TAG_INT: - return nbt::Tag(read(data, cursor)); - case TAG_LONG: - return nbt::Tag(read(data, cursor)); - case TAG_FLOAT: - return nbt::Tag(std::bit_cast(read(data, cursor))); - case TAG_DOUBLE: - return nbt::Tag(std::bit_cast(read(data, cursor))); - case TAG_STRING: { - uint16_t length = read(data, cursor); - if (cursor + length > data.size()) { - throw std::runtime_error("NBT parsing error: invalid string length."); - } - std::string str(data.begin() + cursor, data.begin() + cursor + length); - cursor += length; - return nbt::Tag(str); - } - case TAG_BYTE_ARRAY: { - int32_t length = read(data, cursor); - nbt::TagByteArray array; - if (length > 0) { - array.resize(length); - std::memcpy(array.data(), &data[cursor], length); - cursor += length; - } - return nbt::Tag(array); - } - case TAG_INT_ARRAY: { - int32_t length = read(data, cursor); - nbt::TagIntArray array; - array.reserve(length); - for (int32_t i = 0; i < length; ++i) { - array.push_back(read(data, cursor)); - } - return nbt::Tag(array); - } - case TAG_LONG_ARRAY: { - int32_t length = read(data, cursor); - nbt::TagLongArray array; - array.reserve(length); - for (int32_t i = 0; i < length; ++i) { - array.push_back(read(data, cursor)); - } - return nbt::Tag(array); - } - case TAG_LIST: - return nbt::Tag(std::make_shared(parseList(data, cursor))); - case TAG_COMPOUND: - return nbt::Tag(std::make_shared(parseCompound(data, cursor))); - default: - throw std::runtime_error("Unsupported NBT tag type: " + std::to_string(tagType)); - } -} From 801908597d10cdbbd30a54b85cadf2c064a7d2ad Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" Date: Fri, 10 Oct 2025 16:29:05 +0000 Subject: [PATCH 22/27] Apply clang-format [skip ci] --- src/world/worldManager.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/world/worldManager.cpp b/src/world/worldManager.cpp index f586dcd..5c101b1 100644 --- a/src/world/worldManager.cpp +++ b/src/world/worldManager.cpp @@ -1,6 +1,7 @@ -#include "lib/nbtParser.hpp" #include "world/worldManager.hpp" +#include "lib/nbtParser.hpp" + #include #include #include From d960d2fc5abd6de6ee1ca95ada3cb3472fbe392a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Antoine=20Mathi=C3=A9?= Date: Fri, 10 Oct 2025 19:12:15 +0200 Subject: [PATCH 23/27] rebased --- include/world/worldManager.hpp | 3 ++- src/server.cpp | 6 ++++-- src/world/worldManager.cpp | 20 ++++++++++++++++++-- 3 files changed, 24 insertions(+), 5 deletions(-) diff --git a/include/world/worldManager.hpp b/include/world/worldManager.hpp index 512057b..fb53325 100644 --- a/include/world/worldManager.hpp +++ b/include/world/worldManager.hpp @@ -56,7 +56,8 @@ class WorldManager { // Decompresses a Gzip file into a byte vector std::vector decompressGzip(std::filesystem::path compressedFilePath); // Loads and parses the level.dat file - Data loadLevelDat(std::filesystem::path levelDatPath); + Data loadLevelDat(std::filesystem::path levelDatPath); + std::filesystem::path locateRegionFileByChunkCoord(int localX, int localZ); private: Data _LevelDat; diff --git a/src/server.cpp b/src/server.cpp index 40fbaf1..cf61a0a 100644 --- a/src/server.cpp +++ b/src/server.cpp @@ -1,10 +1,9 @@ -#include "network/server.hpp" - #include "config.hpp" #include "lib/filesystem.hpp" #include "lib/json.hpp" #include "logger.hpp" #include "network/networking.hpp" +#include "network/server.hpp" #include "player.hpp" #include "world/worldManager.hpp" @@ -88,6 +87,9 @@ int Server::start_server() { return 1; } + std::filesystem::path regionFile = _worldManager.locateRegionFileByChunkCoord(0, 0); + g_logger->logGameInfo(INFO, "Region File: " + regionFile.string(), "SERVER"); + size_t workerCount = 4; if (workerCount == 0) workerCount = 4; // fallback diff --git a/src/world/worldManager.cpp b/src/world/worldManager.cpp index 5c101b1..f287d06 100644 --- a/src/world/worldManager.cpp +++ b/src/world/worldManager.cpp @@ -1,7 +1,9 @@ -#include "world/worldManager.hpp" - +#include "lib/filesystem.hpp" #include "lib/nbtParser.hpp" +#include "logger.hpp" +#include "world/worldManager.hpp" +#include #include #include #include @@ -132,3 +134,17 @@ Data WorldManager::loadLevelDat(std::filesystem::path levelDatPath) { return dataStruct; } + +std::filesystem::path WorldManager::locateRegionFileByChunkCoord(int localX, int localZ) { + const auto regionDir = getPath().parent_path() / "world" / "region"; + const std::string filename = + "r." + std::to_string(localX / 32) + "." + std::to_string(localZ / 32) + ".mca"; + const std::filesystem::path path = regionDir / filename; + + if (std::filesystem::exists(path)) { + return path; + } else { + g_logger->logGameInfo(ERROR, "Cannot find the region file asked" + path.string()); + throw std::runtime_error("Cannot find the region file asked"); + } +} From 97de55609e07e63c196b608b077f78ee8d0e4266 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" Date: Fri, 10 Oct 2025 17:14:07 +0000 Subject: [PATCH 24/27] Apply clang-format [skip ci] --- src/server.cpp | 3 ++- src/world/worldManager.cpp | 3 ++- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/src/server.cpp b/src/server.cpp index cf61a0a..7a8b9e0 100644 --- a/src/server.cpp +++ b/src/server.cpp @@ -1,9 +1,10 @@ +#include "network/server.hpp" + #include "config.hpp" #include "lib/filesystem.hpp" #include "lib/json.hpp" #include "logger.hpp" #include "network/networking.hpp" -#include "network/server.hpp" #include "player.hpp" #include "world/worldManager.hpp" diff --git a/src/world/worldManager.cpp b/src/world/worldManager.cpp index f287d06..6465e14 100644 --- a/src/world/worldManager.cpp +++ b/src/world/worldManager.cpp @@ -1,7 +1,8 @@ +#include "world/worldManager.hpp" + #include "lib/filesystem.hpp" #include "lib/nbtParser.hpp" #include "logger.hpp" -#include "world/worldManager.hpp" #include #include From 5f37981259af7a70d5b864febfc2aa22deb32f9d Mon Sep 17 00:00:00 2001 From: Antoine Mathie Date: Sat, 11 Oct 2025 01:56:29 +0200 Subject: [PATCH 25/27] feat: chunk loading via chunk coord, data-generator submodule (see usage in repo readme) --- .clang-format | 2 +- .gitmodules | 3 + data-generator | 1 + ideas/chunks-spec.md | 527 -------------------- ideas/console-log.md | 33 -- include/network/networking.hpp | 5 + include/network/server.hpp | 12 +- include/world/world.hpp | 120 +++++ include/world/worldManager.hpp | 66 --- src/networking/packet/chunkBatch.cpp | 59 ++- src/networking/packet/chunkDataSimple.cpp | 175 +++++-- src/server.cpp | 5 +- src/world/{worldManager.cpp => manager.cpp} | 112 ++++- src/world/query.cpp | 217 ++++++++ 14 files changed, 615 insertions(+), 722 deletions(-) create mode 100644 .gitmodules create mode 160000 data-generator delete mode 100644 ideas/chunks-spec.md delete mode 100644 ideas/console-log.md create mode 100644 include/world/world.hpp delete mode 100644 include/world/worldManager.hpp rename src/world/{worldManager.cpp => manager.cpp} (58%) create mode 100644 src/world/query.cpp diff --git a/.clang-format b/.clang-format index edb7a86..ce02044 100644 --- a/.clang-format +++ b/.clang-format @@ -5,7 +5,7 @@ TabWidth: 4 # how wide a tab renders (adjust per team preference) UseTab: Always # use tabs for indentation, spaces for alignment ContinuationIndentWidth: 8 BreakBeforeBraces: Attach -ColumnLimit: 100 +ColumnLimit: 150 AllowShortIfStatementsOnASingleLine: true AllowShortFunctionsOnASingleLine: true PointerAlignment: Left diff --git a/.gitmodules b/.gitmodules new file mode 100644 index 0000000..f495b05 --- /dev/null +++ b/.gitmodules @@ -0,0 +1,3 @@ +[submodule "data-generator"] + path = data-generator + url = https://github.com/Random-stuff-unlimited/data-generator.git diff --git a/data-generator b/data-generator new file mode 160000 index 0000000..cf8252a --- /dev/null +++ b/data-generator @@ -0,0 +1 @@ +Subproject commit cf8252a510541dd67bbb6c54258a083360950d87 diff --git a/ideas/chunks-spec.md b/ideas/chunks-spec.md deleted file mode 100644 index 7eb80ba..0000000 --- a/ideas/chunks-spec.md +++ /dev/null @@ -1,527 +0,0 @@ -Title: Chunk Streaming, Caching, and World-Sync Subsystem (Spec Sheet) -Version: 0.1 -Owner: Antoine (Server Runtime) -Status: Draft -Last Updated: 2025-10-08 - -1) Goals -- Stream chunks from Anvil region files on demand, decode via libnbt++, and - maintain a bounded in-memory cache. -- Keep main server loop authoritative over simulation (entities, blocks, light). -- Maintain consistency between background I/O/decoding and live world state. -- Pin spawn and simulation-radius chunks; prefetch neighbors; evict by LRU/TTL. -- Support async load and async save (writeback) without stalling the tick. -- Provide deterministic activation/eviction phases in the tick. - -2) Non-Goals -- Procedural generation (assume existing Anvil data). -- Full lighting algorithm specification (only interfaces/hooks). -- Network protocol specifics. - -3) Architecture Overview - -The system follows a layered architecture with clear separation of concerns: - -``` -┌─────────────────────────────────────────────────────────────┐ -│ Game Logic Layer │ -│ ┌─────────────────┐ ┌─────────────────┐ ┌──────────────┐ │ -│ │ EntitySystem │ │ BlockSystem │ │ Other Systems│ │ -│ └─────────────────┘ └─────────────────┘ └──────────────┘ │ -└─────────────────────────────────────────────────────────────┘ - │ - ▼ -┌─────────────────────────────────────────────────────────────┐ -│ Simulation Layer │ -│ ┌─────────────────────────────────────────────────────────┐ │ -│ │ WorldState │ │ -│ │ ActiveSet │ PendingLoads │ PendingActivations │ │ -│ └─────────────────────────────────────────────────────────┘ │ -└─────────────────────────────────────────────────────────────┘ - │ - ▼ -┌─────────────────────────────────────────────────────────────┐ -│ Orchestration Layer │ -│ ┌─────────────────────────────────────────────────────────┐ │ -│ │ ChunkManager │ │ -│ │ Cache │ LRU │ ThreadPools │ Futures │ │ -│ └─────────────────────────────────────────────────────────┘ │ -└─────────────────────────────────────────────────────────────┘ - │ - ▼ -┌─────────────────────────────────────────────────────────────┐ -│ Serialization Layer │ -│ ┌─────────────────┐ ┌──────────────────────┐ │ -│ │ ChunkCodec │ │ DataVersion │ │ -│ │ (NBT ↔ Snap) │ │ Compatibility │ │ -│ └─────────────────┘ └──────────────────────┘ │ -└─────────────────────────────────────────────────────────────┘ - │ - ▼ -┌─────────────────────────────────────────────────────────────┐ -│ I/O Layer │ -│ ┌─────────────────┐ ┌─────────────────┐ ┌──────────────┐ │ -│ │ RegionFile │ │ RegionCache │ │ FileSystem │ │ -│ │ (.mca) │ │ (FD mgmt) │ │ Backend │ │ -│ └─────────────────┘ └─────────────────┘ └──────────────┘ │ -└─────────────────────────────────────────────────────────────┘ -``` - -Key Architectural Principles: -- **Single ownership**: Each layer owns its data structures exclusively -- **Async boundaries**: Cross-layer communication via futures/queues -- **Immutable handoffs**: Data passed between threads as immutable snapshots -- **Bounded resources**: Memory and CPU usage controlled at each layer -- **Graceful degradation**: System continues operating under resource pressure - -Data Flow Patterns: -1. **Load Path**: I/O → Decode → Cache → Activate → Simulate -2. **Save Path**: Simulate → Encode → Cache → I/O -3. **Eviction Path**: Cache → Save Path (if dirty) → Release - -4) Terminology -- ChunkPos: integer pair {x, z} in chunk coordinates (16×16 blocks each). -- Region: 32×32 chunks per .mca file (r...mca). -- Snapshot (immutable): decoded NBT data for a chunk (sections, biomes, - entities list, etc.), safe to move across threads. -- LiveChunk (mutable): runtime structures used by simulation (blocks, entities, - tile entities, light caches, pathing data). -- ActiveSet: map of ChunkPos -> LiveChunk under main-thread ownership. -- DesiredSet: union of spawn + per-player simulation radius + optional - prefetch radius. -- CacheEntry: background cache record (may hold Snapshot or nothing). - -5) Component Interactions - -5.1) Main Thread Tick Cycle -``` -WorldState.tick() { - Phase 0: computeDesiredSet() -> ChunkManager.pin/prefetch() - Phase 1: pollAsyncResults() -> queue activations - Phase 2: activateChunks() + evictChunks() -> modify ActiveSet - Phase 3: runSystems(ActiveSet) -> modify LiveChunks - Phase 4: produceNetworkUpdates() + ChunkManager.tick() -} -``` - -5.2) Background Thread Operations -``` -I/O Thread Pool: - RegionFile.readChunk() -> raw compressed data - RegionFile.writeChunk() <- compressed data - -Decode Thread Pool: - ChunkCodec.decode(raw data) -> Snapshot - -Encode Thread Pool: - ChunkCodec.encode(Snapshot) -> raw data -``` - -5.3) Cross-Thread Communication -- **Main → Background**: Requests via ChunkManager APIs (non-blocking) -- **Background → Main**: Results via std::future (polled, never blocking) -- **Thread Safety**: All cross-thread data is immutable (Snapshot) - -5.4) Memory Management Strategy -``` -Ownership Hierarchy: -├── ChunkManager owns: CacheEntry map, futures, thread pools -├── WorldState owns: ActiveSet, PendingQueues -├── LiveChunk owns: runtime simulation data (mutable) -├── Snapshot owns: decoded NBT data (immutable) -└── RegionFile owns: file descriptors, headers -``` - -5.5) Error Propagation -- **I/O Errors**: RegionFile → ChunkManager (via future) → WorldState (fallback) -- **Decode Errors**: ChunkCodec → ChunkManager → WorldState (empty chunk) -- **Memory Pressure**: ChunkManager → WorldState (throttle activations) - -6) Components -6.1) RegionFile (I/O) -- Responsibility: Read compressed chunk blobs from .mca files. -- Interfaces: - - static path regionPathFor(worldRoot, cx, cz) -> filesystem::path - - ctor(path) - - bool ok() - - optional> readChunk(cx, cz) - - (Future) writeChunk(cx, cz, compressedBlob) [async via Writeback] -- Behavior: - - Parse 8 KiB header (location + timestamps). - - readChunk returns [length:4][compression:1][payload...] as stored. - - Keeps file descriptor open; thread-safe via external serialization (one - RegionFile instance per region, methods may be called from thread pool). -- Errors: returns nullopt for missing chunks; throws only on fatal open errors. - -6.2) ChunkCodec (Decode/Encode) -- Responsibility: Convert between compressed blob and Snapshot. -- Interfaces: - - decodeFromCompressedNbt(ChunkPos, blob) -> Snapshot + stats - - encodeToCompressedNbt(ChunkPos, Snapshot) -> blob + stats -- Behavior: - - Supports compression types: 2=Zlib/Deflate, 1=Gzip, 3=LZ4 (if present). - - Uses libnbt++ to parse NBT tags; maps to Snapshot schema. - - Memory accounting: reports uncompressed size for budgeting. -- Errors: returns null/empty Snapshot on malformed input; logs diagnostics. - -6.3) ChunkManager (Background cache + async orchestration) -- Responsibility: Manage memory-bounded cache of Snapshots and orchestrate - background I/O and decoding/encoding. -- Interfaces: - - getChunkAsync(pos) -> future - - prefetch(pos) -> void (low-priority get) - - pin(pos), unpin(pos) -> void - - saveAsync(pos, Snapshot) -> future - - tick() -> void (eviction by LRU/TTL) - - setMemoryBudget(bytes) -> void - - metrics() -> struct { usedBytes, entries, pinned, inflightLoads, inflightSaves, p50/p95 IO+decode } -- Policies: - - Eviction: LRU with TTL; skip pinned and inflight; drop unpinned first. - - Memory budget: total bytes ~ sum of Snapshot size estimates. - - Prefetch: queued after required loads; dropped first under pressure. -- Concurrency: - - Thread pool(s) for I/O and decode/encode. - - No main-thread blocking except when caller chooses to wait on futures. -- Errors: futures resolve to empty Snapshot on failure; callers decide fallback. - -6.4) WorldState (Main-thread authoritative) -- Responsibility: Owns and mutates LiveChunks; integrates Snapshots deterministically. -- Interfaces: - - ensureActive(pos) -> schedules load if needed (non-blocking) - - deactivate(pos) -> schedules save if dirty, then unload - - getLive(pos) -> LiveChunk* or null - - iterateActive(aabb or radius) -> iterator - - markDirty(pos) -> void - - buildLiveFromSnapshot(pos, Snapshot) -> LiveChunk - - encodeSnapshot(LiveChunk) -> Snapshot (for save) -- Data: - - ActiveSet: unordered_map - - PendingLoads: map> - - PendingActivations: queue<(ChunkPos, Snapshot)> - - PendingEvictions: queue - - WritebackQueue: queue<(ChunkPos, Snapshot)> -- Policies: - - Activation rate limit per tick to bound frame spikes (e.g., 16). - - Defer cross-chunk operations until neighbors are present if required. - -6.5) EntitySystem and Subsystems -- Responsibility: Simulate only within ActiveSet. -- Interfaces: - - onTick(WorldView view) where view queries LiveChunks only. - - TransferQueue for entities crossing chunk borders pending activation. -- Guarantees: - - Never reads background Snapshots directly. - - Handles “chunk not loaded” by deferring or scheduling prefetch. - -7) Tick Phases (Deterministic Order) -- Phase 0: Input & Interest - - Compute DesiredSet from players (Rs sim radius, Rd prefetch radius) + spawn. - - For each pos in DesiredSet: - - If not active and not pending: ChunkManager.pin(pos); pendingLoads[pos] = - getChunkAsync(pos). For prefetch-only area: do not pin. - - For each pos in ActiveSet not in DesiredSet and not dirty: enqueue eviction. -- Phase 1: Drain Async (Non-blocking) - - Poll PendingLoads with wait_for(0ms). - - Move ready results to PendingActivations; remove from PendingLoads. -- Phase 2: World Sync - - Activate up to N per tick: buildLiveFromSnapshot; insert into ActiveSet. - - Process PendingEvictions: if dirty -> encode -> saveAsync; unpin; erase. - - Resolve edge dependencies (e.g., light border fix) if neighbors present. -- Phase 3: Simulation - - Run systems in fixed order on ActiveSet (blocks, tiles, AI, physics, entities). - - Process transfers across chunk borders; if target inactive, queue for next tick. -- Phase 4: Output & Maintenance - - Produce network snapshots from ActiveSet only. - - ChunkManager.tick(); flush writebacks opportunistically. - -8) Memory and Performance -- Budgets: - - Cache budget: default 512 MiB (configurable). - - Activation cap per tick: default 16 (configurable). - - Prefetch radius Rd = Rs + 2..4; disabled under pressure. -- Estimation: - - Snapshot.memoryBytes = sum(capacities) for sections, entities, biomes, light. -- Eviction Order: - - Prefetch-only unpinned -> old LRU unpinned -> TTL-expired -> never pinned. -- Backpressure: - - If usedBytes > budget: stop new prefetch; evict until under budget. - - If still high: reduce Rd; as a last resort, throttle new required loads (warn). - -9) Threading and Safety -- Background threads: I/O, decode, encode only; they never touch LiveChunks. -- Main thread: exclusive owner of ActiveSet and LiveChunks. -- Handoffs: - - Background produces Snapshot (immutable). - - Main thread consumes Snapshot and creates LiveChunk. -- Locks: - - ChunkManager internal locks around maps/LRU and region handle cache. - - WorldState is single-threaded; no locks on ActiveSet. -- Futures: - - Never block the tick loop; poll ready futures only. - -10) Error Handling and Recovery -- Missing chunk in region: Snapshot=null -> generator hook or treat as void. -- Corrupt NBT: log warning with pos and region; skip activation. -- Save failure: retry with backoff; mark chunk “savePending”; keep pinned until - persisted or max retries reached (then escalate). -- Region open failure: mark region offline; degrade gracefully; alert. - -11) Instrumentation and Metrics -- Expose counters/gauges: - - activeChunks, pendingLoads, pendingActivations, pendingEvictions - - cacheUsedBytes/currentBudget, pinnedCount, inflightLoads/saves - - IO latency p50/p95, decode time p50/p95, activation time p50/p95 -- Tracing spans: - - readChunk, decode, encode, writeChunk, activate, evict -- Logs: - - INFO on region opens/closes; WARN on decode/save errors; DEBUG on evictions. - -12) Configuration -- CacheConfig: - - memoryBudgetBytes (default 512 MiB) - - ttlSeconds (default 120) - - enableTTL (default true) -- Runtime: - - ioThreads (default 2), decodeThreads (default 2), encodeThreads (default 2) - - simRadius Rs per world or per player (default 8) - - prefetchRadius Rd relative to Rs (default +2) - - maxActivationsPerTick (default 16) - - saveBatchSize (default 8) -- Paths: - - worldRoot pointing to Anvil world directory (contains region/). - -13) Data Schemas (Abstract) -- Snapshot: - - ChunkPos pos - - int dataVersion - - vector

    sections (Y-indexed; palette + blockStates bits) - - Biome data (per-column or per-section) - - Heightmap(s) - - Entities: vector (raw NBT fields or parsed minimal) - - TileEntities: vector - - Light (optional raw arrays if read) - - size_t memoryBytes -- LiveChunk: - - ChunkPos pos - - Blocks (mutable accessor over sections) - - Entities (engine-owned IDs) - - TileEntities - - Light caches - - Dirty flags: blocks/entities/tileEntities - - Aux: navigation mesh, scheduled ticks -- CacheEntry: - - optional snapshot - - future inflightLoad - - future inflightSave - - bool pinned - - time_point lastUsed - - size_t sizeBytes - -14) APIs (C++ Signatures, indicative) -- ChunkManager - - future getChunkAsync(ChunkPos pos); - - void prefetch(ChunkPos pos); - - void pin(ChunkPos pos); - - void unpin(ChunkPos pos); - - future saveAsync(ChunkPos pos, const Snapshot& s); - - void tick(); - - void setMemoryBudget(size_t bytes); - - Metrics metrics() const; -- WorldState - - void requestEnsureActive(ChunkPos pos); - - void processAsyncLoadsNonBlocking(); // moves ready into PendingActivations - - void activateSome(size_t maxCount); - - void scheduleDeactivate(ChunkPos pos); - - LiveChunk* getLive(ChunkPos pos); - - void markDirty(ChunkPos pos, DirtyMask mask); - - Snapshot encodeSnapshot(const LiveChunk& lc) const; - -15) Edge Policies -- Neighbor-dependent systems (lighting, fluid flow, redstone): - - Allow partial activation with border-deferred mode; reconcile when both - neighbors are active; maintain a “border dirty” mask per face. -- Cross-chunk entity movement: - - If target chunk inactive: queue transfer; ensure target pos in DesiredSet. -- Spawn area: - - Permanently pinned unless server config unpins during high pressure. - -16) Testing Strategy -- Unit: - - Region header parse; readChunk for known fixtures. - - Codec decode/encode roundtrip for multiple DataVersion samples. - - LRU/TTL eviction order under budget change. -- Integration: - - Simulate player walk; assert ActiveSet sliding window; no blocking. - - Memory cap adherence under synthetic pressure. - - Save/load dirty chunk with concurrent evictions. -- Soak: - - Long-running walk across regions; capture latency histograms. - -17) Migration/Compatibility -- Support multiple DataVersions by feature flags in ChunkCodec. -- Backward-compatible save: preserve unknown NBT tags when round-tripping. - -18) Security/Robustness -- Validate NBT lengths vs. header to avoid OOM. -- Cap per-chunk uncompressed size (e.g., 32 MiB) and reject if exceeded. -- Limit inflight loads and activations per tick to avoid spikes. - -19) Future Work -- Compression dictionary caching; in-memory section-level compression. -- Hotset prioritization via LFU or ARC instead of pure LRU. -- NUMA-aware thread pools and file read-ahead/batching. -- Sharded world loops for multi-core scaling (region-based ownership). -20) Implementation Phases - -Phase 1: Foundation (Weeks 1-2) -- RegionFile: Basic .mca reading with header parsing -- ChunkCodec: NBT decode for basic block data only -- Unit tests for I/O and decode paths - -Phase 2: Caching (Weeks 3-4) -- ChunkManager: In-memory cache with LRU eviction -- Thread pools for async I/O and decode -- Integration tests with synthetic load - -Phase 3: World Integration (Weeks 5-6) -- WorldState: ActiveSet management and tick phases -- LiveChunk activation from Snapshots -- Basic entity and block system integration - -Phase 4: Performance (Weeks 7-8) -- Memory budgets and backpressure -- Metrics and instrumentation -- Performance testing and tuning - -Phase 5: Production (Weeks 9-10) -- Error handling and recovery -- Save/writeback implementation -- Soak testing and optimization - -21) Architectural Concerns & Design Alternatives - -21.1) Resource Lifecycle Management -Current Challenge: Complex state transitions between cached, pending, active, and dirty states -can lead to resource leaks or inconsistent states. - -Proposed Solution: State Machine Pattern -``` -ChunkState { - UNLOADED -> [load request] -> LOADING - LOADING -> [load complete] -> CACHED - CACHED -> [activation] -> ACTIVE - ACTIVE -> [modification] -> DIRTY - DIRTY -> [save request] -> SAVING - SAVING -> [save complete] -> CACHED - CACHED/ACTIVE -> [eviction] -> UNLOADED -} -``` - -Benefits: -- Clear ownership at each state -- Deterministic cleanup paths -- Easier debugging and metrics -- Prevents invalid state transitions - -21.2) Alternative Threading Models - -Current: Separate I/O, Decode, Encode thread pools -Alternative A: Single background worker pool with typed tasks -Alternative B: Actor model with mailbox queues per chunk -Alternative C: Lock-free single-producer-single-consumer queues - -Trade-offs Analysis: -- Current model: Higher parallelism, more complex synchronization -- Alternative A: Simpler, but potential head-of-line blocking -- Alternative B: Better isolation, higher memory overhead -- Alternative C: Lowest latency, limited to 1:1 producer-consumer - -Recommendation: Stick with current model but add task priorities. - -21.3) Memory Management Strategies - -Current: Global memory budget with LRU eviction -Alternative A: Per-region memory budgets -Alternative B: Hierarchical budgets (world -> region -> chunk) -Alternative C: Adaptive budgets based on access patterns - -Analysis: -- Current: Simple but can cause hot regions to evict cold regions -- Alternative A: Better locality but complex cross-region coordination -- Alternative B: Most flexible but highest complexity -- Alternative C: Optimal performance but unpredictable behavior - -Recommendation: Implement current model with per-region budget override option. - -21.4) Error Handling Architecture - -Current: Futures resolve to empty on error, caller decides fallback -Alternative A: Exception-based error propagation -Alternative B: Result types with explicit error handling -Alternative C: Error callback system with retry policies - -Considerations: -- Performance: Exceptions have overhead, Results require explicit handling -- Debuggability: Results provide better error context -- Reliability: Callbacks allow centralized retry logic - -Recommendation: Hybrid approach - Results for expected errors, exceptions for programmer errors. - -21.5) Cache Coherency Strategies - -Current: Main thread authoritative, background cache eventually consistent -Potential Issues: -- Save races: Background saves stale data while main thread modifies -- Memory visibility: Cache eviction during active modification -- Temporal coupling: Activation timing affects neighbor-dependent systems - -Proposed Improvements: -- Version stamps on snapshots to detect staleness -- Copy-on-write for active chunks being saved -- Deferred activation queue for neighbor dependencies - -21.6) Scalability Bottlenecks - -Identified Concerns: -1. Single ChunkManager instance limits parallelism -2. Main thread activation limit caps world size growth -3. Region file contention under high load -4. Memory allocator pressure from frequent Snapshot creation - -Mitigation Strategies: -1. Shard ChunkManager by region hash -2. Adaptive activation limits based on frame time budget -3. Read-ahead and batching for region operations -4. Object pooling for common Snapshot components - -21.7) Interface Design Philosophy - -Current: Procedural interfaces with explicit state management -Alternative: RAII-based interfaces with automatic cleanup - -Example Current: -```cpp -manager.pin(pos); -auto future = manager.getChunkAsync(pos); -// ... later -manager.unpin(pos); -``` - -Example Alternative: -```cpp -auto handle = manager.requestChunk(pos); // RAII pin -auto future = handle.getFuture(); -// automatic unpin on handle destruction -``` - -Benefits of RAII approach: -- Exception safety -- Prevents resource leaks -- Clearer ownership semantics - -Drawbacks: -- More complex implementation -- Potential performance overhead -- Less explicit control over timing - -Recommendation: Provide both interfaces - RAII for convenience, explicit for performance-critical paths. diff --git a/ideas/console-log.md b/ideas/console-log.md deleted file mode 100644 index 03b823d..0000000 --- a/ideas/console-log.md +++ /dev/null @@ -1,33 +0,0 @@ -# Console Idea - -### Console Section -- **Server Control**: Start, stop, restart server -- **Player Management**: Kick, ban, whitelist players, view player list, view player info -- **World Management**: Load, save, backup world data -- **Configuration**: Modify server settings on runtime -- **Logging section**: View and filter server logs (network, chat, game info (Filter for warning / error)) - -### Console Architecture -``` -ConsoleManager -├── ServerControl -├── PlayerManagement - ├── player list - ├── player info / Kick / Ban / Whitelist - ├── add player to Whitelist (if enabled) -├── WorldManagement (soon) - ├── world list - ├── world info / Load / Save / Backup - ├── world info -├── Configuration (soon) - ├── config list - ├── config info / Load / Save / Backup -├── LoggingSection - ├── log network / all / chat / gameinfo - ├── filter (error / warning / info) -``` - -# Logging Idea - -1 file network (all error / warning / info) -1 file gameinfo (all error / warning / info) diff --git a/include/network/networking.hpp b/include/network/networking.hpp index 0d17eb7..5025183 100644 --- a/include/network/networking.hpp +++ b/include/network/networking.hpp @@ -145,4 +145,9 @@ 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); + #endif diff --git a/include/network/server.hpp b/include/network/server.hpp index b07dd79..a12f5ec 100644 --- a/include/network/server.hpp +++ b/include/network/server.hpp @@ -4,7 +4,7 @@ class NetworkManager; #include "../config.hpp" #include "../player.hpp" -#include "../world/worldManager.hpp" +#include "../world/world.hpp" #include "id_manager.hpp" #include "lib/json.hpp" @@ -25,8 +25,8 @@ class Server { Config _config; NetworkManager* _networkManager; IdManager _idManager; - WorldManager _worldManager; - Data _worldData; + World::Manager _worldManager; + World::LevelDat _worldData; public: Server(); @@ -50,9 +50,9 @@ class Server { json getPlayerSample(); IdManager& getIdManager() { return (_idManager); } - NetworkManager& getNetworkManager() { return *_networkManager; } - WorldManager& getWorldManager() { return _worldManager; } - Data& getWorldData() { return _worldData; } + NetworkManager& getNetworkManager() { return *_networkManager; } + World::Manager& ManagManagererWorldManager() { return _worldManager; } + World::LevelDat& getWorldData() { return _worldData; } }; #endif diff --git a/include/world/world.hpp b/include/world/world.hpp new file mode 100644 index 0000000..59d48a0 --- /dev/null +++ b/include/world/world.hpp @@ -0,0 +1,120 @@ +#ifndef WORLD_MANAGER_HPP +#define WORLD_MANAGER_HPP + +#include "lib/nbt.hpp" +#include "logger.hpp" + +#include +#include +#include +#include +#include +#include + +namespace World { + + struct LevelDat { // see https://minecraft.wiki/w/Java_Edition_level_format#level.dat_format + // Existing fields + bool allowCommands; + double BorderCenterX; + double BorderCenterY; + double BorderDamagePerBlock; + double BorderSafeZone; + long BorderSizeLerpTarget; + double BorderWarningBlocks; + double BorderWarningTime; + int clearWeatherTime; + int DataVersion; + long DayTime; + std::byte Difficulty; + bool DifficultyLocked; + int GameType; + std::string generatorName; + int generatorVersiona; + bool hardcore; + bool initialized; + long LastPlayed; + std::string LevelName; + bool MapFeatures; + bool raining; + int rainTime; + long RandomSeed; + long SizeOnDisk; + int SpawnX; + int SpawnY; + int SpawnZ; + bool thundering; + int thunderTime; + long Time; + int version; + int WanderingTraderSpawnChange; + int WanderingTraderSpawnDelay; + bool WasModded; + + // The full NBT data, for accessing less common or custom tags + nbt::NBT nbtData; + }; + + struct ChunkData { + int chunkX; + int chunkZ; + + std::vector blockData; + std::vector biomeData; + std::vector heightmaps; + std::vector blockEntities; + + std::vector skyLight; + std::vector blockLight; + + ChunkData(int x, int z) : chunkX(x), chunkZ(z) {} + + bool isEmpty() const { return blockData.empty(); } + }; + + class Manager { + public: + static std::vector decompressGzip(std::filesystem::path compressedFilePath); + static std::vector decompressGzip(const std::vector& compressedData); + static std::vector decompressZlib(const std::vector& compressedData); + static std::filesystem::path locateRegionFileByChunkCoord(int ChunkX, int ChunkZ); + LevelDat loadLevelDat(std::filesystem::path levelDatPath); + + private: + LevelDat _LevelDat; + }; + + class Query { + public: + ChunkData fetchChunk(int chunkX, int chunkZ) { + ChunkData chunk(chunkX, chunkZ); + + try { + auto regionPath = World::Manager::locateRegionFileByChunkCoord(chunkX, chunkZ); + chunk = loadChunkFromRegion(regionPath, chunkX, chunkZ); + } catch (const std::exception& e) { + g_logger->logGameInfo(DEBUG, + "Chunk (" + std::to_string(chunkX) + ", " + std::to_string(chunkZ) + + ") not found, sending empty chunk: " + e.what(), + "World::Query::fetchChunk"); + chunk = generateEmptyChunk(chunkX, chunkZ); + } + + return chunk; + } + + private: + private: + void extractChunkDataFromNBT(const nbt::NBT& chunkNBT, ChunkData& chunk); + void extractSectionsData(const nbt::TagList& sections, ChunkData& chunk); + void extractBlockStatesFromSection(const nbt::TagCompound& blockStates, ChunkData& chunk, int8_t sectionY); + void extractHeightmaps(const nbt::TagCompound& heightmaps, ChunkData& chunk); + void extractBlockEntities(const nbt::TagList& blockEntities, ChunkData& chunk); + void extractBiomesFromSections(const nbt::TagCompound& root, ChunkData& chunk); + ChunkData generateEmptyChunk(int chunkX, int chunkZ); + ChunkData loadChunkFromRegion(const std::filesystem::path& regionPath, int chunkX, int chunkZ); + }; + +} // namespace World + +#endif diff --git a/include/world/worldManager.hpp b/include/world/worldManager.hpp deleted file mode 100644 index fb53325..0000000 --- a/include/world/worldManager.hpp +++ /dev/null @@ -1,66 +0,0 @@ -#ifndef WORLD_MANAGER_HPP -#define WORLD_MANAGER_HPP - -#include "lib/nbt.hpp" - -#include -#include -#include -#include -#include - -struct Data { // see https://minecraft.wiki/w/Java_Edition_level_format#level.dat_format - // Existing fields - bool allowCommands; - double BorderCenterX; - double BorderCenterY; - double BorderDamagePerBlock; - double BorderSafeZone; - long BorderSizeLerpTarget; - double BorderWarningBlocks; - double BorderWarningTime; - int clearWeatherTime; - int DataVersion; - long DayTime; - std::byte Difficulty; - bool DifficultyLocked; - int GameType; - std::string generatorName; - int generatorVersiona; - bool hardcore; - bool initialized; - long LastPlayed; - std::string LevelName; - bool MapFeatures; - bool raining; - int rainTime; - long RandomSeed; - long SizeOnDisk; - int SpawnX; - int SpawnY; - int SpawnZ; - bool thundering; - int thunderTime; - long Time; - int version; - int WanderingTraderSpawnChange; - int WanderingTraderSpawnDelay; - bool WasModded; - - // The full NBT data, for accessing less common or custom tags - nbt::NBT nbtData; -}; - -class WorldManager { - public: - // Decompresses a Gzip file into a byte vector - std::vector decompressGzip(std::filesystem::path compressedFilePath); - // Loads and parses the level.dat file - Data loadLevelDat(std::filesystem::path levelDatPath); - std::filesystem::path locateRegionFileByChunkCoord(int localX, int localZ); - - private: - Data _LevelDat; -}; - -#endif diff --git a/src/networking/packet/chunkBatch.cpp b/src/networking/packet/chunkBatch.cpp index cce29ad..6ff67d1 100644 --- a/src/networking/packet/chunkBatch.cpp +++ b/src/networking/packet/chunkBatch.cpp @@ -59,18 +59,11 @@ void sendChunkBatchSequence(Packet& packet, Server& server) { ThreadSafeQueue* outgoingPackets = server.getNetworkManager().getOutgoingQueue(); if (!player || !outgoingPackets) return; - // Player spawn position (you should get this from player data) - int playerChunkX = 0; // player->getChunkX(); - int playerChunkZ = 0; // player->getChunkZ(); - - // Get view distance from player config - int viewDistance = 5; // Default - if (player->getPlayerConfig()) { - viewDistance = player->getPlayerConfig()->getViewDistance(); - } + int playerChunkX = 0; + int playerChunkZ = 0; + int viewDistance = 3; // Reasonable size - std::cout << "=== Starting chunk batch sequence for player: " << player->getPlayerName() - << " (view distance: " << viewDistance << ") ===\n"; + std::cout << "=== Starting chunk batch sequence for player: " << player->getPlayerName() << " (view distance: " << viewDistance << ") ===\n"; // 1. Send Chunk Batch Start try { @@ -82,8 +75,11 @@ void sendChunkBatchSequence(Packet& packet, Server& server) { return; } - // 2. Send chunks in a radius around player - int chunksCount = 0; + // 2. Send chunks in smaller batches + int chunksCount = 0; + int batchSize = 0; + const int MAX_BATCH_SIZE = 16; // Limit chunks per batch + for (int x = playerChunkX - viewDistance; x <= playerChunkX + viewDistance; x++) { for (int z = playerChunkZ - viewDistance; z <= playerChunkZ + viewDistance; z++) { try { @@ -91,21 +87,38 @@ void sendChunkBatchSequence(Packet& packet, Server& server) { sendChunkData(*chunkPacket, server, x, z); outgoingPackets->push(chunkPacket); chunksCount++; + batchSize++; + + // Send batch finished and start new batch if we hit limit + if (batchSize >= MAX_BATCH_SIZE) { + // Send batch finished + Packet* batchFinishedPacket = new Packet(packet); + sendChunkBatchFinished(*batchFinishedPacket, server, batchSize); + outgoingPackets->push(batchFinishedPacket); + + // Start new batch + Packet* batchStartPacket = new Packet(packet); + sendChunkBatchStart(*batchStartPacket, server); + outgoingPackets->push(batchStartPacket); + + batchSize = 0; + } + } catch (const std::exception& e) { - std::cerr << "Error sending chunk (" << x << ", " << z << "): " << e.what() - << std::endl; + std::cerr << "Error sending chunk (" << x << ", " << z << "): " << e.what() << std::endl; } } } - // 3. Send Chunk Batch Finished - try { - Packet* batchFinishedPacket = new Packet(packet); - sendChunkBatchFinished(*batchFinishedPacket, server, chunksCount); - outgoingPackets->push(batchFinishedPacket); - } catch (const std::exception& e) { - std::cerr << "Error sending chunk batch finished: " << e.what() << std::endl; - return; + // 3. Send final batch finished + if (batchSize > 0) { + try { + Packet* batchFinishedPacket = new Packet(packet); + sendChunkBatchFinished(*batchFinishedPacket, server, batchSize); + outgoingPackets->push(batchFinishedPacket); + } catch (const std::exception& e) { + std::cerr << "Error sending chunk batch finished: " << e.what() << std::endl; + } } std::cout << "=== Chunk batch sequence completed: " << chunksCount << " chunks sent ===\n"; diff --git a/src/networking/packet/chunkDataSimple.cpp b/src/networking/packet/chunkDataSimple.cpp index b7874ff..76de89a 100644 --- a/src/networking/packet/chunkDataSimple.cpp +++ b/src/networking/packet/chunkDataSimple.cpp @@ -12,46 +12,140 @@ void sendChunkData(Packet& packet, Server& server, int chunkX, int chunkZ) { Buffer buf; - // Chunk X and Z coordinates - buf.writeInt(chunkX); - buf.writeInt(chunkZ); + try { + // Use your new chunk loading system + World::Query query; + World::ChunkData chunkData = query.fetchChunk(chunkX, chunkZ); + + // Write chunk coordinates + buf.writeInt(chunkX); + buf.writeInt(chunkZ); + + // Write heightmaps (simplified) + if (!chunkData.heightmaps.empty()) { + buf.writeBytes(chunkData.heightmaps); + } else { + // Empty heightmap + buf.writeByte(0x0A); // Compound tag + buf.writeByte(0x00); // Empty name length + buf.writeByte(0x00); // End tag + } + + // Write chunk data + if (!chunkData.blockData.empty()) { + buf.writeVarInt(chunkData.blockData.size()); + buf.writeBytes(chunkData.blockData); + } else { + // Generate simple empty chunk inline + Buffer emptyData; + const int NUM_SECTIONS = 24; + + for (int section = 0; section < NUM_SECTIONS; section++) { + emptyData.writeByte(0x00); // Block count low + emptyData.writeByte(0x00); // Block count high + + // Block states - single air block + emptyData.writeByte(0); // Bits per entry + emptyData.writeVarInt(0); // Air block state + emptyData.writeVarInt(0); // No data array + + // Biomes - single plains biome + emptyData.writeByte(0); // Bits per entry + emptyData.writeVarInt(1); // Plains biome + emptyData.writeVarInt(0); // No data array + } + + buf.writeVarInt(emptyData.getData().size()); + buf.writeBytes(emptyData.getData()); + } + + // Block entities + buf.writeVarInt(0); + + // Light data (simplified version) + buf.writeVarInt(1); // Sky light mask length + buf.writeLong(0x1FFFFFF); // All sections have sky light + buf.writeVarInt(1); // Block light mask length + buf.writeLong(0); // No block light + buf.writeVarInt(1); // Empty sky light mask length + buf.writeLong(0); // No empty sky light sections + buf.writeVarInt(1); // Empty block light mask length + buf.writeLong(0); // No empty block light sections + + // Sky light arrays + for (int i = 0; i < 25; i++) { + buf.writeVarInt(2048); + for (int j = 0; j < 2048; j++) { + buf.writeByte(0xFF); + } + } + + } catch (const std::exception& e) { + std::cerr << "Error in sendChunkData: " << e.what() << std::endl; + // Return without setting packet data - this will cause the packet to be skipped + return; + } + + // Create final packet + int packetId = 0x27; + int packetIdSize = packet.getVarintSize(packetId); + int totalPayloadSize = packetIdSize + buf.getData().size(); - // Heightmaps (NBT) - minimal implementation using empty compound tag - buf.writeByte(0x0A); - buf.writeByte(0x00); - buf.writeByte(0x00); - buf.writeByte(0x00); + Buffer finalBuf; + finalBuf.writeVarInt(totalPayloadSize); + finalBuf.writeVarInt(packetId); + finalBuf.writeBytes(buf.getData()); - // Chunk data array - simplified version - Buffer chunkData; + packet.getData() = finalBuf; + packet.setPacketSize(finalBuf.getData().size()); + packet.setReturnPacket(PACKET_SEND); + + (void)server; +} - // Number of sections (24 sections for world height -64 to 319) - const int NUM_SECTIONS = 24; +// Helper function to generate empty chunk sections +Buffer generateEmptyChunkSections() { + Buffer chunkData; + const int NUM_SECTIONS = 24; // Sections for world height -64 to 319 for (int section = 0; section < NUM_SECTIONS; section++) { - // Block count (non-air blocks in this section) - write as 2 bytes for short - buf.writeByte(0x00); - buf.writeByte(0x00); - - // Block states palette - chunkData.writeByte(0); - chunkData.writeVarInt(0); - chunkData.writeVarInt(0); - - // Biomes palette - chunkData.writeByte(0); - chunkData.writeVarInt(1); - chunkData.writeVarInt(0); + // Block count (non-air blocks) - 0 for empty sections + chunkData.writeByte(0x00); + chunkData.writeByte(0x00); + + // Block states palette - single entry for air + chunkData.writeByte(0); // Bits per entry (0 = single valued) + chunkData.writeVarInt(0); // Air block state ID + chunkData.writeVarInt(0); // No data array needed for single valued + + // Biomes palette - single entry for plains + chunkData.writeByte(0); // Bits per entry (0 = single valued) + chunkData.writeVarInt(1); // Plains biome ID + chunkData.writeVarInt(0); // No data array needed for single valued } - // Write chunk data size and data - buf.writeVarInt(chunkData.getData().size()); - buf.writeBytes(chunkData.getData()); + return chunkData; +} + +// Helper function to write light data from loaded chunk +void writeLightData(Buffer& buf, const World::ChunkData& chunkData) { + if (!chunkData.skyLight.empty() || !chunkData.blockLight.empty()) { + // Use actual light data from chunk + writeActualLightData(buf, chunkData); + } else { + // Fallback to default light data + writeEmptyLightData(buf); + } +} - // Number of block entities - buf.writeVarInt(0); +void writeActualLightData(Buffer& buf, const World::ChunkData& chunkData) { + // This is complex - you need to reconstruct the light data format + // For now, fallback to empty light data + // TODO: Implement proper light data reconstruction from chunkData.skyLight and chunkData.blockLight + writeEmptyLightData(buf); +} - // Light data - simplified version +void writeEmptyLightData(Buffer& buf) { // Sky Light Mask (BitSet) - all sections have sky light buf.writeVarInt(1); buf.writeLong(0x1FFFFFF); @@ -72,27 +166,10 @@ void sendChunkData(Packet& packet, Server& server, int chunkX, int chunkZ) { for (int i = 0; i < 25; i++) { buf.writeVarInt(2048); for (int j = 0; j < 2048; j++) { - buf.writeByte(0xFF); + buf.writeByte(0xFF); // Full sky light } } - // No Block Light arrays since mask is 0 - - // Create final packet - int packetId = 0x27; - int packetIdSize = packet.getVarintSize(packetId); - int totalPayloadSize = packetIdSize + buf.getData().size(); - - Buffer finalBuf; - finalBuf.writeVarInt(totalPayloadSize); - finalBuf.writeVarInt(packetId); - finalBuf.writeBytes(buf.getData()); - - packet.getData() = finalBuf; - packet.setPacketSize(finalBuf.getData().size()); - packet.setReturnPacket(PACKET_SEND); - - (void)server; } void sendPlayerPositionAndLook(Packet& packet, Server& server) { diff --git a/src/server.cpp b/src/server.cpp index 7a8b9e0..42eee32 100644 --- a/src/server.cpp +++ b/src/server.cpp @@ -1,12 +1,11 @@ -#include "network/server.hpp" - #include "config.hpp" #include "lib/filesystem.hpp" #include "lib/json.hpp" #include "logger.hpp" #include "network/networking.hpp" +#include "network/server.hpp" #include "player.hpp" -#include "world/worldManager.hpp" +#include "world/world.hpp" #include #include diff --git a/src/world/worldManager.cpp b/src/world/manager.cpp similarity index 58% rename from src/world/worldManager.cpp rename to src/world/manager.cpp index 6465e14..c537d03 100644 --- a/src/world/worldManager.cpp +++ b/src/world/manager.cpp @@ -1,8 +1,7 @@ -#include "world/worldManager.hpp" - #include "lib/filesystem.hpp" #include "lib/nbtParser.hpp" #include "logger.hpp" +#include "world/world.hpp" #include #include @@ -19,15 +18,14 @@ #include #include -std::vector WorldManager::decompressGzip(std::filesystem::path compressedFilePath) { +std::vector World::Manager::decompressGzip(std::filesystem::path compressedFilePath) { // Read file into memory std::ifstream file(compressedFilePath, std::ios::binary); if (!file) { throw std::runtime_error("Could not open file: " + compressedFilePath.string()); } - std::vector compressed((std::istreambuf_iterator(file)), - std::istreambuf_iterator()); + std::vector compressed((std::istreambuf_iterator(file)), std::istreambuf_iterator()); file.close(); // Initialize zlib stream @@ -61,7 +59,7 @@ std::vector WorldManager::decompressGzip(std::filesystem::path compress return decompressed; } -Data WorldManager::loadLevelDat(std::filesystem::path levelDatPath) { +World::LevelDat World::Manager::loadLevelDat(std::filesystem::path levelDatPath) { std::vector decompressedData = decompressGzip(levelDatPath); if (decompressedData.empty()) { throw std::runtime_error("Decompressed level.dat data is empty."); @@ -71,12 +69,11 @@ Data WorldManager::loadLevelDat(std::filesystem::path levelDatPath) { nbt::Parser parser; nbt::NBT n = parser.parse(decompressedData); - Data dataStruct; + World::LevelDat dataStruct; dataStruct.nbtData = std::move(n); // --- Populate the Data struct for easy access --- - const auto& dataCompound = - dataStruct.nbtData.getRoot().at("Data").get>(); + const auto& dataCompound = dataStruct.nbtData.getRoot().at("Data").get>(); // Helper to safely get a value from a compound tag auto getTagValue = [&](const std::string& key, auto& member) { @@ -136,11 +133,10 @@ Data WorldManager::loadLevelDat(std::filesystem::path levelDatPath) { return dataStruct; } -std::filesystem::path WorldManager::locateRegionFileByChunkCoord(int localX, int localZ) { - const auto regionDir = getPath().parent_path() / "world" / "region"; - const std::string filename = - "r." + std::to_string(localX / 32) + "." + std::to_string(localZ / 32) + ".mca"; - const std::filesystem::path path = regionDir / filename; +std::filesystem::path World::Manager::locateRegionFileByChunkCoord(int localX, int localZ) { + const auto regionDir = getPath().parent_path() / "world" / "region"; + const std::string filename = "r." + std::to_string(localX / 32) + "." + std::to_string(localZ / 32) + ".mca"; + const std::filesystem::path path = regionDir / filename; if (std::filesystem::exists(path)) { return path; @@ -149,3 +145,91 @@ std::filesystem::path WorldManager::locateRegionFileByChunkCoord(int localX, int throw std::runtime_error("Cannot find the region file asked"); } } + +std::vector World::Manager::decompressZlib(const std::vector& compressedData) { + if (compressedData.empty()) { + return {}; + } + + // Initialize zlib stream + z_stream stream = {}; + stream.next_in = const_cast(compressedData.data()); + stream.avail_in = static_cast(compressedData.size()); + + // Initialize for zlib format (not gzip) + int ret = inflateInit(&stream); + if (ret != Z_OK) { + throw std::runtime_error("Failed to initialize zlib decompression"); + } + + // Estimate output size (start with 4x input size) + std::vector decompressed(compressedData.size() * 4); + + do { + stream.next_out = decompressed.data() + stream.total_out; + stream.avail_out = static_cast(decompressed.size() - stream.total_out); + + ret = inflate(&stream, Z_NO_FLUSH); + + if (ret == Z_STREAM_ERROR || ret == Z_DATA_ERROR || ret == Z_MEM_ERROR) { + inflateEnd(&stream); + throw std::runtime_error("Zlib decompression error: " + std::to_string(ret)); + } + + // If we need more space, double the buffer + if (stream.avail_out == 0 && ret != Z_STREAM_END) { + decompressed.resize(decompressed.size() * 2); + } + + } while (ret != Z_STREAM_END); + + inflateEnd(&stream); + + // Resize to actual decompressed size + decompressed.resize(stream.total_out); + return decompressed; +} + +std::vector World::Manager::decompressGzip(const std::vector& compressedData) { + if (compressedData.empty()) { + return {}; + } + + // Initialize zlib stream for gzip format + z_stream stream = {}; + stream.next_in = const_cast(compressedData.data()); + stream.avail_in = static_cast(compressedData.size()); + + // Use inflateInit2 with gzip flag (16 + MAX_WBITS) + int ret = inflateInit2(&stream, 16 + MAX_WBITS); + if (ret != Z_OK) { + throw std::runtime_error("Failed to initialize gzip decompression"); + } + + // Estimate output size (start with 4x input size) + std::vector decompressed(compressedData.size() * 4); + + do { + stream.next_out = decompressed.data() + stream.total_out; + stream.avail_out = static_cast(decompressed.size() - stream.total_out); + + ret = inflate(&stream, Z_NO_FLUSH); + + if (ret == Z_STREAM_ERROR || ret == Z_DATA_ERROR || ret == Z_MEM_ERROR) { + inflateEnd(&stream); + throw std::runtime_error("Gzip decompression error: " + std::to_string(ret)); + } + + // If we need more space, double the buffer + if (stream.avail_out == 0 && ret != Z_STREAM_END) { + decompressed.resize(decompressed.size() * 2); + } + + } while (ret != Z_STREAM_END); + + inflateEnd(&stream); + + // Resize to actual decompressed size + decompressed.resize(stream.total_out); + return decompressed; +} diff --git a/src/world/query.cpp b/src/world/query.cpp new file mode 100644 index 0000000..cdf6a01 --- /dev/null +++ b/src/world/query.cpp @@ -0,0 +1,217 @@ +#include "lib/nbt.hpp" +#include "lib/nbtParser.hpp" +#include "logger.hpp" +#include "world/world.hpp" + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +World::ChunkData World::Query::loadChunkFromRegion(const std::filesystem::path& regionPath, int chunkX, int chunkZ) { + + // Get the byte index inside the location table + int localX = chunkX & 31, localZ = chunkZ & 31; + int chunkIndex = (localZ << 5) + localX; + + std::ifstream file(regionPath, std::ios::binary); + if (!file.is_open()) { + throw std::runtime_error("Cannot open region file"); + } + + file.seekg(chunkIndex * 4); + uint32_t locationData; + file.read(reinterpret_cast(&locationData), 4); + locationData = ntohl(locationData); + + uint32_t offset = (locationData >> 8) & 0xFFFFFF; + uint8_t sectorCount = locationData & 0xFF; + + if (offset == 0 || sectorCount == 0) { + // Chunk doesn't exist in this region + return ChunkData(chunkX, chunkZ); + } + + file.seekg(offset * 4096); + + uint32_t chunkLength; + file.read(reinterpret_cast(&chunkLength), 4); + chunkLength = ntohl(chunkLength); + + uint8_t compressionType; + file.read(reinterpret_cast(&compressionType), 1); + + std::vector compressedData(chunkLength - 1); + file.read(reinterpret_cast(compressedData.data()), chunkLength - 1); + + std::vector decompressedData; + switch (compressionType) { + case 1: // GZip + decompressedData = World::Manager::decompressGzip(compressedData); + break; + case 2: // Zlib + decompressedData = World::Manager::decompressZlib(compressedData); + break; + case 3: // Uncompressed + decompressedData = compressedData; + break; + default: + throw std::runtime_error("Unknown compression type: " + std::to_string(compressionType)); + }; + + nbt::Parser parser; + nbt::NBT chunkNBT = parser.parse(decompressedData); + + ChunkData chunk(chunkX, chunkZ); + extractChunkDataFromNBT(chunkNBT, chunk); + + return chunk; +} + +void World::Query::extractChunkDataFromNBT(const nbt::NBT& chunkNBT, World::ChunkData& chunk) { + try { + const auto& root = chunkNBT.getRoot(); + + // Modern format (1.18+) - data directly in root + + // Extract sections (block data) + if (root.contains("sections")) { + const auto& sectionsTag = root.at("sections").get>(); + extractSectionsData(*sectionsTag, chunk); + } + + // Extract heightmaps + if (root.contains("Heightmaps")) { + const auto& heightmapsTag = root.at("Heightmaps").get>(); + extractHeightmaps(*heightmapsTag, chunk); + } + + // Extract biomes from sections + extractBiomesFromSections(root, chunk); + + // Extract block entities + if (root.contains("block_entities")) { + const auto& blockEntitiesTag = root.at("block_entities").get>(); + extractBlockEntities(*blockEntitiesTag, chunk); + } + + } catch (const std::exception& e) { + g_logger->logGameInfo(ERROR, "Failed to extract chunk data from NBT: " + std::string(e.what()), "World::Query"); + // Leave chunk data empty - it will be treated as empty chunk + } +} + +void World::Query::extractSectionsData(const nbt::TagList& sections, World::ChunkData& chunk) { + for (size_t i = 0; i < sections.size(); i++) { + const auto& sectionTag = sections[i].get>(); + + // Get section Y coordinate + int8_t sectionY = 0; + if (sectionTag->contains("Y")) { + sectionY = sectionTag->at("Y").get(); + } + + // Extract block states + if (sectionTag->contains("block_states")) { + const auto& blockStatesTag = sectionTag->at("block_states").get>(); + extractBlockStatesFromSection(*blockStatesTag, chunk, sectionY); + } + + // Extract light data if present + if (sectionTag->contains("SkyLight")) { + const auto& skyLightTag = sectionTag->at("SkyLight").get(); + // Append to chunk.skyLight + size_t offset = chunk.skyLight.size(); + chunk.skyLight.resize(offset + skyLightTag.size()); + std::memcpy(chunk.skyLight.data() + offset, skyLightTag.data(), skyLightTag.size()); + } + + if (sectionTag->contains("BlockLight")) { + const auto& blockLightTag = sectionTag->at("BlockLight").get(); + // Append to chunk.blockLight + size_t offset = chunk.blockLight.size(); + chunk.blockLight.resize(offset + blockLightTag.size()); + std::memcpy(chunk.blockLight.data() + offset, blockLightTag.data(), blockLightTag.size()); + } + } +} + +void World::Query::extractBlockStatesFromSection(const nbt::TagCompound& blockStates, World::ChunkData& chunk, int8_t sectionY) { + // Block states contain palette and packed data array + + if (blockStates.contains("data")) { + const auto& dataTag = blockStates.at("data").get(); + + // For now, just append raw packed data + // In a full implementation, you'd unpack the bits based on palette size + size_t offset = chunk.blockData.size(); + chunk.blockData.resize(offset + dataTag.size() * sizeof(int64_t)); + std::memcpy(chunk.blockData.data() + offset, dataTag.data(), dataTag.size() * sizeof(int64_t)); + } + + // Note: To properly decode blocks, you'd also need to: + // 1. Read the "palette" array to get block state mappings + // 2. Calculate bits per entry based on palette size + // 3. Unpack the long array using the calculated bits per entry + // 4. Map indices back to actual block states using the palette +} + +void World::Query::extractHeightmaps(const nbt::TagCompound& heightmaps, World::ChunkData& chunk) { + // Modern chunks typically have multiple heightmap types + if (heightmaps.contains("MOTION_BLOCKING")) { + const auto& motionBlockingTag = heightmaps.at("MOTION_BLOCKING").get(); + + size_t dataSize = motionBlockingTag.size() * sizeof(int64_t); + chunk.heightmaps.resize(dataSize); + std::memcpy(chunk.heightmaps.data(), motionBlockingTag.data(), dataSize); + } +} + +void World::Query::extractBiomesFromSections(const nbt::TagCompound& root, World::ChunkData& chunk) { + // In modern format, biomes are stored in sections + if (root.contains("sections")) { + const auto& sectionsTag = root.at("sections").get>(); + + for (size_t i = 0; i < sectionsTag->size(); i++) { + const auto& sectionTag = (*sectionsTag)[i].get>(); + + if (sectionTag->contains("biomes")) { + const auto& biomesTag = sectionTag->at("biomes").get>(); + + if (biomesTag->contains("data")) { + const auto& biomeDataTag = biomesTag->at("data").get(); + + // Append biome data + size_t offset = chunk.biomeData.size(); + chunk.biomeData.resize(offset + biomeDataTag.size() * sizeof(int64_t)); + std::memcpy(chunk.biomeData.data() + offset, biomeDataTag.data(), biomeDataTag.size() * sizeof(int64_t)); + } + } + } + } +} + +void World::Query::extractBlockEntities(const nbt::TagList& blockEntities, World::ChunkData& chunk) { + // For now, just reserve some space + // In a full implementation, you'd serialize each block entity properly + chunk.blockEntities.reserve(blockEntities.size() * 100); // Rough estimate + + // You could iterate through and extract specific block entity data if needed + // For basic functionality, leaving empty is fine +} + +World::ChunkData World::Query::generateEmptyChunk(int chunkX, int chunkZ) { + World::ChunkData emptyChunk(chunkX, chunkZ); + + // Leave all vectors empty - this represents an empty chunk + // The isEmpty() function will return true for this chunk + + g_logger->logGameInfo(DEBUG, "Generated empty chunk (" + std::to_string(chunkX) + ", " + std::to_string(chunkZ) + ")", "World::Query"); + + return emptyChunk; +} From 9aeb36083fd060b31e83ec0a0c515039f1f0e90c Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" Date: Fri, 10 Oct 2025 23:57:55 +0000 Subject: [PATCH 26/27] Apply clang-format [skip ci] --- include/lib/nbt.hpp | 6 +-- include/lib/nbtParser.hpp | 2 +- include/logger.hpp | 5 +- src/entities/player.cpp | 13 +++-- src/lib/MD5.cpp | 3 +- src/lib/UUID.cpp | 7 ++- src/lib/buffer.cpp | 11 ++--- src/lib/config.cpp | 17 +++---- src/lib/idManager.cpp | 6 +-- src/lib/logger.cpp | 24 +++------ src/lib/nbtParser.cpp | 3 +- src/lib/packet.cpp | 21 +++----- src/networking/networkManager.cpp | 11 ++--- src/networking/networkQueuer.cpp | 3 +- src/networking/packet/cookieRequest.cpp | 4 +- src/networking/packet/packetRouter.cpp | 65 +++++++------------------ src/networking/packet/status.cpp | 12 ++--- src/server.cpp | 46 ++++++----------- 18 files changed, 82 insertions(+), 177 deletions(-) diff --git a/include/lib/nbt.hpp b/include/lib/nbt.hpp index 93388a8..11f4d22 100644 --- a/include/lib/nbt.hpp +++ b/include/lib/nbt.hpp @@ -43,10 +43,8 @@ namespace std { namespace std { template constexpr To bit_cast(const From& src) noexcept { static_assert(sizeof(To) == sizeof(From), "bit_cast requires same size types"); - static_assert(std::is_trivially_copyable_v, - "bit_cast requires trivially copyable To type"); - static_assert(std::is_trivially_copyable_v, - "bit_cast requires trivially copyable From type"); + static_assert(std::is_trivially_copyable_v, "bit_cast requires trivially copyable To type"); + static_assert(std::is_trivially_copyable_v, "bit_cast requires trivially copyable From type"); To dst; std::memcpy(&dst, &src, sizeof(To)); return dst; diff --git a/include/lib/nbtParser.hpp b/include/lib/nbtParser.hpp index 03196a3..6fe258a 100644 --- a/include/lib/nbtParser.hpp +++ b/include/lib/nbtParser.hpp @@ -26,7 +26,7 @@ namespace nbt { std::string parseTagName(const std::vector& data, size_t& cursor); TagCompound parseCompound(const std::vector& data, size_t& cursor); TagList parseList(const std::vector& data, size_t& cursor); - Tag parseTag(const std::vector& data, size_t& cursor, uint8_t tagType); + Tag parseTag(const std::vector& data, size_t& cursor, uint8_t tagType); }; } // namespace nbt diff --git a/include/logger.hpp b/include/logger.hpp index b39a3f0..fb9c778 100644 --- a/include/logger.hpp +++ b/include/logger.hpp @@ -37,10 +37,7 @@ class LogManager { ~LogManager(); // Core logging methods - void log(LogLevel level, - LogCategory category, - const std::string& message, - const std::string& source = ""); + void log(LogLevel level, LogCategory category, const std::string& message, const std::string& source = ""); void logNetwork(LogLevel level, const std::string& message, const std::string& source = ""); void logGameInfo(LogLevel level, const std::string& message, const std::string& source = ""); diff --git a/src/entities/player.cpp b/src/entities/player.cpp index 6c9518f..2f6944a 100644 --- a/src/entities/player.cpp +++ b/src/entities/player.cpp @@ -6,13 +6,12 @@ #include Player::Player(Server& server) - : _name("Player_entity"), _state(PlayerState::None), _socketFd(-1), x(0), y(0), z(0), health(0), - _uuid(), _playerId(server.getIdManager().allocate()), _server(server), - _config(new PlayerConfig()) {} + : _name("Player_entity"), _state(PlayerState::None), _socketFd(-1), x(0), y(0), z(0), health(0), _uuid(), + _playerId(server.getIdManager().allocate()), _server(server), _config(new PlayerConfig()) {} Player::Player(const std::string& name, const PlayerState state, const int socket, Server& server) - : _state(state), _socketFd(socket), x(0), y(0), z(0), health(20), _uuid(), - _playerId(server.getIdManager().allocate()), _server(server), _config(new PlayerConfig()) { + : _state(state), _socketFd(socket), x(0), y(0), z(0), health(20), _uuid(), _playerId(server.getIdManager().allocate()), _server(server), + _config(new PlayerConfig()) { if (name.length() > 32) _name = name.substr(0, 31); else @@ -49,7 +48,7 @@ int Player::getPlayerID() const { return (_playerId); } // PlayerConfig implementation PlayerConfig::PlayerConfig() - : _chatMode(0), _mainHand(1), _locale("en_US"), _viewDistance(10), _displayedSkinParts(0), - _chatColors(true), _enableTextFiltering(false), _allowServerListings(true) {} + : _chatMode(0), _mainHand(1), _locale("en_US"), _viewDistance(10), _displayedSkinParts(0), _chatColors(true), _enableTextFiltering(false), + _allowServerListings(true) {} PlayerConfig::~PlayerConfig() {} diff --git a/src/lib/MD5.cpp b/src/lib/MD5.cpp index c352fad..27c65b5 100644 --- a/src/lib/MD5.cpp +++ b/src/lib/MD5.cpp @@ -45,8 +45,7 @@ std::vector MD5::hash(const std::string& input) { for (size_t offset = 0; offset < data.size(); offset += 64) { uint32_t M[16]; for (int i = 0; i < 16; ++i) { - M[i] = (data[offset + i * 4]) | (data[offset + i * 4 + 1] << 8) | - (data[offset + i * 4 + 2] << 16) | (data[offset + i * 4 + 3] << 24); + M[i] = (data[offset + i * 4]) | (data[offset + i * 4 + 1] << 8) | (data[offset + i * 4 + 2] << 16) | (data[offset + i * 4 + 3] << 24); } uint32_t a = A, b = B, c = C, d = D; diff --git a/src/lib/UUID.cpp b/src/lib/UUID.cpp index 0ff6b1f..5f67cca 100644 --- a/src/lib/UUID.cpp +++ b/src/lib/UUID.cpp @@ -21,10 +21,9 @@ void UUID::setLeastSigBits(uint64_t val) { _leastSigBits = val; } std::string UUID::toString() const { std::stringstream ss; - ss << std::hex << std::setfill('0') << std::setw(8) << ((_mostSigBits >> 32) & 0xFFFFFFFF) - << "-" << std::setw(4) << ((_mostSigBits >> 16) & 0xFFFF) << "-" << std::setw(4) - << (_mostSigBits & 0xFFFF) << "-" << std::setw(4) << ((_leastSigBits >> 48) & 0xFFFF) << "-" - << std::setw(12) << (_leastSigBits & 0xFFFFFFFFFFFFULL); + ss << std::hex << std::setfill('0') << std::setw(8) << ((_mostSigBits >> 32) & 0xFFFFFFFF) << "-" << std::setw(4) + << ((_mostSigBits >> 16) & 0xFFFF) << "-" << std::setw(4) << (_mostSigBits & 0xFFFF) << "-" << std::setw(4) << ((_leastSigBits >> 48) & 0xFFFF) + << "-" << std::setw(12) << (_leastSigBits & 0xFFFFFFFFFFFFULL); return ss.str(); } diff --git a/src/lib/buffer.cpp b/src/lib/buffer.cpp index 6b0f645..1ca0ea0 100644 --- a/src/lib/buffer.cpp +++ b/src/lib/buffer.cpp @@ -17,13 +17,9 @@ uint8_t Buffer::readByte() { void Buffer::writeByte(uint8_t byte) { _data.push_back(byte); } -void Buffer::writeBytes(const std::string& data) { - _data.insert(_data.end(), data.begin(), data.end()); -} +void Buffer::writeBytes(const std::string& data) { _data.insert(_data.end(), data.begin(), data.end()); } -void Buffer::writeBytes(const std::vector& data) { - _data.insert(_data.end(), data.begin(), data.end()); -} +void Buffer::writeBytes(const std::vector& data) { _data.insert(_data.end(), data.begin(), data.end()); } void Buffer::writeUUID(const UUID& uuid) { uint64_t msb = uuid.getMostSigBits(); @@ -138,8 +134,7 @@ void Buffer::writeBool(bool value) { writeByte(value ? 0x01 : 0x00); } void Buffer::writeNBT(const std::string& nbtData) { writeBytes(nbtData); } void Buffer::writePosition(int32_t x, int32_t y, int32_t z) { - int64_t packed = ((int64_t)(x & 0x3FFFFFF) << 38) | ((int64_t)(y & 0xFFF) << 26) | - (int64_t)(z & 0x3FFFFFF); + int64_t packed = ((int64_t)(x & 0x3FFFFFF) << 38) | ((int64_t)(y & 0xFFF) << 26) | (int64_t)(z & 0x3FFFFFF); writeLong(packed); } diff --git a/src/lib/config.cpp b/src/lib/config.cpp index a81c821..586a0f4 100644 --- a/src/lib/config.cpp +++ b/src/lib/config.cpp @@ -10,13 +10,11 @@ using json = nlohmann::json; Config::Config() - : _execPath(getPath()), _gameVersion("1.21.5"), _protocolVersion(770), - _serverMotd("A Minecraft Server"), _serverAddress("127.0.0.1"), _serverPort(25565), - _serverSize(20), _worldName("world"), _gamemode("survival"), _difficulty("normal") {} + : _execPath(getPath()), _gameVersion("1.21.5"), _protocolVersion(770), _serverMotd("A Minecraft Server"), _serverAddress("127.0.0.1"), + _serverPort(25565), _serverSize(20), _worldName("world"), _gamemode("survival"), _difficulty("normal") {} bool Config::loadConfig() { - std::ifstream inputFile(_execPath.parent_path() / - "config.json"); // Should change the config path later if needed + std::ifstream inputFile(_execPath.parent_path() / "config.json"); // Should change the config path later if needed if (!inputFile.is_open()) { g_logger->logGameInfo(DEBUG, "Error: Could not open: config.json", "SERVER"); @@ -37,8 +35,7 @@ bool Config::loadConfig() { Config::setGamemode(config["world"]["gamemode"]); Config::setDifficulty(config["world"]["difficulty"]); } catch (json::parse_error& e) { - g_logger->logGameInfo( - ERROR, "Error parsing config.json: " + std::string(e.what()), "SERVER"); + g_logger->logGameInfo(ERROR, "Error parsing config.json: " + std::string(e.what()), "SERVER"); inputFile.close(); return true; } @@ -47,8 +44,7 @@ bool Config::loadConfig() { } bool Config::reloadConfig() { - std::ifstream inputFile(_execPath.root_directory() / - "config.json"); // Should change the config path later if needed + std::ifstream inputFile(_execPath.root_directory() / "config.json"); // Should change the config path later if needed if (!inputFile.is_open()) { g_logger->logGameInfo(DEBUG, "Error: Could not open: config.json", "SERVER"); @@ -67,8 +63,7 @@ bool Config::reloadConfig() { Config::setGamemode(config["world"]["gamemode"]); Config::setDifficulty(config["world"]["difficulty"]); } catch (json::parse_error& e) { - g_logger->logGameInfo( - ERROR, "Error parsing config.json: " + std::string(e.what()), "SERVER"); + g_logger->logGameInfo(ERROR, "Error parsing config.json: " + std::string(e.what()), "SERVER"); inputFile.close(); return true; } diff --git a/src/lib/idManager.cpp b/src/lib/idManager.cpp index dd5633e..f616e1a 100644 --- a/src/lib/idManager.cpp +++ b/src/lib/idManager.cpp @@ -25,8 +25,7 @@ uint32_t IdManager::allocate() { void IdManager::release(uint32_t id) { std::lock_guard lock(_mutex); if (id >= _nextId) { - std::cerr << "[IdManager] WARNING: Trying to release invalid ID " << id - << " (nextId: " << _nextId << ")" << std::endl; + std::cerr << "[IdManager] WARNING: Trying to release invalid ID " << id << " (nextId: " << _nextId << ")" << std::endl; return; } if (_freedIds.find(id) != _freedIds.end()) { @@ -35,8 +34,7 @@ void IdManager::release(uint32_t id) { } _freedIds.insert(id); - std::cout << "[IdManager] Released ID: " << id << " (freed count: " << _freedIds.size() << ")" - << std::endl; + std::cout << "[IdManager] Released ID: " << id << " (freed count: " << _freedIds.size() << ")" << std::endl; } size_t IdManager::getAllocatedCount() const { diff --git a/src/lib/logger.cpp b/src/lib/logger.cpp index 26e8b82..bdc9e87 100644 --- a/src/lib/logger.cpp +++ b/src/lib/logger.cpp @@ -56,7 +56,7 @@ std::string LogManager::getCurrentTimestamp() { std::string LogManager::getDetailedTimestamp() { auto now = std::chrono::system_clock::now(); auto time_t = std::chrono::system_clock::to_time_t(now); - auto ms = std::chrono::duration_cast(now.time_since_epoch()) % 1000; + auto ms = std::chrono::duration_cast(now.time_since_epoch()) % 1000; std::stringstream ss; ss << std::put_time(std::localtime(&time_t), "%H:%M:%S"); @@ -111,10 +111,7 @@ bool LogManager::initializeLogDirectory() { return true; } -void LogManager::log(LogLevel level, - LogCategory category, - const std::string& message, - const std::string& source) { +void LogManager::log(LogLevel level, LogCategory category, const std::string& message, const std::string& source) { LogEntry entry; entry.timestamp = std::chrono::system_clock::now(); entry.level = level; @@ -128,22 +125,15 @@ void LogManager::log(LogLevel level, _logQueue.push(entry); } - if (category == GAMEINFO || - category == NETWORK) { // Remove category == NETWORK on release build + if (category == GAMEINFO || category == NETWORK) { // Remove category == NETWORK on release build std::string formattedEntry = formatLogEntry(entry); std::cout << formattedEntry << std::endl; } } -void LogManager::logNetwork(LogLevel level, const std::string& message, const std::string& source) { - log(level, NETWORK, message, source); -} +void LogManager::logNetwork(LogLevel level, const std::string& message, const std::string& source) { log(level, NETWORK, message, source); } -void LogManager::logGameInfo(LogLevel level, - const std::string& message, - const std::string& source) { - log(level, GAMEINFO, message, source); -} +void LogManager::logGameInfo(LogLevel level, const std::string& message, const std::string& source) { log(level, GAMEINFO, message, source); } void LogManager::writerThreadLoop() { while (_running || !_logQueue.empty()) { @@ -184,9 +174,7 @@ std::string LogManager::formatLogEntry(const LogEntry& entry) { // Add timestamp auto time_t = std::chrono::system_clock::to_time_t(entry.timestamp); - auto ms = std::chrono::duration_cast( - entry.timestamp.time_since_epoch()) % - 1000; + auto ms = std::chrono::duration_cast(entry.timestamp.time_since_epoch()) % 1000; ss << "[" << std::put_time(std::localtime(&time_t), "%H:%M:%S"); ss << "." << std::setfill('0') << std::setw(3) << ms.count() << "] "; diff --git a/src/lib/nbtParser.cpp b/src/lib/nbtParser.cpp index f5f0950..90237f8 100644 --- a/src/lib/nbtParser.cpp +++ b/src/lib/nbtParser.cpp @@ -177,8 +177,7 @@ namespace nbt { case TAG_COMPOUND: return Tag(std::make_shared(parseCompound(data, cursor))); default: - throw std::runtime_error("NBT parsing error: unsupported tag type: " + - std::to_string(tagType)); + throw std::runtime_error("NBT parsing error: unsupported tag type: " + std::to_string(tagType)); } } diff --git a/src/lib/packet.cpp b/src/lib/packet.cpp index 10d7541..f52745e 100644 --- a/src/lib/packet.cpp +++ b/src/lib/packet.cpp @@ -22,8 +22,7 @@ using json = nlohmann::json; Packet::~Packet() {} Packet::Packet(const Packet& other) - : _size(other._size), _id(other._id), _data(other._data), _player(other._player), - _socketFd(other._socketFd), _returnPacket(other._returnPacket) { + : _size(other._size), _id(other._id), _data(other._data), _player(other._player), _socketFd(other._socketFd), _returnPacket(other._returnPacket) { std::cout << "[Packet] Copy constructor called" << std::endl; } @@ -81,8 +80,7 @@ Packet::Packet(Player* player) : _player(player), _socketFd(-1), _returnPacket(0 } } -Packet::Packet(int socketFd, Server& server) - : _player(nullptr), _socketFd(socketFd), _returnPacket(0) { +Packet::Packet(int socketFd, Server& server) : _player(nullptr), _socketFd(socketFd), _returnPacket(0) { // g_logger->logNetwork(INFO, "Constructor (socket): Socket FD = " + std::to_string(_socketFd), // "Packet"); @@ -131,8 +129,7 @@ Packet::Packet(int socketFd, Server& server) int Packet::getVarintSize(int32_t value) { if (value < 0) { - std::cerr << "[Packet] ERROR: getVarintSize called with negative value: " << value - << std::endl; + std::cerr << "[Packet] ERROR: getVarintSize called with negative value: " << value << std::endl; throw std::runtime_error("getVarintSize called with negative value"); } int size = 0; @@ -158,8 +155,7 @@ int Packet::readVarint(int sock, int* bytesRead) { while (true) { ssize_t result = ::read(sock, &byte, 1); if (result <= 0) { - std::cerr << "readVarint: Failed to read byte " << localBytesRead << " from socket " - << sock << " (errno: " << errno << ")" << std::endl; + std::cerr << "readVarint: Failed to read byte " << localBytesRead << " from socket " << sock << " (errno: " << errno << ")" << std::endl; return -1; } @@ -170,15 +166,13 @@ int Packet::readVarint(int sock, int* bytesRead) { position += 7; if (position >= 32) { - std::cerr << "readVarint: Varint too long (> 32 bits) after " << localBytesRead - << " bytes" << std::endl; + std::cerr << "readVarint: Varint too long (> 32 bits) after " << localBytesRead << " bytes" << std::endl; return -1; } // Safety check to prevent infinite loops if (localBytesRead > 5) { - std::cerr << "readVarint: Too many bytes read (" << localBytesRead - << "), corrupted varint" << std::endl; + std::cerr << "readVarint: Too many bytes read (" << localBytesRead << "), corrupted varint" << std::endl; return -1; } } @@ -218,8 +212,7 @@ bool Packet::isSocketValid(int sock) { } if (pfd.revents & (POLLHUP | POLLERR)) { - std::cerr << "Socket validation: Socket " << sock << " is disconnected or has error" - << std::endl; + std::cerr << "Socket validation: Socket " << sock << " is disconnected or has error" << std::endl; return false; } diff --git a/src/networking/networkManager.cpp b/src/networking/networkManager.cpp index 2110cce..a7392f0 100644 --- a/src/networking/networkManager.cpp +++ b/src/networking/networkManager.cpp @@ -13,9 +13,8 @@ #include NetworkManager::NetworkManager(size_t workerCount, Server& s) - : _incomingPackets(), _outgoingPackets(), _workerThreads(), _shutdownFlag(false), - _receiverThread(), _senderThread(), _receiverThreadInit(0), _senderThreadInit(0), _server(s), - _epollFd(-1), _serverSocket(-1) { + : _incomingPackets(), _outgoingPackets(), _workerThreads(), _shutdownFlag(false), _receiverThread(), _senderThread(), _receiverThreadInit(0), + _senderThreadInit(0), _server(s), _epollFd(-1), _serverSocket(-1) { _workerThreads.reserve(workerCount); setupEpoll(); @@ -101,8 +100,7 @@ void NetworkManager::start() { if (strcmp(getServer().getConfig().getServerAddress().c_str(), "0.0.0.0") == 0) { serverAddr.sin_addr.s_addr = INADDR_ANY; } else { - if (inet_aton(getServer().getConfig().getServerAddress().c_str(), &serverAddr.sin_addr) == - 0) { + if (inet_aton(getServer().getConfig().getServerAddress().c_str(), &serverAddr.sin_addr) == 0) { close(_serverSocket); throw std::runtime_error("Invalid IP address"); } @@ -110,8 +108,7 @@ void NetworkManager::start() { if (bind(_serverSocket, (struct sockaddr*)&serverAddr, sizeof(serverAddr)) < 0) { close(_serverSocket); - throw std::runtime_error("Failed to bind socket to " + - std::string(getServer().getConfig().getServerAddress()) + ":" + + throw std::runtime_error("Failed to bind socket to " + std::string(getServer().getConfig().getServerAddress()) + ":" + std::to_string(getServer().getConfig().getServerPort())); } diff --git a/src/networking/networkQueuer.cpp b/src/networking/networkQueuer.cpp index 6ae7d5a..3782121 100644 --- a/src/networking/networkQueuer.cpp +++ b/src/networking/networkQueuer.cpp @@ -42,8 +42,7 @@ void NetworkManager::receiverThreadLoop() { event.events = EPOLLIN; event.data.fd = client_fd; if (epoll_ctl(_epollFd, EPOLL_CTL_ADD, client_fd, &event) == -1) { - std::cerr << "[Network Manager] Failed to add new client socket to epoll" - << std::endl; + std::cerr << "[Network Manager] Failed to add new client socket to epoll" << std::endl; close(client_fd); } } diff --git a/src/networking/packet/cookieRequest.cpp b/src/networking/packet/cookieRequest.cpp index 4d3b78e..3118504 100644 --- a/src/networking/packet/cookieRequest.cpp +++ b/src/networking/packet/cookieRequest.cpp @@ -29,8 +29,8 @@ void handleCookieRequest(Packet& packet, Server& server) { // Create a fresh buffer from the packet data to read from beginning Buffer cookieBuffer(packet.getData().getData()); cookieIdentifier = cookieBuffer.readString(32767); // Max string length - // g_logger->logNetwork(INFO, "Cookie Request for identifier: '" + cookieIdentifier + "'", - // "Configuration"); + // g_logger->logNetwork(INFO, "Cookie Request for identifier: '" + cookieIdentifier + "'", + // "Configuration"); } catch (const std::exception& e) { // g_logger->logNetwork(ERROR, "Failed to read cookie identifier: " + std::string(e.what()), // "Configuration"); Send empty response instead of disconnecting diff --git a/src/networking/packet/packetRouter.cpp b/src/networking/packet/packetRouter.cpp index 8a07356..b2cdaca 100644 --- a/src/networking/packet/packetRouter.cpp +++ b/src/networking/packet/packetRouter.cpp @@ -31,9 +31,8 @@ void packetRouter(Packet* packet, Server& server) { } g_logger->logNetwork(INFO, - "Routing packet ID: 0x" + std::to_string(packet->getId()) + - " (size: " + std::to_string(packet->getSize()) + ") for state: " + - std::to_string(static_cast(player->getPlayerState())), + "Routing packet ID: 0x" + std::to_string(packet->getId()) + " (size: " + std::to_string(packet->getSize()) + + ") for state: " + std::to_string(static_cast(player->getPlayerState())), "PacketRouter"); switch (player->getPlayerState()) { @@ -53,11 +52,8 @@ void packetRouter(Packet* packet, Server& server) { handlePlayState(packet, server); break; default: - g_logger->logNetwork(WARN, - "Unknown player state: " + - std::to_string(static_cast(player->getPlayerState())) + - ", disconnecting", - "PacketRouter"); + g_logger->logNetwork( + WARN, "Unknown player state: " + std::to_string(static_cast(player->getPlayerState())) + ", disconnecting", "PacketRouter"); packet->setReturnPacket(PACKET_DISCONNECT); break; } @@ -67,9 +63,7 @@ void packetRouter(Packet* packet, Server& server) { // Handshake State Handler // ======================================== -void handleHandshakeState(Packet* packet, Server& server) { - handleHandshakePacket(*packet, server); -} +void handleHandshakeState(Packet* packet, Server& server) { handleHandshakePacket(*packet, server); } // ======================================== // Status State Handler @@ -81,10 +75,7 @@ void handleStatusState(Packet* packet, Server& server) { } else if (packet->getId() == 0x01) { handlePingPacket(*packet, server); } else { - g_logger->logNetwork(WARN, - "Unknown packet ID in Status state: 0x" + - std::to_string(packet->getId()), - "PacketRouter"); + g_logger->logNetwork(WARN, "Unknown packet ID in Status state: 0x" + std::to_string(packet->getId()), "PacketRouter"); packet->getPlayer()->setPlayerState(PlayerState::None); packet->setReturnPacket(PACKET_DISCONNECT); } @@ -97,9 +88,7 @@ void handleStatusState(Packet* packet, Server& server) { void handleLoginState(Packet* packet, Server& server) { // Add safety check for packet data integrity if (packet->getSize() > 32767) { // Max packet size - g_logger->logNetwork(ERROR, - "Packet size too large: " + std::to_string(packet->getSize()), - "PacketRouter"); + g_logger->logNetwork(ERROR, "Packet size too large: " + std::to_string(packet->getSize()), "PacketRouter"); packet->setReturnPacket(PACKET_DISCONNECT); return; } @@ -110,8 +99,7 @@ void handleLoginState(Packet* packet, Server& server) { handleLoginStartPacket(*packet, server); } else if (packet->getId() == 0x02) { // Login Plugin Response - safe to ignore most of the time - g_logger->logNetwork( - INFO, "Received Login Plugin Response (0x02) - acknowledging", "PacketRouter"); + g_logger->logNetwork(INFO, "Received Login Plugin Response (0x02) - acknowledging", "PacketRouter"); packet->setReturnPacket(PACKET_OK); } else if (packet->getId() == 0x03) { // Login Acknowledged @@ -119,14 +107,10 @@ void handleLoginState(Packet* packet, Server& server) { handleLoginAcknowledged(*packet, server); } else if (packet->getId() == 0x04) { // Cookie Response (login) - g_logger->logNetwork( - INFO, "Received Login Cookie Response (0x04) - acknowledging", "PacketRouter"); + g_logger->logNetwork(INFO, "Received Login Cookie Response (0x04) - acknowledging", "PacketRouter"); packet->setReturnPacket(PACKET_OK); } else { - g_logger->logNetwork(WARN, - "Unknown packet ID in Login state: 0x" + - std::to_string(packet->getId()), - "PacketRouter"); + g_logger->logNetwork(WARN, "Unknown packet ID in Login state: 0x" + std::to_string(packet->getId()), "PacketRouter"); packet->getPlayer()->setPlayerState(PlayerState::None); packet->setReturnPacket(PACKET_DISCONNECT); } @@ -159,18 +143,13 @@ void handleConfigurationState(Packet* packet, Server& server) { } else if (packet->getId() == 0x02) { // Serverbound Plugin Message (configuration) - g_logger->logNetwork(INFO, - "Received Serverbound Plugin Message (0x02), size: " + - std::to_string(packet->getSize()) + " bytes", - "PacketRouter"); + g_logger->logNetwork( + INFO, "Received Serverbound Plugin Message (0x02), size: " + std::to_string(packet->getSize()) + " bytes", "PacketRouter"); packet->setReturnPacket(PACKET_OK); } else if (packet->getId() == 0x03) { // Acknowledge Finish Configuration -> enter Play - g_logger->logNetwork( - INFO, - "Received Acknowledge Finish Configuration - transitioning to Play state", - "PacketRouter"); + g_logger->logNetwork(INFO, "Received Acknowledge Finish Configuration - transitioning to Play state", "PacketRouter"); handleAcknowledgeFinishConfiguration(*packet, server); initGameSequence(packet, server); @@ -204,10 +183,7 @@ void handleConfigurationState(Packet* packet, Server& server) { packet->setReturnPacket(PACKET_OK); } else { - g_logger->logNetwork(WARN, - "Unknown packet ID in Configuration state: 0x" + - std::to_string(packet->getId()), - "PacketRouter"); + g_logger->logNetwork(WARN, "Unknown packet ID in Configuration state: 0x" + std::to_string(packet->getId()), "PacketRouter"); sendDisconnectPacket(packet, "Unknown packet in Configuration state", server); packet->getPlayer()->setPlayerState(PlayerState::None); packet->setReturnPacket(PACKET_DISCONNECT); @@ -244,8 +220,7 @@ void sendDisconnectPacket(Packet* packet, const std::string& reason, Server& ser Player* player = packet->getPlayer(); if (!player) return; - g_logger->logNetwork( - INFO, "Sending disconnect packet to player with reason: " + reason, "PacketRouter"); + g_logger->logNetwork(INFO, "Sending disconnect packet to player with reason: " + reason, "PacketRouter"); try { // Create Disconnect packet (0x02 in Configuration state) @@ -270,9 +245,7 @@ void sendDisconnectPacket(Packet* packet, const std::string& reason, Server& ser g_logger->logNetwork(INFO, "Disconnect packet queued for sending", "PacketRouter"); } catch (const std::exception& e) { - g_logger->logNetwork(ERROR, - "Error creating disconnect packet: " + std::string(e.what()), - "PacketRouter"); + g_logger->logNetwork(ERROR, "Error creating disconnect packet: " + std::string(e.what()), "PacketRouter"); } } @@ -287,8 +260,7 @@ void initGameSequence(Packet* packet, Server& server) { if (player == nullptr) return; // Player should already be in Play state at this point - g_logger->logNetwork( - INFO, "Starting game sequence for player: " + player->getPlayerName(), "PacketRouter"); + g_logger->logNetwork(INFO, "Starting game sequence for player: " + player->getPlayerName(), "PacketRouter"); try { // 1. Send Login (play) packet - 0x2B @@ -322,8 +294,7 @@ void initGameSequence(Packet* packet, Server& server) { packet->setReturnPacket(PACKET_OK); } catch (const std::exception& e) { - g_logger->logNetwork( - ERROR, "Error in game sequence: " + std::string(e.what()), "PacketRouter"); + g_logger->logNetwork(ERROR, "Error in game sequence: " + std::string(e.what()), "PacketRouter"); packet->setReturnPacket(PACKET_ERROR); } } diff --git a/src/networking/packet/status.cpp b/src/networking/packet/status.cpp index 31e88a1..7536ff3 100644 --- a/src/networking/packet/status.cpp +++ b/src/networking/packet/status.cpp @@ -17,14 +17,10 @@ void handleStatusPacket(Packet& packet, Server& server) { return; } - json jres = {{"version", - {{"name", server.getConfig().getVersion()}, - {"protocol", server.getConfig().getProtocolVersion()}}}, - {"players", - {{"max", server.getConfig().getServerSize()}, - {"online", server.getAmountOnline()}, - {"sample", server.getPlayerSample()}}}, - {"description", {{"text", server.getConfig().getServerMotd()}}}}; + json jres = { + {"version", {{"name", server.getConfig().getVersion()}, {"protocol", server.getConfig().getProtocolVersion()}}}, + {"players", {{"max", server.getConfig().getServerSize()}, {"online", server.getAmountOnline()}, {"sample", server.getPlayerSample()}}}, + {"description", {{"text", server.getConfig().getServerMotd()}}}}; std::string payload = jres.dump(); int jsonLen = payload.size(); diff --git a/src/server.cpp b/src/server.cpp index 42eee32..6645d57 100644 --- a/src/server.cpp +++ b/src/server.cpp @@ -1,9 +1,10 @@ +#include "network/server.hpp" + #include "config.hpp" #include "lib/filesystem.hpp" #include "lib/json.hpp" #include "logger.hpp" #include "network/networking.hpp" -#include "network/server.hpp" #include "player.hpp" #include "world/world.hpp" @@ -40,50 +41,31 @@ int Server::start_server() { std::filesystem::path levelDatPath = getPath().parent_path() / worldName / "level.dat"; if (!std::filesystem::exists(levelDatPath)) { - g_logger->logGameInfo( - ERROR, "level.dat not found at: " + levelDatPath.string(), "SERVER"); + g_logger->logGameInfo(ERROR, "level.dat not found at: " + levelDatPath.string(), "SERVER"); return 1; } _worldData = _worldManager.loadLevelDat(levelDatPath); // Log world information - g_logger->logGameInfo( - INFO, "World loaded successfully: " + _worldData.LevelName, "SERVER"); + g_logger->logGameInfo(INFO, "World loaded successfully: " + _worldData.LevelName, "SERVER"); g_logger->logGameInfo(INFO, - "Spawn Point: X=" + std::to_string(_worldData.SpawnX) + - " Y=" + std::to_string(_worldData.SpawnY) + + "Spawn Point: X=" + std::to_string(_worldData.SpawnX) + " Y=" + std::to_string(_worldData.SpawnY) + " Z=" + std::to_string(_worldData.SpawnZ), "SERVER"); - g_logger->logGameInfo( - INFO, "Random Seed: " + std::to_string(_worldData.RandomSeed), "SERVER"); - g_logger->logGameInfo( - INFO, "Game Type: " + std::to_string(_worldData.GameType), "SERVER"); - g_logger->logGameInfo( - INFO, "Data Version: " + std::to_string(_worldData.DataVersion), "SERVER"); - g_logger->logGameInfo(INFO, - "Difficulty: " + - std::to_string(static_cast(_worldData.Difficulty)), - "SERVER"); - g_logger->logGameInfo(INFO, - "Hardcore: " + - std::string(_worldData.hardcore ? "true" : "false"), - "SERVER"); + g_logger->logGameInfo(INFO, "Random Seed: " + std::to_string(_worldData.RandomSeed), "SERVER"); + g_logger->logGameInfo(INFO, "Game Type: " + std::to_string(_worldData.GameType), "SERVER"); + g_logger->logGameInfo(INFO, "Data Version: " + std::to_string(_worldData.DataVersion), "SERVER"); + g_logger->logGameInfo(INFO, "Difficulty: " + std::to_string(static_cast(_worldData.Difficulty)), "SERVER"); + g_logger->logGameInfo(INFO, "Hardcore: " + std::string(_worldData.hardcore ? "true" : "false"), "SERVER"); g_logger->logGameInfo(INFO, "Time: " + std::to_string(_worldData.Time), "SERVER"); - g_logger->logGameInfo( - INFO, "Day Time: " + std::to_string(_worldData.DayTime), "SERVER"); + g_logger->logGameInfo(INFO, "Day Time: " + std::to_string(_worldData.DayTime), "SERVER"); g_logger->logGameInfo(INFO, "Generator: " + _worldData.generatorName, "SERVER"); - g_logger->logGameInfo(INFO, - "Raining: " + std::string(_worldData.raining ? "true" : "false"), - "SERVER"); - g_logger->logGameInfo(INFO, - "Thundering: " + - std::string(_worldData.thundering ? "true" : "false"), - "SERVER"); + g_logger->logGameInfo(INFO, "Raining: " + std::string(_worldData.raining ? "true" : "false"), "SERVER"); + g_logger->logGameInfo(INFO, "Thundering: " + std::string(_worldData.thundering ? "true" : "false"), "SERVER"); } catch (const std::exception& e) { - g_logger->logGameInfo( - ERROR, "Failed to load world: " + std::string(e.what()), "SERVER"); + g_logger->logGameInfo(ERROR, "Failed to load world: " + std::string(e.what()), "SERVER"); return 1; } From 6cc08116bc6c8e4a2dd8e48a6c9aa32c883df813 Mon Sep 17 00:00:00 2001 From: Antoine Mathie Date: Sat, 11 Oct 2025 03:11:52 +0200 Subject: [PATCH 27/27] sub --- data-generator | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/data-generator b/data-generator index cf8252a..ab45d37 160000 --- a/data-generator +++ b/data-generator @@ -1 +1 @@ -Subproject commit cf8252a510541dd67bbb6c54258a083360950d87 +Subproject commit ab45d37535cfab95b2c6d340b7c4f9a14ff45a82