From 87e515b927d15881e39b73e18ac211164f28b88f Mon Sep 17 00:00:00 2001 From: June McEnroe Date: Mon, 31 Jul 2017 21:30:22 -0400 Subject: Show other clients' cursors Also unfuck removing on send failure. --- client.c | 20 +++++++++++ server.c | 118 +++++++++++++++++++++++++++++++++++++++++++-------------------- 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, -- cgit 1.4.1