diff options
author | June McEnroe <programble@gmail.com> | 2017-07-31 21:30:22 -0400 |
---|---|---|
committer | June McEnroe <programble@gmail.com> | 2017-07-31 21:30:22 -0400 |
commit | e2e97511e8b3ff819274b8ea802e20a41e50858f (patch) | |
tree | f9e2c129e18da878366385965ae5c8d9df6e1cd9 | |
parent | Perform enter as two moves rather than a loop (diff) | |
download | torus-e2e97511e8b3ff819274b8ea802e20a41e50858f.tar.gz torus-e2e97511e8b3ff819274b8ea802e20a41e50858f.zip |
Show other clients' cursors
Also unfuck removing on send failure.
-rwxr-xr-x | client.c | 20 | ||||
-rwxr-xr-x | server.c | 118 | ||||
-rw-r--r-- | torus.h | 9 |
3 files changed, 109 insertions, 38 deletions
diff --git a/client.c b/client.c index 4eb726b..d77aeb7 100755 --- a/client.c +++ b/client.c @@ -245,6 +245,17 @@ static void serverTile(void) { } } +static void serverCursor(uint8_t oldX, uint8_t oldY, uint8_t newX, uint8_t newY) { + if (oldX != CURSOR_NONE) { + move(oldY, oldX); + addch(inch() & ~A_REVERSE); + } + if (newX != CURSOR_NONE) { + move(newY, newX); + addch(inch() | A_REVERSE); + } +} + static void readMessage(void) { struct ServerMessage msg; ssize_t len = recv(client, &msg, sizeof(msg), 0); @@ -273,6 +284,15 @@ static void readMessage(void) { ); break; + case SERVER_CURSOR: + serverCursor( + msg.data.c.oldCellX, + msg.data.c.oldCellY, + msg.data.c.newCellX, + msg.data.c.newCellY + ); + break; + default: errx(EX_PROTOCOL, "I don't know what %d means!", msg.type); } diff --git a/server.c b/server.c index 46f4c06..b88c386 100755 --- a/server.c +++ b/server.c @@ -82,52 +82,66 @@ static struct Client *clientAdd(int fd) { return client; } -static void clientRemove(struct Client *client) { - if (client->prev) client->prev->next = client->next; - if (client->next) client->next->prev = client->prev; - if (clientHead == client) clientHead = client->next; - close(client->fd); - free(client); -} +static void clientRemove(struct Client *client); -static bool clientSend(struct Client *client, const struct ServerMessage *msg) { +static bool clientSend(const struct Client *client, const struct ServerMessage *msg) { ssize_t len = send(client->fd, msg, sizeof(*msg), 0); - if (len < 0) { - clientRemove(client); - return false; - } + if (len < 0) return false; if (msg->type == SERVER_TILE) { struct Tile *tile = tileGet(client->tileX, client->tileY); len = send(client->fd, tile, sizeof(*tile), 0); - if (len < 0) { - clientRemove(client); - return false; - } + if (len < 0) return false; } return true; } -static bool clientCast(struct Client *origin, const struct ServerMessage *msg) { - uint32_t tileX = origin->tileX; - uint32_t tileY = origin->tileY; - - bool success = clientSend(origin, msg); - +static void clientCast(const struct Client *origin, const struct ServerMessage *msg) { for (struct Client *client = clientHead; client; client = client->next) { if (client == origin) continue; - if (client->tileX != tileX) continue; - if (client->tileY != tileY) continue; + if (client->tileX != origin->tileX) continue; + if (client->tileY != origin->tileY) continue; - struct Client *next = client->next; if (!clientSend(client, msg)) { - client = next; + client = client->next; + clientRemove(client); if (!client) break; } } +} - return success; +static void clientRemove(struct Client *client) { + if (client->prev) client->prev->next = client->next; + if (client->next) client->next->prev = client->prev; + if (clientHead == client) clientHead = client->next; + + struct ServerMessage msg = { .type = SERVER_CURSOR }; + msg.data.c.oldCellX = client->cellX; + msg.data.c.oldCellY = client->cellY; + msg.data.c.newCellX = CURSOR_NONE; + msg.data.c.newCellX = CURSOR_NONE; + clientCast(client, &msg); + + close(client->fd); + free(client); +} + +static bool clientCursors(const struct Client *client) { + struct ServerMessage msg = { .type = SERVER_CURSOR }; + msg.data.c.oldCellX = CURSOR_NONE; + msg.data.c.oldCellY = CURSOR_NONE; + + for (struct Client *friend = clientHead; friend; friend = friend->next) { + if (friend == client) continue; + if (friend->tileX != client->tileX) continue; + if (friend->tileY != client->tileY) continue; + + msg.data.c.newCellX = friend->cellX; + msg.data.c.newCellY = friend->cellY; + if (!clientSend(client, &msg)) return false; + } + return true; } static bool clientMove(struct Client *client, int8_t dx, int8_t dy) { @@ -158,13 +172,35 @@ static bool clientMove(struct Client *client, int8_t dx, int8_t dy) { if (client->tileX != old.tileX || client->tileY != old.tileY) { msg.type = SERVER_TILE; - return clientSend(client, &msg); + if (!clientSend(client, &msg)) return false; + if (!clientCursors(client)) return false; + + msg.type = SERVER_CURSOR; + msg.data.c.oldCellX = old.cellX; + msg.data.c.oldCellY = old.cellY; + msg.data.c.newCellX = CURSOR_NONE; + msg.data.c.newCellX = CURSOR_NONE; + clientCast(&old, &msg); + + msg.data.c.oldCellX = CURSOR_NONE; + msg.data.c.oldCellY = CURSOR_NONE; + msg.data.c.newCellX = client->cellX; + msg.data.c.newCellY = client->cellY; + clientCast(client, &msg); + + } else { + msg.type = SERVER_CURSOR; + msg.data.c.oldCellX = old.cellX; + msg.data.c.oldCellY = old.cellY; + msg.data.c.newCellX = client->cellX; + msg.data.c.newCellY = client->cellY; + clientCast(client, &msg); } return true; } -static bool clientPut(struct Client *client, uint8_t color, char cell) { +static bool clientPut(const struct Client *client, uint8_t color, char cell) { struct Tile *tile = tileGet(client->tileX, client->tileY); tile->colors[client->cellY][client->cellX] = color; tile->cells[client->cellY][client->cellX] = cell; @@ -174,7 +210,10 @@ static bool clientPut(struct Client *client, uint8_t color, char cell) { msg.data.p.cellY = client->cellY; msg.data.p.color = color; msg.data.p.cell = cell; - return clientCast(client, &msg); + + bool success = clientSend(client, &msg); + clientCast(client, &msg); + return success; } int main() { @@ -238,8 +277,13 @@ int main() { if (nevents < 0) err(EX_OSERR, "kevent"); struct ServerMessage msg = { .type = SERVER_TILE }; - if (!clientSend(client, &msg)) continue; - clientMove(client, 0, 0); + if ( + !clientSend(client, &msg) || + !clientMove(client, 0, 0) || + !clientCursors(client) + ) { + clientRemove(client); + } continue; } @@ -257,17 +301,15 @@ int main() { continue; } + bool success = false; switch (msg.type) { case CLIENT_MOVE: - clientMove(client, msg.data.m.dx, msg.data.m.dy); + success = clientMove(client, msg.data.m.dx, msg.data.m.dy); break; - case CLIENT_PUT: - clientPut(client, msg.data.p.color, msg.data.p.cell); + success = clientPut(client, msg.data.p.color, msg.data.p.cell); break; - - default: - clientRemove(client); } + if (!success) clientRemove(client); } } diff --git a/torus.h b/torus.h index ff9c0e8..9158ef7 100644 --- a/torus.h +++ b/torus.h @@ -47,6 +47,7 @@ enum ServerMessageType { SERVER_TILE, SERVER_MOVE, SERVER_PUT, + SERVER_CURSOR, }; struct ServerMessage { @@ -62,9 +63,17 @@ struct ServerMessage { uint8_t color; char cell; } p; + struct { + uint8_t oldCellX; + uint8_t oldCellY; + uint8_t newCellX; + uint8_t newCellY; + } c; } data; }; +#define CURSOR_NONE UINT8_MAX + enum ClientMessageType { CLIENT_MOVE, CLIENT_PUT, |