summaryrefslogtreecommitdiff
path: root/src/client.c
diff options
context:
space:
mode:
authorLizzy Fleckenstein <lizzy@vlhl.dev>2024-06-23 17:01:27 +0200
committerLizzy Fleckenstein <lizzy@vlhl.dev>2024-06-23 17:01:34 +0200
commitbf3c2eb3509076251b16ded45f8ceb4be60ae98b (patch)
tree02a0070e223022fceddd7777766eb940b71ac434 /src/client.c
parent0c097be7c7809e86f3ebdd1bd9fe2f857919c5cd (diff)
client: handle CPKT_NODES
Signed-off-by: Lizzy Fleckenstein <lizzy@vlhl.dev>
Diffstat (limited to 'src/client.c')
-rw-r--r--src/client.c104
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);