/* TODO * 470 forwarding to another channel implementieren * evtl timeout implementieren * aus config folgendes lesen: * rejoinen? * wie lange warten? * */ #include #include #include using namespace std; #include "../TConnectionInterface.h" #include "../TPluginParentLight.h" #include "../TUserList.h" #include "../mytypes.h" #include "../myfuncs.h" #include "../TConfigReadOnly.h" struct entry_t { char state; int wait; time_t last; string name; }; extern "C" void init(int* csize, int* conndefault, int* chandefault, int* sessdefault) { *csize=sizeof(list*); *conndefault=PFLAGS_EXEC_ONEVENT; *chandefault=0; *sessdefault=0; } extern "C" void plugin (plugincontext* context, ircmessage msg, TPluginParentLight* parent, TConfigReadOnly& config, int reason) { list *liste=*static_cast **>(context->data); if (liste==0) { liste=new list; *static_cast **>(context->data)=liste; } if (reason&PFLAGS_EXEC_ONEVENT) { if ((msg.command=="KICK") && (lcase(ntharg(msg.params,2))==lcase(parent->get_parent()->get_nick()))) //wir wurden gekickt? sauerei! { cout << "we got kicked from " << ntharg(msg.params,1) << endl; if (config.get_valid_boolean(parent->get_parent()->get_networkname() + "." + ntharg(msg.params,1) + ".rejoin", false)) { cout << " trying to rejoin" << endl; entry_t tmp; tmp.state=1; tmp.last=time(NULL)+1; //fake time to wait 1 second ONCE tmp.wait=0; tmp.name=ntharg(msg.params,1); liste->push_back(tmp); context->flags |= PFLAGS_EXEC_ALWAYS; } } //evtl aus datei lesen? // parent->get_parent()->send ("join #DrunkenMan" NEWLINE); // if (config.is_string(parent->get_parent()->get_networkname()+".pass")) // parent->get_parent()->send("PRIVMSG NickServ :identify "+config.get_string(parent->get_parent()->get_networkname()+".nick")+" "+config.get_string(parent->get_parent()->get_networkname()+".pass")); } if (reason&PFLAGS_EXEC_ALWAYS) { for (list::iterator it=liste->begin(); it!=liste->end(); it++) { switch (it->state) { case 1: if (time(NULL)>(it->last+it->wait)) { cout << "DEBUG: waiting is over" << endl; parent->get_parent()->send("join "+it->name); it->state=2; } break; case 2: //waiting for JOIN answer if ((ucase(msg.command)=="JOIN") && (ucase(msg.origin)==ucase(parent->get_parent()->get_nick()))) { it->state=99; cout << "!!!!!!!SUCCESS" << endl; } else { if ((lcase(ntharg(msg.params,1))==lcase(parent->get_parent()->get_nick())) && (lcase(ntharg(msg.params, 2))==lcase(it->name))) { cout << "!!!!!!!!betrifft uns" << endl; int numcmd=atoi(msg.command.c_str()); switch (numcmd) { case 471: //channel is full it->last=time(NULL); it->state=1; it->wait++; break; case 473: //inviteonly parent->get_parent()->send("PRIVMSG ChanServ :invite "+it->name); it->state=3; break; case 474: //banned parent->get_parent()->send("PRIVMSG ChanServ :unban "+it->name); it->state=3; break; case 475: //bad key, no such chan, too many chans. fatal. case 403: case 405: it->state=99; cout << "!!!!!!!!!FATAL" << endl; break; } } } break; case 3: //waiting for CHANSERV answer if ( ((msg.command=="401") && (ucase(ntharg(msg.params,2))=="CHANSERV")) || ((msg.command=="NOTICE") && (ucase(msg.origin)=="CHANSERV")) ) { //answer arrived or no chanserv? it->last=time(NULL); it->state=1; } break; } } bool temp=true; while (temp) { temp=false; for (list::iterator it=liste->begin(); it!=liste->end(); it++) { if (it->state==99) { cout << "cleanup: removing entry for channel " << it->name << "..." << endl; liste->erase(it); temp=true; break; } } } } }