diff options
Diffstat (limited to 'src/client.c')
-rw-r--r-- | src/client.c | 125 |
1 files changed, 125 insertions, 0 deletions
diff --git a/src/client.c b/src/client.c new file mode 100644 index 0000000..0dabbbf --- /dev/null +++ b/src/client.c @@ -0,0 +1,125 @@ +#include <stdio.h> +#include <stdlib.h> +#include <termios.h> +#include <unistd.h> +#include <poll.h> +#include <errno.h> +#include <ctype.h> +#include "str.h" +#include "ser.h" +#include "net.h" +#include "ticker.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() +{ + 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); + peer_init(&c.conn, socket); + + gfx_alt_buffer(true); + + 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: continue; + default: perror("poll"); continue; + } + } + + 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(S("server"), pkt); + + uint64_t dtime; + if (ticker_tick(&t, &dtime)) + gfx_render(&c, dtime); + } +} |