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