From e9076f22fe2a49d1cd8933e54b7b00c5dd943269 Mon Sep 17 00:00:00 2001 From: untodesu Date: Fri, 12 Sep 2025 13:33:52 +0500 Subject: It compiles --- game/server/receive.cc | 5 +++-- game/server/sessions.cc | 4 ++-- game/server/world/overworld.cc | 12 +++++++----- 3 files changed, 12 insertions(+), 9 deletions(-) (limited to 'game/server') diff --git a/game/server/receive.cc b/game/server/receive.cc index 75ac3a6..612674e 100644 --- a/game/server/receive.cc +++ b/game/server/receive.cc @@ -10,6 +10,7 @@ #include "shared/world/chunk_aabb.hh" #include "shared/world/dimension.hh" +#include "shared/world/voxel_registry.hh" #include "shared/coord.hh" #include "shared/protocol.hh" @@ -83,7 +84,7 @@ static void on_entity_head_packet(const protocol::EntityHead& packet) static void on_set_voxel_packet(const protocol::SetVoxel& packet) { if(auto session = sessions::find(packet.peer)) { - if(session->dimension && !session->dimension->set_voxel(packet.voxel, packet.vpos)) { + if(session->dimension && !session->dimension->set_voxel(world::voxel_registry::find(packet.voxel), packet.vpos)) { auto cpos = coord::to_chunk(packet.vpos); auto lpos = coord::to_local(packet.vpos); auto index = coord::to_index(lpos); @@ -102,7 +103,7 @@ static void on_set_voxel_packet(const protocol::SetVoxel& packet) return; } - chunk->set_voxel(packet.voxel, index); + chunk->set_voxel(world::voxel_registry::find(packet.voxel), index); session->dimension->chunks.emplace_or_replace(chunk->get_entity()); diff --git a/game/server/sessions.cc b/game/server/sessions.cc index c06ec3e..32b96a3 100644 --- a/game/server/sessions.cc +++ b/game/server/sessions.cc @@ -65,7 +65,7 @@ static void on_login_request_packet(const protocol::LoginRequest& packet) // FIXME: calculate voxel registry checksum ahead of time // instead of figuring it out every time a new player connects - if(packet.voxel_registry_checksum != world::voxel_registry::calculate_checksum()) { + if(packet.voxel_registry_checksum != world::voxel_registry::get_checksum()) { protocol::Disconnect response; response.reason = "protocol.voxel_registry_checksum"; protocol::send(packet.peer, protocol::encode(response)); @@ -241,7 +241,7 @@ static void on_voxel_set(const world::VoxelSetEvent& event) { protocol::SetVoxel packet; packet.vpos = coord::to_voxel(event.cpos, event.lpos); - packet.voxel = event.voxel; + packet.voxel = event.voxel ? event.voxel->get_id() : NULL_VOXEL_ID; packet.flags = 0U; // UNDONE protocol::broadcast(globals::server_host, protocol::encode(packet)); } diff --git a/game/server/world/overworld.cc b/game/server/world/overworld.cc index eb801de..43059d8 100644 --- a/game/server/world/overworld.cc +++ b/game/server/world/overworld.cc @@ -4,13 +4,15 @@ #include "core/math/vectors.hh" +#include "shared/world/voxel.hh" #include "shared/world/voxel_storage.hh" #include "shared/coord.hh" #include "shared/game_voxels.hh" // FIXME: load these from a file -static void compute_tree_feature(unsigned int height, world::Feature& feature, voxel_id log_voxel, voxel_id leaves_voxel) +static void compute_tree_feature(unsigned int height, world::Feature& feature, const world::Voxel* log_voxel, + const world::Voxel* leaves_voxel) { // Ensure the tree height is too small height = math::max(height, 4U); @@ -251,12 +253,12 @@ void world::Overworld::generate_terrain(const chunk_pos& cpos, VoxelStorage& vox } if(vpos.y < -variation) { - voxels[i] = game_voxels::stone; + voxels[i] = game_voxels::stone->get_id(); continue; } if(is_inside_terrain(vpos)) { - voxels[i] = game_voxels::stone; + voxels[i] = game_voxels::stone->get_id(); continue; } } @@ -308,10 +310,10 @@ void world::Overworld::generate_surface(const chunk_pos& cpos, VoxelStorage& vox if(depth < 5U) { if(depth == 0U) { - voxels[i] = game_voxels::grass; + voxels[i] = game_voxels::grass->get_id(); } else { - voxels[i] = game_voxels::dirt; + voxels[i] = game_voxels::dirt->get_id(); } } } -- cgit From 73cbcdd6e8c849e32abbf9757e603e6a6654e870 Mon Sep 17 00:00:00 2001 From: untodesu Date: Fri, 12 Sep 2025 14:09:34 +0500 Subject: Metaitems --- game/server/sessions.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'game/server') diff --git a/game/server/sessions.cc b/game/server/sessions.cc index 32b96a3..2ab9d74 100644 --- a/game/server/sessions.cc +++ b/game/server/sessions.cc @@ -72,7 +72,7 @@ static void on_login_request_packet(const protocol::LoginRequest& packet) return; } - if(packet.item_registry_checksum != world::item_registry::calculate_checksum()) { + if(packet.item_registry_checksum != world::item_registry::get_checksum()) { protocol::Disconnect response; response.reason = "protocol.item_registry_checksum"; protocol::send(packet.peer, protocol::encode(response)); -- cgit From f210a86c1406ccc6dfd6f14181dd7a1274ee0de4 Mon Sep 17 00:00:00 2001 From: untodesu Date: Fri, 12 Sep 2025 15:09:01 +0500 Subject: Random ticking? In my game?! Hell yeah! --- game/server/game.cc | 7 +++++++ game/server/world/CMakeLists.txt | 2 ++ game/server/world/random_tick.cc | 40 ++++++++++++++++++++++++++++++++++++++++ game/server/world/random_tick.hh | 14 ++++++++++++++ 4 files changed, 63 insertions(+) create mode 100644 game/server/world/random_tick.cc create mode 100644 game/server/world/random_tick.hh (limited to 'game/server') diff --git a/game/server/game.cc b/game/server/game.cc index 8624670..f9802ae 100644 --- a/game/server/game.cc +++ b/game/server/game.cc @@ -28,6 +28,7 @@ #include "shared/protocol.hh" #include "shared/splash.hh" +#include "server/world/random_tick.hh" #include "server/world/universe.hh" #include "server/world/unloader.hh" #include "server/world/worldgen.hh" @@ -69,6 +70,8 @@ void server_game::init(void) world::unloader::init(); world::universe::init(); + + world::random_tick::init(); } void server_game::init_late(void) @@ -128,6 +131,10 @@ void server_game::fixed_update(void) entity::Transform::fixed_update(dimension.second); entity::Gravity::fixed_update(dimension.second); entity::Stasis::fixed_update(dimension.second); + + for(auto [entity, component] : dimension.second->chunks.view().each()) { + world::random_tick::tick(component.cpos, component.chunk); + } } } diff --git a/game/server/world/CMakeLists.txt b/game/server/world/CMakeLists.txt index e8fd4be..58a2216 100644 --- a/game/server/world/CMakeLists.txt +++ b/game/server/world/CMakeLists.txt @@ -2,6 +2,8 @@ target_sources(vserver PRIVATE "${CMAKE_CURRENT_LIST_DIR}/inhabited.hh" "${CMAKE_CURRENT_LIST_DIR}/overworld.cc" "${CMAKE_CURRENT_LIST_DIR}/overworld.hh" + "${CMAKE_CURRENT_LIST_DIR}/random_tick.cc" + "${CMAKE_CURRENT_LIST_DIR}/random_tick.hh" "${CMAKE_CURRENT_LIST_DIR}/universe.cc" "${CMAKE_CURRENT_LIST_DIR}/universe.hh" "${CMAKE_CURRENT_LIST_DIR}/unloader.cc" diff --git a/game/server/world/random_tick.cc b/game/server/world/random_tick.cc new file mode 100644 index 0000000..c5fa47c --- /dev/null +++ b/game/server/world/random_tick.cc @@ -0,0 +1,40 @@ +#include "server/pch.hh" + +#include "server/world/random_tick.hh" + +#include "core/config/number.hh" + +#include "core/io/config_map.hh" + +#include "shared/world/chunk.hh" +#include "shared/world/dimension.hh" +#include "shared/world/voxel.hh" + +#include "shared/coord.hh" + +#include "server/globals.hh" + +static config::Int random_tick_speed(2, 1, 1000); +static std::mt19937_64 random_source; + +void world::random_tick::init(void) +{ + globals::server_config.add_value("world.random_tick_speed", random_tick_speed); + + random_source.seed(std::random_device {}()); +} + +void world::random_tick::tick(const chunk_pos& cpos, Chunk* chunk) +{ + assert(chunk); + + for(int i = 0; i < random_tick_speed.get_value(); ++i) { + auto voxel_index = random_source() % CHUNK_VOLUME; + auto lpos = coord::to_local(voxel_index); + auto vpos = coord::to_voxel(cpos, lpos); + + if(auto voxel = chunk->get_voxel(lpos)) { + voxel->on_tick(chunk->get_dimension(), vpos); + } + } +} diff --git a/game/server/world/random_tick.hh b/game/server/world/random_tick.hh new file mode 100644 index 0000000..4ef1691 --- /dev/null +++ b/game/server/world/random_tick.hh @@ -0,0 +1,14 @@ +#pragma once + +#include "shared/types.hh" + +namespace world +{ +class Chunk; +} // namespace world + +namespace world::random_tick +{ +void init(void); +void tick(const chunk_pos& cpos, Chunk* chunk); +} // namespace world::random_tick -- cgit From 522a7514012da86f7b9643179f0763746f3b232e Mon Sep 17 00:00:00 2001 From: untodesu Date: Fri, 12 Sep 2025 16:15:32 +0500 Subject: Protocol and versioning changes --- game/server/sessions.cc | 24 ++++++++++++++++++++++-- game/server/status.cc | 6 +++++- 2 files changed, 27 insertions(+), 3 deletions(-) (limited to 'game/server') diff --git a/game/server/sessions.cc b/game/server/sessions.cc index 2ab9d74..6758648 100644 --- a/game/server/sessions.cc +++ b/game/server/sessions.cc @@ -12,6 +12,8 @@ #include "core/utils/string.hh" +#include "core/version.hh" + #include "shared/entity/factory.hh" #include "shared/entity/head.hh" #include "shared/entity/player.hh" @@ -42,6 +44,8 @@ private: config::Unsigned sessions::max_players(8U, 1U, 128U); unsigned int sessions::num_players = 0U; +static config::Boolean strict_version_matching(true); + static emhash8::HashMap username_map; static emhash8::HashMap identity_map; static std::vector dimension_listeners; @@ -49,20 +53,36 @@ static std::vector sessions_vector; static void on_login_request_packet(const protocol::LoginRequest& packet) { - if(packet.version > protocol::VERSION) { + if(packet.game_version_major > version::major) { protocol::Disconnect response; response.reason = "protocol.outdated_server"; protocol::send(packet.peer, protocol::encode(response)); return; } - if(packet.version < protocol::VERSION) { + if(packet.game_version_minor < version::minor) { protocol::Disconnect response; response.reason = "protocol.outdated_client"; protocol::send(packet.peer, protocol::encode(response)); return; } + if(strict_version_matching.get_value()) { + if(packet.game_version_minor > version::minor || packet.game_version_patch > version::patch) { + protocol::Disconnect response; + response.reason = "protocol.outdated_server"; + protocol::send(packet.peer, protocol::encode(response)); + return; + } + + if(packet.game_version_minor < version::minor || packet.game_version_patch < version::patch) { + protocol::Disconnect response; + response.reason = "protocol.outdated_client"; + protocol::send(packet.peer, protocol::encode(response)); + return; + } + } + // FIXME: calculate voxel registry checksum ahead of time // instead of figuring it out every time a new player connects if(packet.voxel_registry_checksum != world::voxel_registry::get_checksum()) { diff --git a/game/server/status.cc b/game/server/status.cc index ba1d59d..0edd0a0 100644 --- a/game/server/status.cc +++ b/game/server/status.cc @@ -4,6 +4,8 @@ #include "core/config/number.hh" +#include "core/version.hh" + #include "shared/protocol.hh" #include "shared/splash.hh" @@ -13,10 +15,12 @@ static void on_status_request_packet(const protocol::StatusRequest& packet) { protocol::StatusResponse response; - response.version = protocol::VERSION; + response.game_version_major = version::major; response.max_players = sessions::max_players.get_value(); response.num_players = sessions::num_players; response.motd = splash::get(); + response.game_version_minor = version::minor; + response.game_version_patch = version::patch; protocol::send(packet.peer, protocol::encode(response)); } -- cgit