/*************************************************************************** * Copyright (C) 03/2005 by Olaf Rempel * * razzor@kopf-tisch.de * * * * 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 2 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, write to the * * Free Software Foundation, Inc., * * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * ***************************************************************************/ #include #include #include #include #include #include #include #include #include #include #include "hlswmaster.h" #include "plugin.h" #include "list.h" LIST_HEAD(server_list); /* sichert die server liste */ static pthread_mutex_t server_list_lock = PTHREAD_MUTEX_INITIALIZER; /** * server_cmp() * LIST_FIND helper * * @param struct game_server *a * @param struct game_server *b * @return true wenn es sich um den selben server handelt */ static inline int server_cmp(const struct game_server *a, struct game_server *b) { return (a->gameid == b->gameid && a->ip == b->ip && a->port1 == b->port1 && a->port2 == b->port2); } /** * server_add() * fuegt der internen serverliste einen server hinzu * wenn dieser server schon in der liste vorhanden ist, wird nur * die modtime angepasst * * @param unsigned int gameid * @param struct in_addr ip * @param u_int16_t port1 * @param u_int16_t port2 * @return false bei fehler */ int server_add(u_int16_t gameid, u_int32_t ip, u_int16_t port1, u_int16_t port2) { struct game_server server, *nserver; server.gameid = gameid; server.ip = ip; server.port1 = port1; server.port2 = port2; pthread_mutex_lock(&server_list_lock); /* diesen server in der liste suchen */ nserver = LIST_FIND(&server_list, server_cmp, struct game_server *, &server); if (!nserver) { /* neuen eintrag anlegen */ if (!(nserver = malloc(sizeof(struct game_server)))) { pthread_mutex_unlock(&server_list_lock); return 0; } struct in_addr tmp; tmp.s_addr = server.ip; printf("new server: gameid=%d ip=%s port1=%d port2=%d\n", server.gameid, inet_ntoa(tmp), server.port1, server.port2); memcpy(nserver, &server, sizeof(struct game_server)); list_add_tail(&nserver->list, &server_list); } /* modtime anpassen */ nserver->modtime = time(NULL); pthread_mutex_unlock(&server_list_lock); return 1; } /** * server_collector() * loescht alte server aus der liste * baut aus den verbleibenden die client_liste auf * * TODO: timeout und intervall als config parameter (config file?) */ void server_collector(void) { struct game_server *server, *tmp; unsigned long now, timeout = 120; while (1) { sleep(5); now = time(NULL); pthread_mutex_lock(&server_list_lock); list_for_each_entry_safe(server, tmp, &server_list, list) { if (server->modtime + timeout < now) { list_del(&server->list); free(server); continue; } client_pkt_add(server); } pthread_mutex_unlock(&server_list_lock); client_pkt_commit(); } }