25 #include <system_error> 28 #include <sys/types.h> 29 #include <netinet/in.h> 31 #include <arpa/inet.h> 39 #include <curl/curl.h> 40 #include <curl/easy.h> 57 if (pl->ob->map == NULL)
67 if (pl->socket->is_bot)
153 static size_t metaserver2_writer(
void *ptr,
size_t size,
size_t nmemb,
void *data) {
155 size_t realsize = size*nmemb;
156 LOG(
llevError,
"Message from metaserver:\n%s\n", (
const char*)ptr);
160 static void metaserver2_build_form(
struct curl_httppost **formpost) {
161 struct curl_httppost *lastptr = NULL;
170 curl_formadd(formpost, &lastptr,
171 CURLFORM_COPYNAME,
"hostname",
172 CURLFORM_COPYCONTENTS, local_info.
hostname,
175 snprintf(buf,
sizeof(buf),
"%d", local_info.
portnumber);
176 curl_formadd(formpost, &lastptr,
177 CURLFORM_COPYNAME,
"port",
178 CURLFORM_COPYCONTENTS, buf,
181 curl_formadd(formpost, &lastptr,
182 CURLFORM_COPYNAME,
"html_comment",
186 curl_formadd(formpost, &lastptr,
187 CURLFORM_COPYNAME,
"text_comment",
191 curl_formadd(formpost, &lastptr,
192 CURLFORM_COPYNAME,
"archbase",
193 CURLFORM_COPYCONTENTS, local_info.
archbase,
196 curl_formadd(formpost, &lastptr,
197 CURLFORM_COPYNAME,
"mapbase",
198 CURLFORM_COPYCONTENTS, local_info.
mapbase,
201 curl_formadd(formpost, &lastptr,
202 CURLFORM_COPYNAME,
"codebase",
203 CURLFORM_COPYCONTENTS, local_info.
codebase,
206 curl_formadd(formpost, &lastptr,
207 CURLFORM_COPYNAME,
"flags",
208 CURLFORM_COPYCONTENTS, local_info.
flags,
213 snprintf(buf,
sizeof(buf),
"%d", metaserver2_updateinfo.
num_players);
214 curl_formadd(formpost, &lastptr,
215 CURLFORM_COPYNAME,
"num_players",
216 CURLFORM_COPYCONTENTS, buf,
219 snprintf(buf,
sizeof(buf),
"%d", metaserver2_updateinfo.
in_bytes);
220 curl_formadd(formpost, &lastptr,
221 CURLFORM_COPYNAME,
"in_bytes",
222 CURLFORM_COPYCONTENTS, buf,
225 snprintf(buf,
sizeof(buf),
"%d", metaserver2_updateinfo.
out_bytes);
226 curl_formadd(formpost, &lastptr,
227 CURLFORM_COPYNAME,
"out_bytes",
228 CURLFORM_COPYCONTENTS, buf,
231 snprintf(buf,
sizeof(buf),
"%ld", (
long)metaserver2_updateinfo.
uptime);
232 curl_formadd(formpost, &lastptr,
233 CURLFORM_COPYNAME,
"uptime",
234 CURLFORM_COPYCONTENTS, buf,
242 curl_formadd(formpost, &lastptr,
243 CURLFORM_COPYNAME,
"version",
248 curl_formadd(formpost, &lastptr,
249 CURLFORM_COPYNAME,
"sc_version",
250 CURLFORM_COPYCONTENTS, buf,
254 curl_formadd(formpost, &lastptr,
255 CURLFORM_COPYNAME,
"cs_version",
256 CURLFORM_COPYCONTENTS, buf,
268 struct curl_httppost *formpost = NULL;
269 metaserver2_build_form(&formpost);
272 CURL *curl = curl_easy_init();
274 curl_easy_setopt(curl, CURLOPT_TIMEOUT, 30000);
277 curl_easy_setopt(curl, CURLOPT_URL,
hostname.c_str());
278 curl_easy_setopt(curl, CURLOPT_HTTPPOST, formpost);
284 curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, metaserver2_writer);
286 char errbuf[CURL_ERROR_SIZE];
287 curl_easy_setopt(curl, CURLOPT_ERRORBUFFER, errbuf);
289 CURLcode res = curl_easy_perform(curl);
291 LOG(
llevError,
"metaserver update failed: %s\n", errbuf);
295 curl_easy_cleanup(curl);
297 LOG(
llevError,
"metaserver: could not initialize curl\n");
301 curl_formfree(formpost);
338 static int has_init = 0;
344 curl_global_init(CURL_GLOBAL_ALL);
359 if (local_info.
flags)
368 if ((fp = fopen(buf,
"r")) == NULL) {
372 while (fgets(buf,
sizeof(buf), fp) != NULL) {
376 if ((cp = strrchr(buf,
'\n')) != NULL)
385 if ((cp = strpbrk(buf,
" \t")) != NULL) {
395 if (!
strcasecmp(buf,
"metaserver2_notification")) {
401 LOG(
llevError,
"metaserver2: Unknown value for metaserver2_notification: %s\n", cp);
403 }
else if (!
strcasecmp(buf,
"metaserver2_server")) {
407 LOG(
llevError,
"metaserver2: metaserver2_server must have a value.\n");
409 }
else if (!
strcasecmp(buf,
"localhostname")) {
413 LOG(
llevError,
"metaserver2: localhostname must have a value.\n");
419 LOG(
llevError,
"metaserver2: portnumber must have a value.\n");
425 }
else if (!
strcasecmp(buf,
"html_comment")) {
427 }
else if (!
strcasecmp(buf,
"text_comment")) {
432 local_info.
mapbase = strdup(cp);
436 local_info.
flags = strdup(cp);
438 LOG(
llevError,
"Unknown value in metaserver2 file: %s\n", buf);
449 LOG(
llevError,
"metaserver2 file is set to do notification, but libcurl is not found.\n");
450 LOG(
llevError,
"Either fix your compilation, or turn off metaserver2 notification in \n");
470 local_info.
mapbase = strdup(
"");
473 if (!local_info.
flags)
474 local_info.
flags = strdup(
"");
480 catch (
const std::system_error &err) {
481 LOG(
llevError,
"metaserver2_init: failed to create thread, code %d, what %s\n", err.code().value(), err.what());
#define ST_GET_PARTY_PASSWORD
Player tried to join a password-protected party.
void LOG(LogLevel logLevel, const char *format,...)
Logs a message to stderr, or to file.
player * first_player
First player.
uint16_t csport
Port for new client/server.
#define FLAG_AFK
Player is AFK.
Global type definitions and header inclusions.
#define ST_PLAYING
Usual state.
player * next
Pointer to next player, NULL if this is last.
#define QUERY_FLAG(xyz, p)
int ibytes
ibytes, obytes are bytes in, out.
int strcasecmp(const char *s1, const char *s2)
struct Settings settings
Global settings.
#define VERSION_CS
Version >= 1023 understand setup cmd.
#define FLAG_WIZ
Object has special privilegies.
long seconds(void)
Return wall clock time in seconds.
#define MAX_BUF
Used for all kinds of things.
const char * confdir
Configuration files.
#define FREE_AND_CLEAR(xyz)
Free the pointer and then set it to NULL.