#include #include #include #include #include #include #include #include "str.h" #include "ser.h" #include "net.h" #include "ticker.h" #include "sig.h" #include "content.h" typedef struct { peer conn; struct termios oldtio; str name; str pass; } client; void gfx_alt_buffer(bool enable) { if (enable) printf("\e[?1049h\e[?25l"); else printf("\e[?1049l\e[?25h"); } void gfx_render(client *c, uint64_t dtime) { // TODO: render game } void client_exit(client *c, int ret) { free(c->name.data); free(c->pass.data); peer_free(&c->conn); tcsetattr(STDIN_FILENO, TCSANOW, &c->oldtio); gfx_alt_buffer(false); exit(ret); } void handle_input(client *c, char ch) { ch = tolower(ch); switch (ch) { case 'q': client_exit(c, EXIT_SUCCESS); break; default: break; } } bool handle_pkt(client *c, str pkt) { // TODO: handle network traffic return true; } int main() { signal_setup(); client c = {0}; c.name = str_clone(S("kitten")); c.pass = str_clone(S("")); c.conn.socket = -1; tcgetattr(STDIN_FILENO, &c.oldtio); // TODO: handle error struct termios newtio = c.oldtio; newtio.c_lflag &= ~(ICANON | ECHO); tcsetattr(STDIN_FILENO, TCSANOW, &newtio); // TODO: handle error SET_NONBLOCK(STDIN_FILENO); // TODO: handle error int socket = socket_create("127.0.0.1", "4560", false); if (socket < 0) client_exit(&c, EXIT_FAILURE); str server_name = S("server"); peer_init(&c.conn, socket, &server_name); gfx_alt_buffer(true); SEND_PKT(c.conn, SPKT_HI, ser_str(&pkt, c.name); ser_str(&pkt, c.pass); ) ticker t; ticker_init(&t, NANOS/60); for (;;) { struct pollfd fds[2]; fds[0].fd = STDIN_FILENO; fds[0].events = POLLIN; fds[1] = peer_prepare(&c.conn); if (poll(fds, 2, ticker_timeout(&t)) < 0) { switch (errno) { case EINTR: break; default: perror("poll"); continue; } } if (signal_stop) client_exit(&c, EXIT_SUCCESS); if (fds[0].revents) { // this is cursed // maybe dont do this idk char ch; errno = 0; while (read(STDIN_FILENO, &ch, 1) == 1) handle_input(&c, ch); switch (errno) { case 0: case EWOULDBLOCK: case EINTR: break; default: perror("read"); break; } } str pkt = peer_recv(&c.conn, fds[1]); if (c.conn.disco) client_exit(&c, EXIT_SUCCESS); if (pkt.len > 0 && !handle_pkt(&c, pkt)) invalid_pkt(&c.conn, pkt); uint64_t dtime; if (ticker_tick(&t, &dtime)) gfx_render(&c, dtime); } }