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
|
#include <u.h>
#include <libc.h>
#include <draw.h>
#include "libgeometry/geometry.h"
#include "dat.h"
#include "fns.h"
static int
lobby_takeseat(Lobby *l, char *dir, int cfd, int dfd)
{
if(l->nseats >= l->cap){
l->cap += 8;
l->seats = erealloc(l->seats, l->cap*sizeof(*l->seats));
}
l->seats[l->nseats].name = nil;
memmove(l->seats[l->nseats].conn.dir, dir, sizeof l->seats[l->nseats].conn.dir);
l->seats[l->nseats].conn.ctl = cfd;
l->seats[l->nseats].conn.data = dfd;
return l->nseats++;
}
static int
lobby_leaveseat(Lobby *l, ulong idx)
{
if(idx >= l->cap)
return -1;
if(idx < l->cap - 1)
memmove(&l->seats[idx], &l->seats[idx+1], l->cap*sizeof(*l->seats) - (idx + 1)*sizeof(*l->seats));
return --l->nseats;
}
static int
lobby_getcouple(Lobby *l, Player *couple)
{
if(l->nseats >= 2){
couple[0] = l->seats[l->nseats-2];
couple[1] = l->seats[l->nseats-1];
if(l->nseats < l->cap - 2)
memmove(&l->seats[l->nseats], &l->seats[l->nseats+2], l->cap*sizeof(*l->seats) - (l->nseats + 2)*sizeof(*l->seats));
l->nseats -= 2;
return 0;
}
return -1;
}
static void
lobby_purge(Lobby *l)
{
char status[48], buf[16];
int i, fd;
for(i = 0; i < l->nseats; i++){
snprint(status, sizeof status, "%s/status", l->seats[i].conn.dir);
fd = open(status, OREAD);
if(fd < 0)
goto cleanup;
if(read(fd, buf, sizeof buf) > 0)
if(strncmp(buf, "Close", 5) == 0)
goto cleanup;
else{
close(fd);
continue;
}
cleanup:
close(fd);
l->leaveseat(l, i);
}
}
Lobby *
newlobby(void)
{
Lobby *l;
l = emalloc(sizeof(Lobby));
memset(l, 0, sizeof(*l));
l->takeseat = lobby_takeseat;
l->getcouple = lobby_getcouple;
l->leaveseat = lobby_leaveseat;
l->purge = lobby_purge;
return l;
}
void
dellobby(Lobby *l)
{
free(l->seats);
free(l);
}
|