]> git.lizzy.rs Git - dragonblocks_alpha.git/commitdiff
Add client
authorElias Fleckenstein <eliasfleckenstein@web.de>
Fri, 19 Mar 2021 18:51:30 +0000 (19:51 +0100)
committerElias Fleckenstein <eliasfleckenstein@web.de>
Fri, 19 Mar 2021 18:51:30 +0000 (19:51 +0100)
Makefile
client.c [new file with mode: 0644]
map.c
map.h
node.h
server.c
util.c [new file with mode: 0644]
util.h [new file with mode: 0644]

index 7a160dd8855ef2e918954eef4966b82abe7f3b48..48fc68f7869e1849bf6da24ef30bab078074d12c 100644 (file)
--- a/Makefile
+++ b/Makefile
@@ -1,13 +1,17 @@
-COMMON = array.o binsearch.o linkedlist.o map.o
+COMMON = array.o binsearch.o linkedlist.o map.o util.o
 SERVER = $(COMMON) server.o
+CLIENT = $(COMMON) client.o
 
-all: DragonblocksServer
+all: Dragonblocks DragonblocksServer
+
+Dragonblocks: $(CLIENT)
+       gcc -g -o Dragonblocks $(CLIENT)
 
 DragonblocksServer: $(SERVER)
        gcc -g -o DragonblocksServer $(SERVER)
 
 %.o: %.c
-       gcc -c -g -o $@ -Wall -Wextra -Wpedantic $<
+       gcc -c -g -o $@ -Wall -Wextra -Wpedantic -Werror $<
 
 clean:
        rm *.o
diff --git a/client.c b/client.c
new file mode 100644 (file)
index 0000000..b1f090c
--- /dev/null
+++ b/client.c
@@ -0,0 +1,45 @@
+#include <sys/socket.h>
+#include <netinet/in.h>
+#include <arpa/inet.h>
+#include <unistd.h>
+#include "map.h"
+#include "util.h"
+
+int main(int argc, char **argv)
+{
+       program_name = argv[0];
+
+       int sockfd = socket(AF_INET, SOCK_STREAM, 0);
+
+       if (sockfd == -1)
+               syscall_error("socket");
+
+       if (argc <= 1)
+               internal_error("missing address");
+
+       struct in_addr addr_buf;
+
+       if (inet_aton(argv[1], &addr_buf) == 0)
+               internal_error("invalid address");
+
+       struct sockaddr_in addr = {
+               .sin_family = AF_INET,
+               .sin_port = get_port_from_args(argc, argv, 2),
+               .sin_addr = addr_buf,
+       };
+
+       if (connect(sockfd, (struct sockaddr *) &addr, sizeof(addr)) == -1)
+               syscall_error("connect");
+
+       Map *map = map_create(NULL);
+
+       MapBlock *block = map_deserialize_block(sockfd);
+       map_create_block(map, (v3s32) {0, 0, 0}, block);
+
+       MapNode node = map_get_node(map, (v3s32) {0, 0, 0});
+       printf("%d\n", node.type);
+
+       close(sockfd);
+
+       map_delete(map);
+}
diff --git a/map.c b/map.c
index 9568363fc83bc5bb34cf5dc29751033c248dcf3a..3d8df081ca67e47faa5f9bc737dc8f9ac1bdb894 100644 (file)
--- a/map.c
+++ b/map.c
@@ -1,5 +1,7 @@
 #include <stdlib.h>
 #include <stdbool.h>
+#include <endian.h>
+#include <unistd.h>
 #include "map.h"
 #include "binsearch.h"
 
@@ -67,6 +69,42 @@ MapBlock *map_get_block(Map *map, v3s32 pos, bool create)
        return block;
 }
 
