diff --git a/client.c b/client.c index ccc4e42..a88d035 100644 --- a/client.c +++ b/client.c @@ -278,9 +278,13 @@ int main(int argc, char *argv[]) { } switch (incoming.mtype) { - case Message: + case Message: { printf("%s: %s\n", incoming.sender, incoming.message); + msgbuf_t ack = {.mtype = Signal, .stype = ACK_DELIVERED, .command = ""}; + strncpy(ack.command, incoming.command, COMMAND_LENGTH); + send(server_queue_id, &ack); break; + } case List: { // Check the command field for the list type if (strncmp(incoming.command, "active", COMMAND_LENGTH) == 0) { @@ -316,14 +320,14 @@ int main(int argc, char *argv[]) { case Signal: // Tell the user if the previous message was accepted and/or delivered if (incoming.stype == ACK_ACCEPTED) { - printf("Message sent successfully.\n"); + printf("[Sent]\n"); } else if (incoming.stype == ACK_DELIVERED) { - printf("Message delivered to %s.\n", incoming.sender); + printf("[Delivered: %s]\n", incoming.sender); } else if (incoming.stype == ERR_NOT_FOUND) { - printf("Your message could not be delivered: User not found.\n"); + printf("[Error: User not found]\n"); } else { // Display whatever if I forgot to handle something - printf("Unhandled signal - code %d.\n", incoming.stype); + printf("[Error: Code %d]\n", incoming.stype); } break; case JoinGroup: diff --git a/server.c b/server.c index 3894422..4bfce1e 100644 --- a/server.c +++ b/server.c @@ -65,7 +65,7 @@ static void handle_hearbeat_timeouts(Client_t *clients, int client_count, int se } sem_op.sem_op = 1; semop(semaphore_id, &sem_op, 1); - sleep(HEARTBEAT_TIMEOUT); + sleep(1); } } @@ -85,6 +85,11 @@ int main(int argc, char **argv) { Client_t *clients = shmat(clients_memory_id, NULL, 0); Group_t *groups = malloc(sizeof(Group_t) * group_count); + // Temporary buffer for ACK_DELIVERs + // This could be larger and if there are even more clients in a group it won't be good so let's hope there won't be + saved_message_t message_buffer[20] = {0}; + int message_buffer_count = 0; + int semaphore_id = semget(IPC_PRIVATE, 1, IPC_CREAT | 0666); semctl(semaphore_id, 0, SETVAL, 1); @@ -294,8 +299,8 @@ int main(int argc, char **argv) { } if (has_muted_group) { - printf("Group message to %s blocked (group %s is muted)\n", - target_group->members[i]->nickname, target_group->name); + printf("Group message to %s blocked (group %s is muted)\n", target_group->members[i]->nickname, + target_group->name); continue; } @@ -346,7 +351,7 @@ int main(int argc, char **argv) { if (is_muted) { printf("Message from %s to %s blocked (muted)\n", client->nickname, target_client->nickname); - continue; // Skip this recipient, discard the message + continue; // Skip this recipient, discard the message } // Check if the target is online or not, if they are not, store the message @@ -367,7 +372,7 @@ int main(int argc, char **argv) { strncpy(saved_msg->sender, client->nickname, COMMAND_LENGTH); strncpy(saved_msg->message, msgbuf.message, MESSAGE_LENGTH); msgbuf_t response = { - .mtype = Message, + .mtype = Signal, .stype = ACK_ACCEPTED, }; send(client->queue_id, &response); @@ -380,10 +385,20 @@ int main(int argc, char **argv) { .mtype = Message, .sender = "", }; + get_id(forward_msg.command); strncpy(forward_msg.sender, client->nickname, COMMAND_LENGTH); strncpy(forward_msg.message, msgbuf.message, MESSAGE_LENGTH); send(target_client->queue_id, &forward_msg); + // Add to message buffer for tracking ACK_DELIVERED + if (message_buffer_count < 20) { + saved_message_t *buffered = &message_buffer[message_buffer_count++]; + strncpy(buffered->message_id, forward_msg.command, COMMAND_LENGTH); + strncpy(buffered->sender, client->id, COMMAND_LENGTH); + strncpy(buffered->command, target_client->id, COMMAND_LENGTH); + strncpy(buffered->message, msgbuf.message, MESSAGE_LENGTH); + } + forward_msg.stype = ACK_ACCEPTED; forward_msg.mtype = Signal; send(client->queue_id, &forward_msg); @@ -588,16 +603,12 @@ int main(int argc, char **argv) { // Check if user is already in the group bool is_in_group = false; - printf("Group '%s' has %d member slots\n", target_group->name, target_group->client_count); for (int i = 0; i < target_group->client_count; i++) { if (target_group->members[i] != NULL) { - printf(" Slot %d: %s\n", i, target_group->members[i]->id); if (strncmp(client->id, target_group->members[i]->id, COMMAND_LENGTH) == 0) { is_in_group = true; break; } - } else { - printf(" Slot %d: NULL\n", i); } } @@ -650,7 +661,6 @@ int main(int argc, char **argv) { Group_t *target_group = NULL; for (int i = 0; i < group_count; i++) { - printf("Comparing group[%d].name='%s' with command='%s'\n", i, groups[i].name, msgbuf.command); if (strcmp(groups[i].name, msgbuf.command) == 0) { target_group = &groups[i]; break; @@ -708,7 +718,7 @@ int main(int argc, char **argv) { // Check if muting a group (starts with #) or a user if (msgbuf.command[0] == '#') { // Muting a group - char *group_name = msgbuf.command + 1; // Skip the # + char *group_name = msgbuf.command + 1; // Skip the # // Find the group Group_t *target_group = NULL; @@ -863,11 +873,41 @@ int main(int argc, char **argv) { } break; } - case Signal: - // Signals are sent from server to client, not the other way around - // so we ignore them here lol + case Signal: { + // Handle the delivery signal from the recipent + int message_idx = -1; + if (msgbuf.stype == ACK_DELIVERED) { + for (int i = 0; i < message_buffer_count; i++) { + if (strncmp(msgbuf.command, message_buffer[i].message_id, COMMAND_LENGTH) == 0) { + message_idx = i; + break; + } + } + if (message_idx == -1) + continue; + + saved_message_t *message = &message_buffer[message_idx]; + + for (int i = 0; i < client_count; i++) { + if (strncmp(message->sender, clients[i].id, COMMAND_LENGTH) == 0) { + msgbuf_t ack = {.mtype = Signal, .stype = ACK_DELIVERED, .command = ""}; + + // Send the information to whom the message got delivered to + strncpy(ack.sender, msgbuf.sender, COMMAND_LENGTH); + send(clients[i].queue_id, &ack); + + // Remove from message buffer by shifting remaining elements + for (int j = message_idx; j < message_buffer_count - 1; j++) { + message_buffer[j] = message_buffer[j + 1]; + } + message_buffer_count--; + break; + } + } + } break; } + } } return 0;