/*************************************************************************** * Copyright (C) 04/2006 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 "gamelist.h" #include "logging.h" #define DEFAULT_TIMEOUT 180 GameList::GameList(Config& conf) { timeout = conf.getInteger("global", "game_timeout", DEFAULT_TIMEOUT); TimerService::registerTimer(new Timer(new CleanupEvent(*this), timeout)); } GameList::~GameList() { Iterator* it = createIterator(); while (it->hasNext()) delete it->next(); delete it; } void GameList::cleanup() { long now = time(NULL); Iterator* it = createIterator(); while (it->hasNext()) { GameEntry* ge = it->next(); if (ge->modtime + timeout <= now) { it->remove(); char buf[64]; ge->show(buf, sizeof(buf)); LogSystem::log(LOG_NOTICE, "Game Timeout: %s", buf); delete ge; } } delete it; } void GameList::addGame(int gameid, NetPkt* pkt, int port2) { addGame(gameid, &pkt->getAddress()->sin_addr, pkt->getPort(), port2); } void GameList::addGame(int gameid, struct in_addr *addr, int port1, int port2) { GameEntry* ge = new GameEntry(gameid, addr, port1, port2); int hash = ge->hash(MAX_BUCKETS); bool found = false; Iterator* it = buckets[hash].createIterator(); while (it->hasNext()) { GameEntry* tmp = it->next(); if (ge->compare(tmp) == 0) { tmp->update(); found = true; break; } } if (!found) { char buf[64]; ge->show(buf, sizeof(buf)); LogSystem::log(LOG_NOTICE, "Adding Game : %s", buf); buckets[hash].add(ge); } else { delete ge; } // it holds the lock! delete it; } Iterator* GameList::createIterator() { return new GameListIterator(this); } GameList::GameListIterator::GameListIterator(GameList* gl) : gl(gl), it(0) { gl->mutex.lock(); reset(); } GameList::GameListIterator::~GameListIterator() { delete it; gl->mutex.unlock(); } bool GameList::GameListIterator::hasNext() { if (it->hasNext()) return true; while (bucket < MAX_BUCKETS -1) { delete it; bucket++; it = gl->buckets[bucket].createIterator(); if (it->hasNext()) return true; } return false; } GameEntry* GameList::GameListIterator::next() { return it->next(); } void GameList::GameListIterator::remove() { it->remove(); } void GameList::GameListIterator::reset() { if (it != NULL) delete it; bucket = 0; it = gl->buckets[bucket].createIterator(); }