10 #include <sys/select.h>
14 std::stringstream res;
34 , deleteServer_(false)
41 , nextPongDeadline_(0)
50 disconnectFromNetwork();
68 return config_->autoConnect;
75 activeServer_->ctcpAction( destination, message );
82 activeServer_->names( channel );
87 std::vector<std::string> res;
88 std::map<std::string,std::vector<std::string> >::const_iterator it;
89 for(it = knownUsers_.begin(); it != knownUsers_.end(); ++it) {
90 res.push_back(it->first);
102 std::map<std::string, ChannelMode> res;
103 std::map<std::string, std::vector<std::string> >::const_iterator it;
104 for(it = knownUsers_.begin(); it != knownUsers_.end(); ++it) {
105 if(it->first != channel)
107 std::vector<std::string> users = it->second;
108 std::vector<std::string>::const_iterator it2;
109 for(it2 = users.begin(); it2 != users.end(); ++it2) {
128 std::map<const ServerConfig*, int> randomValues;
134 assert(c1->
network == n_->config());
136 int prio1 = c1->
priority + n_->serverUndesirability(c1);
137 int prio2 = c2->
priority + n_->serverUndesirability(c2);
140 return prio1 < prio2;
149 randomValues[c1] = rand();
152 randomValues[c2] = rand();
154 return randomValues[c1] < randomValues[c2];
166 if( !reconnect && activeServer_ )
172 if( servers().size() == 0 )
174 printf(
"Trying to connect to network '%s', but there are no servers to connect to!\n",
175 config_->displayName.c_str());
182 std::vector<ServerConfig*> sortedServers = servers();
183 std::sort( sortedServers.begin(), sortedServers.end(),
ServerSorter(
this) );
189 connectToServer( best,
true );
193 void dazeus::Network::connectToServer(
ServerConfig *server,
bool reconnect )
195 if( !reconnect && activeServer_ )
197 assert(knownUsers_.size() == 0);
198 assert(identifiedUsers_.size() == 0);
202 activeServer_->disconnectFromServer( SwitchingServersReason );
204 delete(activeServer_);
207 activeServer_ =
new Server( server,
this );
208 activeServer_->connectToServer();
209 if(config_->connectTimeout > 0) {
210 deadline_ = time(NULL) + config_->connectTimeout;
214 void dazeus::Network::joinedChannel(
const std::string &user,
const std::string &receiver)
216 if(user == nick_ && !
contains_ci(knownUsers_, receiver)) {
217 knownUsers_[receiver] = std::vector<std::string>();
219 std::vector<std::string> users =
find_ci(knownUsers_, receiver)->second;
221 find_ci(knownUsers_, receiver)->second.push_back(user);
224 void dazeus::Network::partedChannel(
const std::string &user,
const std::string &,
const std::string &receiver)
231 if(!isKnownUser(user)) {
236 void dazeus::Network::slotQuit(
const std::string &origin,
const std::string&,
const std::string &)
238 std::map<std::string,std::vector<std::string> >::iterator it;
239 for(it = knownUsers_.begin(); it != knownUsers_.end(); ++it) {
242 if(!isKnownUser(origin)) {
247 void dazeus::Network::slotNickChanged(
const std::string &origin,
const std::string &nick,
const std::string & )
255 std::map<std::string,std::vector<std::string> >::iterator it;
256 for(it = knownUsers_.begin(); it != knownUsers_.end(); ++it) {
259 it->second.push_back(nick);
264 void dazeus::Network::kickedChannel(
const std::string&,
const std::string &user,
const std::string&,
const std::string &receiver)
271 if(!isKnownUser(user)) {
276 void dazeus::Network::onFailedConnection()
280 identifiedUsers_.clear();
283 slotIrcEvent(
"DISCONNECT",
"", std::vector<std::string>());
288 flagUndesirableServer( activeServer_->config() );
289 deleteServer_ =
true;
297 activeServer_->ctcpAction( destination, message );
306 if( activeServer_ == 0 )
309 identifiedUsers_.clear();
312 activeServer_->disconnectFromServer( reason );
314 delete activeServer_;
323 activeServer_->join( channel );
331 activeServer_->part( channel );
339 activeServer_->message( destination, message );
345 activeServer_->whois(destination);
350 return config_->servers;
363 return config()->name;
370 return contains(undesirables_, sc) ? undesirables_.find(sc)->second : 0;
376 undesirables_[sc] = undesirables_[sc] + 1;
377 else undesirables_[sc] = 1;
382 undesirables_.erase(sc);
390 std::map<std::string,std::vector<std::string> >::const_iterator it;
391 for(it = knownUsers_.begin(); it != knownUsers_.end(); ++it) {
399 void dazeus::Network::slotWhoisReceived(
const std::string &,
const std::string &nick,
bool identified) {
402 }
else if(identified && !
contains_ci(identifiedUsers_, nick) && isKnownUser(nick)) {
403 identifiedUsers_.push_back(nick);
407 void dazeus::Network::slotNamesReceived(
const std::string&,
const std::string &channel,
const std::vector<std::string> &names,
const std::string & ) {
409 std::vector<std::string> &users =
find_ci(knownUsers_, channel)->second;
410 std::vector<std::string>::const_iterator it;
411 for(it = names.begin(); it != names.end(); ++it) {
413 unsigned int nickStart;
414 for(nickStart = 0; nickStart < n.length(); ++nickStart) {
415 if(n[nickStart] !=
'@' && n[nickStart] !=
'~' && n[nickStart] !=
'+'
416 && n[nickStart] !=
'%' && n[nickStart] !=
'!') {
420 n = n.substr(nickStart);
426 void dazeus::Network::slotTopicChanged(
const std::string&,
const std::string &channel,
const std::string &topic) {
427 topics_[channel] = topic;
430 void dazeus::Network::slotIrcEvent(
const std::string &event,
const std::string &origin,
const std::vector<std::string> ¶ms) {
431 std::string receiver;
432 if(params.size() > 0)
433 receiver = params[0];
435 if(event !=
"ERROR") {
440 #define MIN(a) if(params.size() < a) { fprintf(stderr, "Too few parameters for event %s\n", event.c_str()); return; }
441 if(event ==
"CONNECT") {
442 nextPongDeadline_ = time(NULL) + 30;
443 serverIsActuallyOkay(activeServer_->config());
444 }
else if(event ==
"JOIN") {
446 joinedChannel(origin, receiver);
447 }
else if(event ==
"PART") {
449 partedChannel(origin, std::string(), receiver);
450 }
else if(event ==
"KICK") {
452 kickedChannel(origin, params[1], std::string(), receiver);
453 }
else if(event ==
"QUIT") {
455 if(params.size() > 0) {
458 slotQuit(origin, message, receiver);
459 }
else if(event ==
"NICK") {
461 slotNickChanged(origin, params[0], receiver);
462 }
else if(event ==
"TOPIC") {
464 slotTopicChanged(origin, params[0], params[1]);
467 std::vector<NetworkListener*>::iterator nlit;
468 for(nlit = networkListeners_.begin(); nlit != networkListeners_.end();
470 (*nlit)->ircEvent(event, origin, params,
this);
475 activeServer_->addDescriptors(in_set, out_set, maxfd);
480 deleteServer_ =
false;
481 delete activeServer_;
486 activeServer_->processDescriptors(in_set, out_set);
490 if(deadline_ > time(NULL)) {
494 if(time(NULL) > nextPongDeadline_) {
496 nextPongDeadline_ = time(NULL) + 30;
497 deadline_ = time(NULL) + config_->pongTimeout;
498 activeServer_->ping();
504 flagUndesirableServer(activeServer()->config());
506 onFailedConnection();
509 deleteServer_ =
false;
510 delete activeServer_;
512 connectToNetwork(
true);
516 std::vector<Network*> nets;
522 fd_set sockets, out_sockets;
524 std::vector<Network*>::const_iterator nit;
525 struct timeval timeout;
531 FD_ZERO(&out_sockets);
532 for(nit = networks.begin(); nit != networks.end(); ++nit) {
533 if((*nit)->activeServer()) {
535 (*nit)->addDescriptors(&sockets, &out_sockets, &ircmaxfd);
536 if(ircmaxfd > highest)
548 int socks = select(highest + 1, &sockets, &out_sockets, NULL, &timeout);
550 perror(
"select() failed");
553 else if(socks == 0) {
556 for(nit = networks.begin(); nit != networks.end(); ++nit) {
557 if((*nit)->activeServer()) {
558 (*nit)->processDescriptors(&sockets, &out_sockets);