Line |
Branch |
Exec |
Source |
1 |
|
|
/* |
2 |
|
|
** EPITECH PROJECT, 2024 |
3 |
|
|
** zappy |
4 |
|
|
** File description: |
5 |
|
|
** handle.c |
6 |
|
|
*/ |
7 |
|
|
|
8 |
|
|
#include "server.h" |
9 |
|
|
#include <string.h> |
10 |
|
|
#include <sys/types.h> |
11 |
|
|
|
12 |
|
✗ |
static int accept_new_client(server_t *server) |
13 |
|
|
{ |
14 |
|
✗ |
struct sockaddr_in info; |
15 |
|
✗ |
socklen_t addrlen = sizeof(info); |
16 |
|
✗ |
int client_fd = accept(server->fd, (struct sockaddr *)&info, &addrlen); |
17 |
|
|
|
18 |
|
✗ |
if (client_fd < 0) { |
19 |
|
✗ |
perror("Accept failed"); |
20 |
|
✗ |
return -1; |
21 |
|
|
} |
22 |
|
|
return client_fd; |
23 |
|
|
} |
24 |
|
|
|
25 |
|
✗ |
int create_new_client(server_t *server) |
26 |
|
|
{ |
27 |
|
✗ |
int client_fd = accept_new_client(server); |
28 |
|
|
client_list_t *new_client; |
29 |
|
|
|
30 |
|
✗ |
if (client_fd == -1) |
31 |
|
|
return ERROR_STATUS; |
32 |
|
|
dprintf(client_fd, "WELCOME\n"); |
33 |
|
✗ |
new_client = malloc(sizeof(client_list_t)); |
34 |
|
✗ |
if (!new_client) { |
35 |
|
✗ |
perror("Malloc while creating a client failed"); |
36 |
|
✗ |
return ERROR_STATUS; |
37 |
|
|
} |
38 |
|
✗ |
new_client->client = init_client(client_fd); |
39 |
|
✗ |
if (!new_client->client) { |
40 |
|
✗ |
free(new_client); |
41 |
|
✗ |
return ERROR_STATUS; |
42 |
|
|
} |
43 |
|
✗ |
TAILQ_INSERT_TAIL(&server->clients, new_client, entries); |
44 |
|
✗ |
FD_SET(client_fd, &server->current_sockets); |
45 |
|
✗ |
return OK_STATUS; |
46 |
|
|
} |
47 |
|
|
|
48 |
|
✗ |
client_t *get_client(struct client_tailq *clients, int client_fd) |
49 |
|
|
{ |
50 |
|
|
client_list_t *item; |
51 |
|
|
|
52 |
|
✗ |
TAILQ_FOREACH(item, clients, entries) { |
53 |
|
✗ |
if (item->client->fd == client_fd) { |
54 |
|
|
return item->client; |
55 |
|
|
} |
56 |
|
|
} |
57 |
|
|
return NULL; |
58 |
|
|
} |
59 |
|
|
|
60 |
|
✗ |
static int handle_quit_client( |
61 |
|
|
client_t *client, |
62 |
|
|
server_t *server, |
63 |
|
|
ssize_t check_read, |
64 |
|
|
int client_fd |
65 |
|
|
) |
66 |
|
|
{ |
67 |
|
|
egg_t *egg; |
68 |
|
|
eggs_list_t *item_e; |
69 |
|
|
team_t *team; |
70 |
|
|
|
71 |
|
✗ |
if (check_read != 0) |
72 |
|
|
return NEUTRAL_VALUE; |
73 |
|
✗ |
if (client->is_graphic == false && client->is_connected == true) { |
74 |
|
✗ |
message_to_graphicals(server, "pdi %d\n", client->id); |
75 |
|
✗ |
egg = init_egg(client->x, client->y); |
76 |
|
✗ |
item_e = malloc(sizeof(eggs_list_t)); |
77 |
|
✗ |
if (item_e == NULL) |
78 |
|
|
return ERROR_STATUS; |
79 |
|
✗ |
team = get_team_by_name(&server->teams, client->team_name); |
80 |
|
✗ |
item_e->egg = egg; |
81 |
|
✗ |
TAILQ_INSERT_TAIL(&team->eggs, item_e, entries); |
82 |
|
|
} |
83 |
|
✗ |
close(client_fd); |
84 |
|
✗ |
FD_CLR(client_fd, &server->current_sockets); |
85 |
|
✗ |
remove_client_by_fd(&server->clients, client_fd); |
86 |
|
✗ |
return OK_STATUS; |
87 |
|
|
} |
88 |
|
|
|
89 |
|
✗ |
static ssize_t read_until_newline( |
90 |
|
|
int client_fd, |
91 |
|
|
char *buffer, |
92 |
|
|
size_t buffer_size |
93 |
|
|
) |
94 |
|
|
{ |
95 |
|
|
ssize_t total_read = 0; |
96 |
|
|
ssize_t bytes_read; |
97 |
|
|
|
98 |
|
✗ |
while (total_read < (ssize_t)buffer_size - 1) { |
99 |
|
✗ |
bytes_read = read(client_fd, buffer + total_read, 1); |
100 |
|
✗ |
if (bytes_read < 0) |
101 |
|
|
return -1; |
102 |
|
✗ |
if (bytes_read == 0) |
103 |
|
|
break; |
104 |
|
✗ |
total_read += bytes_read; |
105 |
|
✗ |
if (buffer[total_read - 1] == '\n') |
106 |
|
|
break; |
107 |
|
|
} |
108 |
|
✗ |
buffer[total_read] = '\0'; |
109 |
|
✗ |
return total_read; |
110 |
|
|
} |
111 |
|
|
|
112 |
|
✗ |
int handle_client_data(server_t *server, int client_fd) |
113 |
|
|
{ |
114 |
|
✗ |
client_t *client = get_client(&server->clients, client_fd); |
115 |
|
|
ssize_t check_read; |
116 |
|
|
int quit_status; |
117 |
|
|
|
118 |
|
✗ |
if (!client) |
119 |
|
|
return ERROR_STATUS; |
120 |
|
✗ |
memset(client->message, '\0', sizeof(client->message)); |
121 |
|
✗ |
check_read = read_until_newline(client_fd, |
122 |
|
|
client->message, sizeof(client->message)); |
123 |
|
✗ |
if (check_read < 0) { |
124 |
|
✗ |
close(client_fd); |
125 |
|
✗ |
return ERROR_STATUS; |
126 |
|
|
} |
127 |
|
✗ |
quit_status = handle_quit_client(client, server, check_read, client_fd); |
128 |
|
✗ |
if (quit_status == OK_STATUS) |
129 |
|
|
return OK_STATUS; |
130 |
|
✗ |
if (client->is_connected && quit_status == ERROR_STATUS) |
131 |
|
|
return ERROR_STATUS; |
132 |
|
✗ |
handle_client_message(client, server); |
133 |
|
✗ |
return OK_STATUS; |
134 |
|
|
} |
135 |
|
|
|