daily work

This commit is contained in:
Olaf Rempel 2006-02-05 16:44:38 +01:00 committed by
parent b4478bbc1e
commit 6383cfaf67
26 changed files with 542 additions and 108 deletions

View File

@ -17,8 +17,8 @@ Config::Tupel::Tupel(const char* name_, const char* value_)
Config::Tupel::~Tupel()
{
free(name);
free(value);
free((char*)name);
free((char*)value);
}
/* ------ */
@ -33,7 +33,7 @@ Config::Section::~Section()
while (!tupelList.isEmpty())
delete tupelList.get();
free(name);
free((char*)name);
}
bool Config::Section::addTupel(const char* name, const char* value)
@ -60,9 +60,9 @@ void Config::Section::show() const
delete it;
}
char* Config::Section::getTupelValue(const char* name) const
const char* Config::Section::getTupelValue(const char* name) const
{
char* retval = 0;
const char* retval = 0;
Iterator<Tupel>* it = this->tupelList.createIterator();
while (it->hasNext()) {
Tupel* t = it->next();
@ -78,6 +78,40 @@ char* Config::Section::getTupelValue(const char* name) const
/* ------ */
Config::Section::SectionIterator::SectionIterator(Section* section, const char* name)
: nexttup(0), name(name)
{
it = section->tupelList.createIterator();
}
Config::Section::SectionIterator::~SectionIterator()
{
delete it;
}
bool Config::Section::SectionIterator::hasNext()
{
while (it->hasNext()) {
nexttup = it->next();
if (!strcmp(nexttup->name, name))
return true;
}
return false;
}
char* Config::Section::SectionIterator::next()
{
return (char*)nexttup->value;
}
void Config::Section::SectionIterator::reset()
{
it->reset();
nexttup = 0;
}
/* ------ */
Config::~Config()
{
while (!sectionList.isEmpty())
@ -93,7 +127,7 @@ Config::Section* Config::addSection(const char* name)
bool Config::parseFile(const char* name)
{
Config::Section* section = 0;
Section* section = 0;
FILE *fz;
int i = 0;
char *row, *tok, *tok2;
@ -136,9 +170,11 @@ bool Config::parseFile(const char* name)
}
/* option */
if ((tok = strtok(row, " \n")) && (tok2 = strtok(NULL, " \n"))) {
if (!section->addTupel(tok, tok2))
LogSystem::log(LOG_WARN, "config_parse(): invalid row %d", i);
if ((tok = strtok(row, " \n"))) {
while ((tok2 = strtok(NULL, " \n"))) {
if (!section->addTupel(tok, tok2))
LogSystem::log(LOG_WARN, "config_parse(): invalid row %d", i);
}
}
}
@ -158,26 +194,32 @@ void Config::show() const
delete it;
}
char* Config::getParameter(const char* section, const char* option) const
Config::Section* Config::getSection(const char* name) const
{
char* retval = 0;
Section* retval = 0;
Iterator<Section>* it = sectionList.createIterator();
while (it->hasNext()) {
Section* s = it->next();
if (!strcmp(s->name, section)) {
retval = s->getTupelValue(option);
if (!strcmp(s->name, name)) {
retval = s;
break;
}
}
delete it;
return retval;
}
char* Config::getString(const char* section, const char* option, char* def) const
const char* Config::getParameter(const char* section, const char* option) const
{
char* retval = getParameter(section, option);
Section* s = getSection(section);
return s ? s->getTupelValue(option) : 0;
}
const char* Config::getString(const char* section, const char* option, char* def) const
{
const char* retval = getParameter(section, option);
if (!retval) {
LogSystem::log(LOG_NOTICE,
"Config: [%s:%s] not found => using '%s'",
@ -189,7 +231,7 @@ char* Config::getString(const char* section, const char* option, char* def) cons
int Config::getInteger(const char* section, const char* option, int def) const
{
char* retval = getParameter(section, option);
const char* retval = getParameter(section, option);
if (!retval) {
LogSystem::log(LOG_NOTICE,
"Config: [%s:%s] not found => using '%d'",
@ -198,3 +240,17 @@ int Config::getInteger(const char* section, const char* option, int def) const
}
return atoi(retval);
}
Iterator<char>* Config::createIterator(const char* section, const char* name)
{
Section* s = getSection(section);
if (!s) {
LogSystem::log(LOG_NOTICE,"Config: [%s:%s] not found",
section, name);
return new NullIterator<char>();
} else {
return new Config::Section::SectionIterator(s, name);
}
}

View File

@ -10,36 +10,53 @@ public:
bool parseFile(const char* name);
void show() const;
char* getParameter(const char* section, const char* name) const;
char* getString(const char* section, const char* name, char* def) const;
const char* getParameter(const char* section, const char* name) const;
const char* getString(const char* section, const char* name, char* def) const;
int getInteger(const char* section, const char* name, int def) const;
Iterator<char>* createIterator(const char* section, const char* name);
private:
class Tupel {
public:
Tupel(const char* name, const char* value);
~Tupel();
char* name;
char* value;
const char* name;
const char* value;
};
class Section {
public:
class SectionIterator : public Iterator<char> {
public:
SectionIterator(Section* section, const char* name);
~SectionIterator();
bool hasNext();
char* next();
void reset();
private:
Iterator<Tupel>* it;
Tupel* nexttup;
const char* name;
};
Section(const char* name);
~Section();
bool addTupel(const char* name, const char* option);
char* getTupelValue(const char* name) const;
const char* getTupelValue(const char* name) const;
void show() const;
char* name;
const char* name;
private:
List<Tupel> tupelList;
};
Section* addSection(const char* name);
Section* getSection(const char* name) const;
List<Section> sectionList;
};

63
gameids.h Normal file
View File

@ -0,0 +1,63 @@
#ifndef _GAMEIDS_H_
#define _GAMEIDS_H_
enum {
ID_UNKNOWN = 0, // "Unknown"
ID_HL, // "Halflife"
ID_Q1, // "Quake 1"
ID_Q2, // "Quake 2"
ID_Q3COMP, // "Q3Comp"
ID_UT = 5, // "Unreal Tournament"
ID_Q3A, // "Quake 3 Arena"
ID_EF, // "Elite Force"
ID_RTCW, // "Return to Castle Wolfenstein"
ID_GS1PROT, // "GSProt"
ID_CCR = 10, // "Command & Conquer Renegade"
ID_MOHAA, // "Medal of Honor: Allied Assault"
ID_JK2, // "Jedi Knight 2"
ID_SOF, // "Soldier of Fortune"
ID_UT2K3, // "Unreal Tournament 2003"
ID_AAO = 15, // "America's Army: Operations"
ID_BF1942, // "Battlefield 1942"
ID_AVP2, // "Alien vs. Predator 2"
ID_RUNE, // "Rune"
ID_IGI2, // "Project IGI2: Covert Strike"
ID_NWN = 20, // "Never Winter Nights"
ID_MOHAA_S, // "Medal of Honor: Allied Assault Spearhead"
ID_OPFP, // "Operation Flashpoint"
ID_OPFPR, // "Operation Flashpoint Resistance"
ID_DEVA, // "Devastation"
ID_ET = 25, // "Wolfenstein - Enemy Territory"
ID_EF2, // "Elite Force 2"
ID_JK3, // "Jedi Knight 3"
ID_MOHAA_B, // "Medal of Honor: Allied Assault Breakthrough"
ID_TRIBES2, // "Tribes 2"
ID_HALO = 30, // "Halo"
ID_COD, // "Call of Duty"
ID_SAVAGE, // "Savage: The Battle for Newerth"
ID_UT2K4, // "Unreal Tournament 2004"
ID_HLSTEAM, // "HLSteam"
ID_BFV = 35, // "Battlefield Vietnam"
ID_GS2PROT, // "GS2Prot"
ID_PK, // "Pain Killer"
ID_D3, // "Doom 3"
ID_OGPPROT, // "OGPProt"
ID_HL2 = 40, // "Halflife 2"
ID_TRIBES_V, // "Tribes Vengeance"
ID_COD_UO, // "Call of Duty: United Offensive"
ID_SW_BF, // "Starwars: Battlefront (?)"
ID_SWAT4, // "SWAT 4"
ID_BF2 = 45, // "Battlefield 2"
ID_xxx, // "???"
ID_Q4, // "Quake 4"
ID_COD2 // "Call of Duty 2"
};
struct game_ports {
int portlo;
int porthi;
int id;
};
#endif // _GAMEIDS_H_

View File

@ -20,6 +20,7 @@ int GameParser::execute(void* arg)
while (1) {
NetPkt* pkt = rxQueue.getPkt();
int ret = modList.parse(pkt, this);
switch (ret) {
case PKT_REJECT:
char buf[64];

View File

@ -5,6 +5,9 @@ scan_port 7130
# broadcast scan every X seconds
scan_interval 10
# use this interface(s)
scan_deny_iface lo sit0
# server timeout after X seconds
game_timeout 30
@ -13,4 +16,8 @@ master_ip 0.0.0.0
# logging
logfile hlswmaster.log
logprio 7
logprio DEBUG
[hlswproxy]
parent 1.1.1.1 2.2.2.2
parent 3.3.3.3

View File

@ -11,11 +11,15 @@
#include "timerservice.h"
#include "modulelist.h"
#include "mod_example.h"
#include "mod_halflife.h"
#include "mod_q3engine.h"
#include "mod_d3engine.h"
#include "mod_gamespy1.h"
#include "mod_gamespy2.h"
#define DEFAULT_CONFIG "hlswmaster.conf"
#define DEFAULT_LOGFILE "hlswmaster.log"
#define DEFAULT_LOGPRIO LOG_WARN
#define DEFAULT_LOGPRIO "WARN"
static struct option opts[] = {
{"config", 1, 0, 'c'},
@ -64,21 +68,29 @@ int main(int argc, char *argv[])
Config conf;
conf.parseFile(configfile);
// char* logfile = conf.getString("global", "logfile", DEFAULT_LOGFILE);
// int logprio = conf.getInteger("global", "logprio", DEFAULT_LOGPRIO);
// LogSystem::init(logprio, new FileLog(logfile));
LogSystem::init(LOG_DEBUG, new StdErrLog());
const char* logfile = conf.getString("global", "logfile", DEFAULT_LOGFILE);
const char* logprio = conf.getString("global", "logprio", DEFAULT_LOGPRIO);
if (!debug) {
LogSystem::init(logprio, new FileLog(logfile));
daemon(0, 0);
} else {
LogSystem::init(logprio, new StdErrLog());
}
LogSystem::log(LOG_EVERYTIME, "hlswmaster-ng startup");
// conf.show();
LogSystem::log(LOG_EVERYTIME, "hlswmaster-ng startup (pid:%d)", getpid());
conf.show();
ModuleList modList;
ModuleList modList(conf);
GameScanner scanner(conf, modList);
GameParser parser(conf, scanner, modList);
HlswServer server(conf, parser);
modList.reg(new ModExample(conf));
modList.reg(new ModHalfLife());
modList.reg(new ModQ3Engine());
modList.reg(new ModD3Engine());
modList.reg(new ModGameSpy1());
modList.reg(new ModGameSpy2());
server.start();
parser.start();

View File

@ -16,7 +16,7 @@
HlswServer::HlswServer(Config& conf, GameList& slist)
{
struct sockaddr_in dst;
char *ip;
const char *ip;
if ((sock = socket(PF_INET, SOCK_DGRAM, 0)) < 0) {
LogSystem::log(LOG_CRIT, "HlswServer(): socket()");

24
list.h
View File

@ -7,8 +7,9 @@ template <class T>
class Iterator {
public:
virtual ~Iterator() {}
virtual bool hasNext() const =0;
virtual bool hasNext() =0;
virtual T* next() =0;
virtual void reset() =0;
protected:
Iterator<T>() {}
@ -16,6 +17,18 @@ protected:
Iterator<T>& operator=(const Iterator<T>& it);
};
template <class T>
class NullIterator : public Iterator<T> {
public:
NullIterator() {}
~NullIterator() {}
bool hasNext() { return false; }
T* next() { return 0; }
void reset() {}
};
template <class T>
class List {
public:
@ -134,7 +147,7 @@ private:
: list(list)
{
// ((ListBase*)list)->mutex.lock();
pos = &list->head;
reset();
}
~ListIterator()
@ -142,7 +155,7 @@ private:
// ((ListBase*)list)->mutex.unlock();
}
bool hasNext() const
bool hasNext()
{
return (pos->getNext() != &list->head);
}
@ -153,6 +166,11 @@ private:
return (TT*)pos->getPart();
}
void reset()
{
pos = &list->head;
}
protected:
ListIterator(const ListIterator& lit);
ListIterator& operator=(const ListIterator& lit);

View File

@ -32,14 +32,39 @@ LogSystem* LogSystem::getInstance()
void LogSystem::init(int prio, LogOutput* out)
{
LogSystem* ls = getInstance();
if (out) {
if (ls->output)
delete ls->output;
if (ls->output)
delete ls->output;
ls->output = out;
ls->output = out;
}
ls->priority = prio;
}
void LogSystem::init(const char* prio, LogOutput* out)
{
if (!strcasecmp(prio, "DEBUG"))
init(LOG_DEBUG, out);
else if (!strcasecmp(prio, "INFO"))
init(LOG_INFO, out);
else if (!strcasecmp(prio, "NOTICE"))
init(LOG_NOTICE, out);
else if (!strcasecmp(prio, "WARN"))
init(LOG_WARN, out);
else if (!strcasecmp(prio, "ERROR"))
init(LOG_ERROR, out);
else if (!strcasecmp(prio, "CRIT"))
init(LOG_CRIT, out);
else
log(LOG_CRIT, "invalid logging priority");
}
void LogSystem::log(int prio, const char* fmt, ...)
{
LogSystem* ls = getInstance();

View File

@ -32,6 +32,7 @@ public:
class LogSystem {
public:
static void init(int prio, LogOutput* lo);
static void init(const char* prio, LogOutput* lo);
static void log(int prio, const char* fmt, ...);
private:

26
mod_d3engine.cpp Normal file
View File

@ -0,0 +1,26 @@
#include <string.h>
#include "mod_d3engine.h"
static struct game_ports port_arr[] = {
{ 27666, 27673, ID_D3 }, // Doom 3
{ 28004, 28008, ID_Q4 }, // Quake 4
{ 0,0,0 }
};
static const char scanmsg[] = "\xff\xffgetInfo";
static const char replyhead[] = "\xff\xffinfoResponse";
void ModD3Engine::scan(MultiSock* msock)
{
msock->send(port_arr, scanmsg, strlen(scanmsg));
}
int ModD3Engine::parse(NetPkt* pkt, GameList* slist)
{
// pkt->check_array(arr)
// pkt->check_range(min, max)
// pkt->check_port(port)
// pkt->memcmp(0, buf, len)
return 0;
}

17
mod_d3engine.h Normal file
View File

@ -0,0 +1,17 @@
#ifndef _MODD3ENGINE_H_
#define _MODD3ENGINE_H_
#include "module.h"
class ModD3Engine : public Module {
public:
ModD3Engine() {}
~ModD3Engine() {}
void scan(MultiSock* msock);
int parse(NetPkt* pkt, GameList* slist);
const char* getName() { return "Doom3 engine"; }
};
#endif // _MODD3ENGINE_H_

View File

@ -1,35 +0,0 @@
#ifndef _MODEXAMPLE_H_
#define _MODEXAMPLE_H_
#include "modulelist.h"
#include "logging.h"
class ModExample : public Module {
public:
ModExample(Config& conf)
{
}
~ModExample()
{
}
void scan(MultiSock* msock)
{
LogSystem::log(LOG_DEBUG, "ModExample::scan()");
}
int parse(NetPkt* pkt, GameList* slist)
{
LogSystem::log(LOG_DEBUG, "ModExample::parse()");
return 0;
}
char* getName() {
return "Example Module";
}
protected:
};
#endif // _MODEXAMPLE_H_

23
mod_gamespy1.cpp Normal file
View File

@ -0,0 +1,23 @@
#include <string.h>
#include "mod_gamespy1.h"
static struct game_ports port_arr[] = {
{ 7777, 7788, ID_UT }, // ut(5), ut2k3(14), rune(18), ut2k4(33), aao(15)
{ 22000, 22010, ID_BF1942 }, // bf1942(16)
{ 23000, 23010, ID_BFV }, // bfv(35)
{ 26001, 26011, ID_IGI2 }, // igi2(19)
{ 27888, 27888, ID_AVP2 }, // avp2(17)
{ 0,0,0 }
};
static const char scanmsg[] = "\\status\\";
void ModGameSpy1::scan(MultiSock* msock)
{
msock->send(port_arr, scanmsg, strlen(scanmsg));
}
int ModGameSpy1::parse(NetPkt* pkt, GameList* slist)
{
return 0;
}

17
mod_gamespy1.h Normal file
View File

@ -0,0 +1,17 @@
#ifndef _MODGAMESPY1_H_
#define _MODGAMESPY1_H_
#include "module.h"
class ModGameSpy1 : public Module {
public:
ModGameSpy1() {}
~ModGameSpy1() {}
void scan(MultiSock* msock);
int parse(NetPkt* pkt, GameList* slist);
const char* getName() { return "GameSpy 1 Protocol"; }
};
#endif // _MODGAMESPY1_H_

24
mod_gamespy2.cpp Normal file
View File

@ -0,0 +1,24 @@
#include <string.h>
#include "mod_gamespy2.h"
static struct game_ports port_arr[] = {
{ 7777, 7788, ID_UT }, // ut(5), ut2k3(14), rune(18), ut2k4(33), aao(15)
{ 22000, 22010, ID_BF1942 }, // bf1942(16)
{ 23000, 23010, ID_BFV }, // bfv(35)
{ 26001, 26011, ID_IGI2 }, // igi2(19)
{ 27888, 27888, ID_AVP2 }, // avp2(17)
{ 0,0,0 }
};
static const char scanmsg[] = { 0xFE, 0xFD, 0x00, 0xDE, 0xAD, 0xBE, 0xEF, 0xFF, 0x00, 0x00 };
static const char replyhead[] = { 0x00, 0xDE, 0xAD, 0xBE, 0xEF };
void ModGameSpy2::scan(MultiSock* msock)
{
msock->send(port_arr, scanmsg, sizeof(scanmsg));
}
int ModGameSpy2::parse(NetPkt* pkt, GameList* slist)
{
return 0;
}

17
mod_gamespy2.h Normal file
View File

@ -0,0 +1,17 @@
#ifndef _MODGAMESPY2_H_
#define _MODGAMESPY2_H_
#include "module.h"
class ModGameSpy2 : public Module {
public:
ModGameSpy2() {}
~ModGameSpy2() {}
void scan(MultiSock* msock);
int parse(NetPkt* pkt, GameList* slist);
const char* getName() { return "GameSpy 2 Protocol"; }
};
#endif // _MODGAMESPY1_H_

23
mod_halflife.cpp Normal file
View File

@ -0,0 +1,23 @@
#include <string.h>
#include "mod_halflife.h"
static struct game_ports port_arr[] = {
{ 27015, 27024, ID_HL },
{ 0,0,0 }
};
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";
void ModHalfLife::scan(MultiSock* msock)
{
msock->send(port_arr, scanmsg1, strlen(scanmsg1));
msock->send(port_arr, scanmsg2, strlen(scanmsg2));
msock->send(port_arr, scanmsg3, strlen(scanmsg3));
}
int ModHalfLife::parse(NetPkt* pkt, GameList* slist)
{
return 0;
}

17
mod_halflife.h Normal file
View File

@ -0,0 +1,17 @@
#ifndef _MODHALFLIFE_H_
#define _MODHALFLIFE_H_
#include "module.h"
class ModHalfLife : public Module {
public:
ModHalfLife() {}
~ModHalfLife() {}
void scan(MultiSock* msock);
int parse(NetPkt* pkt, GameList* slist);
const char* getName() { return "HalfLife engine"; }
};
#endif // _MODHALFLIFE_H_

23
mod_q3engine.cpp Normal file
View File

@ -0,0 +1,23 @@
#include <string.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)
{ 0,0,0 }
};
static const char scanmsg[] = "\xff\xff\xff\xffgetStatus";
static const char replyhead[] = "\xff\xff\xff\xffstatusResponse";
void ModQ3Engine::scan(MultiSock* msock)
{
msock->send(port_arr, scanmsg, strlen(scanmsg));
}
int ModQ3Engine::parse(NetPkt* pkt, GameList* slist)
{
return 0;
}

17
mod_q3engine.h Normal file
View File

@ -0,0 +1,17 @@
#ifndef _MODQ3ENGINE_H_
#define _MODQ3ENGINE_H_
#include "module.h"
class ModQ3Engine : public Module {
public:
ModQ3Engine() {}
~ModQ3Engine() {}
void scan(MultiSock* msock);
int parse(NetPkt* pkt, GameList* slist);
const char* getName() { return "Quake3 engine"; }
};
#endif // _MODQ3ENGINE_H_

23
module.h Normal file
View File

@ -0,0 +1,23 @@
#ifndef _MODULE_H_
#define _MODULE_H_
#include "config.h"
#include "multisock.h"
#include "netpkt.h"
#include "gamelist.h"
class Module {
public:
virtual ~Module() {};
virtual void init(Config* conf) {}
virtual void scan(MultiSock* msock) =0;
virtual int parse(NetPkt* pkt, GameList* slist) =0;
virtual const char* getName() =0;
protected:
Module() {};
Module(const Module& ml);
Module& operator=(const Module& ml);
};
#endif // _MODULE_H_

View File

@ -1,7 +1,8 @@
#include "logging.h"
#include "modulelist.h"
ModuleList::ModuleList()
ModuleList::ModuleList(Config& conf)
: conf(conf)
{
}
@ -13,7 +14,8 @@ ModuleList::~ModuleList()
void ModuleList::reg(Module* mod)
{
LogSystem::log(LOG_NOTICE, "Loading Module '%s'", mod->getName());
LogSystem::log(LOG_NOTICE, "Registering module '%s'", mod->getName());
mod->init(&conf);
mlist.addTail(mod);
}

View File

@ -1,27 +1,15 @@
#ifndef _MODULELIST_H_
#define _MODULELIST_H_
#include "config.h"
#include "multisock.h"
#include "netpkt.h"
#include "gamelist.h"
#include "config.h"
class Module {
public:
virtual ~Module() {};
virtual void scan(MultiSock* msock) =0;
virtual int parse(NetPkt* pkt, GameList* slist) =0;
virtual char* getName() =0;
protected:
Module() {};
};
#include "module.h"
class ModuleList {
public:
ModuleList();
ModuleList(Config& conf);
~ModuleList();
void reg(Module* mod);
@ -35,6 +23,7 @@ protected:
private:
List<Module> mlist;
Config& conf;
};
#endif // _MODULELIST_H_

View File

@ -131,26 +131,40 @@ MultiSock::MultiSock(Config& conf)
fgets(buf, BUFSIZE, fp);
int port = conf.getInteger("global", "scan_port", DEFAULT_PORT);
FD_ZERO(&fdsel);
Iterator<char>* it = conf.createIterator("global", "scan_deny_iface");
FD_ZERO(&fdsel);
while (fgets(buf, BUFSIZE, fp) != NULL) {
char* tok = strtok(buf, " :");
// TODO: check against config list
Socket* sock = Socket::createSocket(tok, port);
if (sock) {
FD_SET(sock->getFD(), &fdsel);
sock->show(buf, BUFSIZE);
LogSystem::log(LOG_NOTICE, "adding Interface %s", buf);
ifaceList.add(sock);
it->reset();
while (it->hasNext()) {
if (!strcmp(it->next(), tok)) {
LogSystem::log(LOG_NOTICE, "Interface '%s' denied by config", tok);
tok = 0;
break;
}
}
if (tok) {
Socket* sock = Socket::createSocket(tok, port);
if (sock) {
FD_SET(sock->getFD(), &fdsel);
sock->show(buf, BUFSIZE);
LogSystem::log(LOG_NOTICE, "adding Interface %s", buf);
ifaceList.add(sock);
}
}
}
delete it;
fclose(fp);
delete buf;
if (ifaceList.isEmpty())
LogSystem::log(LOG_CRIT, "No useable Interfaces found!");
}
MultiSock::~MultiSock()
@ -179,9 +193,42 @@ int MultiSock::waitOnSocket()
}
delete it;
LogSystem::log(LOG_WARN, "getRecvSocket(): select()");
LogSystem::log(LOG_WARN, "waitOnSocket(): select()");
}
return -1;
}
void MultiSock::send(struct in_addr *dstip, int dport, const char* data, int size)
{
struct sockaddr_in addr;
addr.sin_family = AF_INET;
addr.sin_port = htons(dport);
addr.sin_addr.s_addr = (dstip ? dstip->s_addr : 0xFFFFFFFF);
Iterator<Socket>* it = ifaceList.createIterator();
while (it->hasNext())
if (sendto(it->next()->getFD(), data, size, 0, (struct sockaddr *)&addr, sizeof(addr)) < 0)
LogSystem::log(LOG_WARN, "MultiSock::send()");
delete it;
usleep(10000);
}
void MultiSock::send(struct game_ports* arr, const char* data, int size)
{
while (arr && arr->portlo && arr->porthi) {
int port;
for (port = arr->portlo; port <= arr->porthi; port++)
send(NULL, port, data, size);
arr++;
}
}
void MultiSock::send(int* arr, const char* data, int size)
{
while (*arr)
send(NULL, *arr++, data, size);
}

View File

@ -6,13 +6,17 @@
#include "list.h"
#include "config.h"
#include "gameids.h"
class MultiSock {
public:
MultiSock(Config& conf);
~MultiSock();
int send(struct in_addr *dstip, int dport, char* data, int size);
void send(struct in_addr *dstip, int dport, const char* data, int size);
void send(struct game_ports* arr, const char* data, int size);
void send(int* arr, const char* data, int size);
int waitOnSocket();
protected: