Coverage report for ai


src/
File: src/client/Client.cpp
Date: 2024-06-25 10:57:00
Lines:
0/123
0.0%
Functions:
0/15
0.0%
Branches:
0/178
0.0%

Line Branch Exec Source
1 /*
2 ** EPITECH PROJECT, 2024
3 ** zappy/ai/client
4 ** File description:
5 ** Client.cpp
6 */
7
8 #include "Client.hpp"
9
10 ✗ Client::Client(const std::string &host, const std::string &teamName, int port)
11 ✗ : _host(host), _teamName(teamName), _port(port)
12 {
13 ✗ setupConnection();
14 ✗ }
15
16 ✗ Client::~Client()
17 {
18 ✗ close(_sockfd);
19 ✗ }
20
21 ✗ void Client::run()
22 {
23 ✗ printColor("Run client\n\n", BRIGHT_BLUE);
24
25 ✗ authenticate();
26 ✗ loop();
27 }
28
29 ✗ void Client::setupConnection()
30 {
31 ✗ _sockfd = socket(AF_INET, SOCK_STREAM, 0);
32 ✗ if (_sockfd < 0)
33 {
34 ✗ perror("Socket creation failed");
35 ✗ exit(EXIT_FAILURE);
36 }
37
38 ✗ struct sockaddr_in serv_addr;
39
40 ✗ serv_addr.sin_family = AF_INET;
41 ✗ serv_addr.sin_port = htons(_port);
42 ✗ if (inet_pton(AF_INET, _host.c_str(), &serv_addr.sin_addr) <= 0)
43 {
44 ✗ perror("Invalid address or address not supported");
45 ✗ exit(EXIT_FAILURE);
46 }
47 ✗ if (connect(_sockfd, (struct sockaddr *)&serv_addr, sizeof(serv_addr)) < 0)
48 {
49 ✗ perror("Connection failed");
50 ✗ exit(EXIT_FAILURE);
51 }
52 else
53 ✗ printColor("🚀✅ Connected to server: " + _host + ":" + std::to_string(_port) + " on team: " + _teamName + "\n", BRIGHT_BLUE);
54 ✗ }
55
56 ✗ void Client::authenticate()
57 {
58 std::string buffer;
59 ✗ Message _message;
60 ✗ unsigned int timeToGetIdentity = 0;
61 ✗ std::string askForIdentity = "";
62
63 // To pass the first message WELCOME
64 ✗ recvMessage(buffer);
65
66 // Ask two time for identity
67 ✗ _message.format("I'm_searching_my_identity");
68 ✗ askForIdentity = "Broadcast " + _message.content;
69 ✗ sendMessage(_teamName);
70 ✗ sendMessage(askForIdentity);
71 ✗ sendMessage(askForIdentity);
72 _message.content = "";
73
74 auto condition = [&]()
75 ✗ { return timeToGetIdentity < 3; };
76
77 ✗ auto action = [&]()
78 {
79 std::string response;
80 ✗ recvMessage(response);
81 ✗ if (response.find("ko") != std::string::npos)
82 {
83 ✗ PRINT_ERROR("Authentication failed: verify teamName");
84 ✗ close(_sockfd);
85 ✗ exit(EXIT_FAILURE);
86 }
87 ✗ if (response.find("message") != std::string::npos)
88 {
89 ✗ _message.content = response;
90 ✗ _message.vigenereDecrypt();
91 return;
92 }
93 ✗ timeToGetIdentity++;
94 ✗ _messageToReadBeforeStart--;
95 ✗ };
96 ✗ interactWithServer(condition, action);
97 try
98 {
99 ✗ initBot(_message.content);
100 }
101 ✗ catch (const ClientException &e)
102 {
103 ✗ PRINT_ERROR(e.what());
104 ✗ close(_sockfd);
105 ✗ exit(EXIT_FAILURE);
106 ✗ }
107 ✗ }
108
109 ✗ void Client::initBot(const std::string identityMessage)
110 {
111 unsigned int id = 0;
112 unsigned int currentMessageId = 0;
113
114 ✗ if (!identityMessage.empty())
115 {
116 ✗ std::cout << "identityMessage: " << identityMessage << std::endl;
117 ✗ std::string job = "";
118 ✗ std::string prefixId = "you_are_bot=";
119 ✗ std::string prefixJob = "your_job=";
120 ✗ std::string prefixCurrentMessageId = "currentMessageId=";
121 size_t pos = identityMessage.find(prefixId);
122 size_t posJob = identityMessage.find(prefixJob);
123 size_t posCurrentMessageId = identityMessage.find(prefixCurrentMessageId);
124
125 ✗ if (pos != std::string::npos)
126 {
127 ✗ std::string idStr = identityMessage.substr(pos + prefixId.size());
128 ✗ id = std::stoi(idStr);
129 }
130 ✗ if (posCurrentMessageId != std::string::npos)
131 {
132 ✗ std::string currentMessageIdStr = identityMessage.substr(posCurrentMessageId + prefixCurrentMessageId.size());
133 ✗ currentMessageId = std::stoi(currentMessageIdStr);
134 }
135 ✗ if (posJob != std::string::npos)
136 {
137 ✗ job = identityMessage.substr(posJob + prefixJob.size());
138 ✗ if (job.find("SIMPLE_BOT") != std::string::npos)
139 ✗ _bot = BotFactory::createBot("SimpleBot");
140 }
141 else
142 {
143 ✗ _bot = BotFactory::createBot("SimpleBot");
144 }
145 }
146 else
147 {
148 ✗ _bot = BotFactory::createBot("SimpleBot"); // TODO: is forker normally
149 ✗ if (_bot == nullptr)
150 ✗ throw ClientException("BotFactory failed");
151 }
152 ✗ if (_bot != nullptr)
153 {
154 ✗ _bot->init(_sockfd, _teamName, _host, _port, id, currentMessageId);
155 }
156 else
157 {
158 ✗ throw ClientException("Bot is null");
159 }
160 ✗ }
161
162 ✗ void Client::sendMessage(const std::string &message)
163 {
164 ✗ std::string messageToSend = message + "\n";
165
166 ✗ send(_sockfd, messageToSend.c_str(), messageToSend.size(), 0);
167 ✗ }
168
169 ✗ void Client::loop()
170 {
171 // clear messsages of servers before start
172 auto condition = [&]()
173 ✗ { return _messageToReadBeforeStart > 0; };
174 ✗ auto action = [&]()
175 {
176 std::string response;
177 ✗ recvMessage(response);
178 ✗ _messageToReadBeforeStart--;
179 ✗ };
180 ✗ interactWithServer(condition, action);
181
182 ✗ _bot->run("start");
183 auto conditionStart = [&]()
184 { return true; };
185 ✗ auto actionStart = [&]()
186 {
187 std::string response;
188 ✗ recvMessage(response);
189 ✗ _bot->run(response);
190 ✗ };
191 ✗ interactWithServer(conditionStart, actionStart);
192 }
193
194 ✗ void Client::recvMessage(std::string &buffer)
195 {
196 ✗ char recvBuffer[1024] = {0};
197 ✗ int valread = read(_sockfd, recvBuffer, 1024);
198
199 ✗ if (valread < 0)
200 {
201 ✗ PRINT_ERROR("Read failed");
202 ✗ close(_sockfd);
203 ✗ exit(FAILURE);
204 }
205 ✗ else if (valread == 0)
206 {
207 ✗ PRINT_ERROR("Server closed the connection");
208 ✗ close(_sockfd);
209 ✗ exit(FAILURE);
210 }
211
212 ✗ buffer = std::string(recvBuffer, valread);
213 ✗ }
214
215 template <typename ConditionFunc, typename ActionFunc>
216 ✗ void Client::interactWithServer(ConditionFunc condition, ActionFunc action)
217 {
218 ✗ while (condition())
219 {
220 ✗ FD_ZERO(&_readfds);
221 ✗ FD_SET(_sockfd, &_readfds);
222 ✗ _tv.tv_sec = 0;
223 ✗ _tv.tv_usec = 10000;
224 ✗ int activity = select(_sockfd + 1, &_readfds, NULL, NULL, &_tv);
225
226 ✗ if (activity > 0 && FD_ISSET(_sockfd, &_readfds))
227 ✗ action();
228 }
229 ✗ }
230