daily work

This commit is contained in:
Olaf Rempel 2006-02-20 21:58:59 +01:00
parent 190be1be3c
commit 38542d7ddf
18 changed files with 191 additions and 84 deletions

View File

@ -4,9 +4,10 @@
#define DEFAULT_TIMEOUT 180
GameList::GameList(Config& conf)
: lastUpdate(0)
{
int interval = conf.getInteger("global", "game_timeout", DEFAULT_TIMEOUT);
TimerService::registerTimer(new Timer(new CleanupEvent(this), interval));
TimerService::registerTimer(new Timer(new CleanupEvent(*this), interval));
}
GameList::~GameList()
@ -17,14 +18,15 @@ void GameList::cleanup()
{
}
long GameList::getLastMod()
long GameList::getLastUpdate()
{
return 0;
lastUpdate++;
return lastUpdate;
}
Iterator<GameEntry>* GameList::createIterator()
{
return new NullIterator<GameEntry>();
return glist.createIterator();
}
void GameList::addGame(int gameid, NetPkt* pkt)
@ -32,4 +34,6 @@ void GameList::addGame(int gameid, NetPkt* pkt)
char buf[64];
pkt->show(buf, sizeof(buf));
LogSystem::log(LOG_NOTICE, "Adding Game %d: %s", gameid, buf);
glist.add(new GameEntry());
}

View File

@ -8,18 +8,17 @@
class GameEntry {
public:
GameEntry();
~GameEntry();
GameEntry() {};
~GameEntry() {};
struct in_addr addr;
int port1;
int port2;
int gameid;
protected:
GameEntry(const GameEntry& ge);
GameEntry& operator=(const GameEntry& ge);
private:
// struct in_addr addr;
int port1;
int port2;
int gameid;
};
@ -31,7 +30,7 @@ public:
void cleanup();
void addGame(int gameid, NetPkt* pkt);
long getLastMod();
long getLastUpdate();
Iterator<GameEntry>* createIterator();
protected:
@ -39,18 +38,18 @@ protected:
GameList& operator=(const GameList& gl);
private:
class CleanupEvent : public Command {
class CleanupEvent : public Event {
public:
CleanupEvent(GameList* gl) : gl(gl) {}
CleanupEvent(GameList& gl) : gl(gl) {}
~CleanupEvent() {}
void execute() { gl->cleanup(); }
void execute() { gl.cleanup(); }
private:
GameList* gl;
GameList& gl;
};
List<GameEntry> glist;
long lastUpdate;
};
#endif // _GAMELIST_H_

View File

@ -3,15 +3,15 @@
#include "gamescanner.h"
#define DEFAULT_INTERVAL 30
#define DEFAULT_SCAN_INTERVAL 30
GameScanner::GameScanner(Config& conf, ModuleList& modList, RecvQueue& rxQueue)
: modList(modList), rxQueue(rxQueue)
{
msock = new MultiSock(conf);
int interval = conf.getInteger("global", "scan_interval", DEFAULT_INTERVAL);
TimerService::registerTimer(new Timer(new ScanEvent(this), interval));
int interval = conf.getInteger("global", "scan_interval", DEFAULT_SCAN_INTERVAL);
TimerService::registerTimer(new Timer(new ScanEvent(*this), interval));
}
GameScanner::~GameScanner()

View File

