Finish ACKs

This commit is contained in:
2026-01-26 23:21:34 +01:00
parent 6ecbdfa9fa
commit 20df30ace8
2 changed files with 63 additions and 19 deletions
+9 -5
View File
@@ -278,9 +278,13 @@ int main(int argc, char *argv[]) {
} }
switch (incoming.mtype) { switch (incoming.mtype) {
case Message: case Message: {
printf("%s: %s\n", incoming.sender, incoming.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; break;
}
case List: { case List: {
// Check the command field for the list type // Check the command field for the list type
if (strncmp(incoming.command, "active", COMMAND_LENGTH) == 0) { if (strncmp(incoming.command, "active", COMMAND_LENGTH) == 0) {
@@ -316,14 +320,14 @@ int main(int argc, char *argv[]) {
case Signal: case Signal:
// Tell the user if the previous message was accepted and/or delivered // Tell the user if the previous message was accepted and/or delivered
if (incoming.stype == ACK_ACCEPTED) { if (incoming.stype == ACK_ACCEPTED) {
printf("Message sent successfully.\n"); printf("[Sent]\n");
} else if (incoming.stype == ACK_DELIVERED) { } 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) { } 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 { } else {
// Display whatever if I forgot to handle something // Display whatever if I forgot to handle something
printf("Unhandled signal - code %d.\n", incoming.stype); printf("[Error: Code %d]\n", incoming.stype);
} }
break; break;
case JoinGroup: case JoinGroup:
+54 -14
View File
@@ -65,7 +65,7 @@ static void handle_hearbeat_timeouts(Client_t *clients, int client_count, int se
} }
sem_op.sem_op = 1; sem_op.sem_op = 1;
semop(semaphore_id, &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); Client_t *clients = shmat(clients_memory_id, NULL, 0);
Group_t *groups = malloc(sizeof(Group_t) * group_count); 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); int semaphore_id = semget(IPC_PRIVATE, 1, IPC_CREAT | 0666);
semctl(semaphore_id, 0, SETVAL, 1); semctl(semaphore_id, 0, SETVAL, 1);
@@ -294,8 +299,8 @@ int main(int argc, char **argv) {
} }
if (has_muted_group) { if (has_muted_group) {
printf("Group message to %s blocked (group %s is muted)\n", printf("Group message to %s blocked (group %s is muted)\n", target_group->members[i]->nickname,
target_group->members[i]->nickname, target_group->name); target_group->name);
continue; continue;
} }
@@ -346,7 +351,7 @@ int main(int argc, char **argv) {
if (is_muted) { if (is_muted) {
printf("Message from %s to %s blocked (muted)\n", client->nickname, target_client->nickname); 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 // 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->sender, client->nickname, COMMAND_LENGTH);
strncpy(saved_msg->message, msgbuf.message, MESSAGE_LENGTH); strncpy(saved_msg->message, msgbuf.message, MESSAGE_LENGTH);
msgbuf_t response = { msgbuf_t response = {
.mtype = Message, .mtype = Signal,
.stype = ACK_ACCEPTED, .stype = ACK_ACCEPTED,
}; };
send(client->queue_id, &response); send(client->queue_id, &response);
@@ -380,10 +385,20 @@ int main(int argc, char **argv) {
.mtype = Message, .mtype = Message,
.sender = "", .sender = "",
}; };
get_id(forward_msg.command);
strncpy(forward_msg.sender, client->nickname, COMMAND_LENGTH); strncpy(forward_msg.sender, client->nickname, COMMAND_LENGTH);
strncpy(forward_msg.message, msgbuf.message, MESSAGE_LENGTH); strncpy(forward_msg.message, msgbuf.message, MESSAGE_LENGTH);
send(target_client->queue_id, &forward_msg); 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.stype = ACK_ACCEPTED;
forward_msg.mtype = Signal; forward_msg.mtype = Signal;
send(client->queue_id, &forward_msg); send(client->queue_id, &forward_msg);
@@ -588,16 +603,12 @@ int main(int argc, char **argv) {
// Check if user is already in the group // Check if user is already in the group
bool is_in_group = false; 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++) { for (int i = 0; i < target_group->client_count; i++) {
if (target_group->members[i] != NULL) { 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) { if (strncmp(client->id, target_group->members[i]->id, COMMAND_LENGTH) == 0) {
is_in_group = true; is_in_group = true;
break; break;
} }
} else {
printf(" Slot %d: NULL\n", i);
} }
} }
@@ -650,7 +661,6 @@ int main(int argc, char **argv) {
Group_t *target_group = NULL; Group_t *target_group = NULL;
for (int i = 0; i < group_count; i++) { 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) { if (strcmp(groups[i].name, msgbuf.command) == 0) {
target_group = &groups[i]; target_group = &groups[i];
break; break;
@@ -708,7 +718,7 @@ int main(int argc, char **argv) {
// Check if muting a group (starts with #) or a user // Check if muting a group (starts with #) or a user
if (msgbuf.command[0] == '#') { if (msgbuf.command[0] == '#') {
// Muting a group // Muting a group
char *group_name = msgbuf.command + 1; // Skip the # char *group_name = msgbuf.command + 1; // Skip the #
// Find the group // Find the group
Group_t *target_group = NULL; Group_t *target_group = NULL;
@@ -863,11 +873,41 @@ int main(int argc, char **argv) {
} }
break; break;
} }
case Signal: case Signal: {
// Signals are sent from server to client, not the other way around // Handle the delivery signal from the recipent
// so we ignore them here lol 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; break;
} }
}
} }
return 0; return 0;