// SAMPLE_PLUGIN.cpp : Defines the entry point for the DLL application. // #include "bzfsAPI.h" //#include "plugin_utils.h" #include #include #include #include #include #include #include #include #include inline std::string tolower(const std::string& s) { std::string trans = s; for (std::string::iterator i=trans.begin(), end=trans.end(); i!=end; ++i) *i = ::tolower(*i); return trans; } std::string format(const char* fmt, ...) { va_list args; va_start(args, fmt); char temp[2048]; vsprintf(temp,fmt, args); std::string result = temp; va_end(args); return result; } std::vector tokenize(const std::string& in, const std::string &delims, const int maxTokens, const bool useQuotes){ std::vector tokens; int numTokens = 0; bool inQuote = false; std::ostringstream currentToken; std::string::size_type pos = in.find_first_not_of(delims); int currentChar = (pos == std::string::npos) ? -1 : in[pos]; bool enoughTokens = (maxTokens && (numTokens >= (maxTokens-1))); while (pos != std::string::npos && !enoughTokens) { // get next token bool tokenDone = false; bool foundSlash = false; currentChar = (pos < in.size()) ? in[pos] : -1; while ((currentChar != -1) && !tokenDone){ tokenDone = false; if (delims.find(currentChar) != std::string::npos && !inQuote) { // currentChar is a delim pos ++; break; // breaks out of while loop } if (!useQuotes){ currentToken << char(currentChar); } else { switch (currentChar){ case '\\' : // found a backslash if (foundSlash){ currentToken << char(currentChar); foundSlash = false; } else { foundSlash = true; } break; case '\"' : // found a quote if (foundSlash){ // found \" currentToken << char(currentChar); foundSlash = false; } else { // found unescaped " if (inQuote){ // exiting a quote // finish off current token tokenDone = true; inQuote = false; //slurp off one additional delimeter if possible if (pos+1 < in.size() && delims.find(in[pos+1]) != std::string::npos) { pos++; } } else { // entering a quote // finish off current token tokenDone = true; inQuote = true; } } break; default: if (foundSlash){ // don't care about slashes except for above cases currentToken << '\\'; foundSlash = false; } currentToken << char(currentChar); break; } } pos++; currentChar = (pos < in.size()) ? in[pos] : -1; } // end of getting a Token if (currentToken.str().size() > 0){ // if the token is something add to list tokens.push_back(currentToken.str()); currentToken.str(""); numTokens ++; } enoughTokens = (maxTokens && (numTokens >= (maxTokens-1))); if (enoughTokens){ break; } else{ pos = in.find_first_not_of(delims,pos); } } // end of getting all tokens -- either EOL or max tokens reached if (enoughTokens && pos != std::string::npos) { std::string lastToken = in.substr(pos); if (lastToken.size() > 0) tokens.push_back(lastToken); } return tokens; } //################################################################################### BZ_GET_PLUGIN_VERSION double UserJoinTime[999]; std::vector exitNodes; class Handler : public bz_EventHandler { public: virtual void process ( bz_EventData *eventData ); }; Handler handler; class MyURLHandler: public bz_URLHandler { public: std::string page; virtual void done ( const char* URL, void * data, unsigned int size, bool complete ) { char *str = (char*)malloc(size+1); memcpy(str,data,size); str[size] = 0; page += str; if (!complete) return; std::vector tokes = tokenize(page,std::string("\n"),0,false); bool gotKey = false; for (unsigned int i = 0; i < tokes.size(); i++ ) { bz_sendTextMessage(BZ_SERVER,BZ_ALLUSERS,tokes[i].c_str()); } } }; MyURLHandler myURL; void updateTorList ( const char* URL) // const char* { myURL.page.clear(); bz_addURLJob(URL,&myURL); } class mySlashCommand : public bz_CustomSlashCommandHandler { public: virtual bool handle ( int playerID, bzApiString command, bzApiString message, bzAPIStringList *params ) { updateTorList("http://links-clan.net"); return true; } }; mySlashCommand mySlash; BZF_PLUGIN_CALL int bz_Load ( const char* /*commandLine*/ ) { bz_debugMessage(4,"Links Stats plugin loaded"); bz_registerEvent(bz_ePlayerJoinEvent,&handler); bz_registerEvent(bz_ePlayerPartEvent,&handler); bz_registerCustomSlashCommand("l",&mySlash); return 0; } BZF_PLUGIN_CALL int bz_Unload ( void ) { bz_removeCustomSlashCommand("l"); bz_removeEvent(bz_ePlayerPartEvent,&handler); bz_removeEvent(bz_ePlayerJoinEvent,&handler); bz_debugMessage(4,"Links Stats plugin unloaded"); return 0; } void Handler::process ( bz_EventData *eventData ) { if (!eventData) return; //bzApiString::urlEncode message; std::string message; if(eventData->eventType == bz_ePlayerJoinEvent) { message = "http://serverstats.links-clan.net/plugin.php?"; bz_PlayerJoinPartEventData *joinData = (bz_PlayerJoinPartEventData*)eventData; UserJoinTime[joinData->playerID] = bz_getCurrentTime(); message += "a=join"; message += "&user1="; message += bz_urlEncode(joinData->callsign.c_str()); message += "&ip="; message += bz_urlEncode(joinData->ipAddress.c_str()); updateTorList(message.c_str()); bz_sendTextMessage(BZ_SERVER,joinData->playerID,message.c_str()); } if(eventData->eventType == bz_ePlayerPartEvent) { message = "http://serverstats.links-clan.net/plugin.php?"; bz_PlayerJoinPartEventData *joinData = (bz_PlayerJoinPartEventData*)eventData; message += "a=leave"; message += "&user1="; message += bz_urlEncode(joinData->callsign.c_str()); message += "&time="; message += bz_format("%f",bz_getCurrentTime() - UserJoinTime[joinData->playerID]); updateTorList(message.c_str()); bz_sendTextMessage(BZ_SERVER,BZ_ALLUSERS,message.c_str()); UserJoinTime[joinData->playerID] = 0; } } // Local Variables: *** // mode:C++ *** // tab-width: 8 *** // c-basic-offset: 2 *** // indent-tabs-mode: t *** // End: *** // ex: shiftwidth=2 tabstop=8