daily work
This commit is contained in:
parent
33e97b1eaa
commit
bb96fb05a3
20
Makefile
20
Makefile
|
@ -1,15 +1,20 @@
|
|||
CFLAGS := -O2 -pipe -Wall -Wunused -Wno-deprecated
|
||||
LIBS := -lpthread
|
||||
|
||||
SRC := $(wildcard *.cpp)
|
||||
OBJS := $(SRC:.cpp=.o)
|
||||
DEPS := $(SRC:.cpp=.d)
|
||||
HLSWMASTER_SRC := config.o gameentry.o gamelist.o gameparser.o gamescanner.o \
|
||||
hlswmaster.o hlswserver.o list.o logging.o modhelper.o modulelist.o \
|
||||
multisock.o netpkt.o recvqueue.o socket.o timerservice.o thread.o \
|
||||
mod_d3engine.o mod_gamespy1.o mod_gamespy2.o mod_halflife.o \
|
||||
mod_hlswproxy.o mod_q3engine.o mod_quake2.o mod_ut.o
|
||||
|
||||
all: hlswmaster
|
||||
all: hlswmaster masterquery
|
||||
|
||||
hlswmaster: $(OBJS)
|
||||
hlswmaster: $(HLSWMASTER_SRC) hlswmaster.o
|
||||
$(CXX) $(CFLAGS) $^ $(LIBS) -o $@
|
||||
|
||||
masterquery: masterquery.o
|
||||
$(CC) $(CFLAGS) $^ $(LIBS) -o $@
|
||||
|
||||
%.o: %.cpp
|
||||
$(CXX) $(CFLAGS) -c $< -o $@
|
||||
|
||||
|
@ -20,6 +25,7 @@ dist:
|
|||
git-tar-tree HEAD hlswmaster-ng | gzip -9 -c > hlswmaster-ng.tar.gz
|
||||
|
||||
clean:
|
||||
rm -f hlswmaster *.d *.o *.log
|
||||
rm -f hlswmaster masterquery *.d *.o *.log
|
||||
|
||||
-include $(DEPS)
|
||||
##DEPS := $(wildcard *.cpp)
|
||||
##-include $(DEPS:.cpp=.d)
|
||||
|
|
2
config.h
2
config.h
|
@ -34,7 +34,6 @@ private:
|
|||
~SectionIterator();
|
||||
bool hasNext();
|
||||
char* next();
|
||||
void add(char* part) {}
|
||||
void remove() {}
|
||||
void reset();
|
||||
|
||||
|
@ -53,7 +52,6 @@ private:
|
|||
|
||||
const char* name;
|
||||
|
||||
private:
|
||||
List<Tupel> tupelList;
|
||||
};
|
||||
|
||||
|
|
|
@ -12,12 +12,13 @@ public:
|
|||
GameList(Config& conf);
|
||||
~GameList();
|
||||
|
||||
void cleanup();
|
||||
void addGame(int gameid, NetPkt* pkt, int port2 = 0, bool swap = false);
|
||||
|
||||
long getLastUpdate();
|
||||
Iterator<GameEntry>* createIterator();
|
||||
|
||||
void cleanup();
|
||||
|
||||
protected:
|
||||
GameList(const GameList& gl);
|
||||
GameList& operator=(const GameList& gl);
|
||||
|
|
|
@ -14,7 +14,7 @@ game_timeout 30
|
|||
# master answers with this source IP
|
||||
master_ip 0.0.0.0
|
||||
|
||||
# rebuild master liste every X seconds
|
||||
# rebuild master list every X seconds
|
||||
rebuild_interval 5
|
||||
|
||||
# logging
|
||||
|
@ -22,5 +22,4 @@ logfile hlswmaster.log
|
|||
logprio DEBUG
|
||||
|
||||
[hlswproxy]
|
||||
parent 1.1.1.1 2.2.2.2
|
||||
parent 3.3.3.3
|
||||
master_ip 10.10.0.30 10.10.0.31
|
||||
|
|
|
@ -13,11 +13,14 @@
|
|||
#include "hlswserver.h"
|
||||
#include "timerservice.h"
|
||||
|
||||
#include "mod_halflife.h"
|
||||
#include "mod_q3engine.h"
|
||||
#include "mod_d3engine.h"
|
||||
#include "mod_gamespy1.h"
|
||||
#include "mod_gamespy2.h"
|
||||
#include "mod_halflife.h"
|
||||
#include "mod_hlswproxy.h"
|
||||
#include "mod_q3engine.h"
|
||||
#include "mod_quake2.h"
|
||||
#include "mod_ut.h"
|
||||
|
||||
#define DEFAULT_CONFIG "hlswmaster.conf"
|
||||
#define DEFAULT_LOGFILE "hlswmaster.log"
|
||||
|
@ -90,16 +93,21 @@ int main(int argc, char *argv[])
|
|||
GameParser parser(rxQueue, modList, gameList);
|
||||
HlswServer server(conf, gameList);
|
||||
|
||||
// modList.reg(new ModHalfLife());
|
||||
// modList.reg(new ModQ3Engine());
|
||||
// modList.reg(new ModD3Engine());
|
||||
modList.reg(new ModD3Engine());
|
||||
modList.reg(new ModGameSpy1());
|
||||
// modList.reg(new ModGameSpy2());
|
||||
modList.reg(new ModGameSpy2());
|
||||
modList.reg(new ModHalfLife());
|
||||
modList.reg(new ModHlswProxy(conf));
|
||||
modList.reg(new ModQ3Engine());
|
||||
modList.reg(new ModQuake2());
|
||||
modList.reg(new ModUT());
|
||||
|
||||
server.start();
|
||||
parser.start();
|
||||
scanner.start();
|
||||
|
||||
LogSystem::log(LOG_EVERYTIME, "hlswmaster-ng running...");
|
||||
|
||||
while (1) {
|
||||
TimerService::checkTimers();
|
||||
usleep(500000);
|
||||
|
|
|
@ -16,7 +16,6 @@ public:
|
|||
~HlswServer();
|
||||
|
||||
int execute(void* arg);
|
||||
|
||||
void rebuild(GameList& gl);
|
||||
|
||||
protected:
|
||||
|
|
10
list.h
10
list.h
|
@ -8,7 +8,6 @@ public:
|
|||
virtual ~IteratorBase() {}
|
||||
virtual bool hasNext() =0;
|
||||
virtual void* next() =0;
|
||||
virtual void add(void* part) {}; // TODO: why not =0;
|
||||
virtual void remove() =0;
|
||||
virtual void reset() =0;
|
||||
|
||||
|
@ -65,7 +64,6 @@ protected:
|
|||
|
||||
bool hasNext();
|
||||
void* next();
|
||||
void add(void* part);
|
||||
void remove();
|
||||
void reset();
|
||||
|
||||
|
@ -77,6 +75,8 @@ protected:
|
|||
private:
|
||||
ListEntryBase head;
|
||||
Mutex mutex;
|
||||
|
||||
friend class ListIteratorBase;
|
||||
};
|
||||
|
||||
|
||||
|
@ -84,7 +84,6 @@ template <class T>
|
|||
class Iterator : public IteratorBase {
|
||||
public:
|
||||
virtual T* next() =0;
|
||||
virtual void add(T* part) =0;
|
||||
};
|
||||
|
||||
template <class T>
|
||||
|
@ -95,13 +94,12 @@ public:
|
|||
|
||||
bool hasNext() { return false; }
|
||||
T* next() { return NULL; }
|
||||
void add(T* part) {}
|
||||
void remove() {}
|
||||
void reset() {}
|
||||
};
|
||||
|
||||
template <class T>
|
||||
class List : private ListBase {
|
||||
class List : public ListBase {
|
||||
public:
|
||||
List() {}
|
||||
~List() {}
|
||||
|
@ -124,7 +122,6 @@ private:
|
|||
|
||||
bool hasNext() { return ListIteratorBase::hasNext(); }
|
||||
TT* next() { return (TT*)ListIteratorBase::next(); }
|
||||
void add(TT* part) {}
|
||||
void remove() {}
|
||||
void reset() { ListIteratorBase::reset(); }
|
||||
};
|
||||
|
@ -137,7 +134,6 @@ private:
|
|||
|
||||
bool hasNext() { return ListIteratorBase::hasNext(); }
|
||||
TT* next() { return (TT*)ListIteratorBase::next(); }
|
||||
void add(TT* part) { ListIteratorBase::add(part); }
|
||||
void remove() { ListIteratorBase::remove(); }
|
||||
void reset() { ListIteratorBase::reset(); }
|
||||
};
|
||||
|
|
|
@ -11,7 +11,7 @@ public:
|
|||
void scan(MultiSock* msock);
|
||||
int parse(NetPkt* pkt, GameList* slist);
|
||||
|
||||
const char* getName() { return "Doom3 engine"; }
|
||||
const char* getName() { return "Doom3 protocol"; }
|
||||
};
|
||||
|
||||
#endif // _MODD3ENGINE_H_
|
||||
|
|
|
@ -3,6 +3,8 @@
|
|||
#include "modhelper.h"
|
||||
#include "mod_gamespy1.h"
|
||||
|
||||
#define MODGS1_GC_TIMEOUT 5
|
||||
|
||||
static struct game_ports port_arr[] = {
|
||||
{ 7777, 7788, ID_UT }, // ut, ut2k3, rune, ut2k4, aao, POSTAL2
|
||||
{ 22000, 22010, ID_BF1942 }, // bf1942(16)
|
||||
|
@ -38,7 +40,7 @@ static const char reply_fear[] = "fear\\";
|
|||
|
||||
ModGameSpy1::ModGameSpy1()
|
||||
{
|
||||
// TODO: cleanup event
|
||||
TimerService::registerTimer(new Timer(new GcEvent(*this), MODGS1_GC_TIMEOUT));
|
||||
}
|
||||
|
||||
ModGameSpy1::~ModGameSpy1()
|
||||
|
@ -86,39 +88,41 @@ int ModGameSpy1::parse(NetPkt* pkt, GameList* glist)
|
|||
offset = pkt->find(0, search_final, strlen(search_final));
|
||||
final = (offset != -1);
|
||||
|
||||
char buf[64];
|
||||
pkt->show(buf, sizeof(buf));
|
||||
|
||||
/* single final packet -> shortcut */
|
||||
if (final && (subid == 1)) {
|
||||
LogSystem::log(LOG_DEBUG, "single final");
|
||||
pkt2 = pkt;
|
||||
|
||||
/* non-final multi-part */
|
||||
} else if (!final) {
|
||||
LogSystem::log(LOG_DEBUG, "non final");
|
||||
LogSystem::log(LOG_DEBUG, "non final %s (%d/%d)", buf, queryid, subid);
|
||||
list.addTail(new MultiPart(pkt, queryid, subid));
|
||||
return PARSE_ACCEPT_FREED;
|
||||
return PARSE_ACCEPT_FREED; // parser must not free pkt
|
||||
|
||||
/* final multipart */
|
||||
} else {
|
||||
LogSystem::log(LOG_DEBUG, "multi final");
|
||||
LogSystem::log(LOG_DEBUG, "multi final %s (%d/%d)", buf, queryid, subid);
|
||||
pkt2 = merge(pkt, queryid, subid);
|
||||
if (pkt2 == NULL) {
|
||||
LogSystem::log(LOG_NOTICE, "GameSpy1: unable to merge");
|
||||
return PARSE_ACCEPT_FREED;
|
||||
LogSystem::log(LOG_NOTICE, "ModGameSpy1: failed to merge");
|
||||
return PARSE_ACCEPT; // let parser free pkt
|
||||
}
|
||||
}
|
||||
|
||||
retval = parse_real(pkt2, glist, gameid);
|
||||
|
||||
if (pkt2 != pkt)
|
||||
delete pkt2;
|
||||
delete pkt2; // free merged packet
|
||||
|
||||
return retval;
|
||||
return retval; // ACCPET/REJECT -> let parser free pkt
|
||||
}
|
||||
|
||||
ModGameSpy1::MultiPart::MultiPart(NetPkt* pkt, int queryid, int subid)
|
||||
: pkt(pkt), queryid(queryid), subid(subid)
|
||||
{
|
||||
timeout = time(NULL) + 5;
|
||||
timeout = time(NULL) + MODGS1_GC_TIMEOUT;
|
||||
}
|
||||
|
||||
NetPkt* ModGameSpy1::merge(NetPkt* pkt, int queryid, int subid)
|
||||
|
@ -145,6 +149,7 @@ NetPkt* ModGameSpy1::merge(NetPkt* pkt, int queryid, int subid)
|
|||
|
||||
if (searchid == mp->subid) {
|
||||
tmppkt->append(mp->pkt);
|
||||
delete mp->pkt;
|
||||
searchid++;
|
||||
}
|
||||
}
|
||||
|
@ -155,7 +160,6 @@ NetPkt* ModGameSpy1::merge(NetPkt* pkt, int queryid, int subid)
|
|||
delete it;
|
||||
|
||||
tmppkt->append(pkt);
|
||||
delete pkt;
|
||||
|
||||
if (!found) {
|
||||
delete tmppkt;
|
||||
|
@ -165,6 +169,25 @@ NetPkt* ModGameSpy1::merge(NetPkt* pkt, int queryid, int subid)
|
|||
return tmppkt;
|
||||
}
|
||||
|
||||
void ModGameSpy1::gc()
|
||||
{
|
||||
Iterator<MultiPart>* it = list.createIteratorRW();
|
||||
long now = time(NULL);
|
||||
char buf[64];
|
||||
|
||||
while (it->hasNext()) {
|
||||
MultiPart* mp = it->next();
|
||||
if (mp->timeout <= now) {
|
||||
mp->pkt->show(buf, sizeof(buf));
|
||||
LogSystem::log(LOG_NOTICE, "ModGameSpy1 gc removed: %s (%d/%d)",
|
||||
buf, mp->queryid, mp->subid);
|
||||
it->remove();
|
||||
}
|
||||
}
|
||||
|
||||
delete it;
|
||||
}
|
||||
|
||||
int ModGameSpy1::parse_real(NetPkt* pkt, GameList* glist, int gameid)
|
||||
{
|
||||
int port, offset, pos1, pos2;
|
||||
|
|
|
@ -12,7 +12,9 @@ public:
|
|||
void scan(MultiSock* msock);
|
||||
int parse(NetPkt* pkt, GameList* glist);
|
||||
|
||||
const char* getName() { return "GameSpy 1 Protocol"; }
|
||||
const char* getName() { return "GameSpy 1 protocol"; }
|
||||
|
||||
void gc();
|
||||
|
||||
private:
|
||||
class MultiPart {
|
||||
|
@ -27,6 +29,16 @@ private:
|
|||
long timeout;
|
||||
};
|
||||
|
||||
class GcEvent : public Event {
|
||||
public:
|
||||
GcEvent(ModGameSpy1& mgs1) : mgs1(mgs1) {}
|
||||
~GcEvent() {}
|
||||
void execute() { mgs1.gc(); }
|
||||
|
||||
private:
|
||||
ModGameSpy1& mgs1;
|
||||
};
|
||||
|
||||
NetPkt* merge(NetPkt* pkt, int queryid, int subid);
|
||||
int parse_real(NetPkt* pkt, GameList* glist, int gameid);
|
||||
|
||||
|
|
|
@ -11,7 +11,7 @@ public:
|
|||
void scan(MultiSock* msock);
|
||||
int parse(NetPkt* pkt, GameList* glist);
|
||||
|
||||
const char* getName() { return "GameSpy 2 Protocol"; }
|
||||
const char* getName() { return "GameSpy 2 protocol"; }
|
||||
};
|
||||
|
||||
#endif // _MODGAMESPY1_H_
|
||||
|
|
|
@ -11,8 +11,8 @@ static const char scanmsg1[] = "\xff\xff\xff\xff""details";
|
|||
static const char scanmsg2[] = "\xff\xff\xff\xff\x54";
|
||||
static const char scanmsg3[] = "\xff\xff\xff\xff""TSource Engine Query";
|
||||
|
||||
static const char reply1[] = "m\x00";
|
||||
static const char reply2[] = "I\x07";
|
||||
static const char reply1[] = { 0xFF, 0xFF, 0xFF, 0xFF, 0x49, 0x07 }; // I.
|
||||
static const char reply2[] = { 0xFF, 0xFF, 0xFF, 0xFF, 0x6D, 0x00 }; // m
|
||||
|
||||
void ModHalfLife::scan(MultiSock* msock)
|
||||
{
|
||||
|
@ -29,25 +29,29 @@ int ModHalfLife::parse(NetPkt* pkt, GameList* glist)
|
|||
if (ModHelper::checkPorts(pkt, port_arr) == 0)
|
||||
return PARSE_REJECT;
|
||||
|
||||
// check 0xFF 0xFF 0xFF 0xFF
|
||||
if (!pkt->compare(0, scanmsg1, 4))
|
||||
return PARSE_REJECT;
|
||||
// eat weird connection attempts
|
||||
if (pkt->getSize() <= 4)
|
||||
return PARSE_ACCEPT_QUIRK;
|
||||
|
||||
/* check for short answer without ip/port */
|
||||
if (pkt->compare(4, reply1, 2)) {
|
||||
glist->addGame(ID_HL, pkt);
|
||||
return PARSE_ACCEPT;
|
||||
}
|
||||
|
||||
/* second query?! */
|
||||
if (pkt->compare(4, reply2, 2)) {
|
||||
/* Halflife2 answer */
|
||||
if (pkt->compare(0, reply1, sizeof(reply1))) {
|
||||
glist->addGame(ID_HL2, pkt);
|
||||
return PARSE_ACCEPT;
|
||||
}
|
||||
|
||||
/* parse server IP */
|
||||
/* Halflife1 short answer */
|
||||
if (pkt->compare(0, reply2, sizeof(reply2))) {
|
||||
glist->addGame(ID_HL, pkt);
|
||||
return PARSE_ACCEPT;
|
||||
}
|
||||
|
||||
/* Halflife1 answer (with IP:port) */
|
||||
if (!pkt->compare(0, reply2, sizeof(reply2) -1))
|
||||
return PARSE_REJECT;
|
||||
|
||||
/* try to parse server IP */
|
||||
pos = 5;
|
||||
if ((count = pkt->parse_ip(pos, &tmp)) == 0)
|
||||
if ((count = pkt->parse_ip(pos, &tmp)) < 7)
|
||||
return PARSE_REJECT;
|
||||
|
||||
/* parse server port */
|
||||
|
@ -55,8 +59,15 @@ int ModHalfLife::parse(NetPkt* pkt, GameList* glist)
|
|||
if ((count = pkt->parse_int(pos, &port)) == 0)
|
||||
return PARSE_REJECT;
|
||||
|
||||
// TODO: check server IP?
|
||||
//glist->add(ID_HL, &tmp, port, 0);
|
||||
glist->addGame(ID_HL, pkt);
|
||||
// IP is 0.0.0.0 or 127.0.0.1 -> do not use IP info
|
||||
if (tmp.s_addr == 0x00000000 || tmp.s_addr == 0x0100007F) {
|
||||
glist->addGame(ID_HL, pkt);
|
||||
|
||||
} else {
|
||||
// TODO: implement
|
||||
glist->addGame(ID_HL, pkt);
|
||||
//glist->add(ID_HL, &tmp, port, false);
|
||||
}
|
||||
|
||||
return PARSE_ACCEPT;
|
||||
}
|
||||
|
|
|
@ -11,7 +11,7 @@ public:
|
|||
void scan(MultiSock* msock);
|
||||
int parse(NetPkt* pkt, GameList* glist);
|
||||
|
||||
const char* getName() { return "HalfLife engine"; }
|
||||
const char* getName() { return "Half-Life protocol"; }
|
||||
};
|
||||
|
||||
#endif // _MODHALFLIFE_H_
|
||||
|
|
|
@ -11,7 +11,7 @@ public:
|
|||
void scan(MultiSock* msock);
|
||||
int parse(NetPkt* pkt, GameList* glist);
|
||||
|
||||
const char* getName() { return "Quake3 engine"; }
|
||||
const char* getName() { return "Quake3 protocol"; }
|
||||
};
|
||||
|
||||
#endif // _MODQ3ENGINE_H_
|
||||
|
|
|
@ -1,5 +1,19 @@
|
|||
#include "modhelper.h"
|
||||
|
||||
void ModHelper::send(MultiSock* msock, int port, const char* data, int size)
|
||||
{
|
||||
struct sockaddr_in addr;
|
||||
addr.sin_family = AF_INET;
|
||||
addr.sin_addr.s_addr = 0xFFFFFFFF;
|
||||
addr.sin_port = htons(port);
|
||||
|
||||
NetPkt* pkt = new NetPkt(data, size);
|
||||
pkt->setAddress(&addr);
|
||||
msock->sendto(pkt);
|
||||
|
||||
delete pkt;
|
||||
}
|
||||
|
||||
void ModHelper::send(MultiSock* msock, struct game_ports* arr, const char* data, int size)
|
||||
{
|
||||
struct sockaddr_in addr;
|
||||
|
|
|
@ -7,7 +7,9 @@
|
|||
|
||||
class ModHelper {
|
||||
public:
|
||||
static void send(MultiSock* msock, int port, const char* data, int size);
|
||||
static void send(MultiSock* msock, struct game_ports* arr, const char* data, int size);
|
||||
|
||||
static int checkPorts(NetPkt* pkt, struct game_ports* arr);
|
||||
|
||||
protected:
|
||||
|
|
13
netpkt.cpp
13
netpkt.cpp
|
@ -1,6 +1,12 @@
|
|||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <unistd.h>
|
||||
|
||||
// needed for string.h / memmem()
|
||||
#ifndef __USE_GNU
|
||||
#define __USE_GNU
|
||||
#endif
|
||||
|
||||
#include <string.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/socket.h>
|
||||
|
@ -159,11 +165,6 @@ bool NetPkt::sameAddress(NetPkt* pkt)
|
|||
|
||||
void NetPkt::append(NetPkt* pkt)
|
||||
{
|
||||
char buf1[64], buf2[64];
|
||||
this->show(buf1, sizeof(buf1));
|
||||
pkt->show(buf2, sizeof(buf2));
|
||||
LogSystem::log(LOG_DEBUG, "append (%s) + (%s)", buf1, buf2);
|
||||
|
||||
unsigned int new_alloc = size + pkt->size;
|
||||
|
||||
char* new_data = new char[new_alloc];
|
||||
|
@ -177,6 +178,4 @@ void NetPkt::append(NetPkt* pkt)
|
|||
|
||||
memcpy((void*)(data + size), pkt->data, pkt->size);
|
||||
size += pkt->size;
|
||||
|
||||
delete pkt;
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue