diff options
author | Lizzy Fleckenstein <lizzy@vlhl.dev> | 2024-06-23 17:01:27 +0200 |
---|---|---|
committer | Lizzy Fleckenstein <lizzy@vlhl.dev> | 2024-06-23 17:01:34 +0200 |
commit | bf3c2eb3509076251b16ded45f8ceb4be60ae98b (patch) | |
tree | 02a0070e223022fceddd7777766eb940b71ac434 /src/client.c | |
parent | 0c097be7c7809e86f3ebdd1bd9fe2f857919c5cd (diff) |
client: handle CPKT_NODES
Signed-off-by: Lizzy Fleckenstein <lizzy@vlhl.dev>
Diffstat (limited to 'src/client.c')
-rw-r--r-- | src/client.c | 104 |
1 files changed, 95 insertions, 9 deletions
diff --git a/src/client.c b/src/client.c index 0ab1b53..79a012d 100644 --- a/src/client.c +++ b/src/client.c @@ -5,12 +5,14 @@ #include <poll.h> #include <errno.h> #include <ctype.h> +#include <stdint.h> #include "str.h" #include "ser.h" #include "net.h" #include "ticker.h" #include "sig.h" #include "content.h" +#include "chunk.h" typedef struct { str name; @@ -25,6 +27,9 @@ typedef struct { uint64_t self_id; array(player) players; str server_motd; + chunk map; + node *map_swap; + vec2 player_pos; } client; void gfx_alt_buffer(bool enable) @@ -35,6 +40,16 @@ void gfx_alt_buffer(bool enable) printf("\e[?1049l\e[?25h"); } +void gfx_clear_effects() +{ + printf("\e[0m"); +} + +void gfx_set_color(color c, bool bg) +{ + printf("\e[%u;2;%u;%u;%um", bg ? 48 : 38, c.r, c.g, c.b); +} + void gfx_clear() { printf("\e[2J"); @@ -47,6 +62,21 @@ void gfx_render(client *c, uint64_t dtime) printf("%.*s\n", PSTR(c->server_motd)); for (size_t i = 0; i < c->players.len; i++) printf("%.*s\n", PSTR(c->players.data[i].name)); + for (size_t y = 0; y < c->map.bounds.size.y; y++) { + for (size_t x = 0; x < c->map.bounds.size.y; x++) { + node *n = chunk_index(c->map, UVEC2(x, y)); + if (!n->present) { + gfx_set_color(color_from_u32(0x555555), true); + gfx_set_color(color_from_u32(0xffffff), false); + printf("??"); + } else { + gfx_set_color(n->col, true); + printf(" "); + } + } + gfx_clear_effects(); + printf("\n"); + } fflush(stdout); } @@ -72,6 +102,7 @@ void client_exit(client *c, int ret) peer_free(&c->conn); tcsetattr(STDIN_FILENO, TCSANOW, &c->oldtio); gfx_alt_buffer(false); + fflush(stdout); exit(ret); } @@ -85,22 +116,72 @@ void handle_input(client *c, char ch) } } -bool handle_players(str *w, client *c) +void map_set_center(client *c, vec2 center) +{ + chunk old = c->map; + + c->map.data = c->map_swap; + c->map.bounds.pos = center; + c->map_swap = old.data; + + chunk_clear(c->map); + chunk_copy(c->map, old); +} + +bool deser_color(str *r, color *c) +{ + return deser_u8(r, &c->r) && deser_u8(r, &c->g) && deser_u8(r, &c->b); +} + +bool deser_node(str *r, node *n) +{ + if (!deser_bool(r, &n->present)) return false; + if (!n->present) return true; + + return deser_i8(r, &n->z) + && deser_color(r, &n->col); +} + +bool handle_nodes(str *pkt, client *c) +{ + chunk ch; + if (!deser_vec2(pkt, &ch.bounds.pos)) return false; + if (!deser_uvec2(pkt, &ch.bounds.size)) return false; + + if (ch.bounds.size.x * ch.bounds.size.y > NODES_PKT_MAX) return false; + + node nodes[ch.bounds.size.x * ch.bounds.size.y]; + ch.pitch = ch.bounds.size.y; + ch.data = nodes; + + for (uint32_t x = 0; x < ch.bounds.size.x; x++) + for (uint32_t y = 0; y < ch.bounds.size.y; y++) + if (!deser_node(pkt, chunk_index(ch, UVEC2(x, y)))) return false; + + chunk_copy(c->map, ch); + return true; +} + +bool handle_reset_map(str *pkt, client *c) +{ + (void) pkt; + chunk_clear(c->map); + return true; +} + +bool handle_players(str *pkt, client *c) { free_players(c); uint16_t len; - if (!deser_u16(w, &len)) - return false; + if (!deser_u16(pkt, &len)) return false; c->players.data = malloc(sizeof *c->players.data * len); for (c->players.len = 0; c->players.len < len; c->players.len++) { player *p = &c->players.data[c->players.len]; - if (!deser_str(w, &p->name)) - return false; - if (!deser_u64(w, &p->id)) - return false; + if (!deser_str(pkt, &p->name)) return false; + if (!deser_u64(pkt, &p->id)) return false; if (str_eq(p->name, c->name)) c->self_id = p->id; p->name = str_clone(p->name); @@ -111,8 +192,7 @@ bool handle_players(str *w, client *c) bool handle_hi(str *w, client *c) { str motd; - if (!deser_str(w, &motd)) - return false; + if (!deser_str(w, &motd)) return false; c->server_motd = str_clone(motd); return true; @@ -127,6 +207,8 @@ bool handle_pkt(client *c, str pkt) switch (type) { case CPKT_HI: return handle_hi(&pkt, c); case CPKT_PLAYERS: return handle_players(&pkt, c); + case CPKT_RESET_MAP: return handle_reset_map(&pkt, c); + case CPKT_NODES: return handle_nodes(&pkt, c); default: return false; } } @@ -163,6 +245,7 @@ int main(int argc, char **argv) str server_name = S("server"); peer_init(&c.conn, socket, &server_name); + setvbuf(stdout, NULL, _IOFBF, 0); gfx_alt_buffer(true); SEND_PKT(c.conn, SPKT_HI, @@ -170,6 +253,9 @@ int main(int argc, char **argv) ser_str(&pkt, c.pass); ) + c.map = chunk_alloc(box2_around(VEC2(0, 0), SIGHT_RANGE)); + c.map_swap = malloc(c.map.bounds.size.x * c.map.bounds.size.y * sizeof(node)); + ticker t; ticker_init(&t, NANOS/60); |