typedef enum
{
- MBS_RECIEVING, // currently deserializing
- MBS_FRESH, // first deserialisation finished, not processed by sync thread yet
- MBS_READY, // ready to use and processed by sync thread
+ MBS_RECIEVING, // currently deserializing
+ MBS_FRESH, // first deserialisation finished, not processed by sync thread yet
+ MBS_READY, // ready to use and processed by sync thread
} MapBlockState;
typedef struct
{
- MapBlockState state; // keep track of the deserialisation and sync processing state
- bool queue; // whether the block is in meshgen queue
- u64 last_synced; // keep track of when a block was synced the last time (used to detect when a block got out of and then back into range)
- Object *obj; // mesh object, generated by blockmesh file
+ MapBlockState state; // keep track of the deserialisation and sync processing state
+ bool queue; // whether the block is in meshgen queue
+ u64 last_synced; // keep track of when a block was synced the last time (used to detect when a block got out of and then back into range)
+ Object *obj; // mesh object, generated by blockmesh file
} MapBlockExtraData;
extern struct ClientMap
{
- Map *map; // map object
- Queue *queue; // MapBlock * queue (thread safe)
- bool cancel; // used to notify meshgen and sync thread about quit
- pthread_t meshgen_threads[NUM_MESHGEN_THREADS]; // consumer threads for meshgen queue
- pthread_t sync_thread; // this thread requests new / changed blocks from server
- u32 simulation_distance; // simulation distance sent by server
- size_t blocks_count; // cached number of facecache positions to process every sync step (matches simulation distance)
+ Map *map; // map object
+ Queue *queue; // MapBlock * queue (thread safe)
+ bool cancel; // used to notify meshgen and sync thread about quit
+ pthread_t meshgen_threads[NUM_MESHGEN_THREADS]; // consumer threads for meshgen queue
+ pthread_t sync_thread; // this thread requests new / changed blocks from server
+ u32 simulation_distance; // simulation distance sent by server
+ size_t blocks_count; // cached number of facecache positions to process every sync step (matches simulation distance)
} client_map;
-void client_map_init(); // ClientMap singleton constructor
-void client_map_deinit(); // ClientMap singleton destructor
-void client_map_set_simulation_distance(u32 simulation_distance); // update simulation distance
-void client_map_start(); // start meshgen and sync threads
-void client_map_stop(); // stop meshgen and sync threads
-void client_map_block_received(MapBlock *block); // called when a block was actually recieved from server
-void client_map_schedule_update_block_mesh(MapBlock *block); // enqueue block to mesh update queue
+void client_map_init(); // ClientMap singleton constructor
+void client_map_deinit(); // ClientMap singleton destructor
+void client_map_set_simulation_distance(u32 simulation_distance); // update simulation distance
+void client_map_start(); // start meshgen and sync threads
+void client_map_stop(); // stop meshgen and sync threads
+void client_map_block_received(MapBlock *block); // called when a block was actually recieved from server
+void client_map_schedule_update_block_mesh(MapBlock *block); // enqueue block to mesh update queue
#endif
{
struct
{
- char *paths[6]; // input
- int indices[6]; // input
- Texture *textures[6]; // output
+ char *paths[6]; // input
+ int indices[6]; // input
+ Texture *textures[6]; // output
} tiles;
NodeVisibility visibility;
bool mipmap;
extern struct ClientPlayer
{
- v3f64 pos; // feet position
- v3f64 velocity; // current velocity
- aabb3f64 box; // axis-aligned bounding box (used for collision), with 0, 0, 0 being the feet position
- f32 yaw, pitch; // look direction
- f64 eye_height; // eye height above feet
- pthread_rwlock_t rwlock; // used to protect the above properties
- bool fly; // can the player fly?
- bool collision; // should the player collide with the floor?
- Object *obj; // 3D mesh object (currently always invisible), not thread safe
+ v3f64 pos; // feet position
+ v3f64 velocity; // current velocity
+ aabb3f64 box; // axis-aligned bounding box (used for collision), with 0, 0, 0 being the feet position
+ f32 yaw, pitch; // look direction
+ f64 eye_height; // eye height above feet
+ pthread_rwlock_t rwlock; // used to protect the above properties
+ bool fly; // can the player fly?
+ bool collision; // should the player collide with the floor?
+ Object *obj; // 3D mesh object (currently always invisible), not thread safe
} client_player;
-void client_player_init(); // ClientPlayer singleton constructor
-void client_player_deinit(); // ClientPlayer singleton destructor
-void client_player_add_to_scene(); // create mesh object
-void client_player_jump(); // jump if possible
-v3f64 client_player_get_position(); // get position (thread-safe)
-void client_player_set_position(v3f64 pos); // set position (thread-safe)
-void client_player_tick(f64 dtime); // to be called every frame
+void client_player_init(); // ClientPlayer singleton constructor
+void client_player_deinit(); // ClientPlayer singleton destructor
+void client_player_add_to_scene(); // create mesh object
+void client_player_jump(); // jump if possible
+v3f64 client_player_get_position(); // get position (thread-safe)
+void client_player_set_position(v3f64 pos); // set position (thread-safe)
+void client_player_tick(f64 dtime); // to be called every frame
#endif
typedef enum
{
- NODE_UNKNOWN, // Used for unknown nodes received from server (caused by outdated clients)
+ NODE_UNKNOWN, // Used for unknown nodes received from server (caused by outdated clients)
NODE_AIR,
NODE_GRASS,
NODE_DIRT,
NODE_WATER,
NODE_LAVA,
NODE_VULCANO_STONE,
- NODE_UNLOADED, // Used for nodes in unloaded blocks
+ NODE_UNLOADED, // Used for nodes in unloaded blocks
} Node;
struct MapNode;
#include <stdbool.h>
#include "map.h"
-void database_init(); // open and initialize world SQLite3 database
-void database_deinit(); // close database
-bool database_load_block(MapBlock *block); // load a block from map database (initializes state, mgs buffer and data), returns false on failure
-void database_save_block(MapBlock *block); // save a block to database
-bool database_load_meta(const char *key, s64 *value_ptr); // load a meta entry
-void database_save_meta(const char *key, s64 value); // save / update a meta entry
-bool database_load_player(char *name, v3f64 *pos_ptr); // load player data from database
-void database_create_player(char *name, v3f64 pos); // insert new player into database
-void database_update_player_pos(char *name, v3f64 pos); // update player position
+void database_init(); // open and initialize world SQLite3 database
+void database_deinit(); // close database
+bool database_load_block(MapBlock *block); // load a block from map database (initializes state, mgs buffer and data), returns false on failure
+void database_save_block(MapBlock *block); // save a block to database
+bool database_load_meta(const char *key, s64 *value_ptr); // load a meta entry
+void database_save_meta(const char *key, s64 value); // save / update a meta entry
+bool database_load_player(char *name, v3f64 *pos_ptr); // load player data from database
+void database_create_player(char *name, v3f64 pos); // insert new player into database
+void database_update_player_pos(char *name, v3f64 pos); // update player position
#endif
#include "server/server_map.h"
void mapgen_set_node(v3s32 pos, MapNode node, MapgenStage mgs, List *changed_blocks);
-void mapgen_generate_block(MapBlock *block, List *changed_blocks); // generate a block (does not manage block state or threading)
+void mapgen_generate_block(MapBlock *block, List *changed_blocks); // generate a block (does not manage block state or threading)
#endif
typedef struct
{
- int sockfd; // TCP socket to accept new connections
- pthread_rwlock_t clients_rwlck; // lock to protect client list
- List clients; // Client * -> NULL map with all connected clients
- pthread_rwlock_t players_rwlck; // lock to protect player list
- List players; // char * -> Client * map with clients that have finished auth
+ int sockfd; // TCP socket to accept new connections
+ pthread_rwlock_t clients_rwlck; // lock to protect client list
+ List clients; // Client * -> NULL map with all connected clients
+ pthread_rwlock_t players_rwlck; // lock to protect player list
+ List players; // char * -> Client * map with clients that have finished auth
struct {
- u32 simulation_distance; // perimeter of the cube that players can see blocks in is simulation_distance * 2 + 1
- } config; // configuration, ToDo: read from config file
+ u32 simulation_distance; // perimeter of the cube that players can see blocks in is simulation_distance * 2 + 1
+ } config; // configuration, ToDo: read from config file
} Server;
typedef struct Client
{
- int fd; // TCP socket for connection
- pthread_mutex_t mtx; // mutex to protect socket
- ClientState state; // state of the client (created, auth, active, disconnected)
- char *address; // address string to use as identifier for log messages until auth is completed
- char *name; // player name (must be unique)
- Server *server; // pointer to server object (essentially the same for all clients)
- pthread_t net_thread; // reciever thread ID
- v3f64 pos; // player position
+ int fd; // TCP socket for connection
+ pthread_mutex_t mtx; // mutex to protect socket
+ ClientState state; // state of the client (created, auth, active, disconnected)
+ char *address; // address string to use as identifier for log messages until auth is completed
+ char *name; // player name (must be unique)
+ Server *server; // pointer to server object (essentially the same for all clients)
+ pthread_t net_thread; // reciever thread ID
+ v3f64 pos; // player position
} Client;
typedef enum
{
- DISCO_NO_REMOVE = 0x01, // don't remove from client and player list (to save extra work on server shutdown)
- DISCO_NO_SEND = 0x02, // don't notfiy client about the disconnect (if client sent disconnect themselves or the TCP connection died)
- DISCO_NO_MESSAGE = 0x04, // don't log a message about the disconnect (used on server shutdown)
- DISCO_NO_JOIN = 0x08, // don't wait for the reciever thread to finish (if TCP connection death was reported by reciever thread, the thread is already dead)
+ DISCO_NO_REMOVE = 0x01, // don't remove from client and player list (to save extra work on server shutdown)
+ DISCO_NO_SEND = 0x02, // don't notfiy client about the disconnect (if client sent disconnect themselves or the TCP connection died)
+ DISCO_NO_MESSAGE = 0x04, // don't log a message about the disconnect (used on server shutdown)
+ DISCO_NO_JOIN = 0x08, // don't wait for the reciever thread to finish (if TCP connection death was reported by reciever thread, the thread is already dead)
} DiscoFlag;
-void server_disconnect_client(Client *client, int flags, const char *detail); // disconnect a client with various options an an optional detail message (flags: DiscoFlag bitmask)
+void server_disconnect_client(Client *client, int flags, const char *detail); // disconnect a client with various options an an optional detail message (flags: DiscoFlag bitmask)
#endif
typedef enum
{
- SERVER_COMMAND_NULL, // invalid command
- SC_DISCONNECT, // client notifies server about disconnecting
- SC_AUTH, // client wants to authentify [body: name (zero terminated string)]
- SC_SETNODE, // player placed a node [body: pos (v3s32), node (Node)]
- SC_POS, // player moved [body: pos (v3f)]
- SC_REQUEST_BLOCK, // request to send a block [body: pos (v3s32)]
- SERVER_COMMAND_COUNT, // count of available commands
+ SERVER_COMMAND_NULL, // invalid command
+ SC_DISCONNECT, // client notifies server about disconnecting
+ SC_AUTH, // client wants to authentify [body: name (zero terminated string)]
+ SC_SETNODE, // player placed a node [body: pos (v3s32), node (Node)]
+ SC_POS, // player moved [body: pos (v3f)]
+ SC_REQUEST_BLOCK, // request to send a block [body: pos (v3s32)]
+ SERVER_COMMAND_COUNT, // count of available commands
} ServerCommand;
#ifdef _CLIENT_H_
typedef enum
{
- MBS_CREATED, // block exists but was not yet generated
- MBS_GENERATING, // currently generating in a seperate thread
- MBS_READY, // generation finished
+ MBS_CREATED, // block exists but was not yet generated
+ MBS_GENERATING, // currently generating in a seperate thread
+ MBS_READY, // generation finished
} MapBlockState;
typedef enum
{
- MGS_VOID, // initial air, can be overridden by anything
- MGS_TERRAIN, // basic terrain, can be overridden by anything except the void
- MGS_BOULDERS, // boulders, replace terrain
- MGS_TREES, // trees replace boulders
- MGS_PLAYER, // player-placed nodes or things placed after map generation
+ MGS_VOID, // initial air, can be overridden by anything
+ MGS_TERRAIN, // basic terrain, can be overridden by anything except the void
+ MGS_BOULDERS, // boulders, replace terrain
+ MGS_TREES, // trees replace boulders
+ MGS_PLAYER, // player-placed nodes or things placed after map generation
} MapgenStage;
typedef MapgenStage MapgenStageBuffer[MAPBLOCK_SIZE][MAPBLOCK_SIZE][MAPBLOCK_SIZE];
typedef struct
{
- char *data; // cached serialized data
- size_t size; // size of data
- size_t rawsize; // size of decompressed data
- MapBlockState state; // generation state of the block
- pthread_t mapgen_thread; // thread that is generating block
- MapgenStageBuffer mgs_buffer; // buffer to make sure mapgen only overrides things it should
+ char *data; // cached serialized data
+ size_t size; // size of data
+ size_t rawsize; // size of decompressed data
+ MapBlockState state; // generation state of the block
+ pthread_t mapgen_thread; // thread that is generating block
+ MapgenStageBuffer mgs_buffer; // buffer to make sure mapgen only overrides things it should
} MapBlockExtraData;
extern struct ServerMap {
- Map *map; // map object, data is stored here
- bool joining_threads; // prevent threads from removing themselves from the thread list if thread list is being cleared anyway
- pthread_mutex_t joining_threads_mtx; // mutex to protect joining threads
- List mapgen_threads; // a list of mapgen threads (need to be joined before shutdown)
- pthread_mutex_t mapgen_threads_mtx; // mutex to protect mapgen thread list
- s32 spawn_height; // height to spawn players at
+ Map *map; // map object, data is stored here
+ bool joining_threads; // prevent threads from removing themselves from the thread list if thread list is being cleared anyway
+ pthread_mutex_t joining_threads_mtx; // mutex to protect joining threads
+ List mapgen_threads; // a list of mapgen threads (need to be joined before shutdown)
+ pthread_mutex_t mapgen_threads_mtx; // mutex to protect mapgen thread list
+ s32 spawn_height; // height to spawn players at
} server_map; // ServerMap singleton
-void server_map_init(Server *server); // ServerMap singleton constructor
-void server_map_deinit(); // ServerMap singleton destructor
-void server_map_requested_block(Client *client, v3s32 pos); // handle block request from client (thread safe)
-void server_map_prepare_spawn(); // prepare spawn region
+void server_map_init(Server *server); // ServerMap singleton constructor
+void server_map_deinit(); // ServerMap singleton destructor
+void server_map_requested_block(Client *client, v3s32 pos); // handle block request from client (thread safe)
+void server_map_prepare_spawn(); // prepare spawn region
#endif
voxelctx_s(ctx, 4.0f);
voxelctx_x(ctx, 0.1f);
voxelctx_light(ctx, voxelctx_random(ctx, 0.0f, 0.1f));
- //voxelctx_cylinder(ctx, NODE_OAK_WOOD, true);
+ // voxelctx_cylinder(ctx, NODE_OAK_WOOD, true);
voxelctx_cube(ctx, NODE_OAK_WOOD, true);
voxelctx_pop(ctx);
voxelctx_light(ctx, -0.5f);
voxelctx_sat(ctx, 0.5f);
- /*voxelctx_s(ctx, 50);
- voxelctx_ry(ctx, 45);
-
- voxelctx_push(ctx);
- voxelctx_cube(ctx, NODE_OAK_LEAVES, true);
- voxelctx_pop(ctx);
-
- voxelctx_delete(ctx);
- if (true)
- return;*/
-
f32 n = voxelctx_random(ctx, 40.0f, 10.0f);
voxelctx_push(ctx);
#endif
#include <dragontype/number.h>
-#define ever (;;) // infinite for loop with style
-#define INBRACES(str) (str) ? "(" : "", (str) ? (str) : "", (str) ? ")" : "" // wrapper for printf to optionally add a message in braces if message is not NULL
-#define CMPBOUNDS(x) ((x) == 0 ? 0 : (x) > 0 ? 1 : -1) // resolves to 1 if x > 0, 0 if x == 0 and -1 if x < 0
-#define fallthrough __attribute__ ((fallthrough)) // prevent compiler warning about implicit fallthrough with style
+#define ever (;;) // infinite for loop with style
+#define INBRACES(str) (str) ? "(" : "", (str) ? (str) : "", (str) ? ")" : "" // wrapper for printf to optionally add a message in braces if message is not NULL
+#define CMPBOUNDS(x) ((x) == 0 ? 0 : (x) > 0 ? 1 : -1) // resolves to 1 if x > 0, 0 if x == 0 and -1 if x < 0
+#define fallthrough __attribute__ ((fallthrough)) // prevent compiler warning about implicit fallthrough with style
#define unused __attribute__ ((unused))
#define U32(x) (((u32) 1 << 31) + (x))
-extern const char *program_name; // this has to be set to program name on startup
+extern const char *program_name; // this has to be set to program name on startup
-void syscall_error(const char *err); // print system call related error message and exit
-void internal_error(const char *err); // print general error message and exit
-char *read_string(int fd, size_t bufsiz); // read from fd until \0 or EOF terminator
-char *address_string(struct sockaddr_in6 *addr); // convert IPv6 address to human readable, return allocated buffer
-void my_compress(const void *uncompressed, size_t uncompressed_size, char **compressed, size_t *compressed_size); // compress data using ZLib and store result(buffer allocated by malloc) in compressed
-bool my_decompress(const char *compressed, size_t compressed_size, void *decompressed, size_t expected_decompressed_size); // decompress data and put result into decompressed, return false if decompressed size does not match expected_decompressed_size
-bool within_simulation_distance(v3f64 player_pos, v3s32 block_pos, u32 simulation_distance); // return true if a player is close enough to a block to access it
+void syscall_error(const char *err); // print system call related error message and exit
+void internal_error(const char *err); // print general error message and exit
+char *read_string(int fd, size_t bufsiz); // read from fd until \0 or EOF terminator
+char *address_string(struct sockaddr_in6 *addr); // convert IPv6 address to human readable, return allocated buffer
+void my_compress(const void *uncompressed, size_t uncompressed_size, char **compressed, size_t *compressed_size); // compress data using ZLib and store result(buffer allocated by malloc) in compressed
+bool my_decompress(const char *compressed, size_t compressed_size, void *decompressed, size_t expected_decompressed_size); // decompress data and put result into decompressed, return false if decompressed size does not match expected_decompressed_size
+bool within_simulation_distance(v3f64 player_pos, v3s32 block_pos, u32 simulation_distance); // return true if a player is close enough to a block to access it
f64 clamp(f64 v, f64 min, f64 max);
char *format_string(const char *format, ...);
void *buffer_read(unsigned char **buffer, size_t *bufsiz, size_t size);