diff --git a/src/server/cmds/private_conversation/cmd_messages.c b/src/server/cmds/private_conversation/cmd_messages.c new file mode 100644 index 0000000..eb7870d --- /dev/null +++ b/src/server/cmds/private_conversation/cmd_messages.c @@ -0,0 +1,69 @@ +/* +** EPITECH PROJECT, 2024 +** my_teams +** File description: +** cmd_messages +*/ + +#include +#include +#include +#include +#include +#include + +#include "cmds/cmds_utils.h" +#include "command.h" +#include "private_parts.h" +#include "ressources_infos.h" +#include "server.h" + +static discussion_t *get_conv(server_t *server, uuid_t uuid1, uuid_t uuid2) +{ + discussion_t *discussion = NULL; + + for (size_t i = 0; i < server->discussions.size; i++) { + discussion = &server->discussions.arr[i]; + if ((uuid_compare(discussion->user_1uuid, uuid1) == 0 && + uuid_compare(discussion->user_2uuid, uuid2) == 0) || + (uuid_compare(discussion->user_1uuid, uuid2) == 0 && + uuid_compare(discussion->user_2uuid, uuid1) == 0)) + return discussion; + } + return NULL; +} + +static void send_list(client_t *client, discussion_t *discussion) +{ + message_info_t info = {0}; + message_t *mess = NULL; + + dprintf(client->fd, "226"); + fsync(client->fd); + write(client->fd, + &discussion->messages.size, sizeof(discussion->messages.size)); + for (size_t i = 0; i < discussion->messages.size; i++) { + mess = &discussion->messages.arr[i]; + uuid_copy(info.sender_uuid, mess->sender_uuid); + info.timestamp = mess->timestamp; + strncpy(info.body, mess->body, MAX_BODY_LENGTH); + write(client->fd, &info, sizeof(info)); + } +} + +void cmd_messages(server_t *server, client_t *client) +{ + uuid_t uuid = {0}; + size_t arg_pos = 0; + discussion_t *discussion = NULL; + + if (!server || !client || !is_logged_in(client)) + return; + if (!get_uuid(server, client, &uuid, &arg_pos)) + return; + discussion = get_conv(server, client->user, uuid); + if (!discussion) + return; + printf("fjdhskfhsdkj\n"); + send_list(client, discussion); +} diff --git a/src/server/cmds/private_conversation/cmd_send.c b/src/server/cmds/private_conversation/cmd_send.c new file mode 100644 index 0000000..d309031 --- /dev/null +++ b/src/server/cmds/private_conversation/cmd_send.c @@ -0,0 +1,86 @@ +/* +** EPITECH PROJECT, 2024 +** my_teams +** File description: +** cmd_send +*/ + +#include +#include +#include +#include +#include +#include +#include + +#include "cmds/cmds_utils.h" +#include "command.h" +#include "private_parts.h" +#include "ressources_infos.h" +#include "server.h" +#include "utils.h" + +static void send_to_user(server_t *server, message_t *message, uuid_t receive) +{ + message_info_t info = {0}; + + uuid_copy(info.sender_uuid, message->sender_uuid); + info.timestamp = message->timestamp; + strcpy(info.body, message->body); + for (size_t i = 0; i < server->clients.size; i++) { + if (uuid_compare(server->clients.arr[i].user, receive) == 0) { + write(server->clients.arr[i].fd, "320", 3); + write(server->clients.arr[i].fd, &info, sizeof(info)); + } + } +} + +static bool send_message( + server_t *server, client_t *client, message_t *message, uuid_t uuid) +{ + discussion_t *disc = get_discussion(server, message->sender_uuid, uuid); + char sender[UUID_STR_LEN] = {0}; + char receiver[UUID_STR_LEN] = {0}; + + if (uuid_is_null(disc->user_1uuid) || uuid_is_null(disc->user_2uuid)) { + uuid_copy(disc->user_1uuid, client->user); + uuid_copy(disc->user_2uuid, uuid); + } + append_to_array(&disc->messages, sizeof(message_t), message); + uuid_unparse(client->user, sender); + uuid_unparse(uuid, receiver); + server_event_private_message_sended(sender, receiver, message->body); + send_to_user(server, message, uuid); + return true; +} + +static bool create_message( + server_t *server, client_t *client, uuid_t uuid, size_t *arg_pos) +{ + message_t message = {0}; + char *description = NULL; + + uuid_copy(message.sender_uuid, client->user); + message.timestamp = time(NULL); + description = get_quoted_arg(client->buffer, *arg_pos, arg_pos); + if (description == NULL) { + dprintf(client->fd, "502 Syntax error.\n"); + return false; + } + strncpy(message.body, description, MAX_BODY_LENGTH); + send_message(server, client, &message, uuid); + return true; +} + +void cmd_send(server_t *server, client_t *client) +{ + uuid_t uuid = {0}; + size_t arg_pos = 0; + + if (!server || !client || !is_logged_in(client)) + return; + if (!get_uuid(server, client, &uuid, &arg_pos)) + return; + if (!create_message(server, client, uuid, &arg_pos)) + return; +} diff --git a/src/server/cmds/private_conversation/private_parts.c b/src/server/cmds/private_conversation/private_parts.c new file mode 100644 index 0000000..2ca6c86 --- /dev/null +++ b/src/server/cmds/private_conversation/private_parts.c @@ -0,0 +1,54 @@ +/* +** EPITECH PROJECT, 2024 +** my_teams +** File description: +** private_parts +*/ + +#include "private_parts.h" +#include "cmds/cmds_utils.h" +#include "server.h" +#include + +discussion_t *get_discussion( + server_t *server, uuid_t uuid1, uuid_t uuid2) +{ + discussion_t *discussion = NULL; + discussion_t new = {0}; + + for (size_t i = 0; i < server->discussions.size; i++) { + discussion = &server->discussions.arr[i]; + if ((uuid_compare(discussion->user_1uuid, uuid1) == 0 && + uuid_compare(discussion->user_2uuid, uuid2) == 0) || + (uuid_compare(discussion->user_1uuid, uuid2) == 0 && + uuid_compare(discussion->user_2uuid, uuid1) == 0)) + return discussion; + } + append_to_array(&server->discussions, sizeof(discussion_t), &new); + return &server->discussions.arr[server->discussions.size - 1]; +} + +bool user_exist( + server_t *server, client_t *client, uuid_t uuid, char *uuid_str) +{ + if (get_user_by_uuid(server, uuid)) + return true; + write(client->fd, "514", 3); + write(client->fd, uuid_str, UUID_STR_LEN); + return false; +} + +bool get_uuid( + server_t *server, client_t *client, uuid_t *uuid, size_t *arg_pos) +{ + char *arg1 = NULL; + + arg1 = get_quoted_arg(client->buffer, 0, arg_pos); + if (!arg1) { + dprintf(client->fd, "502 Syntax error.\n"); + return false; + } + *arg_pos += 1; + uuid_parse(arg1, *uuid); + return user_exist(server, client, *uuid, arg1); +} diff --git a/src/server/cmds/private_conversation/private_parts.h b/src/server/cmds/private_conversation/private_parts.h new file mode 100644 index 0000000..7b55ecf --- /dev/null +++ b/src/server/cmds/private_conversation/private_parts.h @@ -0,0 +1,18 @@ +/* +** EPITECH PROJECT, 2024 +** my_teams +** File description: +** private_parts +*/ + +#pragma once + +#include "server.h" +#include + +discussion_t *get_discussion( + server_t *server, uuid_t uuid1, uuid_t uuid2); +bool user_exist( + server_t *server, client_t *client, uuid_t uuid, char *uuid_str); +bool get_uuid( + server_t *server, client_t *client, uuid_t *uuid, size_t *arg_pos); diff --git a/src/server/command.h b/src/server/command.h index 29d070e..9a8c1d5 100644 --- a/src/server/command.h +++ b/src/server/command.h @@ -27,6 +27,9 @@ void cmd_subscribed(server_t *server, client_t *client); void cmd_info(server_t *server, client_t *client); +void cmd_send(server_t *server, client_t *client); +void cmd_messages(server_t *server, client_t *client); + static const struct cmd_s { char *name; void (*func)(server_t *server, client_t *client); @@ -39,8 +42,9 @@ static const struct cmd_s { {"LIST", cmd_list, "based on the context, list all the sub resources"}, {"LOGIN", cmd_login, "set the user_name used by client"}, {"LOGOUT", cmd_logout, "disconnect the client from the server"}, - {"MESSAGES", NULL, "list all messages exchanged with the specified user"}, - {"SEND", NULL, "send a message to specific user"}, + {"MESSAGES", cmd_messages, "list all messages exchanged with the " + "specified user"}, + {"SEND", cmd_send, "send a message to specific user"}, {"SUBSCRIBE", cmd_subscribe, "subscribe to the events of a team and its " "sub directories (enable reception of all events from a team)"}, {"SUBSCRIBED", cmd_subscribed, "list all subscribed teams or list all " diff --git a/src/server/server.h b/src/server/server.h index 8fc02a3..5989236 100644 --- a/src/server/server.h +++ b/src/server/server.h @@ -64,12 +64,19 @@ typedef struct { } team_t; typedef struct { - uuid_t uuid; + uuid_t sender_uuid; + char body[MAX_BODY_LENGTH]; + time_t timestamp; +} message_t; + +typedef struct { + uuid_t user_1uuid; + uuid_t user_2uuid; struct { size_t size; size_t alloc; - uuid_t *arr; - } users; + message_t *arr; + } messages; } discussion_t; typedef struct { @@ -96,8 +103,9 @@ typedef struct { team_t *arr; } teams; struct { - discussion_t *arr; size_t size; + size_t alloc; + discussion_t *arr; } discussions; struct { size_t size;