|
Atrinik Server 2.5
|
00001 /************************************************************************ 00002 * Atrinik, a Multiplayer Online Role Playing Game * 00003 * * 00004 * Copyright (C) 2009-2011 Alex Tokar and Atrinik Development Team * 00005 * * 00006 * Fork from Daimonin (Massive Multiplayer Online Role Playing Game) * 00007 * and Crossfire (Multiplayer game for X-windows). * 00008 * * 00009 * This program is free software; you can redistribute it and/or modify * 00010 * it under the terms of the GNU General Public License as published by * 00011 * the Free Software Foundation; either version 2 of the License, or * 00012 * (at your option) any later version. * 00013 * * 00014 * This program is distributed in the hope that it will be useful, * 00015 * but WITHOUT ANY WARRANTY; without even the implied warranty of * 00016 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * 00017 * GNU General Public License for more details. * 00018 * * 00019 * You should have received a copy of the GNU General Public License * 00020 * along with this program; if not, write to the Free Software * 00021 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. * 00022 * * 00023 * The author can be reached at admin@atrinik.org * 00024 ************************************************************************/ 00025 00030 #include <pthread.h> 00031 #include <global.h> 00032 #include <curl/curl.h> 00033 00034 static void *metaserver_thread(void *junk); 00035 00038 typedef struct ms_update_info 00039 { 00042 char num_players[MAX_BUF]; 00043 00046 char csport[MAX_BUF]; 00047 00050 char *players; 00051 } ms_update_info; 00052 00055 pthread_mutex_t ms_info_mutex; 00056 00059 ms_update_info metaserver_info; 00060 00063 void metaserver_info_update() 00064 { 00065 player *pl; 00066 uint32 num_players = 0; 00067 StringBuffer *sb = stringbuffer_new(); 00068 00069 for (pl = first_player; pl; pl = pl->next) 00070 { 00071 if (pl->state != ST_PLAYING) 00072 { 00073 continue; 00074 } 00075 00076 if (!pl->ms_privacy && !pl->dm_stealth) 00077 { 00078 if (sb->pos) 00079 { 00080 stringbuffer_append_string(sb, ":"); 00081 } 00082 00083 stringbuffer_append_string(sb, pl->quick_name); 00084 } 00085 00086 num_players++; 00087 } 00088 00089 pthread_mutex_lock(&ms_info_mutex); 00090 00091 if (metaserver_info.players) 00092 { 00093 free(metaserver_info.players); 00094 } 00095 00096 snprintf(metaserver_info.num_players, sizeof(metaserver_info.num_players), "%u", num_players); 00097 metaserver_info.players = stringbuffer_finish(sb); 00098 pthread_mutex_unlock(&ms_info_mutex); 00099 } 00100 00103 void metaserver_init() 00104 { 00105 int ret; 00106 pthread_t thread_id; 00107 00108 if (!settings.meta_on) 00109 { 00110 return; 00111 } 00112 00113 pthread_mutex_init(&ms_info_mutex, NULL); 00114 00115 memset(&metaserver_info, 0, sizeof(metaserver_info)); 00116 /* Store the port number. */ 00117 snprintf(metaserver_info.csport, sizeof(metaserver_info.csport), "%d", settings.csport); 00118 metaserver_info_update(); 00119 00120 /* Init global cURL */ 00121 curl_global_init(CURL_GLOBAL_ALL); 00122 ret = pthread_create(&thread_id, NULL, metaserver_thread, NULL); 00123 00124 if (ret) 00125 { 00126 LOG(llevError, "metaserver_init(): Failed to create thread: %d.\n", ret); 00127 } 00128 } 00129 00137 static size_t metaserver_writer(void *ptr, size_t size, size_t nmemb, void *data) 00138 { 00139 size_t realsize = size * nmemb; 00140 00141 (void) data; 00142 00143 LOG(llevDebug, "metaserver_writer(): Returned data:\n%s\n", (const char *) ptr); 00144 00145 return realsize; 00146 } 00147 00150 static void metaserver_update() 00151 { 00152 struct curl_httppost *formpost = NULL, *lastptr = NULL; 00153 CURL *curl; 00154 CURLcode res = 0; 00155 00156 /* Hostname. */ 00157 curl_formadd(&formpost, &lastptr, CURLFORM_COPYNAME, "hostname", CURLFORM_COPYCONTENTS, settings.meta_host, CURLFORM_END); 00158 00159 /* Server version. */ 00160 curl_formadd(&formpost, &lastptr, CURLFORM_COPYNAME, "version", CURLFORM_COPYCONTENTS, VERSION, CURLFORM_END); 00161 00162 /* Server comment. */ 00163 curl_formadd(&formpost, &lastptr, CURLFORM_COPYNAME, "text_comment", CURLFORM_COPYCONTENTS, settings.meta_comment, CURLFORM_END); 00164 00165 /* Server name. */ 00166 curl_formadd(&formpost, &lastptr, CURLFORM_COPYNAME, "name", CURLFORM_COPYCONTENTS, settings.meta_name, CURLFORM_END); 00167 00168 pthread_mutex_lock(&ms_info_mutex); 00169 /* Number of players. */ 00170 curl_formadd(&formpost, &lastptr, CURLFORM_COPYNAME, "num_players", CURLFORM_COPYCONTENTS, metaserver_info.num_players, CURLFORM_END); 00171 00172 /* Player names. */ 00173 curl_formadd(&formpost, &lastptr, CURLFORM_COPYNAME, "players", CURLFORM_COPYCONTENTS, metaserver_info.players, CURLFORM_END); 00174 00175 /* Port number. */ 00176 curl_formadd(&formpost, &lastptr, CURLFORM_COPYNAME, "port", CURLFORM_COPYCONTENTS, metaserver_info.csport, CURLFORM_END); 00177 pthread_mutex_unlock(&ms_info_mutex); 00178 00179 /* Init "easy" cURL */ 00180 curl = curl_easy_init(); 00181 00182 if (curl) 00183 { 00184 /* What URL that receives this POST */ 00185 curl_easy_setopt(curl, CURLOPT_URL, settings.meta_server); 00186 curl_easy_setopt(curl, CURLOPT_HTTPPOST, formpost); 00187 00188 /* Almost always, we will get HTTP data returned 00189 * to us - instead of it going to stderr, 00190 * we want to take care of it ourselves. */ 00191 curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, metaserver_writer); 00192 res = curl_easy_perform(curl); 00193 00194 if (res) 00195 { 00196 LOG(llevDebug, "metaserver_update(): easy_perform got error %d (%s).\n", res, curl_easy_strerror(res)); 00197 } 00198 00199 /* Always cleanup */ 00200 curl_easy_cleanup(curl); 00201 } 00202 00203 /* Free the form */ 00204 curl_formfree(formpost); 00205 00206 /* Output info that the data was updated. */ 00207 if (!res) 00208 { 00209 time_t now = time(NULL); 00210 00211 LOG(llevDebug, "metaserver_update(): Sent data at %.19s.\n", ctime(&now)); 00212 } 00213 } 00214 00218 static void *metaserver_thread(void *junk) 00219 { 00220 while (1) 00221 { 00222 metaserver_update(); 00223 sleep(300); 00224 } 00225 00226 (void) junk; 00227 return NULL; 00228 }
1.7.4