00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00029 #include "lamoule.h"
00030
00034 Lamoule::Lamoule(BotKernel*b)
00035 {
00036 this->author = "eponyme";
00037 this->description = "ladder lamoule";
00038 this->version = VERSION;
00039 this->name = "lamoule";
00040 this->bindFunction("lamoule",IN_COMMAND_HANDLER,"lamoule",0,10);
00041 this->bindFunction("topshot",IN_COMMAND_HANDLER,"topshot",0,10);
00042 this->bindFunction("top5",IN_COMMAND_HANDLER,"top5",0,10);
00043 this->bindFunction("player",IN_COMMAND_HANDLER,"player",0,10);
00044 this->bindFunction("deleteplayer",IN_COMMAND_HANDLER,"deleteplayer",0,10);
00045 this->bindFunction("toptotal",IN_COMMAND_HANDLER,"toptotal",0,10);
00046 this->bindFunction("nextscore",IN_COMMAND_HANDLER,"nextscore",0,10);
00047 this->bindFunction("increase",IN_COMMAND_HANDLER,"increase",0,10);
00048 this->bindFunction("3600",IN_LOOP,"purifyFile",0,10);
00049 this->addRequirement("admin");
00050 this->addRequirement("usersinfos");
00051
00052 this->nextScore = 0 ;
00053 this->MAX_SCORE=1000;
00054 this->FIRST_FLOOR = 250 ;
00055 this->SECOND_FLOOR = 800 ;
00056 this->doc = new TiXmlDocument(b->getDatasDir()+"lamoule.xml");
00057 if ( this->doc->LoadFile() ) {
00058 this->root = this->doc->FirstChild();
00059 }
00060 else {
00061 this->initFile();
00062 }
00063 }
00064
00068 void Lamoule::initFile()
00069 {
00070 TiXmlElement born("trustyrc_lamoule_ladder");
00071 this->doc->InsertEndChild(born);
00072 this->root = this->doc->FirstChild();
00073 TiXmlElement ladderNode( "ladder" );
00074 this->root->InsertEndChild(ladderNode);
00075
00076 TiXmlElement topNode("topshot" );
00077 topNode.SetAttribute( "nick","" );
00078 topNode.SetAttribute( "score", "0" );
00079 topNode.SetAttribute( "date", "" );
00080 this->root->InsertEndChild(topNode);
00081
00082 this->doc->SaveFile();
00083 }
00084
00089 vector<string> Lamoule::getTopShot()
00090 {
00091 vector<string> back;
00092 TiXmlHandle docHandle (this->doc);
00093 TiXmlElement*elem = docHandle.FirstChild("trustyrc_lamoule_ladder").FirstChild("topshot").Element();
00094 if ( elem ) {
00095 back.push_back(elem->Attribute("nick"));
00096 back.push_back(elem->Attribute("score"));
00097 back.push_back(elem->Attribute("date"));
00098 }
00099 return back;
00100 }
00101
00108 void Lamoule::setTopShot(string nick,string score,string date)
00109 {
00110 TiXmlHandle docHandle (this->doc);
00111 TiXmlElement*elem = docHandle.FirstChild("trustyrc_lamoule_ladder").FirstChild("topshot").Element();
00112 if ( elem ) {
00113 elem->SetAttribute("nick",nick);
00114 elem->SetAttribute("score",score);
00115 elem->SetAttribute("date",date);
00116 this->doc->SaveFile();
00117 }
00118 }
00119
00125 void Lamoule::addPlayer(string nick,unsigned int initialScore)
00126 {
00127 time_t now;
00128 time(&now);
00129 TiXmlElement newNode("player");
00130 newNode.SetAttribute("nick",nick);
00131 newNode.SetAttribute("total",Tools::intToStr(initialScore));
00132 newNode.SetAttribute("nbLamoule","1");
00133 newNode.SetAttribute("lastLamoule",Tools::intToStr(int(now)));
00134 this->root->FirstChild("ladder")->InsertEndChild(newNode);
00135 this->doc->SaveFile();
00136 }
00137
00143 int Lamoule::generateScore() {
00144 int score;
00145 if ( this->nextScore != 0 ) {
00146 score = this->nextScore;
00147 this->nextScore = 0 ;
00148 }
00149 else {
00150 score = Tools::random(0,this->MAX_SCORE);
00151 if ( score >= this->SECOND_FLOOR ) {
00152 score = Tools::random(0,score) ;
00153 if ( score >= this->SECOND_FLOOR ) {
00154 score = Tools::random(0,score) ;
00155 }
00156 }
00157 else if ((score >= this->FIRST_FLOOR) && (score < this->SECOND_FLOOR)) {
00158 score = Tools::random(0,score) ;
00159 }
00160 }
00161 return score;
00162 }
00163
00172 char Lamoule::increaseScore(string nick,int score,unsigned int diffAttempts,bool checkTop)
00173 {
00174 time_t now;
00175 time(&now);
00176 char timeFormat[17];
00177 bool found = false;
00178 for(TiXmlElement*child = this->root->FirstChild("ladder")->FirstChildElement(); child!=0; child=child->NextSiblingElement()) {
00179 if ( Tools::to_lower(child->Attribute("nick")) == Tools::to_lower(nick) ) {
00180 found = true ;
00181 if (difftime(now,Tools::strToInt(child->Attribute("lastLamoule"))) > diffAttempts) {
00182 child->SetAttribute("total",(int)(Tools::strToDouble(child->Attribute("total"))+score));
00183 child->SetAttribute("nbLamoule",Tools::strToInt(child->Attribute("nbLamoule"))+1);
00184 child->SetAttribute("lastLamoule",now);
00185 this->doc->SaveFile();
00186 }
00187 else {
00188 return '\0';
00189 }
00190 break;
00191 }
00192 }
00193 if (!found) {
00194 this->addPlayer(nick,score);
00195 }
00196 if ( checkTop ) {
00197 if ( score > Tools::strToInt(this->getTopShot()[1]) ) {
00198 strftime(timeFormat,18,"%y-%m-%d %X",localtime(&now));
00199 this->setTopShot(nick,Tools::intToStr(score),timeFormat);
00200 return 't';
00201 }
00202 }
00203 return 'o';
00204 }
00205
00213 vector<TiXmlElement *> Lamoule::sort(sort_criterion criterion,int min_attempts)
00214 {
00215 vector<TiXmlElement *> vecBack;
00216 vector<TiXmlElement*>::iterator it;
00217 vecBack.clear();
00218 bool inserted;
00219 double tempXML,tempVEC;
00220 for(TiXmlElement*child = this->root->FirstChild("ladder")->FirstChildElement(); child!=0; child=child->NextSiblingElement()) {
00221 inserted = false;
00222 if ( Tools::strToInt(child->Attribute("nbLamoule")) >= min_attempts ) {
00223 if ( vecBack.empty() ) {
00224 vecBack.push_back(child);
00225 }
00226 else {
00227 for (it = vecBack.begin();it != vecBack.end();it++) {
00228 if (criterion == AVERAGE) {
00229 tempXML = Tools::strToDouble(child->Attribute("total")) / Tools::strToDouble(child->Attribute("nbLamoule")) ;
00230 tempVEC = Tools::strToDouble((*it)->Attribute("total")) / Tools::strToDouble((*it)->Attribute("nbLamoule")) ;
00231 if ( (tempXML >= tempVEC) ) {
00232 vecBack.insert(it,child);
00233 inserted = true;
00234 break;
00235 }
00236 }
00237 else if ( criterion == TOTAL ) {
00238 tempXML = Tools::strToDouble(child->Attribute("total")) ;
00239 tempVEC = Tools::strToDouble((*it)->Attribute("total")) ;
00240 if ( (tempXML >= tempVEC) ) {
00241 vecBack.insert(it,child);
00242 inserted = true;
00243 break;
00244 }
00245 }
00246 }
00247 if ( ! inserted ) {
00248 vecBack.push_back(child);
00249 }
00250 }
00251 }
00252 }
00253 return vecBack;
00254 }
00255
00262 vector<string> Lamoule::get5first(sort_criterion criterion,int min_attempts)
00263 {
00264 vector<string> back;
00265 vector<TiXmlElement *> vecElems ;
00266 unsigned int i;
00267 vecElems.clear();
00268 back.clear();
00269 string nbPlayers;
00270 vecElems = this->sort(criterion,min_attempts);
00271 nbPlayers = Tools::intToStr(vecElems.size());
00272 i = 0 ;
00273 while ((i < 5) && (i < vecElems.size()))
00274 {
00275 back.push_back("("+Tools::intToStr(i+1)+"/"+nbPlayers+") " + ""+string(vecElems[i]->Attribute("nick")) + " => average:" + Tools::doubleToStr(Tools::strToDouble(string(vecElems[i]->Attribute("total")))/Tools::strToDouble(string(vecElems[i]->Attribute("nbLamoule")))) + " total:" + string(vecElems[i]->Attribute("total"))+"" );
00276 i++;
00277 }
00278 return back ;
00279 }
00280
00292 vector<string> Lamoule::getInfosPlayer(string nick,int min_attempts)
00293 {
00294 vector<TiXmlElement *> vecElems ;
00295 vector<string> back;
00296 vecElems.clear();
00297 bool found = false;
00298 vecElems = this->sort(AVERAGE,min_attempts);
00299 unsigned int i ;
00300 for (i=0 ; i < vecElems.size() ; i ++ ) {
00301 if ( Tools::to_lower(vecElems[i]->Attribute("nick")) == Tools::to_lower(nick) )
00302 {
00303 found = true;
00304 break;
00305 }
00306 }
00307 for(TiXmlElement*child = this->root->FirstChild("ladder")->FirstChildElement(); child!=0; child=child->NextSiblingElement()) {
00308 if ( Tools::to_lower(child->Attribute("nick")) == Tools::to_lower(nick) ) {
00309 back.push_back(child->Attribute("total"));
00310 back.push_back(child->Attribute("nbLamoule")) ;
00311 back.push_back(Tools::doubleToStr(double(Tools::strToDouble(child->Attribute("total")) / Tools::strToDouble(child->Attribute("nbLamoule")))));
00312 back.push_back(child->Attribute("lastLamoule")) ;
00313 if (found) {
00314 back.push_back(Tools::intToStr(i+1));
00315 }
00316 else {
00317 back.push_back("-");
00318 }
00319 break;
00320 }
00321 }
00322 return back ;
00323 }
00324
00330 bool Lamoule::deletePlayer(string nick)
00331 {
00332 for(TiXmlElement*child = this->root->FirstChild("ladder")->FirstChildElement(); child!=0; child=child->NextSiblingElement()) {
00333 if ( Tools::to_lower(child->Attribute("nick")) == Tools::to_lower(nick) ) {
00334 child->Parent()->RemoveChild(child) ;
00335 this->doc->SaveFile();
00336 return true;
00337 }
00338 }
00339 return false;
00340 }
00341
00346 void Lamoule::purifyFile(int reset_time)
00347 {
00348 time_t now;
00349 time(&now);
00350 for(TiXmlElement*child = this->root->FirstChild("ladder")->FirstChildElement(); child!=0; child=child->NextSiblingElement()) {
00351 if ( difftime(now,Tools::strToInt(child->Attribute("lastLamoule"))) >= reset_time ) {
00352 child->Parent()->RemoveChild(child) ;
00353 }
00354 }
00355 this->doc->SaveFile();
00356 }
00357
00362 bool Lamoule::setNextScore(int score)
00363 {
00364 if ( score < this->MAX_SCORE ) {
00365 this->nextScore = score;
00366 return true;
00367 }
00368 else {
00369 return false;
00370 }
00371 }
00372
00373 extern "C"
00374 {
00375 Plugin *contruct_lamoule(BotKernel*b)
00376 {
00377 return new Lamoule(b);
00378 }
00379 void destroy_lamoule(Plugin*p)
00380 {
00381 delete p;
00382 }
00383 bool lamoule (Message*m,Plugin*p,BotKernel*b)
00384 {
00385 vector<string*> list,chanUsers;
00386 map<string,Channel*>::iterator fter ;
00387 map<string,Channel*>* users;
00388 string nick="";
00389 pPlugin * ppUI = b->getPlugin("usersinfos");
00390 Lamoule*lm= (Lamoule*)p;
00391 UsersInfos*ui = NULL;
00392 int rdm,rdm2 ;
00393 string message,bonus;
00394 char back;
00395 if (m->isPublic()) {
00396 rdm = lm->generateScore() ;
00397 string lamoule = "la mou" ;
00398 for (int i = 0; i < (rdm/10) ; i ++) {
00399 lamoule += "u" ;
00400 }
00401 lamoule += "le !!!" ;
00402 rdm2 = Tools::random(0,50) ;
00403 switch (rdm2 ) {
00404 case 1 : if ( ppUI != NULL ) {
00405 ui=(UsersInfos*)ppUI->object;
00406 users = ui->getUsers();
00407 fter = users->find(m->getSource());
00408 if ( fter != users->end() ) {
00409 chanUsers = ((Channel*)fter->second)->getUsers();
00410 if ( chanUsers.size() > 0 ) {
00411 nick = chanUsers[Tools::random(0,chanUsers.size()-1)][0];
00412 }
00413 else {
00414 nick = m->getNickSender();
00415 }
00416 }
00417 }
00418 if ( nick == m->getNickSender() ) {
00419 bonus = " ("+nick+" cratered. : 0)";
00420 rdm = 0;
00421 }
00422 else {
00423 bonus = " (railed by "+nick+" : -100)" ;
00424 rdm -= 100 ;
00425 if ( rdm < 0 ) {
00426 rdm = 0 ;
00427 }
00428 }
00429 break;
00430 case 2 : if ( ppUI != NULL ) {
00431 ui=(UsersInfos*)ppUI->object;
00432 users = ui->getUsers();
00433 fter = users->find(m->getSource());
00434 if ( fter != users->end() ) {
00435 chanUsers = ((Channel*)fter->second)->getUsers();
00436 if ( chanUsers.size() > 0 ) {
00437 nick = chanUsers[Tools::random(0,chanUsers.size()-1)][0];
00438 }
00439 else {
00440 nick = m->getNickSender();
00441 }
00442 }
00443 }
00444 if ( nick == m->getNickSender() ) {
00445 bonus = " ("+nick+" killed himself. : 0)";
00446 }
00447 else {
00448 bonus = " (pummeled by "+nick+" : 0)";
00449 }
00450 rdm = 0 ;
00451 break ;
00452 case 3 : bonus = " (MH taken !!! : +100)" ;
00453 rdm += 100 ;
00454 if ( rdm >= 1000 ) {
00455 rdm = 950 ;
00456 }
00457 break;
00458 case 4 : bonus = " (YA taken !!! : +50)" ;
00459 rdm += 50 ;
00460 if ( rdm >= 1000 ) {
00461 rdm = 950 ;
00462 }
00463 break;
00464 case 5 : bonus = " (RA taken !!! : +100)" ;
00465 rdm += 100 ;
00466 if ( rdm >= 1000 ) {
00467 rdm = 950 ;
00468 }
00469 break;
00470 default : bonus = "";
00471 }
00472 back = lm->increaseScore(m->getNickSender(),rdm,Tools::strToInt(b->getCONFF()->getValue(p->getName()+".diff_attempts")),true);
00473 if (back!='\0') {
00474 message = lamoule+", "+ Tools::intToStr(rdm) + " pour " +m->getNickSender()+""+bonus;
00475 if ( back == 't' ) {
00476 message += " (TOPSHOT !!!)";
00477 }
00478 b->send(IRCProtocol::sendMsg(m->getSource(),message));
00479 }
00480 else {
00481 b->send(IRCProtocol::sendNotice(m->getNickSender(),"A lamoule every "+b->getCONFF()->getValue(p->getName()+".diff_attempts")+" seconds " + m->getNickSender() +""));
00482 }
00483 }
00484 return true;
00485 }
00486 bool topshot (Message*m,Plugin*p,BotKernel*b) {
00487 Lamoule*lm= (Lamoule*)p;
00488 vector<string> back;
00489 if (m->isPublic()) {
00490 back = lm->getTopShot();
00491 b->send(IRCProtocol::sendMsg(m->getSource(),"* Topshot by " + back[0] + " : " + back[1] + " on " +back[2] +" *"));
00492 }
00493 return true;
00494 }
00495 bool nextscore (Message*m,Plugin*p,BotKernel*b) {
00496 pPlugin * ppAdm = b->getPlugin("admin");
00497 Lamoule*lm= (Lamoule*)p;
00498 Admin*adm = NULL;
00499 if (ppAdm!=NULL) {
00500 adm = (Admin*)ppAdm->object ;
00501 if (m->isPublic() && adm->isSuperAdmin(m->getSender()) && (m->nbParts()==5)) {
00502 if (lm->setNextScore(Tools::strToInt(m->getPart(4))) ) {
00503 b->send(IRCProtocol::sendNotice(m->getNickSender(),"Done." ));
00504 }
00505 else {
00506 b->send(IRCProtocol::sendNotice(m->getNickSender(),"Not done." ));
00507 }
00508 }
00509 }
00510 return true;
00511 }
00512 bool increase (Message*m,Plugin*p,BotKernel*b) {
00513 pPlugin * ppAdm = b->getPlugin("admin");
00514 Lamoule*lm= (Lamoule*)p;
00515 Admin*adm = NULL;
00516 if (ppAdm!=NULL) {
00517 adm = (Admin*)ppAdm->object ;
00518 if (m->isPublic() && adm->isSuperAdmin(m->getSender()) && (m->nbParts()==6)) {
00519 if (lm->increaseScore(m->getPart(4),Tools::strToInt(m->getPart(5)),0,false) == 'o' ) {
00520 b->send(IRCProtocol::sendNotice(m->getNickSender(),"done." ));
00521 }
00522 else {
00523 b->send(IRCProtocol::sendNotice(m->getNickSender(),"not done." ));
00524 }
00525 }
00526 }
00527 return true;
00528 }
00529 bool player (Message*m,Plugin*p,BotKernel*b) {
00530 time_t now;
00531 time(&now);
00532 vector<string> infos;
00533 Lamoule*lm= (Lamoule*)p;
00534 if ( m->isPublic() && (m->nbParts()==5) ) {
00535 infos = lm->getInfosPlayer(m->getPart(4),Tools::strToInt(b->getCONFF()->getValue(p->getName()+".min_attempts"))) ;
00536 if ( infos.size() > 0 ) {
00537 b->send(IRCProtocol::sendMsg(m->getSource(),"* "+m->getPart(4)+" => total:" + infos[0]+ " shots:" + infos[1]+ " average:"+infos[2]+ " rank:"+infos[4]+ " reset:"+ Tools::doubleToStr((Tools::strToDouble(b->getCONFF()->getValue(p->getName()+".reset_time")) - difftime(now,Tools::strToInt(infos[3])))/3600) + "H *") ) ;
00538 }
00539 else {
00540 b->send(IRCProtocol::sendMsg(m->getSource(),"* Non existent nick *") ) ;
00541 }
00542 }
00543 return true;
00544 }
00545 bool deleteplayer (Message*m,Plugin*p,BotKernel*b) {
00546 pPlugin * ppAdm = b->getPlugin("admin");
00547 Lamoule*lm= (Lamoule*)p;
00548 Admin*adm = NULL;
00549 if (ppAdm!=NULL) {
00550 adm = (Admin*)ppAdm->object ;
00551 if ( m->isPublic() && (m->nbParts()==5) && adm->isSuperAdmin(m->getSender()) ) {
00552 if (lm->deletePlayer(m->getPart(4)) ) {
00553 b->send(IRCProtocol::sendNotice(m->getNickSender(),"Done." ));
00554 }
00555 else {
00556 b->send(IRCProtocol::sendNotice(m->getNickSender(),"Not done." ));
00557 }
00558 }
00559 }
00560 return true;
00561 }
00562 bool top5 (Message*m,Plugin*p,BotKernel*b) {
00563 vector<string> back;
00564 Lamoule*lm= (Lamoule*)p;
00565 if (m->isPublic())
00566 {
00567 back =lm->get5first(AVERAGE,Tools::strToInt(b->getCONFF()->getValue(p->getName()+".min_attempts")));
00568 for (unsigned int i = 0 ; i < back.size() ; i ++ ) {
00569 b->send(IRCProtocol::sendMsg(m->getSource(),back[i] ));
00570 }
00571 }
00572 return true;
00573 }
00574 bool toptotal (Message*m,Plugin*p,BotKernel*b) {
00575 vector<string> back;
00576 Lamoule*lm= (Lamoule*)p;
00577 if (m->isPublic())
00578 {
00579 back =lm->get5first(TOTAL,Tools::strToInt(b->getCONFF()->getValue(p->getName()+".min_attempts")));
00580 for (unsigned int i = 0 ; i < back.size() ; i ++ ) {
00581 b->send(IRCProtocol::sendMsg(m->getSource(),back[i] ));
00582 }
00583 }
00584 return true;
00585 }
00586 bool purifyFile (Message*m,Plugin*p,BotKernel*b) {
00587 Lamoule*lm= (Lamoule*)p;
00588 lm->purifyFile(Tools::strToInt(b->getCONFF()->getValue(p->getName()+".reset_time")));
00589 return true;
00590 }
00591 }