daily work
This commit is contained in:
parent
190be1be3c
commit
38542d7ddf
12
gamelist.cpp
12
gamelist.cpp
|
@ -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());
|
||||
}
|
||||
|
|
27
gamelist.h
27
gamelist.h
|
@ -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_
|
||||
|
|
|
@ -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()
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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());
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
|
17
hlswserver.h
17
hlswserver.h
|
@ -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
4
list.h
|
@ -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()
|
||||
|
|
|
@ -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"; }
|
||||
};
|
||||
|
|
|
@ -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"; }
|
||||
};
|
||||
|
|
|
@ -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"; }
|
||||
};
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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"; }
|
||||
};
|
||||
|
|
10
netpkt.cpp
10
netpkt.cpp
|
@ -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);
|
||||
}
|
||||
|
|
1
netpkt.h
1
netpkt.h
|
@ -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);
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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;
|
||||
};
|
||||
|
|
Loading…
Reference in New Issue