@ -22,14 +22,14 @@ protected:
GameScanner& operator=(const GameScanner& hs);
private:
class ScanEvent : public Command {
class ScanEvent : public Event {
public:
ScanEvent(GameScanner* gs) : gs(gs) {}
ScanEvent(GameScanner& gs) : gs(gs) {}
~ScanEvent() {}
void execute() { gs->scan(); }
void execute() { gs.scan(); }
private:
GameScanner* gs;
GameScanner& gs;
};
ModuleList& modList;

View File

@ -3,7 +3,7 @@
scan_port 7130
# broadcast scan every X seconds
scan_interval 10
scan_interval 30
# use this interface(s)
scan_deny_iface
@ -14,6 +14,9 @@ game_timeout 30
# master answers with this source IP
master_ip 0.0.0.0
# rebuild master liste every X seconds
rebuild_interval 5
# logging
logfile hlswmaster.log
logprio DEBUG

View File

@ -88,10 +88,10 @@ int main(int argc, char *argv[])
GameScanner scanner(conf, modList, rxQueue);
GameParser parser(rxQueue, modList, gameList);
HlswServer server(conf);
HlswServer server(conf, gameList);
// modList.reg(new ModHalfLife());
modList.reg(new ModQ3Engine());
// modList.reg(new ModQ3Engine());
// modList.reg(new ModD3Engine());
// modList.reg(new ModGameSpy1());
// modList.reg(new ModGameSpy2());

View File

@ -12,6 +12,15 @@
#define HLSW_MASTER_PORT 7140
static const char hlsw_header[] = "\xFF\xFF\xFF\xFFHLSWLANSEARCH";
#define DEFAULT_REBUILD_INTERVAL 5
struct hlsw_entry {
uint16_t gameid;
uint32_t ip;
uint16_t port1;
uint16_t port2;
} __attribute__ ((packed));
HlswServer::HlswPacket::HlswPacket(HlswPacket* next)
: next(next), count(0)
{
@ -27,13 +36,18 @@ HlswServer::HlswPacket::~HlswPacket()
bool HlswServer::HlswPacket::addGame(GameEntry* ge)
{
if (count < 140) {
count++;
return true;
} else {
if (count >= 140)
return false;
}
struct hlsw_entry tmp;
tmp.gameid = ge->gameid;
tmp.ip = ge->addr.s_addr;
tmp.port1 = ge->port1;
tmp.port2 = ge->port2;
memcpy(data + sizeof(hlsw_header) + count * 10, &tmp, sizeof(tmp));
count++;
return true;
}
void HlswServer::HlswPacket::send(int socket, struct sockaddr_in* dst)
@ -47,19 +61,18 @@ void HlswServer::HlswPacket::send(int socket, struct sockaddr_in* dst)
}
}
HlswServer::HlswServer(Config& conf)
HlswServer::HlswServer(Config& conf, GameList& glist)
: lastUpdate(0)
{
struct sockaddr_in dst;
const char *ip;
if ((sock = socket(PF_INET, SOCK_DGRAM, 0)) < 0) {
LogSystem::log(LOG_CRIT, "HlswServer(): socket()");
return;
}
ip = conf.getString("global", "master_ip", "0.0.0.0");
const char *ip = conf.getString("global", "master_ip", "0.0.0.0");
LogSystem::log(LOG_NOTICE, "HlswServer listen on %s:%d", ip, HLSW_MASTER_PORT);
struct sockaddr_in dst;
dst.sin_family = AF_INET;
dst.sin_port = htons(HLSW_MASTER_PORT);
inet_aton(ip, &dst.sin_addr);
@ -69,6 +82,9 @@ HlswServer::HlswServer(Config& conf)
return;
}
int interval = conf.getInteger("global", "rebuild_interval", DEFAULT_REBUILD_INTERVAL);
TimerService::registerTimer(new Timer(new RebuildEvent(*this, glist), interval));
pktlist = new HlswPacket(NULL);
}
@ -90,12 +106,6 @@ int HlswServer::execute(void* arg)
len = sizeof(src);
ret = recvfrom(sock, buf, sizeof(buf), 0, (struct sockaddr *)&src, &len);
if (ret != sizeof(hlsw_header)) {
LogSystem::log(LOG_NOTICE, "HlswServer: invalid packet");
continue;
}
/* testen ob es sich um ein HLSW anforderung handelt */
if (memcmp(buf, hlsw_header, sizeof(hlsw_header))) {
LogSystem::log(LOG_NOTICE, "HlswServer: not a hlsw packet");
continue;
@ -108,23 +118,27 @@ int HlswServer::execute(void* arg)
return 0;
}
void HlswServer::rebuild(GameList& glist) {
Iterator<GameEntry>* it = glist.createIterator();
HlswPacket* newlist = NULL;
while (it->hasNext()) {
GameEntry* d = it->next();
if (!newlist || !newlist->addGame(d)) {
newlist = new HlswPacket(newlist);
newlist->addGame(d);
}
}
mutex.lock();
HlswPacket* oldlist = pktlist;
pktlist = newlist;
mutex.unlock();
delete oldlist;
delete it;
void HlswServer::rebuild(GameList& glist) {
if (glist.getLastUpdate() > lastUpdate) {
HlswPacket* newlist = new HlswPacket(NULL);
Iterator<GameEntry>* it = glist.createIterator();
while (it->hasNext()) {
GameEntry* d = it->next();
if (!newlist->addGame(d)) {
newlist = new HlswPacket(newlist);
newlist->addGame(d);
}
}
lastUpdate = glist.getLastUpdate();
delete it;
mutex.lock();
HlswPacket* oldlist = pktlist;
pktlist = newlist;
mutex.unlock();
delete oldlist;
}
}

View File

@ -10,18 +10,29 @@
class HlswServer : public Thread {
public:
HlswServer(Config& conf);
HlswServer(Config& conf, GameList& glist);
~HlswServer();
int execute(void* arg);
void rebuild(GameList& glist);
void rebuild(GameList& gl);
protected:
HlswServer(const HlswServer& hs);
HlswServer& operator=(const HlswServer& hs);
private:
class RebuildEvent : public Event {
public:
RebuildEvent(HlswServer& hs, GameList& gl) : hs(hs), gl(gl) {}
~RebuildEvent() {}
void execute() { hs.rebuild(gl); }
private:
HlswServer& hs;
GameList& gl;
};
class HlswPacket {
public:
HlswPacket(HlswPacket* next);
@ -39,6 +50,8 @@ private:
HlswPacket* pktlist;
Mutex mutex;
int sock;
long lastUpdate;
};
#endif // _HLSWSERVER_H_

4
list.h
View File

@ -146,13 +146,13 @@ private:
ListIterator(const List<TT>* list)
: list(list)
{
// ((ListBase*)list)->mutex.lock();
((List<TT>*)list)->mutex.lock();
reset();
}
~ListIterator()
{
// ((ListBase*)list)->mutex.unlock();
((List<TT>*)list)->mutex.unlock();
}
bool hasNext()

View File

@ -9,7 +9,7 @@ public:
~ModGameSpy1() {}
void scan(MultiSock* msock);
int parse(NetPkt* pkt, GameList* slist);
int parse(NetPkt* pkt, GameList* glist);
const char* getName() { return "GameSpy 1 Protocol"; }
};

View File

@ -9,7 +9,7 @@ public:
~ModGameSpy2() {}
void scan(MultiSock* msock);
int parse(NetPkt* pkt, GameList* slist);
int parse(NetPkt* pkt, GameList* glist);
const char* getName() { return "GameSpy 2 Protocol"; }
};

