]> git.lizzy.rs Git - dragonblocks_alpha.git/blob - src/util.c
Rename NODE_INVALID to NODE_UNKNOWN
[dragonblocks_alpha.git] / src / util.c
1 #include <stdio.h>
2 #include <stdlib.h>
3 #include <unistd.h>
4 #include <string.h>
5 #include <zlib.h>
6 #include "map.h"
7 #include "util.h"
8
9 const char *program_name;
10
11 // print system call related error message and exit
12 void syscall_error(const char *err)
13 {
14         perror(err);
15         exit(EXIT_FAILURE);
16 }
17
18 // print general error message and exit
19 void internal_error(const char *err)
20 {
21         fprintf(stderr, "%s: %s\n", program_name, err);
22         exit(EXIT_FAILURE);
23 }
24
25 // read from fd until \0 or EOF terminator
26 // store result including terminator into allocated buffer until bufsiz+1 is hit, return NULL on read error
27 char *read_string(int fd, size_t bufsiz)
28 {
29         char buf[bufsiz + 1];
30         buf[bufsiz] = 0;
31         for (size_t i = 0;; i++) {
32                 char c;
33                 if (read(fd, &c, 1) == -1) {
34                         perror("read");
35                         return NULL;
36                 }
37                 if (i < bufsiz)
38                         buf[i] = c;
39                 if (c == EOF || c == 0)
40                         break;
41         }
42         return strdup(buf);
43 }
44
45 // convert IPv6 address to human readable, return allocated buffer
46 char *address_string(struct sockaddr_in6 *addr)
47 {
48         char address[INET6_ADDRSTRLEN] = {0};
49         char port[6] = {0};
50
51         if (inet_ntop(addr->sin6_family, &addr->sin6_addr, address, INET6_ADDRSTRLEN) == NULL)
52                 perror("inet_ntop");
53         sprintf(port, "%d", ntohs(addr->sin6_port));
54
55         char *result = malloc(strlen(address) + 1 + strlen(port) + 1);
56         sprintf(result, "%s:%s", address, port);
57         return result;
58 }
59
60 // convert #RRGGBB color to v3f32
61 v3f32 html_to_v3f32(const char *html)
62 {
63         unsigned int r, g, b;
64         sscanf(html, "#%2x%2x%2x", &r, &g, &b);
65         return (v3f32) {(f32) r / 255.0f, (f32) g / 255.0f, (f32) b / 255.0f};
66 }
67
68 // compress data using ZLib and store result(buffer allocated by malloc) in compressed
69 void my_compress(const void *uncompressed, size_t uncompressed_size, char **compressed, size_t *compressed_size)
70 {
71         char compressed_buffer[uncompressed_size];
72
73         z_stream stream;
74         stream.zalloc = Z_NULL;
75         stream.zfree = Z_NULL;
76         stream.opaque = Z_NULL;
77
78         stream.avail_in = stream.avail_out = uncompressed_size;
79         stream.next_in = (Bytef *) uncompressed;
80         stream.next_out = (Bytef *) compressed_buffer;
81
82         deflateInit(&stream, Z_BEST_COMPRESSION);
83         deflate(&stream, Z_FINISH);
84         deflateEnd(&stream);
85
86         *compressed_size = stream.total_out;
87         *compressed = malloc(*compressed_size);
88         memcpy(*compressed, compressed_buffer, *compressed_size);
89 }
90
91 // decompress data and put result into decompressed, return false if decompressed size does not match expected_decompressed_size
92 bool my_decompress(const char *compressed, size_t compressed_size, void *decompressed, size_t expected_decompressed_size)
93 {
94         z_stream stream;
95         stream.zalloc = Z_NULL;
96         stream.zfree = Z_NULL;
97         stream.opaque = Z_NULL;
98
99         stream.avail_in = compressed_size;
100         stream.next_in = (Bytef *) compressed;
101         stream.avail_out = expected_decompressed_size;
102         stream.next_out = (Bytef *) decompressed;
103
104         inflateInit(&stream);
105         inflate(&stream, Z_NO_FLUSH);
106         inflateEnd(&stream);
107
108         return stream.total_out == expected_decompressed_size;
109 }
110
111 // return true if a player is close enough to a block to access it
112 bool within_simulation_distance(v3f64 player_pos, v3s32 block_pos, u32 simulation_distance)
113 {
114         v3s32 player_block_pos = map_node_to_block_pos((v3s32) {player_pos.x, player_pos.y, player_pos.z}, NULL);
115         return abs(player_block_pos.x - block_pos.x) <= simulation_distance && abs(player_block_pos.y - block_pos.y) <= simulation_distance && abs(player_block_pos.z - block_pos.z) <= simulation_distance;
116 }