X-Git-Url: http://git.pk910.de/?p=NeonServV5.git;a=blobdiff_plain;f=src%2Fmodules%2Fstats.mod%2Fmodule.c;fp=src%2Fmodules%2Fstats.mod%2Fmodule.c;h=ee8a20d98b2436156e845b4d196eb277262e8ff1;hp=0000000000000000000000000000000000000000;hb=406c308308e4d131475a692cd425cb156e0776f1;hpb=7d9422966272d2d0998280521a8347d42bd8e1cb diff --git a/src/modules/stats.mod/module.c b/src/modules/stats.mod/module.c new file mode 100644 index 0000000..ee8a20d --- /dev/null +++ b/src/modules/stats.mod/module.c @@ -0,0 +1,167 @@ +/* module.c - NeonServ v5.4 + * Copyright (C) 2011-2012 Philipp Kreil (pk910) + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ +#include "../module.h" +#include "../../timeq.h" +#include "../../ConfigParser.h" +#include "../../mysqlConn.h" +#include "../../ClientSocket.h" +#include "../../UserNode.h" + +#define STATS_UPDATE_SECONDS 1800 +#define STATS_UPDATE_HOST "neonserv.krypton-bouncer.de" +#define STATS_UPDATE_PORT 1675 +#define STATS_IDENTIFIER_LEN 10 +#define STATS_IDENTIFIER_POOL "abcdefghijklmnopqrstuvwxyz0123456789#*+-_.:;,!ยง$%&/()=?[]{}<>|@" +#define STATS_IDENTIFIER_POOL_SIZE 63 + +static TIMEQ_CALLBACK(stats_timer_callback); + +static int module_initialize() { + return 0; +} + +static void module_start(int type) { + if(!timeq_name_exists("stats")) + timeq_add_name("stats", 60, module_id, stats_timer_callback, NULL); +} + +static void module_loop() { + +} + +static void module_stop(int type) { + timeq_del_name("stats"); +} + +static char *get_identifier() { + MYSQL_RES *res; + MYSQL_ROW row; + printf_mysql_query("SELECT `value` FROM `settings` WHERE `name` = 'identifier'"); + res = mysql_use(); + if(!(row = mysql_fetch_row(res))) { + srand(time(NULL)); + char identifier[STATS_IDENTIFIER_LEN+1]; + int i; + char *pool = STATS_IDENTIFIER_POOL; + for(i = 0; i < STATS_IDENTIFIER_LEN; i++) { + identifier[i] = pool[(rand() % STATS_IDENTIFIER_POOL_SIZE)]; + } + identifier[i] = 0; + printf_mysql_query("INSERT INTO `settings` (`name`, `value`) VALUES ('identifier', '%s')", escape_string(identifier)); + printf_mysql_query("SELECT `value` FROM `settings` WHERE `name` = 'identifier'"); + res = mysql_use(); + row = mysql_fetch_row(res); + if(!row) return NULL; + } + if(strlen(row[0]) < 10) return NULL; + return row[0]; +} + +static TIMEQ_CALLBACK(stats_timer_callback) { + timeq_add_name("stats", STATS_UPDATE_SECONDS, module_id, stats_timer_callback, NULL); + char tmp[200]; + char pkgbuf[1024]; + int pkgpos = 0; + char *modname = get_module_name(module_id); + char *bot_identifier = get_identifier(); + if(!bot_identifier) return; + //build update package + pkgpos += sprintf(pkgbuf + pkgpos, "nsupdate\n%s\n%s.%d %s\n", bot_identifier, NEONSERV_VERSION, get_patchlevel(), (strcmp(get_revision(), "") ? get_revision() : "-")); + sprintf(tmp, "modules/%s/hide_networkname", modname); + if(get_int_field(tmp)) + pkgpos += sprintf(pkgbuf + pkgpos, "*\n"); + else { + struct ClientSocket *bot; + for(bot = getBots(SOCKET_FLAG_READY, NULL); bot; bot = getBots(SOCKET_FLAG_READY, bot)) { + if(bot->network_name) break; + } + if(bot) + pkgpos += sprintf(pkgbuf + pkgpos, "%s\n", bot->network_name); + else + pkgpos += sprintf(pkgbuf + pkgpos, "?\n"); + } + sprintf(tmp, "modules/%s/hide_botnick", modname); + if(get_int_field(tmp)) + pkgpos += sprintf(pkgbuf + pkgpos, "*\n"); + else { + struct ClientSocket *bot, *bot1, *bot2, *bot3; + for(bot = getBots(SOCKET_FLAG_READY, NULL); bot; bot = getBots(SOCKET_FLAG_READY, bot)) { + if(bot->botid == 1 && (bot->flags & SOCKET_FLAG_PREFERRED)) + bot1 = bot; + else if((bot->flags & SOCKET_FLAG_PREFERRED)) + bot2 = bot; + else + bot3 = bot; + } + if(bot1) + bot = bot1; + else if(bot2) + bot = bot2; + else + bot = bot3; + if(bot) { + pkgpos += sprintf(pkgbuf + pkgpos, "%s!%s@%s %d\n", bot->user->nick, bot->user->ident, bot->host, bot->port); + } else + pkgpos += sprintf(pkgbuf + pkgpos, "?\n"); + } + sprintf(tmp, "modules/%s/hide_chancount", modname); + if(get_int_field(tmp)) + pkgpos += sprintf(pkgbuf + pkgpos, "*\n"); + else { + int channel_count = getChannelCount(); + pkgpos += sprintf(pkgbuf + pkgpos, "%d\n", channel_count); + } + sprintf(tmp, "modules/%s/hide_usercount", modname); + if(get_int_field(tmp)) + pkgpos += sprintf(pkgbuf + pkgpos, "*\n"); + else { + int user_count = getUserCount(); + int chanuser_count = getChanUserCount(); + pkgpos += sprintf(pkgbuf + pkgpos, "%d %d\n", user_count, chanuser_count); + } + pkgbuf[pkgpos] = 0; + //send package + #ifndef WIN32 + struct sockaddr_in si_other; + int sock = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP); + if (sock == -1) return; + memset((char *) &si_other, 0, sizeof(si_other)); + si_other.sin_family = AF_INET; + si_other.sin_port = htons(STATS_UPDATE_PORT); + if (!inet_aton(STATS_UPDATE_HOST, &si_other.sin_addr)) { + struct hostent *host = gethostbyname(STATS_UPDATE_HOST); + if (!host) return; + si_other.sin_addr = *(struct in_addr*)host->h_addr; + } + #else + struct sockaddr_in si_other; + int sock = socket(PF_INET, SOCK_DGRAM, IPPROTO_UDP); + if (sock == -1) return; + si_other.sin_family = AF_INET; + si_other.sin_port = htons(STATS_UPDATE_PORT); + si_other.sin_addr.s_addr = inet_addr(client->host); + if (si_other.sin_addr.s_addr == INADDR_NONE) { + struct hostent *host = gethostbyname(client->host); + if(!host) return; + memcpy(&(si_other.sin_addr), host->h_addr_list[0], 4); + } + #endif + sendto(sock, pkgbuf, pkgpos, 0, &si_other, sizeof(si_other)); + close(sock); +} + +MODULE_HEADER(module_initialize, module_start, module_loop, module_stop);