diff options
author | Lizzy Fleckenstein <lizzy@vlhl.dev> | 2024-06-19 20:50:41 +0200 |
---|---|---|
committer | Lizzy Fleckenstein <lizzy@vlhl.dev> | 2024-06-19 20:50:41 +0200 |
commit | 47984162974a8f7d9903d352567005ac569c5a87 (patch) | |
tree | ab265785ceaae0585aec80f6d5209e6289cbefd3 /src | |
parent | 9720c7efddf2d7595c9a0b021bc5fc6327c22bcf (diff) |
client: receive and display player list
Signed-off-by: Lizzy Fleckenstein <lizzy@vlhl.dev>
Diffstat (limited to 'src')
-rw-r--r-- | src/client.c | 79 | ||||
-rw-r--r-- | src/net.c | 8 | ||||
-rw-r--r-- | src/ser.c | 14 | ||||
-rw-r--r-- | src/server.c | 34 | ||||
-rw-r--r-- | src/ticker.c | 2 |
5 files changed, 102 insertions, 35 deletions
diff --git a/src/client.c b/src/client.c index d15ba8e..08eae9d 100644 --- a/src/client.c +++ b/src/client.c @@ -13,10 +13,17 @@ #include "content.h" typedef struct { + str name; + uint64_t id; +} player; + +typedef struct { peer conn; struct termios oldtio; str name; str pass; + uint64_t self_id; + array(player) players; } client; void gfx_alt_buffer(bool enable) @@ -27,9 +34,29 @@ void gfx_alt_buffer(bool enable) printf("\e[?1049l\e[?25h"); } +void gfx_clear() +{ + printf("\e[2J"); +} + void gfx_render(client *c, uint64_t dtime) { - // TODO: render game + gfx_clear(); + printf("\e[H"); + for (size_t i = 0; i < c->players.len; i++) + printf("%.*s\n", PSTR(c->players.data[i].name)); + fflush(stdout); +} + +void free_players(client *c) +{ + for (size_t i = 0; i < c->players.len; i++) + free(c->players.data[i].name.data); + + free(c->players.data); + + c->players.len = 0; + c->players.data = NULL; } void client_exit(client *c, int ret) @@ -37,6 +64,8 @@ void client_exit(client *c, int ret) free(c->name.data); free(c->pass.data); + free_players(c); + peer_free(&c->conn); tcsetattr(STDIN_FILENO, TCSANOW, &c->oldtio); gfx_alt_buffer(false); @@ -53,20 +82,56 @@ void handle_input(client *c, char ch) } } -bool handle_pkt(client *c, str pkt) +bool handle_players(str *w, client *c) { - // TODO: handle network traffic + free_players(c); + + uint16_t len; + if (!deser_u16(w, &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 (str_cmp(p->name, c->name) == 0) + c->self_id = p->id; + p->name = str_clone(p->name); + } return true; } -int main() +bool handle_pkt(client *c, str pkt) { + pkt_type type; + if (!deser_pkt_type(&pkt, &type)) + return false; + + switch (type) { + case CPKT_PLAYERS: return handle_players(&pkt, c); + default: return false; + } +} + +int main(int argc, char **argv) +{ + if (argc < 4) { + fprintf(stderr, "usage: %s server port name [pass]\n", argv[0]); + return EXIT_FAILURE; + } + signal_setup(); client c = {0}; - c.name = str_clone(S("kitten")); - c.pass = str_clone(S("")); + const char *server = argv[1]; + const char *port = argv[2]; + c.name = str_clone(str_intro(argv[3])); + c.pass = str_clone(argc < 5 ? S("") : str_intro(argv[4])); c.conn.socket = -1; @@ -78,7 +143,7 @@ int main() SET_NONBLOCK(STDIN_FILENO); // TODO: handle error - int socket = socket_create("127.0.0.1", "4560", false); + int socket = socket_create(server, port, false); if (socket < 0) client_exit(&c, EXIT_FAILURE); str server_name = S("server"); @@ -9,6 +9,7 @@ #include <poll.h> #include <errno.h> #include <netdb.h> +#include <assert.h> #include <sys/types.h> #include <sys/socket.h> #include <netinet/in.h> @@ -20,7 +21,7 @@ void invalid_pkt(peer *from, str pkt) { // TODO: maybe inform peer about failure? not sure // FIXME: hexdumping a gazillon bytes to stderr might be an issue - fprintf(stderr, "invalid pkt from %*s: ", PSTR(*from->name)); + fprintf(stderr, "invalid pkt from %.*s: ", PSTR(*from->name)); for (size_t i = 0; i < pkt.len; i++) fprintf(stderr, "%02x%c", (uint8_t) pkt.data[i], i+1 == pkt.len ? '\n' : ' '); } @@ -103,13 +104,16 @@ void peer_free(peer *p) static void next_in(peer *p, bool header, size_t len) { + p->in.promised = len; p->in.header = header; p->in.len = 0; - p->in.buffer = malloc(p->in.promised = len); } + static bool peer_in_ready(peer *p) { + assert(p->in.promised > p->in.len); + errno = 0; ssize_t got = read(p->socket, p->in.buffer + p->in.len, p->in.promised - p->in.len); if (got <= 0) { @@ -28,25 +28,25 @@ void ser_str(strbuf *w, str x) void ser_u8(strbuf *w, uint8_t x) { - ser_bytes(w, &x, 1); + ser_bytes(w, &x, sizeof x); } void ser_u16(strbuf *w, uint16_t x) { x = htole16(x); - ser_bytes(w, &x, 2); + ser_bytes(w, &x, sizeof x); } void ser_u32(strbuf *w, uint32_t x) { x = htole32(x); - ser_bytes(w, &x, 4); + ser_bytes(w, &x, sizeof x); } void ser_u64(strbuf *w, uint64_t x) { x = htole64(x); - ser_bytes(w, &x, 8); + ser_bytes(w, &x, sizeof x); } #define SER_SIGN(N) void ser_i##N(strbuf *w, int##N##_t x) { ser_u##N(w, x); }; @@ -98,7 +98,7 @@ bool deser_u8(str *r, uint8_t *buf) bool deser_u16(str *r, uint16_t *buf) { - if (!deser_bytes(r, buf, 2)) + if (!deser_bytes(r, buf, sizeof *buf)) return false; *buf = le16toh(*buf); return true; @@ -106,7 +106,7 @@ bool deser_u16(str *r, uint16_t *buf) bool deser_u32(str *r, uint32_t *buf) { - if (!deser_bytes(r, buf, 4)) + if (!deser_bytes(r, buf, sizeof *buf)) return false; *buf = le32toh(*buf); return true; @@ -114,7 +114,7 @@ bool deser_u32(str *r, uint32_t *buf) bool deser_u64(str *r, uint64_t *buf) { - if (!deser_bytes(r, buf, 8)) + if (!deser_bytes(r, buf, sizeof *buf)) return false; *buf = le64toh(*buf); return true; diff --git a/src/server.c b/src/server.c index 0addcf2..bcca3a9 100644 --- a/src/server.c +++ b/src/server.c @@ -103,7 +103,7 @@ void map_load_node(map *m, uint32_t x, uint32_t y, uint32_t color) case 0xff9de2: n->type = N_VALLEY_FLOWER; break; // TODO: color case 0x016300: n->type = N_BIG_TREE; break; default: - fprintf(stderr, "invalid color in map %*s at %"PRIu32" %"PRIu32": %06x\n", + fprintf(stderr, "invalid color in map %.*s at %"PRIu32" %"PRIu32": %06x\n", PSTR(m->name), x, y, color); n->present = false; break; @@ -195,8 +195,8 @@ void ser_node(strbuf *w, node *n) void send_players(game *g) { for (size_t i = 0; i < g->players.len; i++) { - player *p = &g->players.data[i]; - if (p->auth) SEND_PKT(p->conn, CPKT_PLAYERS, + player *to = &g->players.data[i]; + if (to->auth) SEND_PKT(to->conn, CPKT_PLAYERS, ser_u16(&pkt, g->players.len); for (size_t i = 0; i < g->players.len; i++) { player *p = &g->players.data[i]; @@ -264,7 +264,7 @@ bool handle_hi(str pkt, player *p, game *g) return false; if (str_cmp(g->passphrase, pass) != 0) { - printf("wrong passphrase from %*s\n", PSTR(name)); // TODO: log ip ? + printf("wrong passphrase from %.*s\n", PSTR(name)); // TODO: log ip ? SEND_PKT(p->conn, CPKT_FAIL, ser_fail_reason(&pkt, FAIL_WRONG_PASS);) return true; // valid pkt, but invalid passphrase } @@ -277,7 +277,7 @@ bool handle_hi(str pkt, player *p, game *g) } } - printf("player authenticated as %*s\n", PSTR(name)); + printf("player authenticated as %.*s\n", PSTR(name)); p->auth = true; p->name = str_clone(name); @@ -342,16 +342,8 @@ int main() for (;;) { struct pollfd fds[g.players.len + 1]; - for (size_t i = 0; i < g.players.len;) { - player *p = &g.players.data[i]; - if (p->conn.disco) { - printf("player %*s disconnected\n", PSTR(p->name)); - player_remove(p, &g); - continue; - } - - fds[i++] = peer_prepare(&p->conn); - } + for (size_t i = 0; i < g.players.len; i++) + fds[i] = peer_prepare(&g.players.data[i].conn); fds[g.players.len].fd = g.accept_fd; fds[g.players.len].events = POLLIN; @@ -370,9 +362,13 @@ int main() player *p = &g.players.data[i]; str pkt = peer_recv(&p->conn, fds[i]); - if (p->conn.disco || pkt.len == 0) - continue; - if (!handle_pkt(pkt, p, &g)) + if (p->conn.disco) { + printf("player %.*s disconnected\n", PSTR(p->name)); + player_remove(p, &g); + goto cont; + } + + if (pkt.len > 0 && !handle_pkt(pkt, p, &g)) invalid_pkt(&p->conn, pkt); } @@ -388,5 +384,7 @@ int main() p->name = S("(unauthenticated)"); peer_init(&p->conn, socket, &p->name); } + + cont: continue; } } diff --git a/src/ticker.c b/src/ticker.c index d3c25b5..c0d7df9 100644 --- a/src/ticker.c +++ b/src/ticker.c @@ -13,7 +13,7 @@ static struct timespec timestamp_now() static uint64_t timestamp_diff(struct timespec a, struct timespec b) { - return NANOS * ((uint64_t) a.tv_sec - b.tv_sec) + ((int64_t) a.tv_nsec - b.tv_nsec); + return ((uint64_t) a.tv_sec - b.tv_sec) * NANOS + a.tv_nsec - b.tv_nsec; } void ticker_init(ticker *t, uint64_t f) |