diff options
| author | untodesu <kirill@untode.su> | 2025-09-12 16:16:06 +0500 |
|---|---|---|
| committer | untodesu <kirill@untode.su> | 2025-09-12 16:16:06 +0500 |
| commit | fc80fa024fc93dac6ea89461ef36f455c5e468a2 (patch) | |
| tree | 7c4ea8f03b6778572d59784dc28b600e3f8f2268 /game/server | |
| parent | 12947aafcc6a6eb362cc454e2149796ec9265743 (diff) | |
| parent | 522a7514012da86f7b9643179f0763746f3b232e (diff) | |
| download | voxelius-fc80fa024fc93dac6ea89461ef36f455c5e468a2.tar.bz2 voxelius-fc80fa024fc93dac6ea89461ef36f455c5e468a2.zip | |
Merge pull request #15 from untodesu/metavoxels
Metavoxels
Diffstat (limited to 'game/server')
| -rw-r--r-- | game/server/game.cc | 7 | ||||
| -rw-r--r-- | game/server/receive.cc | 5 | ||||
| -rw-r--r-- | game/server/sessions.cc | 30 | ||||
| -rw-r--r-- | game/server/status.cc | 6 | ||||
| -rw-r--r-- | game/server/world/CMakeLists.txt | 2 | ||||
| -rw-r--r-- | game/server/world/overworld.cc | 12 | ||||
| -rw-r--r-- | game/server/world/random_tick.cc | 40 | ||||
| -rw-r--r-- | game/server/world/random_tick.hh | 14 |
8 files changed, 103 insertions, 13 deletions
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<world::ChunkComponent>().each()) {
+ world::random_tick::tick(component.cpos, component.chunk);
+ }
}
}
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<world::Inhabited>(chunk->get_entity());
diff --git a/game/server/sessions.cc b/game/server/sessions.cc index c06ec3e..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<std::string, Session*> username_map;
static emhash8::HashMap<std::uint64_t, Session*> identity_map;
static std::vector<DimensionListener> dimension_listeners;
@@ -49,30 +53,46 @@ static std::vector<Session> 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::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));
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));
@@ -241,7 +261,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/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));
}
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/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<unsigned int>(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();
}
}
}
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 |
