1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
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);
}
}
|