125 lines
4.6 KiB
C++
125 lines
4.6 KiB
C++
#pragma once
|
|
|
|
#include <string>
|
|
#include <thread>
|
|
#include "../../core/world/Universe.hpp"
|
|
#include "../../core/world/actions.hpp"
|
|
#include "../../core/data/math.hpp"
|
|
#include "../../core/data/safe_queue.hpp"
|
|
#include "../../core/data/safe_priority_queue.hpp"
|
|
#include "../../core/data/file.hpp"
|
|
#include "../../core/data/mem.hpp"
|
|
#include "../net/Server.hpp"
|
|
#include "Area.hpp"
|
|
|
|
namespace buffer {
|
|
class Abstract;
|
|
}
|
|
|
|
using namespace data;
|
|
/// Universe data
|
|
namespace world::server {
|
|
class Chunk;
|
|
|
|
/// Whole universe container in abstract server
|
|
class Universe: public world::Universe {
|
|
public:
|
|
/// Server config
|
|
struct options: world::Universe::options {
|
|
/// Storage path
|
|
std::string folderPath = "world";
|
|
|
|
net::exposure connection = net::exposure{"", 4242, 1, "content/key.pem", "content/cert.pem"};
|
|
|
|
/// Iteration count in part break search
|
|
size_t floodFillLimit = CHUNK_SIZE;
|
|
};
|
|
|
|
Universe(const options &);
|
|
virtual ~Universe();
|
|
|
|
/// Update physics
|
|
void update(float deltaTime);
|
|
/// Send-Receive packets
|
|
//NOTE: triggers onPacket, onConnect & onDisconnect
|
|
void pull();
|
|
/// Apply new options
|
|
void setOptions(const options &);
|
|
|
|
/// Set volume of voxel with pos as center
|
|
/// MAYBE: allow set multi area
|
|
ItemList set(const area_<voxel_pos> &pos, int radius, action::Shape shape, const Voxel &val);
|
|
|
|
/// Instante entity
|
|
entity_instance_id addEntity(entity_id type, const Entity::Instance &instance);
|
|
Entity::Instance* findEntity(entity_id type, entity_id id);
|
|
|
|
/// Move player
|
|
bool movePlayer(data::generational::id id, glm::ifvec3 pos);
|
|
|
|
/// Get nearest voxel colliding ray
|
|
/// @note ray in world scale
|
|
ray_result raycast(const geometry::Ray &ray) const override;
|
|
|
|
bool isAreaFree(const area_<voxel_pos> &pos, geometry::Shape shape, uint16_t radius) const override;
|
|
|
|
/// Check for collision on destination
|
|
bool collide_end(const glm::ifvec3 &pos, const glm::vec3 &vel, int density, float radius) const;
|
|
/// Check for collision at position
|
|
bool collide_point(const glm::ifvec3 &pos, const glm::vec3 &vel, int density) const;
|
|
|
|
protected:
|
|
/// Save all chunks (saveThread uses virtual calls)
|
|
void saveAll(bool remove);
|
|
|
|
/// Handle networking requests
|
|
std::optional<uint16_t> onConnect(net::server::Peer*);
|
|
bool onDisconnect(net::server::Peer*, bool, uint16_t);
|
|
bool onPacket(net::server::Peer*, const data::out_view&, net::PacketFlags);
|
|
void broadcastAreas();
|
|
data::out_buffer serializeChunk(area_<chunk_pos>, const std::shared_ptr<Chunk>&);
|
|
virtual void broadcastMessage(const std::string &);
|
|
virtual void broadcastEntities();
|
|
|
|
using area_map = robin_hood::unordered_map<area_id, std::shared_ptr<Area>>;
|
|
|
|
virtual std::shared_ptr<Chunk> createChunk(const chunk_pos &pos, const std::unique_ptr<generator::Abstract> &rnd) const;
|
|
virtual std::shared_ptr<Chunk> createChunk(std::istream &str) const;
|
|
virtual std::shared_ptr<Chunk> createChunk() const;
|
|
|
|
virtual void updateChunk(area_map::iterator&, world::ChunkContainer::iterator&, chunk_pos, float deltaTime);
|
|
virtual void loadChunk(area_<chunk_pos>, chunk_pos, const world::ChunkContainer &);
|
|
|
|
robin_hood::unordered_set<data::generational::id> movedPlayers;
|
|
voxel_pos spawnPoint;
|
|
|
|
/// Alive areas containing chunks
|
|
area_map areas;
|
|
|
|
using area_it_t = robin_hood::pair<area_id, std::shared_ptr<Area>>;
|
|
/// Dead areas
|
|
data::generational::vector<Area::params> far_areas;
|
|
void saveAreas() const;
|
|
|
|
data::generational::vector<Entity> entities;
|
|
|
|
bool running = true;
|
|
std::vector<std::thread> workers;
|
|
safe_priority_queue_map<area_<chunk_pos>, std::shared_ptr<Area>, int, area_hash> loadQueue; //NOTE: consider Area const (getRegion uses mutex)
|
|
safe_queue<robin_hood::pair<area_<chunk_pos>, std::shared_ptr<Chunk>>> loadedQueue;
|
|
|
|
using save_task_t = std::pair<area_it_t, robin_hood::pair<chunk_pos, std::shared_ptr<world::server::Chunk>>>;
|
|
data::safe_queue<save_task_t> saveQueue; //NOTE: consider Area and Chunk const
|
|
|
|
uint16_t loadDistance;
|
|
uint16_t keepDistance;
|
|
std::string folderPath;
|
|
size_t floodFillLimit;
|
|
|
|
net::server::Server host;
|
|
|
|
data::file_content dict_content;
|
|
zstd::dict_set dicts;
|
|
zstd::write_ctx dict_write_ctx;
|
|
};
|
|
} |