View File

@ -9,7 +9,7 @@ public:
~ModHalfLife() {}
void scan(MultiSock* msock);
int parse(NetPkt* pkt, GameList* slist);
int parse(NetPkt* pkt, GameList* glist);
const char* getName() { return "HalfLife engine"; }
};

View File

@ -1,23 +1,86 @@
#include <string.h>
#include "logging.h"
#include "mod_q3engine.h"
static struct game_ports port_arr[] = {
{ 27960, 27969, ID_Q3A }, // q3(6), ef(7), et25), rtcw(8)
{ 28070, 28070, ID_JK2 }, // jk2(12)
{ 28960, 28963, ID_COD }, // cod(31), cod:uo(42), cod2(48)
{ 29070, 29070, ID_JK3 }, // jk3(27)
// { 28070, 28070, ID_JK2 }, // jk2(12)
// { 28960, 28963, ID_COD }, // cod(31), cod:uo(42), cod2(48)
// { 29070, 29070, ID_JK3 }, // jk3(27)
{ 0,0,0 }
};
static const char scanmsg[] = "\xff\xff\xff\xffgetStatus";
static const char replyhead[] = "\xff\xff\xff\xffstatusResponse";
static const char search_version[] = "\\version\\";
static const char search_gamename[] = "\\gamename\\";
static const char reply_q3[] = "Q3 ";
static const char reply_ef[] = "ST:V HM ";
static const char reply_rtcw[] = "Wolf ";
static const char reply_et[] = "ET";
static const char reply_jk2[] = "JK2MP";
static const char reply_jk3[] = "JAmp";
static const char reply_cod[] = "Call of Duty\\";
static const char reply_coduo[] = "CoD:United Offensive\\";
static const char reply_cod2[] = "Call of Duty 2\\";
void ModQ3Engine::scan(MultiSock* msock)
{
msock->send(port_arr, scanmsg, strlen(scanmsg));
}
int ModQ3Engine::parse(NetPkt* pkt, GameList* slist)
int ModQ3Engine::parse(NetPkt* pkt, GameList* glist)
{
int gameid = 0, pos1, pos2;
if (!pkt->checkPortArray(port_arr))
return PARSE_REJECT;
if (!pkt->compare(0, replyhead, strlen(replyhead)))
return PARSE_REJECT;
pos1 = pkt->find(0, search_version, strlen(search_version));
if (pos1 != -1) {
pos1 += strlen(search_version);
if (pkt->compare(pos1, reply_q3, strlen(reply_q3)))
gameid = ID_Q3A;
else if (pkt->compare(pos1, reply_ef, strlen(reply_ef)))
gameid = ID_EF;
else if (pkt->compare(pos1, reply_rtcw, strlen(reply_rtcw)))
gameid = ID_RTCW;
else if (pkt->compare(pos1, reply_et, strlen(reply_et)))
gameid = ID_ET;
else if (pkt->compare(pos1, reply_jk2, strlen(reply_jk2)))
gameid = ID_JK2;
else if (pkt->compare(pos1, reply_jk3, strlen(reply_jk3)))
gameid = ID_JK3;
}
pos2 = pkt->find(0, search_gamename, strlen(search_gamename));
if (gameid == 0 && pos2 != -1) {
pos2 += strlen(search_gamename);
if (pkt->compare(pos2, reply_cod, strlen(reply_cod)))
gameid = ID_COD;
else if (pkt->compare(pos2, reply_coduo, strlen(reply_coduo)))
gameid = ID_COD_UO;
else if (pkt->compare(pos2, reply_cod2, strlen(reply_cod2)))
gameid = ID_COD2;
}
if (gameid == 0)
return PARSE_REJECT;
glist->addGame(gameid, pkt);
return PARSE_ACCEPT;
}