+void map_create_block(Map *map, v3s32 pos, MapBlock *block)
+{
+       block->pos = pos;
+
+       MapSector *sector = map_get_sector(map, (v2s32) {pos.x, pos.z}, true);
+       BinsearchResult res = binsearch(&pos.y, sector->blocks.ptr, sector->blocks.siz, &block_compare);
+       if (res.success) {
+               map_raw_delete_block(sector->blocks.ptr[res.index]);
+               sector->blocks.ptr[res.index] = block;
+       } else {
+               array_insert(&sector->blocks, block, res.index);
+       }
+}
+
+void map_serialize_block(int fd, MapBlock *block)
+{
+       ITERATE_MAPBLOCK {
+               u32 encoded_type = htobe32((u32) block->data[x][y][z].type);
+               write(fd, &encoded_type, 4);
+       }
+}
+
+MapBlock *map_deserialize_block(int fd)
+{
+       MapBlock *block = malloc(sizeof(MapBlock));
+       ITERATE_MAPBLOCK {
+               u32 encoded_type;
+               read(fd, &encoded_type, 4);
+               Node type = be32toh(encoded_type);
+               if (type >= MAX_NODES)
+                       type = NODE_INVALID;
+               block->data[x][y][z] = map_node_create(type);
+       }
+       return block;
+}
+
 MapNode map_get_node(Map *map, v3s32 pos)
 {
        MapBlock *block = map_get_block(map, (v3s32) {pos.x / 16, pos.y / 16, pos.z / 16}, false);
diff --git a/map.h b/map.h
index 606cb938e63f25e5d4fe640663ba5a4a72695558..e9fb7a678b6e37eb65363b5466b4f3dc8337e975 100644 (file)
--- a/map.h
+++ b/map.h
@@ -39,8 +39,8 @@ MapSector *map_get_sector(Map *map, v2s32 pos, bool create);
 MapBlock *map_get_block(Map *map, v3s32 pos, bool create);
 void map_create_block(Map *map, v3s32 pos, MapBlock *block);
 
-void map_serialize_block(int fd, MapBlock *); // ToDo
-MapBlock *map_deserialize_block(int fd); // ToDo
+void map_serialize_block(int fd, MapBlock *);
+MapBlock *map_deserialize_block(int fd);
 
 void map_delete_block(MapBlock *); // ToDo
 void map_unload_block(MapBlock *); // ToDo
diff --git a/node.h b/node.h
index 602837a1418959244cc9e49e6f6900d80441b7f1..0f5954d4405d1b170a12283cd52128bbaa5e9a62 100644 (file)
--- a/node.h
+++ b/node.h
@@ -4,10 +4,12 @@
 typedef enum
 {
        NODE_UNLOADED,          // Used for nodes in unloaded blocks
+       NODE_INVALID,           // Used for invalid nodes sent by server
        NODE_AIR,
        NODE_GRASS,
        NODE_DIRT,
        NODE_STONE,
+       MAX_NODES,
 } Node;
 
 #endif
index 538b0b58d2555cbe4352ffa7dda7745a96195b78..d6742080cbb6f05d670d6ad2f182263d0d9a25b1 100644 (file)
--- a/server.c
+++ b/server.c
@@ -1,21 +1,54 @@
 #include <assert.h>
+#include <sys/socket.h>
+#include <netinet/in.h>
+#include <unistd.h>
 #include "map.h"
+#include "util.h"
 
-int main()
+int main(int argc, char **argv)
 {
+       program_name = argv[0];
+
+       int sockfd = socket(AF_INET, SOCK_STREAM, 0);
+
+       if (sockfd == -1)
+               syscall_error("socket");
+
+       struct sockaddr_in srv_addr = {
+               .sin_family = AF_INET,
+               .sin_port = get_port_from_args(argc, argv, 1),
+               .sin_addr = {.s_addr = INADDR_ANY},
+       };
+
+       int flag = 1;
+
+       if (setsockopt(sockfd, SOL_SOCKET, SO_REUSEADDR, &flag, 4) == -1)
+               syscall_error("setsockopt");
+
+       if (bind(sockfd, (struct sockaddr *) &srv_addr, sizeof(srv_addr)) == -1)
+               syscall_error("bind");
+
+       if (listen(sockfd, 3) == -1)
+               syscall_error("listen");
+
        Map *map = map_create(NULL);
        map_set_node(map, (v3s32) {0, 0, 0}, map_node_create(NODE_STONE));
-       printf("test 1 passed\n");
-       map_set_node(map, (v3s32) {0, 5, 89}, map_node_create(NODE_DIRT));
-       printf("test 2 passed\n");
-       map_set_node(map, (v3s32) {321, 0, 89}, map_node_create(NODE_GRASS));
-       printf("test 3 passed\n");
-       map_set_node(map, (v3s32) {3124, 99, 2}, map_node_create(NODE_GRASS));
-       printf("test 4 passed\n");
+
+       struct sockaddr_in cli_addr_buf;
+       socklen_t cli_addrlen_buf;
+
+       int fd = accept(sockfd, (struct sockaddr *) &cli_addr_buf, &cli_addrlen_buf);
+
+       if (fd == -1)
+               syscall_error("accept");
+
        MapBlock *block = map_get_block(map, (v3s32) {0, 0, 0}, false);
        assert(block);
-       printf("(0 | 0 | 0) Block dump:\n");
-       ITERATE_MAPBLOCK printf("%d", block->data[x][y][z].type);
+       map_serialize_block(fd, block);
+       close(fd);
+
+       shutdown(sockfd, SHUT_RDWR);
+       close(sockfd);
 
        map_delete(map);
 }
diff --git a/util.c b/util.c
new file mode 100644 (file)
index 0000000..391b269
--- /dev/null
+++ b/util.c
@@ -0,0 +1,32 @@
+#include <stdio.h>
+#include <stdlib.h>
+#include <limits.h>
+#include <arpa/inet.h>
+#include "util.h"
+
+const char *program_name;
+
+void syscall_error(const char *err)
+{
+       perror(err);
+       exit(EXIT_FAILURE);
+}
+
+void internal_error(const char *err)
+{
+       fprintf(stderr, "%s: %s\n", program_name, err);
+       exit(EXIT_FAILURE);
+}
+
+unsigned short get_port_from_args(int argc, char **argv, int index)
+{
+       if (argc <= index)
+               internal_error("missing port");
+
+       unsigned int port = atoi(argv[index]);
+
+       if (port == 0 || port > USHRT_MAX)
+               internal_error("invalid port");
+
+       return htons(port);
+}
diff --git a/util.h b/util.h
new file mode 100644 (file)
index 0000000..b431c60
--- /dev/null
+++ b/util.h
@@ -0,0 +1,12 @@
+#ifndef _UTIL_H_
+#define _UTIL_H_
+
+#include "types.h"
+
+extern const char *program_name;
+
+void syscall_error(const char *err);
+void internal_error(const char *err);
+u16 get_port_from_args(int argc, char **argv, int index);
+
+#endif