summaryrefslogtreecommitdiffstats
path: root/game/server
diff options
context:
space:
mode:
authoruntodesu <kirill@untode.su>2025-09-12 16:16:06 +0500
committeruntodesu <kirill@untode.su>2025-09-12 16:16:06 +0500
commitfc80fa024fc93dac6ea89461ef36f455c5e468a2 (patch)
tree7c4ea8f03b6778572d59784dc28b600e3f8f2268 /game/server
parent12947aafcc6a6eb362cc454e2149796ec9265743 (diff)
parent522a7514012da86f7b9643179f0763746f3b232e (diff)
downloadvoxelius-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.cc7
-rw-r--r--game/server/receive.cc5
-rw-r--r--game/server/sessions.cc30
-rw-r--r--game/server/status.cc6
-rw-r--r--game/server/world/CMakeLists.txt2
-rw-r--r--game/server/world/overworld.cc12
-rw-r--r--game/server/world/random_tick.cc40
-rw-r--r--game/server/world/random_tick.hh14
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