summaryrefslogtreecommitdiff
path: root/src/client.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/client.c')
-rw-r--r--src/client.c125
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);
+ }
+}