9 const char *program_name;
11 // print system call related error message and exit
12 void syscall_error(const char *err)
18 // print general error message and exit
19 void internal_error(const char *err)
21 fprintf(stderr, "%s: %s\n", program_name, err);
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)
31 for (size_t i = 0;; i++) {
33 if (read(fd, &c, 1) == -1) {
39 if (c == EOF || c == 0)
45 // convert IPv6 address to human readable, return allocated buffer
46 char *address_string(struct sockaddr_in6 *addr)
48 char address[INET6_ADDRSTRLEN] = {0};
51 if (inet_ntop(addr->sin6_family, &addr->sin6_addr, address, INET6_ADDRSTRLEN) == NULL)
53 sprintf(port, "%d", ntohs(addr->sin6_port));
55 char *result = malloc(strlen(address) + 1 + strlen(port) + 1);
56 sprintf(result, "%s:%s", address, port);
60 // convert #RRGGBB color to v3f32
61 v3f32 html_to_v3f32(const char *html)
64 sscanf(html, "#%2x%2x%2x", &r, &g, &b);
65 return (v3f32) {(f32) r / 255.0f, (f32) g / 255.0f, (f32) b / 255.0f};
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)
71 char compressed_buffer[uncompressed_size];
74 stream.zalloc = Z_NULL;
75 stream.zfree = Z_NULL;
76 stream.opaque = Z_NULL;
78 stream.avail_in = stream.avail_out = uncompressed_size;
79 stream.next_in = (Bytef *) uncompressed;
80 stream.next_out = (Bytef *) compressed_buffer;
82 deflateInit(&stream, Z_BEST_COMPRESSION);
83 deflate(&stream, Z_FINISH);
86 *compressed_size = stream.total_out;
87 *compressed = malloc(*compressed_size);
88 memcpy(*compressed, compressed_buffer, *compressed_size);
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)
95 stream.zalloc = Z_NULL;
96 stream.zfree = Z_NULL;
97 stream.opaque = Z_NULL;
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;
104 inflateInit(&stream);
105 inflate(&stream, Z_NO_FLUSH);
108 return stream.total_out == expected_decompressed_size;
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)
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;