View File

@ -9,7 +9,7 @@ public:
~ModQ3Engine() {}
void scan(MultiSock* msock);
int parse(NetPkt* pkt, GameList* slist);
int parse(NetPkt* pkt, GameList* glist);
const char* getName() { return "Quake3 engine"; }
};

View File

@ -78,3 +78,13 @@ bool NetPkt::compare(int offset, const char* buf, int len)
return (memcmp(this->data + offset, buf, len) == 0);
}
int NetPkt::find(int offset, const char *buf, int len)
{
if (offset >= this->size)
return -1;
void* found = memmem(this->data + offset, this->size, buf, len);
return (found == NULL) ? -1 : ((char*)found - this->data);
}

View File

@ -17,6 +17,7 @@ public:
int checkPortArray(struct game_ports* arr);
bool compare(int offset, const char* buf, int len);
int find(int offset, const char *buf, int len);
protected:
NetPkt(const NetPkt& x);

View File

@ -2,14 +2,14 @@
#include "timerservice.h"
Timer::Timer(Command* cmd, unsigned int timeval)
: next(0), cmd(cmd), timeval(timeval)
Timer::Timer(Event* event, unsigned int timeval)
: next(0), event(event), timeval(timeval)
{
}
Timer::~Timer()
{
delete cmd;
delete event;
}
TimerService::~TimerService()
@ -39,7 +39,7 @@ void TimerService::checkTimeouts()
long now = time(NULL);
Timer* search = firstTimer;
while (search != NULL && search->timeout <= now) {
search->cmd->execute();
search->event->execute();
firstTimer = search->next;
addTimer(search, false);

View File

@ -3,19 +3,19 @@
#include "mutex.h"
class Command {
class Event {
public:
virtual ~Command() {};
virtual ~Event() {};
virtual void execute() =0;
protected:
Command() {};
Event() {};
};
class Timer {
friend class TimerService;
public:
Timer(Command* cmd, unsigned int timeval);
Timer(Event* event, unsigned int timeval);
~Timer();
protected:
@ -24,7 +24,7 @@ protected:
private:
Timer* next;
Command* cmd;
Event* event;
int timeval;
long timeout;
};