mirror of
https://github.com/zhenyan121/Cubed.git
synced 2026-08-08 17:57:02 +08:00
Compare commits
2 Commits
d15037e7a3
...
efa49a98b7
| Author | SHA1 | Date | |
|---|---|---|---|
| efa49a98b7 | |||
| 3a9ab6a14a |
54
include/Cubed/gameplay/client_entity_manager.hpp
Normal file
54
include/Cubed/gameplay/client_entity_manager.hpp
Normal file
@@ -0,0 +1,54 @@
|
|||||||
|
#pragma once
|
||||||
|
#include "Cubed/gameplay/ecs/entity.hpp"
|
||||||
|
#include "glm/ext/vector_float3.hpp"
|
||||||
|
#include "world/entity.pb.h"
|
||||||
|
|
||||||
|
#include <entt/entt.hpp>
|
||||||
|
#include <tbb/concurrent_hash_map.h>
|
||||||
|
#include <tbb/concurrent_queue.h>
|
||||||
|
namespace Cubed {
|
||||||
|
class ClientWorld;
|
||||||
|
class ClientEntityManager {
|
||||||
|
public:
|
||||||
|
enum class Command { CREATE };
|
||||||
|
|
||||||
|
ClientEntityManager(ClientWorld& world);
|
||||||
|
void update();
|
||||||
|
void init();
|
||||||
|
// not thread safe
|
||||||
|
void add_entity(EntityID id, std::string_view name, const glm::vec3& pos);
|
||||||
|
|
||||||
|
void receive_entity_create(S2CEntityCreate& s2c);
|
||||||
|
|
||||||
|
private:
|
||||||
|
struct EntityCreateElement {
|
||||||
|
EntityID id;
|
||||||
|
std::string name;
|
||||||
|
glm::vec3 pos;
|
||||||
|
};
|
||||||
|
using EntityMap = tbb::concurrent_hash_map<EntityID, entt::entity>;
|
||||||
|
using acc = EntityMap::accessor;
|
||||||
|
using cacc = EntityMap::const_accessor;
|
||||||
|
using CreateFunc = std::function<void(EntityID id)>;
|
||||||
|
using TaskElement = std::variant<EntityCreateElement>;
|
||||||
|
using TaskPair = std::pair<Command, TaskElement>;
|
||||||
|
|
||||||
|
ClientWorld& m_world;
|
||||||
|
entt::registry m_registry;
|
||||||
|
EntityMap m_entities;
|
||||||
|
std::unordered_map<std::string_view, CreateFunc> m_factories;
|
||||||
|
tbb::concurrent_queue<TaskPair> m_tasks;
|
||||||
|
|
||||||
|
void handle_task();
|
||||||
|
|
||||||
|
template <typename... Args> void add_entity(EntityID id, Args&&... args) {
|
||||||
|
auto entity = m_registry.create();
|
||||||
|
|
||||||
|
((m_registry.emplace<std::remove_cvref_t<Args>>(
|
||||||
|
entity, std::forward<Args>(args))),
|
||||||
|
...);
|
||||||
|
m_entities.emplace(id, entity);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
} // namespace Cubed
|
||||||
@@ -5,6 +5,7 @@
|
|||||||
#include "Cubed/gameplay/chat_message.hpp"
|
#include "Cubed/gameplay/chat_message.hpp"
|
||||||
#include "Cubed/gameplay/chunk_pos.hpp"
|
#include "Cubed/gameplay/chunk_pos.hpp"
|
||||||
#include "Cubed/gameplay/client_chunk.hpp"
|
#include "Cubed/gameplay/client_chunk.hpp"
|
||||||
|
#include "Cubed/gameplay/client_entity_manager.hpp"
|
||||||
#include "Cubed/gameplay/client_player_manager.hpp"
|
#include "Cubed/gameplay/client_player_manager.hpp"
|
||||||
#include "Cubed/gameplay/game_time.hpp"
|
#include "Cubed/gameplay/game_time.hpp"
|
||||||
#include "Cubed/gameplay/local_player.hpp"
|
#include "Cubed/gameplay/local_player.hpp"
|
||||||
@@ -84,6 +85,7 @@ public:
|
|||||||
Config& get_config();
|
Config& get_config();
|
||||||
WorldScene& world_scene();
|
WorldScene& world_scene();
|
||||||
ClientPlayerManager& player_manager();
|
ClientPlayerManager& player_manager();
|
||||||
|
ClientEntityManager& entity_manager();
|
||||||
void set_direct_exit();
|
void set_direct_exit();
|
||||||
|
|
||||||
void receive_chat_message(ChatMsg& msg);
|
void receive_chat_message(ChatMsg& msg);
|
||||||
@@ -92,10 +94,10 @@ public:
|
|||||||
bool enable_voice_chat() const;
|
bool enable_voice_chat() const;
|
||||||
int get_per_tick_time() const override;
|
int get_per_tick_time() const override;
|
||||||
template <typename Fn>
|
template <typename Fn>
|
||||||
void register_ticktimer(std::string_view id, TickType threshold, Fn&& f) {
|
void register_timer(std::string_view id, float threshold, Fn&& f) {
|
||||||
m_ticktimers.emplace(
|
m_timers.emplace(std::piecewise_construct,
|
||||||
std::piecewise_construct, std::forward_as_tuple(std::string(id)),
|
std::forward_as_tuple(std::string(id)),
|
||||||
std::forward_as_tuple(threshold, std::forward<Fn>(f)));
|
std::forward_as_tuple(threshold, std::forward<Fn>(f)));
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
@@ -126,14 +128,13 @@ private:
|
|||||||
|
|
||||||
static constexpr int WORLD_EXIT_TIMEOUT = 200;
|
static constexpr int WORLD_EXIT_TIMEOUT = 200;
|
||||||
static constexpr int MAX_UPLOAD_CHUNK_SUM = 16;
|
static constexpr int MAX_UPLOAD_CHUNK_SUM = 16;
|
||||||
|
ClientEntityManager m_entity_manager;
|
||||||
ClientPlayerManager m_player_manager;
|
ClientPlayerManager m_player_manager;
|
||||||
ChunkHashMap m_chunks;
|
ChunkHashMap m_chunks;
|
||||||
AudioEngine& m_audio;
|
AudioEngine& m_audio;
|
||||||
Config& m_config;
|
Config& m_config;
|
||||||
WorldScene& m_world_scene;
|
WorldScene& m_world_scene;
|
||||||
std::vector<glm::vec4> m_planes;
|
std::vector<glm::vec4> m_planes;
|
||||||
std::jthread m_client_thread;
|
|
||||||
|
|
||||||
tbb::concurrent_queue<std::unique_ptr<ClientChunk>> m_pending_upload_queue;
|
tbb::concurrent_queue<std::unique_ptr<ClientChunk>> m_pending_upload_queue;
|
||||||
tbb::concurrent_queue<ChunkPos> m_dirty_chunk_queue;
|
tbb::concurrent_queue<ChunkPos> m_dirty_chunk_queue;
|
||||||
@@ -144,7 +145,6 @@ private:
|
|||||||
std::deque<ChunkPos> m_dirty_queue;
|
std::deque<ChunkPos> m_dirty_queue;
|
||||||
std::vector<const ChunkRenderSnapshot*> m_render_snapshots;
|
std::vector<const ChunkRenderSnapshot*> m_render_snapshots;
|
||||||
|
|
||||||
tbb::concurrent_unordered_map<std::string, TickTimer> m_ticktimers;
|
|
||||||
std::unordered_map<std::string, Timer> m_timers;
|
std::unordered_map<std::string, Timer> m_timers;
|
||||||
std::atomic<bool> m_exit_direct{false};
|
std::atomic<bool> m_exit_direct{false};
|
||||||
std::atomic<bool> m_game_running{false};
|
std::atomic<bool> m_game_running{false};
|
||||||
@@ -164,8 +164,6 @@ private:
|
|||||||
|
|
||||||
Random m_random;
|
Random m_random;
|
||||||
|
|
||||||
void client_run(std::stop_token token);
|
|
||||||
|
|
||||||
void set_block(const glm::ivec3& pos, unsigned id);
|
void set_block(const glm::ivec3& pos, unsigned id);
|
||||||
|
|
||||||
void update_chunk(const ChunkPosSet& old, const ChunkPosSet& now);
|
void update_chunk(const ChunkPosSet& old, const ChunkPosSet& now);
|
||||||
|
|||||||
@@ -1,15 +1,9 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
#include "Cubed/gameplay/ecs/animation.hpp"
|
#include "Cubed/gameplay/ecs/animation.hpp"
|
||||||
#include "Cubed/gameplay/ecs/entity.hpp"
|
|
||||||
#include "Cubed/gameplay/ecs/identity.hpp"
|
|
||||||
#include "Cubed/gameplay/ecs/transform.hpp"
|
#include "Cubed/gameplay/ecs/transform.hpp"
|
||||||
#include "Cubed/gameplay/model.hpp"
|
#include "Cubed/gameplay/model.hpp"
|
||||||
namespace Cubed {
|
namespace Cubed {
|
||||||
struct ClientEntity {
|
struct BaseClientCreature {
|
||||||
|
|
||||||
Entity entity;
|
|
||||||
|
|
||||||
EntityInfo info;
|
|
||||||
|
|
||||||
Transform transform;
|
Transform transform;
|
||||||
|
|
||||||
|
|||||||
@@ -1,32 +1,27 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
#include "Cubed/gameplay/ecs/entity.hpp"
|
|
||||||
#include "Cubed/gameplay/ecs/health.hpp"
|
#include "Cubed/gameplay/ecs/health.hpp"
|
||||||
#include "Cubed/gameplay/ecs/identity.hpp"
|
|
||||||
#include "Cubed/gameplay/ecs/movement.hpp"
|
#include "Cubed/gameplay/ecs/movement.hpp"
|
||||||
#include "Cubed/gameplay/ecs/state.hpp"
|
#include "Cubed/gameplay/ecs/state.hpp"
|
||||||
#include "Cubed/gameplay/ecs/transform.hpp"
|
#include "Cubed/gameplay/ecs/transform.hpp"
|
||||||
#include "Cubed/gameplay/hitbox.hpp"
|
#include "Cubed/gameplay/hitbox.hpp"
|
||||||
namespace Cubed {
|
namespace Cubed {
|
||||||
struct ServerEntity {
|
|
||||||
|
|
||||||
Entity entity;
|
struct BaseServerCreature {
|
||||||
|
Transform transform{};
|
||||||
|
|
||||||
EntityInfo info;
|
Velocity velocity{};
|
||||||
|
|
||||||
Transform transform;
|
Movement movement{};
|
||||||
|
|
||||||
Velocity velocity;
|
MoveState move_state{};
|
||||||
|
|
||||||
Movement movement;
|
Direction direction{};
|
||||||
|
|
||||||
MoveState move_state;
|
Gravity gravity{};
|
||||||
|
|
||||||
Direction direction;
|
Health health{};
|
||||||
|
|
||||||
Gravity gravity;
|
HitboxID hitbox{};
|
||||||
|
|
||||||
Health health;
|
|
||||||
|
|
||||||
HitboxID hitbox;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace Cubed
|
} // namespace Cubed
|
||||||
@@ -16,9 +16,9 @@ struct Direction {
|
|||||||
};
|
};
|
||||||
|
|
||||||
struct Transform {
|
struct Transform {
|
||||||
Position position;
|
Position position{};
|
||||||
Orientation orientation;
|
Orientation orientation{};
|
||||||
Direction direction;
|
Direction direction{};
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace Cubed
|
} // namespace Cubed
|
||||||
@@ -61,6 +61,7 @@ enum class PacketEnum : uint16_t {
|
|||||||
BLOCK_CHANGE_RSP = 3004,
|
BLOCK_CHANGE_RSP = 3004,
|
||||||
S2C_CLEAR_ALL_CHUNKS = 3005,
|
S2C_CLEAR_ALL_CHUNKS = 3005,
|
||||||
UPDATE_TIME = 3006,
|
UPDATE_TIME = 3006,
|
||||||
|
S2C_ENTITY_CREATE = 3007,
|
||||||
CHAT_MSG = 4001,
|
CHAT_MSG = 4001,
|
||||||
VOICE_MSG = 4002,
|
VOICE_MSG = 4002,
|
||||||
PING = 9001,
|
PING = 9001,
|
||||||
@@ -111,6 +112,9 @@ template <> constexpr uint16_t get_packet_id<BlockChangeRsp>() {
|
|||||||
template <> constexpr uint16_t get_packet_id<S2C_ClearAllChunks>() {
|
template <> constexpr uint16_t get_packet_id<S2C_ClearAllChunks>() {
|
||||||
return std::to_underlying(PacketEnum::S2C_CLEAR_ALL_CHUNKS);
|
return std::to_underlying(PacketEnum::S2C_CLEAR_ALL_CHUNKS);
|
||||||
}
|
}
|
||||||
|
template <> constexpr uint16_t get_packet_id<S2CEntityCreate>() {
|
||||||
|
return std::to_underlying(PacketEnum::S2C_ENTITY_CREATE);
|
||||||
|
}
|
||||||
template <> constexpr uint16_t get_packet_id<UpdateTime>() {
|
template <> constexpr uint16_t get_packet_id<UpdateTime>() {
|
||||||
return std::to_underlying(PacketEnum::UPDATE_TIME);
|
return std::to_underlying(PacketEnum::UPDATE_TIME);
|
||||||
}
|
}
|
||||||
|
|||||||
42
include/Cubed/gameplay/server_entity_manager.hpp
Normal file
42
include/Cubed/gameplay/server_entity_manager.hpp
Normal file
@@ -0,0 +1,42 @@
|
|||||||
|
#pragma once
|
||||||
|
#include "Cubed/gameplay/ecs/entity.hpp"
|
||||||
|
#include "glm/ext/vector_float3.hpp"
|
||||||
|
|
||||||
|
#include <entt/entt.hpp>
|
||||||
|
#include <tbb/concurrent_hash_map.h>
|
||||||
|
namespace Cubed {
|
||||||
|
class ServerWorld;
|
||||||
|
class ServerEntityManager {
|
||||||
|
public:
|
||||||
|
ServerEntityManager(ServerWorld& world);
|
||||||
|
|
||||||
|
void init();
|
||||||
|
// not thread safe
|
||||||
|
void add_entity(std::string_view name, const glm::vec3& pos);
|
||||||
|
|
||||||
|
private:
|
||||||
|
using EntityMap = tbb::concurrent_hash_map<EntityID, entt::entity>;
|
||||||
|
using acc = EntityMap::accessor;
|
||||||
|
using cacc = EntityMap::const_accessor;
|
||||||
|
using CreateFunc = std::function<EntityID()>;
|
||||||
|
ServerWorld& m_world;
|
||||||
|
entt::registry m_registry;
|
||||||
|
EntityID m_next = 0;
|
||||||
|
EntityMap m_entities;
|
||||||
|
std::unordered_map<std::string_view, CreateFunc> m_factories;
|
||||||
|
|
||||||
|
void send_entity_create(EntityID id, std::string_view name,
|
||||||
|
const glm::vec3& pos);
|
||||||
|
|
||||||
|
template <typename... Args> EntityID add_entity(Args&&... args) {
|
||||||
|
auto entity = m_registry.create();
|
||||||
|
|
||||||
|
((m_registry.emplace<std::remove_cvref_t<Args>>(
|
||||||
|
entity, std::forward<Args>(args))),
|
||||||
|
...);
|
||||||
|
auto id = m_next++;
|
||||||
|
m_entities.emplace(id, entity);
|
||||||
|
return id;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
} // namespace Cubed
|
||||||
@@ -7,6 +7,7 @@
|
|||||||
#include "Cubed/gameplay/packet.hpp" // IWYU pragma: keep
|
#include "Cubed/gameplay/packet.hpp" // IWYU pragma: keep
|
||||||
#include "Cubed/gameplay/river_worm.hpp"
|
#include "Cubed/gameplay/river_worm.hpp"
|
||||||
#include "Cubed/gameplay/server_chunk.hpp"
|
#include "Cubed/gameplay/server_chunk.hpp"
|
||||||
|
#include "Cubed/gameplay/server_entity_manager.hpp"
|
||||||
#include "Cubed/gameplay/server_player.hpp"
|
#include "Cubed/gameplay/server_player.hpp"
|
||||||
#include "Cubed/gameplay/world.hpp"
|
#include "Cubed/gameplay/world.hpp"
|
||||||
#include "Cubed/tools/priority_thread_pool.hpp"
|
#include "Cubed/tools/priority_thread_pool.hpp"
|
||||||
@@ -87,6 +88,8 @@ public:
|
|||||||
void handle_voice_message(VoiceMsg& msg);
|
void handle_voice_message(VoiceMsg& msg);
|
||||||
int chunk_size() const;
|
int chunk_size() const;
|
||||||
|
|
||||||
|
std::vector<std::shared_ptr<Session>> get_all_session() const;
|
||||||
|
|
||||||
int get_block(const glm::ivec3& block_pos) const override;
|
int get_block(const glm::ivec3& block_pos) const override;
|
||||||
bool is_solid(const glm::ivec3& block_pos) const override;
|
bool is_solid(const glm::ivec3& block_pos) const override;
|
||||||
bool can_pass_block(const glm::ivec3& block_pos) const override;
|
bool can_pass_block(const glm::ivec3& block_pos) const override;
|
||||||
@@ -132,7 +135,7 @@ private:
|
|||||||
using uuid_cacc = PlayerUUIDMap::const_accessor;
|
using uuid_cacc = PlayerUUIDMap::const_accessor;
|
||||||
|
|
||||||
Config& m_config;
|
Config& m_config;
|
||||||
|
ServerEntityManager m_entity_manager;
|
||||||
// key = uuid
|
// key = uuid
|
||||||
PlayerHashMap m_players;
|
PlayerHashMap m_players;
|
||||||
ChunkHashMap m_chunks;
|
ChunkHashMap m_chunks;
|
||||||
@@ -162,7 +165,7 @@ private:
|
|||||||
std::atomic<bool> m_tick_running{true};
|
std::atomic<bool> m_tick_running{true};
|
||||||
std::atomic<int> m_per_tick_time = DEFAULT_PER_TICK_TIME; // ms
|
std::atomic<int> m_per_tick_time = DEFAULT_PER_TICK_TIME; // ms
|
||||||
|
|
||||||
mutable std::shared_mutex m_player_mutex;
|
mutable std::shared_mutex m_players_mutex;
|
||||||
std::mutex m_need_gen_queue_mutex;
|
std::mutex m_need_gen_queue_mutex;
|
||||||
std::condition_variable_any m_gen_cv;
|
std::condition_variable_any m_gen_cv;
|
||||||
|
|
||||||
|
|||||||
@@ -1,5 +1,7 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
#include "Cubed//gameplay/ecs/server_entity.hpp"
|
#include "Cubed/gameplay/ecs/movement.hpp"
|
||||||
|
#include "Cubed/gameplay/ecs/state.hpp"
|
||||||
|
#include "Cubed/gameplay/ecs/transform.hpp"
|
||||||
#include "Cubed/gameplay/world.hpp"
|
#include "Cubed/gameplay/world.hpp"
|
||||||
namespace Cubed {
|
namespace Cubed {
|
||||||
|
|
||||||
@@ -7,10 +9,6 @@ class PhysicalSystem {
|
|||||||
public:
|
public:
|
||||||
static glm::vec3 get_move_distance(float dt, const Direction& d,
|
static glm::vec3 get_move_distance(float dt, const Direction& d,
|
||||||
const Velocity& v);
|
const Velocity& v);
|
||||||
static std::tuple<bool, bool, bool> update(float dt, ServerEntity& e,
|
|
||||||
World& world);
|
|
||||||
static std::tuple<bool, bool, bool>
|
|
||||||
update(float dt, ServerEntity& e, World& world, glm::vec3& moved_pos);
|
|
||||||
|
|
||||||
static std::tuple<bool, bool, bool>
|
static std::tuple<bool, bool, bool>
|
||||||
update(float dt, World& world, glm::vec3& moved_pos, Velocity& v,
|
update(float dt, World& world, glm::vec3& moved_pos, Velocity& v,
|
||||||
|
|||||||
@@ -1,12 +1,12 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include "Cubed/gameplay/ecs/server_entity.hpp"
|
#include "Cubed/gameplay/ecs/movement.hpp"
|
||||||
#include "Cubed/gameplay/ecs/state.hpp"
|
#include "Cubed/gameplay/ecs/state.hpp"
|
||||||
|
#include "Cubed/gameplay/ecs/transform.hpp"
|
||||||
|
|
||||||
namespace Cubed {
|
namespace Cubed {
|
||||||
class SpeedSystem {
|
class SpeedSystem {
|
||||||
public:
|
public:
|
||||||
static void update(float dt, ServerEntity& e);
|
|
||||||
static void update(float dt, Velocity& v, MoveState& move_state,
|
static void update(float dt, Velocity& v, MoveState& move_state,
|
||||||
Movement& movement, Direction& direction,
|
Movement& movement, Direction& direction,
|
||||||
const Gravity& g);
|
const Gravity& g);
|
||||||
|
|||||||
7
include/Cubed/tools/cubed_concepts.hpp
Normal file
7
include/Cubed/tools/cubed_concepts.hpp
Normal file
@@ -0,0 +1,7 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <type_traits>
|
||||||
|
namespace Cubed {
|
||||||
|
template <typename T>
|
||||||
|
concept Ptr = std::is_pointer_v<T>;
|
||||||
|
}
|
||||||
15
include/Cubed/tools/net_utils.hpp
Normal file
15
include/Cubed/tools/net_utils.hpp
Normal file
@@ -0,0 +1,15 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "Cubed/tools/cubed_concepts.hpp"
|
||||||
|
#include "common/vector3.pb.h"
|
||||||
|
#include "glm/ext/vector_float3.hpp"
|
||||||
|
namespace Cubed {
|
||||||
|
namespace Tools {
|
||||||
|
template <Ptr T> void set_net_pos(T ptr, const glm::vec3& pos) {
|
||||||
|
Vec3* p = ptr->mutable_pos();
|
||||||
|
p->set_x(pos.x);
|
||||||
|
p->set_y(pos.y);
|
||||||
|
p->set_z(pos.z);
|
||||||
|
}
|
||||||
|
} // namespace Tools
|
||||||
|
} // namespace Cubed
|
||||||
@@ -100,4 +100,6 @@ target_sources(${PROJECT_NAME}
|
|||||||
gameplay/systems/physical_system.cpp
|
gameplay/systems/physical_system.cpp
|
||||||
gameplay/systems/speed_system.cpp
|
gameplay/systems/speed_system.cpp
|
||||||
gameplay/client_player_manager.cpp
|
gameplay/client_player_manager.cpp
|
||||||
|
gameplay/server_entity_manager.cpp
|
||||||
|
gameplay/client_entity_manager.cpp
|
||||||
)
|
)
|
||||||
53
src/gameplay/client_entity_manager.cpp
Normal file
53
src/gameplay/client_entity_manager.cpp
Normal file
@@ -0,0 +1,53 @@
|
|||||||
|
#include "Cubed/gameplay/client_entity_manager.hpp"
|
||||||
|
|
||||||
|
#include "Cubed/gameplay/creatures/pig.hpp"
|
||||||
|
#include "Cubed/gameplay/ecs/client_entity.hpp"
|
||||||
|
#include "Cubed/gameplay/ecs/identity.hpp"
|
||||||
|
#include "Cubed/gameplay/ecs/transform.hpp"
|
||||||
|
#include "Cubed/render/model_manager.hpp"
|
||||||
|
#include "Cubed/tools/cubed_assert.hpp"
|
||||||
|
namespace Cubed {
|
||||||
|
ClientEntityManager::ClientEntityManager(ClientWorld& world) : m_world(world) {}
|
||||||
|
void ClientEntityManager::update() { handle_task(); }
|
||||||
|
void ClientEntityManager::init() {
|
||||||
|
m_factories.emplace("cubed:pig", [this](EntityID id) {
|
||||||
|
BaseClientCreature c;
|
||||||
|
c.model = ModelManager::instance().get_model_id("cubed:pig");
|
||||||
|
add_entity(id, Entity{id}, EntityInfo{"cubed:pig", ""}, std::move(c),
|
||||||
|
PigTag{});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
// not thread safe
|
||||||
|
void ClientEntityManager::add_entity(EntityID id, std::string_view name,
|
||||||
|
const glm::vec3& pos) {
|
||||||
|
|
||||||
|
m_factories[name](id);
|
||||||
|
acc a;
|
||||||
|
ASSERT(m_entities.find(a, id));
|
||||||
|
auto* c = m_registry.try_get<Transform>(a->second);
|
||||||
|
ASSERT(c);
|
||||||
|
c->position.value = pos;
|
||||||
|
}
|
||||||
|
|
||||||
|
void ClientEntityManager::receive_entity_create(S2CEntityCreate& s2c) {
|
||||||
|
EntityCreateElement c;
|
||||||
|
c.id = s2c.id();
|
||||||
|
c.name = s2c.name();
|
||||||
|
c.pos = {s2c.pos().x(), s2c.pos().y(), s2c.pos().z()};
|
||||||
|
m_tasks.emplace(Command::CREATE, std::move(c));
|
||||||
|
}
|
||||||
|
|
||||||
|
void ClientEntityManager::handle_task() {
|
||||||
|
TaskPair pair;
|
||||||
|
while (m_tasks.try_pop(pair)) {
|
||||||
|
switch (pair.first) {
|
||||||
|
case Command::CREATE:
|
||||||
|
auto* p = std::get_if<EntityCreateElement>(&pair.second);
|
||||||
|
ASSERT(p);
|
||||||
|
|
||||||
|
add_entity(p->id, p->name, p->pos);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace Cubed
|
||||||
@@ -1,4 +1,3 @@
|
|||||||
#pragma once
|
|
||||||
#include "Cubed/gameplay/client_player_manager.hpp"
|
#include "Cubed/gameplay/client_player_manager.hpp"
|
||||||
|
|
||||||
#include "Cubed/gameplay/client_world.hpp"
|
#include "Cubed/gameplay/client_world.hpp"
|
||||||
|
|||||||
@@ -23,8 +23,8 @@ struct ChunkRenderData {
|
|||||||
} // namespace
|
} // namespace
|
||||||
|
|
||||||
ClientWorld::ClientWorld(AudioEngine& auido, Config& config, WorldScene& scene)
|
ClientWorld::ClientWorld(AudioEngine& auido, Config& config, WorldScene& scene)
|
||||||
: m_player_manager(*this), m_audio(auido), m_config(config),
|
: m_entity_manager(*this), m_player_manager(*this), m_audio(auido),
|
||||||
m_world_scene(scene) {}
|
m_config(config), m_world_scene(scene) {}
|
||||||
|
|
||||||
ClientWorld::~ClientWorld() {
|
ClientWorld::~ClientWorld() {
|
||||||
m_client->close();
|
m_client->close();
|
||||||
@@ -51,7 +51,7 @@ ClientWorld::~ClientWorld() {
|
|||||||
std::lock_guard lk(m_delete_vao_mutex);
|
std::lock_guard lk(m_delete_vao_mutex);
|
||||||
m_pending_delete_vao.clear();
|
m_pending_delete_vao.clear();
|
||||||
}
|
}
|
||||||
m_ticktimers.clear();
|
m_timers.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
const std::optional<LookBlock>& ClientWorld::get_look_block_pos() const {
|
const std::optional<LookBlock>& ClientWorld::get_look_block_pos() const {
|
||||||
@@ -363,6 +363,7 @@ void ClientWorld::send_player_water_sound(bool underwater,
|
|||||||
|
|
||||||
void ClientWorld::init(std::string_view player_name,
|
void ClientWorld::init(std::string_view player_name,
|
||||||
std::shared_ptr<NetworkClient> client) {
|
std::shared_ptr<NetworkClient> client) {
|
||||||
|
m_entity_manager.init();
|
||||||
m_player_manager.init(player_name);
|
m_player_manager.init(player_name);
|
||||||
m_client = client;
|
m_client = client;
|
||||||
|
|
||||||
@@ -371,10 +372,10 @@ void ClientWorld::init(std::string_view player_name,
|
|||||||
m_random.init(ChunkGenerator::seed());
|
m_random.init(ChunkGenerator::seed());
|
||||||
|
|
||||||
// timer
|
// timer
|
||||||
register_ticktimer("player_pos", 1, [this]() {
|
register_timer("player_pos", 0.05f, [this]() {
|
||||||
m_player_manager.report_player_info(m_client.get());
|
m_player_manager.report_player_info(m_client.get());
|
||||||
});
|
});
|
||||||
m_timers.try_emplace("Birds Sound", 60.0f, [this]() {
|
register_timer("Birds Sound", 60.0f, [this]() {
|
||||||
auto player_pos = m_player_manager.get_local().get_player_pos();
|
auto player_pos = m_player_manager.get_local().get_player_pos();
|
||||||
if (player_pos.y < SEA_LEVEL) {
|
if (player_pos.y < SEA_LEVEL) {
|
||||||
return;
|
return;
|
||||||
@@ -390,7 +391,7 @@ void ClientWorld::init(std::string_view player_name,
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
m_timers.try_emplace("Ocean Wave", 3.0f, [this]() {
|
register_timer("Ocean Wave", 3.0f, [this]() {
|
||||||
auto player_pos = m_player_manager.get_local().get_player_pos();
|
auto player_pos = m_player_manager.get_local().get_player_pos();
|
||||||
if (player_pos.y < SEA_LEVEL - 10 || player_pos.y > SEA_LEVEL + 10) {
|
if (player_pos.y < SEA_LEVEL - 10 || player_pos.y > SEA_LEVEL + 10) {
|
||||||
return;
|
return;
|
||||||
@@ -410,7 +411,7 @@ void ClientWorld::init(std::string_view player_name,
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
m_timers.try_emplace("under water bubble", 1.5f, [this]() {
|
register_timer("under water bubble", 1.5f, [this]() {
|
||||||
if (m_player_manager.get_local().is_underwater()) {
|
if (m_player_manager.get_local().is_underwater()) {
|
||||||
auto ans = m_random.random_int(1, 2);
|
auto ans = m_random.random_int(1, 2);
|
||||||
std::string sound =
|
std::string sound =
|
||||||
@@ -420,7 +421,7 @@ void ClientWorld::init(std::string_view player_name,
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
m_timers.try_emplace("bgm change", 350.0f, [this]() {
|
register_timer("bgm change", 350.0f, [this]() {
|
||||||
if (m_day_tick >= 17000 || m_day_tick < 5000) {
|
if (m_day_tick >= 17000 || m_day_tick < 5000) {
|
||||||
m_audio.change_bgm("bgm/bgm002.ogg");
|
m_audio.change_bgm("bgm/bgm002.ogg");
|
||||||
} else {
|
} else {
|
||||||
@@ -455,11 +456,11 @@ void ClientWorld::start_client_thread(std::string_view uuid) {
|
|||||||
}
|
}
|
||||||
// response
|
// response
|
||||||
m_player_manager.get_local().set_uuid(uuid);
|
m_player_manager.get_local().set_uuid(uuid);
|
||||||
|
/*
|
||||||
m_client_thread = std::jthread([this](std::stop_token token) {
|
m_client_thread = std::jthread([this](std::stop_token token) {
|
||||||
m_game_running = true;
|
m_game_running = true;
|
||||||
client_run(token);
|
client_run(token);
|
||||||
});
|
});*/
|
||||||
|
|
||||||
// Wait for 20 ticks, after the server's central chunk is generated, then
|
// Wait for 20 ticks, after the server's central chunk is generated, then
|
||||||
// request chunks
|
// request chunks
|
||||||
@@ -470,10 +471,11 @@ void ClientWorld::start_client_thread(std::string_view uuid) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void ClientWorld::stop_client_thread() {
|
void ClientWorld::stop_client_thread() {
|
||||||
|
/*
|
||||||
m_client_thread.request_stop();
|
m_client_thread.request_stop();
|
||||||
if (m_client_thread.joinable()) {
|
if (m_client_thread.joinable()) {
|
||||||
m_client_thread.join();
|
m_client_thread.join();
|
||||||
}
|
}*/
|
||||||
m_game_running = false;
|
m_game_running = false;
|
||||||
}
|
}
|
||||||
void ClientWorld::start_thread_pool() {
|
void ClientWorld::start_thread_pool() {
|
||||||
@@ -512,6 +514,7 @@ void ClientWorld::reload_config(bool chunk_build) {
|
|||||||
m_player_manager.reload_config();
|
m_player_manager.reload_config();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
void ClientWorld::client_run(std::stop_token stoken) {
|
void ClientWorld::client_run(std::stop_token stoken) {
|
||||||
Logger::info("Client Thread Started");
|
Logger::info("Client Thread Started");
|
||||||
using Clock = std::chrono::steady_clock;
|
using Clock = std::chrono::steady_clock;
|
||||||
@@ -527,6 +530,7 @@ void ClientWorld::client_run(std::stop_token stoken) {
|
|||||||
std::this_thread::sleep_until(next);
|
std::this_thread::sleep_until(next);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
*/
|
||||||
|
|
||||||
void ClientWorld::update_chunk(const ChunkPosSet& old, const ChunkPosSet& now) {
|
void ClientWorld::update_chunk(const ChunkPosSet& old, const ChunkPosSet& now) {
|
||||||
|
|
||||||
@@ -677,6 +681,7 @@ const AudioEngine& ClientWorld::get_audio() const { return m_audio; }
|
|||||||
Config& ClientWorld::get_config() { return m_config; }
|
Config& ClientWorld::get_config() { return m_config; }
|
||||||
WorldScene& ClientWorld::world_scene() { return m_world_scene; }
|
WorldScene& ClientWorld::world_scene() { return m_world_scene; }
|
||||||
ClientPlayerManager& ClientWorld::player_manager() { return m_player_manager; }
|
ClientPlayerManager& ClientWorld::player_manager() { return m_player_manager; }
|
||||||
|
ClientEntityManager& ClientWorld::entity_manager() { return m_entity_manager; }
|
||||||
void ClientWorld::set_direct_exit() { m_exit_direct = true; }
|
void ClientWorld::set_direct_exit() { m_exit_direct = true; }
|
||||||
void ClientWorld::request_exit() {
|
void ClientWorld::request_exit() {
|
||||||
if (m_receive_exit) {
|
if (m_receive_exit) {
|
||||||
|
|||||||
@@ -142,7 +142,13 @@ asio::awaitable<void> NetworkClient::read_loop() {
|
|||||||
if (decode_packet(*msg, body_data, header)) {
|
if (decode_packet(*msg, body_data, header)) {
|
||||||
m_world.receive_voice_message(*msg);
|
m_world.receive_voice_message(*msg);
|
||||||
}
|
}
|
||||||
}
|
} break;
|
||||||
|
case std::to_underlying(PacketEnum::S2C_ENTITY_CREATE): {
|
||||||
|
auto* msg = Arena::Create<S2CEntityCreate>(&arena);
|
||||||
|
if (decode_packet(*msg, body_data, header)) {
|
||||||
|
m_world.entity_manager().receive_entity_create(*msg);
|
||||||
|
}
|
||||||
|
} break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} catch (const asio::system_error& e) {
|
} catch (const asio::system_error& e) {
|
||||||
|
|||||||
53
src/gameplay/server_entity_manager.cpp
Normal file
53
src/gameplay/server_entity_manager.cpp
Normal file
@@ -0,0 +1,53 @@
|
|||||||
|
#include "Cubed/gameplay/server_entity_manager.hpp"
|
||||||
|
|
||||||
|
#include "Cubed/gameplay/creatures/pig.hpp"
|
||||||
|
#include "Cubed/gameplay/ecs/identity.hpp"
|
||||||
|
#include "Cubed/gameplay/ecs/server_entity.hpp"
|
||||||
|
#include "Cubed/gameplay/hitbox_manager.hpp"
|
||||||
|
#include "Cubed/gameplay/server_world.hpp"
|
||||||
|
#include "Cubed/gameplay/session.hpp"
|
||||||
|
#include "Cubed/tools/cubed_assert.hpp"
|
||||||
|
#include "Cubed/tools/net_utils.hpp"
|
||||||
|
using namespace google::protobuf;
|
||||||
|
|
||||||
|
namespace Cubed {
|
||||||
|
ServerEntityManager::ServerEntityManager(ServerWorld& world) : m_world(world) {}
|
||||||
|
|
||||||
|
void ServerEntityManager::init() {
|
||||||
|
m_factories.try_emplace("cubed:pig", [this]() {
|
||||||
|
BaseServerCreature c;
|
||||||
|
c.hitbox = HitboxManager::instance().get_hitbox_id("cubed:pig");
|
||||||
|
return add_entity(Entity{m_next}, EntityInfo{"cubed:pig", ""},
|
||||||
|
std::move(c), PigTag{});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
void ServerEntityManager::add_entity(std::string_view name,
|
||||||
|
const glm::vec3& pos) {
|
||||||
|
ASSERT(m_factories.contains(name));
|
||||||
|
auto e = m_factories[name]();
|
||||||
|
acc c;
|
||||||
|
if (m_entities.find(c, e)) {
|
||||||
|
auto t = m_registry.try_get<BaseServerCreature>(c->second);
|
||||||
|
ASSERT(t);
|
||||||
|
t->transform.position.value = pos;
|
||||||
|
}
|
||||||
|
send_entity_create(e, name, pos);
|
||||||
|
}
|
||||||
|
|
||||||
|
void ServerEntityManager::send_entity_create(EntityID id, std::string_view name,
|
||||||
|
const glm::vec3& pos) {
|
||||||
|
auto sessions = m_world.get_all_session();
|
||||||
|
|
||||||
|
Arena arena;
|
||||||
|
auto* s2c = Arena::Create<S2CEntityCreate>(&arena);
|
||||||
|
s2c->set_id(id);
|
||||||
|
s2c->set_name(name);
|
||||||
|
Tools::set_net_pos(s2c, pos);
|
||||||
|
|
||||||
|
for (auto& s : sessions) {
|
||||||
|
s->send(make_packet(*s2c));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace Cubed
|
||||||
@@ -16,7 +16,8 @@ using namespace google::protobuf;
|
|||||||
namespace fs = std::filesystem;
|
namespace fs = std::filesystem;
|
||||||
using nlohmann::json;
|
using nlohmann::json;
|
||||||
namespace Cubed {
|
namespace Cubed {
|
||||||
ServerWorld::ServerWorld(Config& config) : m_config(config) {}
|
ServerWorld::ServerWorld(Config& config)
|
||||||
|
: m_config(config), m_entity_manager(*this) {}
|
||||||
|
|
||||||
ServerWorld::~ServerWorld() { stop(); }
|
ServerWorld::~ServerWorld() { stop(); }
|
||||||
|
|
||||||
@@ -85,7 +86,7 @@ void ServerWorld::send_time() {
|
|||||||
rsp->set_day_tick(m_day_tick);
|
rsp->set_day_tick(m_day_tick);
|
||||||
rsp->set_game_tick(m_game_ticks);
|
rsp->set_game_tick(m_game_ticks);
|
||||||
{
|
{
|
||||||
std::shared_lock lock(m_player_mutex);
|
std::shared_lock lock(m_players_mutex);
|
||||||
for (auto& [uuid, player] : m_players) {
|
for (auto& [uuid, player] : m_players) {
|
||||||
player.get_session()->send(make_packet(*rsp), 3);
|
player.get_session()->send(make_packet(*rsp), 3);
|
||||||
}
|
}
|
||||||
@@ -96,7 +97,7 @@ void ServerWorld::send_chunk(int task_id, const std::string& uuid,
|
|||||||
ChunkPos pos) {
|
ChunkPos pos) {
|
||||||
|
|
||||||
{
|
{
|
||||||
std::shared_lock lock(m_player_mutex);
|
std::shared_lock lock(m_players_mutex);
|
||||||
auto it = m_players.find(uuid);
|
auto it = m_players.find(uuid);
|
||||||
if (it == m_players.end()) {
|
if (it == m_players.end()) {
|
||||||
return;
|
return;
|
||||||
@@ -159,7 +160,7 @@ void ServerWorld::send_chunk(int task_id, const std::string& uuid,
|
|||||||
}
|
}
|
||||||
std::shared_ptr<Session> s;
|
std::shared_ptr<Session> s;
|
||||||
{
|
{
|
||||||
std::shared_lock lock(m_player_mutex);
|
std::shared_lock lock(m_players_mutex);
|
||||||
auto it = m_players.find(uuid);
|
auto it = m_players.find(uuid);
|
||||||
if (it != m_players.end()) {
|
if (it != m_players.end()) {
|
||||||
s = it->second.get_session();
|
s = it->second.get_session();
|
||||||
@@ -176,10 +177,12 @@ void ServerWorld::send_chunk(int task_id, const std::string& uuid,
|
|||||||
|
|
||||||
void ServerWorld::init_world() {
|
void ServerWorld::init_world() {
|
||||||
|
|
||||||
|
m_entity_manager.init();
|
||||||
|
|
||||||
register_timer("player disconnect", 5, [this]() {
|
register_timer("player disconnect", 5, [this]() {
|
||||||
std::vector<std::string> disconnect;
|
std::vector<std::string> disconnect;
|
||||||
{
|
{
|
||||||
std::shared_lock lock(m_player_mutex);
|
std::shared_lock lock(m_players_mutex);
|
||||||
for (auto& [uuid, player] : m_players) {
|
for (auto& [uuid, player] : m_players) {
|
||||||
if (player.is_disconnect(m_game_ticks)) {
|
if (player.is_disconnect(m_game_ticks)) {
|
||||||
disconnect.emplace_back(uuid);
|
disconnect.emplace_back(uuid);
|
||||||
@@ -243,7 +246,7 @@ void ServerWorld::gen_chunks_internal(const std::string& uuid) {
|
|||||||
ChunkPosSet old_set;
|
ChunkPosSet old_set;
|
||||||
sync_and_collect_missing_chunks(need_gen_chunks_pos, required_chunks_set);
|
sync_and_collect_missing_chunks(need_gen_chunks_pos, required_chunks_set);
|
||||||
{
|
{
|
||||||
std::lock_guard lock(m_player_mutex);
|
std::lock_guard lock(m_players_mutex);
|
||||||
auto it = m_players.find(uuid);
|
auto it = m_players.find(uuid);
|
||||||
if (it == m_players.end()) {
|
if (it == m_players.end()) {
|
||||||
return;
|
return;
|
||||||
@@ -564,7 +567,7 @@ void ServerWorld::sync_player_pos(const C2S_PlayerInfo& prsp) {
|
|||||||
auto yaw = prsp.yaw();
|
auto yaw = prsp.yaw();
|
||||||
auto pitch = prsp.pitch();
|
auto pitch = prsp.pitch();
|
||||||
{
|
{
|
||||||
std::lock_guard lock(m_player_mutex);
|
std::lock_guard lock(m_players_mutex);
|
||||||
auto it = m_players.find(uuid);
|
auto it = m_players.find(uuid);
|
||||||
if (it == m_players.end()) {
|
if (it == m_players.end()) {
|
||||||
Logger::warn("Player {} is not in this Server", uuid);
|
Logger::warn("Player {} is not in this Server", uuid);
|
||||||
@@ -583,7 +586,7 @@ void ServerWorld::sync_player_pos(const C2S_PlayerInfo& prsp) {
|
|||||||
// update other player pos;
|
// update other player pos;
|
||||||
std::vector<std::shared_ptr<Session>> other;
|
std::vector<std::shared_ptr<Session>> other;
|
||||||
{
|
{
|
||||||
std::shared_lock lock(m_player_mutex);
|
std::shared_lock lock(m_players_mutex);
|
||||||
for (auto& [o_uuid, player] : m_players) {
|
for (auto& [o_uuid, player] : m_players) {
|
||||||
if (o_uuid == uuid) {
|
if (o_uuid == uuid) {
|
||||||
continue;
|
continue;
|
||||||
@@ -624,7 +627,7 @@ void ServerWorld::sync_player_water_sound(const PlayerWaterSound& rsp) {
|
|||||||
std::vector<std::shared_ptr<Session>> other;
|
std::vector<std::shared_ptr<Session>> other;
|
||||||
|
|
||||||
{
|
{
|
||||||
std::shared_lock lock(m_player_mutex);
|
std::shared_lock lock(m_players_mutex);
|
||||||
for (auto& [o_uuid, player] : m_players) {
|
for (auto& [o_uuid, player] : m_players) {
|
||||||
if (o_uuid == uuid) {
|
if (o_uuid == uuid) {
|
||||||
continue;
|
continue;
|
||||||
@@ -660,7 +663,7 @@ void ServerWorld::handle_player_login(const std::string& name,
|
|||||||
Logger::info("Player {} (uuid {}) join the world", name, uuid);
|
Logger::info("Player {} (uuid {}) join the world", name, uuid);
|
||||||
bool sucess = true;
|
bool sucess = true;
|
||||||
{
|
{
|
||||||
std::lock_guard lock(m_player_mutex);
|
std::lock_guard lock(m_players_mutex);
|
||||||
auto [_, inserted] = m_players.emplace(
|
auto [_, inserted] = m_players.emplace(
|
||||||
std::piecewise_construct, std::forward_as_tuple(std::string(uuid)),
|
std::piecewise_construct, std::forward_as_tuple(std::string(uuid)),
|
||||||
std::forward_as_tuple(name, uuid, *this, session, m_game_ticks));
|
std::forward_as_tuple(name, uuid, *this, session, m_game_ticks));
|
||||||
@@ -710,7 +713,7 @@ void ServerWorld::handle_player_exit(const std::string& uuid) {
|
|||||||
ChunkPosSet old_set;
|
ChunkPosSet old_set;
|
||||||
std::string name;
|
std::string name;
|
||||||
{
|
{
|
||||||
std::lock_guard lock(m_player_mutex);
|
std::lock_guard lock(m_players_mutex);
|
||||||
auto it = m_players.find(uuid);
|
auto it = m_players.find(uuid);
|
||||||
if (it != m_players.end()) {
|
if (it != m_players.end()) {
|
||||||
name = it->second.get_name();
|
name = it->second.get_name();
|
||||||
@@ -737,7 +740,7 @@ void ServerWorld::handle_player_exit(const std::string& uuid) {
|
|||||||
|
|
||||||
std::vector<std::shared_ptr<Session>> sessions;
|
std::vector<std::shared_ptr<Session>> sessions;
|
||||||
{
|
{
|
||||||
std::shared_lock lock(m_player_mutex);
|
std::shared_lock lock(m_players_mutex);
|
||||||
for (auto& [uuid, player] : m_players) {
|
for (auto& [uuid, player] : m_players) {
|
||||||
sessions.emplace_back(player.get_session());
|
sessions.emplace_back(player.get_session());
|
||||||
}
|
}
|
||||||
@@ -754,7 +757,7 @@ void ServerWorld::handle_player_exit(const std::string& uuid) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
glm::vec3 ServerWorld::get_player_pos(const std::string& uuid) const {
|
glm::vec3 ServerWorld::get_player_pos(const std::string& uuid) const {
|
||||||
std::shared_lock lock(m_player_mutex);
|
std::shared_lock lock(m_players_mutex);
|
||||||
auto it = m_players.find(uuid);
|
auto it = m_players.find(uuid);
|
||||||
if (it == m_players.end()) {
|
if (it == m_players.end()) {
|
||||||
Logger::error("Can't find player uuid {}", uuid);
|
Logger::error("Can't find player uuid {}", uuid);
|
||||||
@@ -766,7 +769,7 @@ glm::vec3 ServerWorld::get_player_pos(const std::string& uuid) const {
|
|||||||
void ServerWorld::handle_chunk_req(int task_id, const std::string& uuid,
|
void ServerWorld::handle_chunk_req(int task_id, const std::string& uuid,
|
||||||
ChunkPos pos) {
|
ChunkPos pos) {
|
||||||
{
|
{
|
||||||
std::shared_lock lock(m_player_mutex);
|
std::shared_lock lock(m_players_mutex);
|
||||||
auto it = m_players.find(uuid);
|
auto it = m_players.find(uuid);
|
||||||
if (it == m_players.end()) {
|
if (it == m_players.end()) {
|
||||||
return;
|
return;
|
||||||
@@ -804,7 +807,7 @@ void ServerWorld::handle_voice_message(VoiceMsg& msg) {
|
|||||||
std::vector<std::shared_ptr<Session>> session;
|
std::vector<std::shared_ptr<Session>> session;
|
||||||
|
|
||||||
{
|
{
|
||||||
std::shared_lock lock(m_player_mutex);
|
std::shared_lock lock(m_players_mutex);
|
||||||
for (auto& [key, player] : m_players) {
|
for (auto& [key, player] : m_players) {
|
||||||
if (key == uuid) {
|
if (key == uuid) {
|
||||||
continue;
|
continue;
|
||||||
@@ -851,7 +854,7 @@ void ServerWorld::handle_block_change(const BlockChangeReq& req) {
|
|||||||
std::vector<std::shared_ptr<Session>> sessions;
|
std::vector<std::shared_ptr<Session>> sessions;
|
||||||
auto chunk_pos = get_chunk_pos(x, z);
|
auto chunk_pos = get_chunk_pos(x, z);
|
||||||
{
|
{
|
||||||
std::shared_lock lock(m_player_mutex);
|
std::shared_lock lock(m_players_mutex);
|
||||||
for (auto& [uuid, player] : m_players) {
|
for (auto& [uuid, player] : m_players) {
|
||||||
if (player.has_player(chunk_pos)) {
|
if (player.has_player(chunk_pos)) {
|
||||||
auto session = player.get_session();
|
auto session = player.get_session();
|
||||||
@@ -934,7 +937,7 @@ void ServerWorld::send_server_stop() {
|
|||||||
Arena arena;
|
Arena arena;
|
||||||
auto* rsp = Arena::Create<LogoutRsp>(&arena);
|
auto* rsp = Arena::Create<LogoutRsp>(&arena);
|
||||||
rsp->set_server_stop(true);
|
rsp->set_server_stop(true);
|
||||||
std::shared_lock lock(m_player_mutex);
|
std::shared_lock lock(m_players_mutex);
|
||||||
for (auto& [uuid, player] : m_players) {
|
for (auto& [uuid, player] : m_players) {
|
||||||
player.get_session()->send(make_packet(*rsp), 0);
|
player.get_session()->send(make_packet(*rsp), 0);
|
||||||
}
|
}
|
||||||
@@ -947,7 +950,7 @@ void ServerWorld::boardcast_message(const std::string& name,
|
|||||||
|
|
||||||
std::vector<std::shared_ptr<Session>> m_session;
|
std::vector<std::shared_ptr<Session>> m_session;
|
||||||
{
|
{
|
||||||
std::shared_lock lock(m_player_mutex);
|
std::shared_lock lock(m_players_mutex);
|
||||||
for (auto& [_, p] : m_players) {
|
for (auto& [_, p] : m_players) {
|
||||||
m_session.emplace_back(p.get_session());
|
m_session.emplace_back(p.get_session());
|
||||||
}
|
}
|
||||||
@@ -990,6 +993,15 @@ void ServerWorld::set_chunk_load_style(int id) {
|
|||||||
|
|
||||||
int ServerWorld::chunk_size() const { return m_chunks.size(); }
|
int ServerWorld::chunk_size() const { return m_chunks.size(); }
|
||||||
|
|
||||||
|
std::vector<std::shared_ptr<Session>> ServerWorld::get_all_session() const {
|
||||||
|
std::shared_lock lock(m_players_mutex);
|
||||||
|
std::vector<std::shared_ptr<Session>> sessions;
|
||||||
|
for (const auto& [_, player] : m_players) {
|
||||||
|
sessions.emplace_back(player.get_session());
|
||||||
|
}
|
||||||
|
return sessions;
|
||||||
|
}
|
||||||
|
|
||||||
int ServerWorld::get_block(const glm::ivec3& block_pos) const {
|
int ServerWorld::get_block(const glm::ivec3& block_pos) const {
|
||||||
auto [chunk_x, chunk_z] = get_chunk_pos(block_pos.x, block_pos.z);
|
auto [chunk_x, chunk_z] = get_chunk_pos(block_pos.x, block_pos.z);
|
||||||
chunk_cacc cacc;
|
chunk_cacc cacc;
|
||||||
|
|||||||
@@ -99,21 +99,6 @@ bool update_z(const glm::vec3& pos, const glm::vec3& distance, World& world,
|
|||||||
}
|
}
|
||||||
|
|
||||||
} // namespace
|
} // namespace
|
||||||
std::tuple<bool, bool, bool> PhysicalSystem::update(float dt, ServerEntity& e,
|
|
||||||
World& world) {
|
|
||||||
glm::vec3 pos = e.transform.position.value;
|
|
||||||
auto ans = update(dt, e, world, pos);
|
|
||||||
e.transform.position.value = pos;
|
|
||||||
return ans;
|
|
||||||
}
|
|
||||||
|
|
||||||
std::tuple<bool, bool, bool> PhysicalSystem::update(float dt, ServerEntity& e,
|
|
||||||
World& world,
|
|
||||||
glm::vec3& moved_pos) {
|
|
||||||
|
|
||||||
return update(dt, world, moved_pos, e.velocity, e.direction, e.move_state,
|
|
||||||
e.hitbox);
|
|
||||||
}
|
|
||||||
|
|
||||||
std::tuple<bool, bool, bool>
|
std::tuple<bool, bool, bool>
|
||||||
PhysicalSystem::update(float dt, World& world, glm::vec3& moved_pos,
|
PhysicalSystem::update(float dt, World& world, glm::vec3& moved_pos,
|
||||||
|
|||||||
@@ -1,9 +1,6 @@
|
|||||||
#include "Cubed/gameplay/systems/speed_system.hpp"
|
#include "Cubed/gameplay/systems/speed_system.hpp"
|
||||||
|
|
||||||
namespace Cubed {
|
namespace Cubed {
|
||||||
void SpeedSystem::update(float dt, ServerEntity& e) {
|
|
||||||
update(dt, e.velocity, e.move_state, e.movement, e.direction, e.gravity);
|
|
||||||
}
|
|
||||||
|
|
||||||
void SpeedSystem::update(float dt, Velocity& v, MoveState& move_state,
|
void SpeedSystem::update(float dt, Velocity& v, MoveState& move_state,
|
||||||
Movement& movement, Direction& direction,
|
Movement& movement, Direction& direction,
|
||||||
|
|||||||
@@ -10,4 +10,5 @@ import "system/pong.proto";
|
|||||||
import "world/chunk_data.proto";
|
import "world/chunk_data.proto";
|
||||||
import "world/block_change.proto";
|
import "world/block_change.proto";
|
||||||
import "world/time.proto";
|
import "world/time.proto";
|
||||||
|
import "world/entity.proto";
|
||||||
import "chat/chat.proto";
|
import "chat/chat.proto";
|
||||||
9
src/proto/world/entity.proto
Normal file
9
src/proto/world/entity.proto
Normal file
@@ -0,0 +1,9 @@
|
|||||||
|
syntax = "proto3";
|
||||||
|
|
||||||
|
import "common/vector3.proto";
|
||||||
|
|
||||||
|
message S2CEntityCreate {
|
||||||
|
uint64 id = 1;
|
||||||
|
string name = 2;
|
||||||
|
Vec3 pos = 3;
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user