]> git.lizzy.rs Git - dragonblocks_alpha.git/commitdiff
Add MapBlock serialisation buffer
authorElias Fleckenstein <eliasfleckenstein@web.de>
Mon, 29 Mar 2021 20:36:04 +0000 (22:36 +0200)
committerElias Fleckenstein <eliasfleckenstein@web.de>
Mon, 29 Mar 2021 20:36:04 +0000 (22:36 +0200)
README.md
src/map.c
src/map.h
src/server.c
src/servermap.c

index 894a64076df6216a2a3a3b114bd8b99eb4486586..a6f6a56eff1fc6e4aa252dae24a0213c4be68397 100644 (file)
--- a/README.md
+++ b/README.md
@@ -1,5 +1,7 @@
 # Dragonblocks alpha
 
+A multiplayer voxelgame for POSIX.1-2008 systems.
+
 ## Usage
 ```bash
 ./DragonblocksServer <port>
index e40fe62bc0eb9df95c151da722551b7741773de0..0cb35f0ef1b5b445cb6032ebf590873acfe8aa27 100644 (file)
--- a/src/map.c
+++ b/src/map.c
@@ -3,6 +3,7 @@
 #include <unistd.h>
 #include <stdio.h>
 #include <math.h>
+#include <endian.h>
 #include "map.h"
 #include "util.h"
 
@@ -128,13 +129,18 @@ bool map_deserialize_node(int fd, MapNode *node)
        return true;
 }
 
-bool map_serialize_block(int fd, MapBlock *block)
+bool map_serialize_block(FILE *file, MapBlock *block)
 {
-       if (! write_v3s32(fd, block->pos))
+       s32 pos[3] = {
+               htobe32(block->pos.x),
+               htobe32(block->pos.y),
+               htobe32(block->pos.z),
+       };
+       if (fwrite(pos, 1, sizeof(pos), file) != sizeof(pos))
                return false;
 
-       if (write(fd, block->data, sizeof(block->data)) == -1)
-               perror("write");
+       if (fwrite(block->data, 1, sizeof(block->data), file) !=  sizeof(block->data))
+               perror("fwrite");
        else
                return true;
 
@@ -192,13 +198,13 @@ bool map_deserialize_block(int fd, Map *map, MapBlock **blockptr, bool dummy)
        return ret;
 }
 
-bool map_serialize(int fd, Map *map)
+bool map_serialize(FILE *file, Map *map)
 {
        for (size_t s = 0; s < map->sectors.siz; s++) {
                MapSector *sector = map_get_sector_raw(map, s);
                for (size_t b = 0; b < sector->blocks.siz; b++)
-                       if (! map_serialize_block(fd, map_get_block_raw(sector, b)))
-                               return false;
+                       if (! map_serialize_block(file, map_get_block_raw(sector, b)))
+                               return true;
        }
        return true;
 }
index c8b92663509d53cfde2f19d2b3ec71d59fa8df2d..fcb5aef411d200b15252c3d7d4599bcdab01f628 100644 (file)
--- a/src/map.h
+++ b/src/map.h
@@ -57,9 +57,9 @@ MapBlock *map_get_block(Map *map, v3s32 pos, bool create);
 void map_free_block(MapBlock *block);
 
 bool map_deserialize_node(int fd, MapNode *buf);
-bool map_serialize_block(int fd, MapBlock *block);
+bool map_serialize_block(FILE *file, MapBlock *block);
 bool map_deserialize_block(int fd, Map *map, MapBlock **blockptr, bool dummy);
-bool map_serialize(int fd, Map *map);
+bool map_serialize(FILE *file, Map *map);
 void map_deserialize(int fd, Map *map);
 
 v3s32 map_node_to_block_pos(v3s32 pos, v3u8 *offset);
index 0816dba291854357fa7f3d4926bb213326659916..a4b33c47b1f663e15d295eefb847a28777eca770 100644 (file)
@@ -106,7 +106,7 @@ void server_start(int fd)
 
        mapfile = fopen("map", "w");
        if (mapfile) {
-               if (map_serialize(fileno(mapfile), server.map))
+               if (map_serialize(mapfile, server.map))
                        printf("Saved map\n");
                else
                        perror("map_serialize");
index dac8a39912788bfa941a0e573d6703b1d8cd8b23..fa4a1bb029b92b1d6289262bbd7f48d78bb13991 100644 (file)
@@ -1,4 +1,7 @@
 #include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+#include <unistd.h>
 #include <perlin/perlin.h>
 #include "servermap.h"
 
@@ -36,6 +39,32 @@ static void generate_block(MapBlock *block)
        block->state = MBS_READY;
 }
 
+typedef struct
+{
+       char *ptr;
+       size_t size;
+} MapBlockBuffer;
+
+static void serialize_block(Client *client, MapBlock *block)
+{
+       MapBlockBuffer *buffer = block->extra;
+
+       if (! buffer) {
+               buffer = malloc(sizeof(MapBlockBuffer));
+
+               FILE *buffile = open_memstream(&buffer->ptr, &buffer->size);
+               map_serialize_block(buffile, block);
+               fflush(buffile);
+               fclose(buffile);
+
+               block->extra = buffer;
+       }
+
+       pthread_mutex_lock(&client->mtx);
+       (void) (write_u32(client->fd, CC_BLOCK) && write(client->fd, buffer->ptr, buffer->size) != -1);
+       pthread_mutex_unlock(&client->mtx);
+}
+
 static void send_block(MapBlock *block)
 {
        pthread_mutex_lock(&block->mtx);
@@ -45,11 +74,8 @@ static void send_block(MapBlock *block)
                if (block->state != MBS_READY)
                        break;
                Client *client = pair->value;
-               if (client->state == CS_ACTIVE) {
-                       pthread_mutex_lock(&client->mtx);
-                       (void) (write_u32(client->fd, CC_BLOCK) && map_serialize_block(client->fd, block));
-                       pthread_mutex_unlock(&client->mtx);
-               }
+               if (client->state == CS_ACTIVE)
+                       serialize_block(client, block);
        }
        pthread_mutex_unlock(&block->mtx);
 }
@@ -59,7 +85,7 @@ static void send_block(MapBlock *block)
 static size_t pos_chache_count = POS_CACHE_COUNT;
 static v3s32 pos_cache[POS_CACHE_COUNT];
 
-static void create_pos_cache()
+static void init_pos_cache()
 {
        size_t i = -1;
 #define ADDPOS(a, b, c, va, vb, vc) \
@@ -107,21 +133,27 @@ static void send_blocks(Client *client, bool init)
        v3s32 pos = map_node_to_block_pos((v3s32) {client->pos.x, client->pos.y, client->pos.z}, NULL);
        for (size_t i = 0; i < pos_chache_count; i++) {
                MapBlock *block = map_get_block(client->server->map, (v3s32) {pos.x + pos_cache[i].x, pos.y + pos_cache[i].y, pos.z + pos_cache[i].z}, ! init);
-               if (init)
-                       (void) (block && write_u32(client->fd, CC_BLOCK) && map_serialize_block(client->fd, block));
-               else switch (block->state) {
-                       case MBS_CREATED:
-                               generate_block(block);
-                               __attribute__ ((fallthrough));
-                       case MBS_MODIFIED:
-                               send_block(block);
-                               __attribute__ ((fallthrough));
-                       case MBS_PROCESSING:
-                               i = -1;
-                               sched_yield();
-                               __attribute__ ((fallthrough));
-                       case MBS_READY:
-                               break;
+               if (init) {
+                       if (block)
+                               serialize_block(client, block);
+               } else switch (block->state) {
+               case MBS_CREATED:
+                       generate_block(block);
+                       __attribute__ ((fallthrough));
+               case MBS_MODIFIED:
+                       if (block->extra) {
+                               free(((MapBlockBuffer *) block->extra)->ptr);
+                               free(block->extra);
+                               block->extra = NULL;
+                       }
+                       send_block(block);
+                       __attribute__ ((fallthrough));
+               case MBS_PROCESSING:
+                       i = -1;
+                       sched_yield();
+                       __attribute__ ((fallthrough));
+               case MBS_READY:
+                       break;
                }
        }
 }
@@ -141,7 +173,7 @@ static void *block_send_thread(void *cli)
 void servermap_init(Server *srv)
 {
        server = srv;
-       create_pos_cache();
+       init_pos_cache();
 }
 
 void servermap_add_client(Client *client)