void leagueOverSeer::URLDone(const char* /*URL*/, const void* data, unsigned int /*size*/, bool /*complete*/) //Everything went fine with the report { std::string siteData = (const char*)(data); //Convert the data to a std::string bz_debugMessagef(1, "URL Job Successful! Data returned: %s", siteData.c_str()); if (strcmp(siteData.substr(0, 6).c_str(), "INSERT") == 0 || strcmp(siteData.substr(0, 6).c_str(), "DELETE") == 0) doQuery(siteData); else if (strcmp(siteData.c_str(), "<html>") < 0) { bz_sendTextMessagef(BZ_SERVER, BZ_ALLUSERS, "%s", siteData.c_str()); bz_debugMessagef(DEBUG, "%s", siteData.c_str()); } }
sqlite3_stmt* leagueOverSeer::prepareQuery(std::string sql) { /* Thanks to blast for this function */ // Search our std::map for this statement PreparedStatementMap::iterator itr = preparedStatements.find(sql); // If it doesn't exist, create it if (itr == preparedStatements.end()) { sqlite3_stmt* newStatement; if (sqlite3_prepare_v2(db, sql.c_str(), -1, &newStatement, 0) != SQLITE_OK) { bz_debugMessagef(2, "DEBUG :: League Over Seer :: SQLite :: Failed to generate prepared statement for '%s' :: Error #%i: %s", sql.c_str(), sqlite3_errcode(db), sqlite3_errmsg(db)); return NULL; } else { preparedStatements[sql] = newStatement; } } return preparedStatements[sql]; }
void leagueOverSeer::doQuery(std::string query) { /* Execute a SQL query without the need of any return values */ bz_debugMessage(2, "DEBUG :: League Over Seer :: Executing following SQL query..."); bz_debugMessagef(2, "DEBUG :: League Over Seer :: %s", query.c_str()); char* db_err = 0; //a place to store the error sqlite3_exec(db, query.c_str(), NULL, 0, &db_err); //execute if (db_err != 0) //print out any errors { bz_debugMessage(2, "DEBUG :: League Over Seer :: SQL ERROR!"); bz_debugMessagef(2, "DEBUG :: League Over Seer :: %s", db_err); } }
void leagueOverSeer::updateTeamNames(void) { int totaltanks = bz_getTeamCount(eRogueTeam) + bz_getTeamCount(eRedTeam) + bz_getTeamCount(eGreenTeam) + bz_getTeamCount(eBlueTeam) + bz_getTeamCount(ePurpleTeam) + bz_getTeamCount(eObservers); if (totaltanks > 0) return; // Build the POST data for the URL job std::string teamNameDump = "query=teamDump"; bz_debugMessagef(DEBUG, "DEBUG :: League Over Seer :: Updating Team name database..."); bz_addURLJob(LEAGUE_URL.c_str(), this, teamNameDump.c_str()); //Send the team update request to the league website }
void LogDetail::Init ( const char* /*commandLine*/ ) { Register(bz_eSlashCommandEvent); Register(bz_eRawChatMessageEvent); Register(bz_eServerMsgEvent); Register(bz_ePlayerJoinEvent); Register(bz_ePlayerPartEvent); Register(bz_ePlayerAuthEvent); Register(bz_eMessageFilteredEvent); bz_debugMessage(0, "SERVER-STATUS Running"); bz_debugMessagef(0, "SERVER-MAPNAME %s", bz_getPublicDescription().c_str()); listPlayers( join , NULL ); }
void leagueOverSeer::Cleanup (void) { bz_debugMessagef(0, "League Over Seer %i.%i.%i (%i) unloaded.", MAJOR, MINOR, REV, BUILD); Flush(); // Clean up all the events // Remove the prepared SQLite statement from memory sqlite3_finalize(getPlayerMotto); // Remove all the slash commands bz_removeCustomSlashCommand("official"); bz_removeCustomSlashCommand("fm"); bz_removeCustomSlashCommand("finish"); bz_removeCustomSlashCommand("cancel"); bz_removeCustomSlashCommand("spawn"); bz_removeCustomSlashCommand("resume"); bz_removeCustomSlashCommand("pause"); }
void HTTPServer::process(bz_EventData *eventData) { if (eventData->eventType == bz_eTickEvent) { update(); } else { bz_NewNonPlayerConnectionEventData_V1 *connData = (bz_NewNonPlayerConnectionEventData_V1*)eventData; // log out the data if our level is high enough if (bz_getDebugLevel() >= 4) { char *temp = (char*)malloc(connData->size+1); memcpy(temp,connData->data,connData->size); temp[connData->size] = 0; bz_debugMessagef(4,"Plug-in HTTPServer: Non ProtoConnection connection from %d with %s",connData->connectionID,temp); free(temp); } // we go an accept everyone so that we can see if they are going to give us an HTTP command if(bz_registerNonPlayerConnectionHandler(connData->connectionID, this)) { // record the connection HTTPConnection connection; connection.connectionID = connData->connectionID; connection.request = eUnknown; connection.sessionID = generateSessionID(); // new ID in case they don't have one HTTPConnectionMap::iterator itr = liveConnections.find(connection.connectionID); if (itr != liveConnections.end()) liveConnections.erase(itr); // something weird is happening here liveConnections[connection.connectionID] = connection; // go and process any data they have and see what the deal is pending(connData->connectionID, (char*)connData->data, connData->size); } } }
void HTTPServer::pending(int connectionID, void *d, unsigned int s) { HTTPConnectionMap::iterator itr = liveConnections.find(connectionID); if (itr == liveConnections.end()) return; HTTPConnection &connection = itr->second; // grab the current data if(d && s) { char *t = (char*)malloc(s+1); memcpy(t,d,s); t[s] = 0; connection.currentData += t; free(t); } // see what our status is if (!connection.request) { std::stringstream stream(connection.currentData); std::string request, resource, httpVersion; stream >> request >> resource >> httpVersion; if (request.size() && resource.size() && httpVersion.size()) { if (compare_nocase(request,"get") == 0) connection.request = eGet; else if (compare_nocase(request,"head") == 0) connection.request = eHead; else if (compare_nocase(request,"post") == 0) connection.request = ePost; else if (compare_nocase(request,"put") == 0) connection.request = ePut; else if (compare_nocase(request,"delete") == 0) connection.request = eDelete; else if (compare_nocase(request,"trace") == 0) connection.request = eTrace; else if (compare_nocase(request,"options") == 0) connection.request = eOptions; else if (compare_nocase(request,"connect") == 0) connection.request = eConnect; else connection.request = eOther; if (httpVersion != "HTTP/1.1" && httpVersion != "HTTP/1.0") bz_debugMessagef(1,"HTTPServer HTTP version of %s requested",httpVersion.c_str()); if (resource.size() > 1) { size_t p = resource.find_first_of('/'); if (p != std::string::npos) { if (p == 0) p = resource.find_first_of('/',p+1); if (p == std::string::npos) { // there is only one / so the stuff after the slash in the vdir and the resource is NULL connection.vdir.resize(resource.size()-1); std::copy(resource.begin()+1,resource.end(),connection.vdir.begin()); } else { connection.vdir.resize(p-1); std::copy(resource.begin()+1,resource.begin()+p,connection.vdir.begin()); connection.resource.resize(resource.size()-p-1); std::copy(resource.begin()+p+1,resource.end(),connection.resource.begin()); } } } } }
void LogDetail::Event( bz_EventData *eventData ) { bz_ChatEventData_V1 *chatData = (bz_ChatEventData_V1 *) eventData; bz_ServerMsgEventData_V1 *serverMsgData = (bz_ServerMsgEventData_V1 *) eventData; bz_SlashCommandEventData_V1 *cmdData = (bz_SlashCommandEventData_V1 *) eventData; bz_PlayerJoinPartEventData_V1 *joinPartData = (bz_PlayerJoinPartEventData_V1 *) eventData; bz_PlayerAuthEventData_V1 *authData = (bz_PlayerAuthEventData_V1 *) eventData; bz_MessageFilteredEventData_V1 *filteredData = (bz_MessageFilteredEventData_V1 *) eventData; char temp[9] = {0}; if (eventData) { switch (eventData->eventType) { case bz_eSlashCommandEvent: // Slash commands are case insensitive // Tokenize the stream and check the first word // /report -> MSG-REPORT // anything -> MSG-COMMAND strncpy(temp, cmdData->message.c_str(), 8); if (strcasecmp( temp, "/REPORT ") == 0) { bz_debugMessagef(0, "MSG-REPORT %s %s", displayCallsign( cmdData->from ).c_str(), cmdData->message.c_str()+8); } else { bz_debugMessagef(0, "MSG-COMMAND %s %s", displayCallsign( cmdData->from ).c_str(), cmdData->message.c_str()+1); } break; case bz_eRawChatMessageEvent: if ((chatData->to == BZ_ALLUSERS) && (chatData->team == eNoTeam)) { bz_debugMessagef(0, "MSG-BROADCAST %s %s", displayCallsign( chatData->from ).c_str(), chatData->message.c_str()); } else if (chatData->to == BZ_NULLUSER) { if (chatData->team == eAdministrators) { bz_debugMessagef(0, "MSG-ADMIN %s %s", displayCallsign( chatData->from ).c_str(), chatData->message.c_str()); } else { bz_debugMessagef(0, "MSG-TEAM %s %s %s", displayCallsign( chatData->from ).c_str(), displayTeam( chatData->team ).c_str(), chatData->message.c_str()); } } else { bz_debugMessagef(0, "MSG-DIRECT %s %s %s", displayCallsign( chatData->from ).c_str(), displayCallsign( chatData->to ).c_str(), chatData->message.c_str()); } break; case bz_eMessageFilteredEvent: bz_debugMessagef(0, "MSG-FILTERED %s %s", displayCallsign( filteredData->playerID ).c_str(), filteredData->filteredMessage.c_str()); break; case bz_eServerMsgEvent: if ((serverMsgData->to == BZ_ALLUSERS) && (serverMsgData->team == eNoTeam)) { bz_debugMessagef(0, "MSG-BROADCAST 6:SERVER %s", serverMsgData->message.c_str()); } else if (serverMsgData->to == BZ_NULLUSER) { if (serverMsgData->team == eAdministrators) { bz_debugMessagef(0, "MSG-ADMIN 6:SERVER %s", serverMsgData->message.c_str()); } else { bz_debugMessagef(0, "MSG-TEAM 6:SERVER %s %s", displayTeam( serverMsgData->team ).c_str(), serverMsgData->message.c_str()); } } else { bz_debugMessagef(0, "MSG-DIRECT 6:SERVER %s %s", displayCallsign( serverMsgData->to ).c_str(), serverMsgData->message.c_str()); } break; case bz_ePlayerJoinEvent: { if (joinPartData->record) { bz_debugMessagef(0, "PLAYER-JOIN %s #%d%s %s %s", displayCallsign( joinPartData->playerID).c_str(), joinPartData->playerID, displayBZid( joinPartData->playerID ).c_str(), displayTeam( joinPartData->record->team ).c_str(), displayPlayerPrivs( joinPartData->playerID ).c_str()); listPlayers( join, joinPartData); } } break; case bz_ePlayerPartEvent: bz_debugMessagef(0, "PLAYER-PART %s #%d%s %s", displayCallsign( joinPartData->playerID ).c_str(), joinPartData->playerID, displayBZid( joinPartData->playerID ).c_str(), joinPartData->reason.c_str()); listPlayers( part, joinPartData); break; case bz_ePlayerAuthEvent: bz_debugMessagef(0, "PLAYER-AUTH %s %s", displayCallsign( authData->playerID ).c_str(), displayPlayerPrivs( authData->playerID ).c_str()), listPlayers( join, joinPartData); break; default : break; } } }
void leagueOverSeer::Init (const char* commandLine) { bz_debugMessagef(0, "League Over Seer %i.%i.%i (%i) loaded.", MAJOR, MINOR, REV, BUILD); Register(bz_eCaptureEvent); Register(bz_eGameEndEvent); Register(bz_eGameStartEvent); Register(bz_eGetPlayerMotto); Register(bz_ePlayerJoinEvent); Register(bz_eTickEvent); bz_registerCustomSlashCommand("official", this); bz_registerCustomSlashCommand("fm",this); bz_registerCustomSlashCommand("finish",this); bz_registerCustomSlashCommand("cancel",this); bz_registerCustomSlashCommand("spawn",this); bz_registerCustomSlashCommand("resume",this); bz_registerCustomSlashCommand("pause",this); //Set all boolean values for the plugin to false officialMatch = false; doNotReportMatch = false; matchParticipantsRecorded = false; funMatch = false; teamOnePoints = 0; teamTwoPoints = 0; matchDuration = bz_getTimeLimit(); matchStartTime = 0; matchRollCall = 90; loadConfig(commandLine); //Load the configuration data when the plugin is loaded if (mapchangePath != "" && rotLeague) //Check to see if the plugin is for a rotational league { //Open the mapchange.out file to see what map is being used std::ifstream infile; infile.open(mapchangePath.c_str()); getline(infile,map); infile.close(); map = map.substr(0, map.length() - 5); //Remove the '.conf' from the mapchange.out file bz_debugMessagef(DEBUG, "DEBUG :: League Over Seer :: Current map being played: %s", map.c_str()); } teamOne = eNoTeam; teamTwo = eNoTeam; while (teamOne == eNoTeam || teamTwo == eNoTeam) { if (bz_getTeamPlayerLimit(eRedTeam) > 0 && teamOne == eNoTeam) { teamOne = eRedTeam; continue; } if (bz_getTeamPlayerLimit(eGreenTeam) > 0 && teamOne == eNoTeam) { teamOne = eGreenTeam; continue; } if (bz_getTeamPlayerLimit(eBlueTeam) > 0 && teamOne == eNoTeam) { teamOne = eBlueTeam; continue; } if (bz_getTeamPlayerLimit(ePurpleTeam) > 0 && teamOne == eNoTeam) { teamOne = ePurpleTeam; continue; } // Figure out the other team if (bz_getTeamPlayerLimit(eRedTeam) > 0 && teamOne != eRedTeam && teamTwo == eNoTeam) { teamTwo = eRedTeam; continue; } if (bz_getTeamPlayerLimit(eGreenTeam) > 0 && teamOne != eGreenTeam && teamTwo == eNoTeam) { teamTwo = eGreenTeam; continue; } if (bz_getTeamPlayerLimit(eBlueTeam) > 0 && teamOne != eBlueTeam && teamTwo == eNoTeam) { teamTwo = eBlueTeam; continue; } if (bz_getTeamPlayerLimit(ePurpleTeam) > 0 && teamOne != ePurpleTeam && teamTwo == eNoTeam) { teamTwo = ePurpleTeam; continue; } } bz_debugMessagef(0, "DEBUG :: League Over Seer :: Using the following database: %s", SQLiteDB.c_str()); sqlite3_open(SQLiteDB.c_str(),&db); if (db == 0) //we couldn't read the database provided { bz_debugMessagef(0, "DEBUG :: League Over Seer :: Error! Could not connect to: %s", SQLiteDB.c_str()); bz_debugMessage(0, "DEBUG :: League Over Seer :: Unloading League Over Seer plugin..."); bz_unloadPlugin(Name()); } if (db != 0) //if the database connection succeed and the database is empty, let's create the tables needed doQuery("CREATE TABLE IF NOT EXISTS [Players] (BZID INTEGER NOT NULL PRIMARY KEY DEFAULT 0, TEAM TEXT NOT NULL DEFAULT Teamless, SQUAD TEXT);"); // Prepare the SQL query to get the team names based on a BZID getPlayerMotto = prepareQuery("SELECT team FROM players WHERE bzid = ?"); updateTeamNames(); }
void leagueOverSeer::URLError(const char* /*URL*/, int errorCode, const char *errorString) //The server owner must have set up the URLs wrong because this shouldn't happen { bz_debugMessage(DEBUG, "DEBUG :: League Over Seer :: Match report failed with the following error:"); bz_debugMessagef(DEBUG, "DEBUG :: League Over Seer :: Error code: %i - %s", errorCode, errorString); }
bool leagueOverSeer::SlashCommand(int playerID, bz_ApiString command, bz_ApiString /*message*/, bz_APIStringList *params) { int timeToStart = atoi(params->get(0).c_str()); bz_BasePlayerRecord *playerData = bz_getPlayerByIndex(playerID); if (command == "official") //Someone used the /official command { if (playerData->team == eObservers) //Observers can't start matches bz_sendTextMessage(BZ_SERVER, playerID, "Observers are not allowed to start matches."); else if ((bz_getTeamCount(eRedTeam) < 2 && bz_getTeamPlayerLimit(eRedTeam) > 0) || (bz_getTeamCount(eGreenTeam) < 2 && bz_getTeamPlayerLimit(eGreenTeam) > 0) || (bz_getTeamCount(eBlueTeam) < 2 && bz_getTeamPlayerLimit(eBlueTeam) > 0) || (bz_getTeamCount(ePurpleTeam) < 2 && bz_getTeamPlayerLimit(ePurpleTeam) > 0)) //An official match cannot be 1v1 or 2v1 bz_sendTextMessage(BZ_SERVER, playerID, "You may not have an official match with less than 2 players per team."); else if (funMatch) //A fun match cannot be declared an official match bz_sendTextMessage(BZ_SERVER,playerID,"Fun matches cannot be turned into official matches."); else if (!playerData->verified || !bz_hasPerm(playerID,"spawn")) //If they can't spawn, they aren't a league player so they can't start a match bz_sendTextMessage(BZ_SERVER,playerID,"Only registered league players may start an official match."); else if (bz_isCountDownActive() || bz_isCountDownInProgress()) //A countdown is in progress already bz_sendTextMessage(BZ_SERVER,playerID,"There is currently a countdown active, you may not start another."); else if (playerData->verified && playerData->team != eObservers && bz_hasPerm(playerID,"spawn") && !bz_isCountDownActive() && !funMatch) //Check the user is not an obs and is a league member { officialMatch = true; //Notify the plugin that the match is official bz_debugMessagef(DEBUG, "DEBUG :: League Over Seer :: Official match started by %s (%s).", playerData->callsign.c_str(), playerData->ipAddress.c_str()); bz_sendTextMessagef(BZ_SERVER, BZ_ALLUSERS, "Official match started by %s.", playerData->callsign.c_str()); if (timeToStart <= 120 && timeToStart > 5) bz_startCountdown (timeToStart, bz_getTimeLimit(), "Server"); //Start the countdown with a custom countdown time limit under 2 minutes else bz_startCountdown (10, bz_getTimeLimit(), "Server"); //Start the countdown for the official match } else bz_sendTextMessage(BZ_SERVER, playerID, "You do not have permission to run the /official command."); return true; } else if (command == "fm") //Someone uses the /fm command { if (bz_isCountDownActive() || bz_isCountDownInProgress() || funMatch || officialMatch) //There is already a countdown bz_sendTextMessage(BZ_SERVER, playerID, "There is currently a countdown active, you may not start another."); else if (playerData->team == eObservers) //Observers can't start matches bz_sendTextMessage(BZ_SERVER,playerID,"Observers are not allowed to start matches."); else if (!playerData->verified || !bz_hasPerm(playerID,"spawn")) //If they can't spawn, they aren't a league player so they can't start a match bz_sendTextMessage(BZ_SERVER,playerID,"Only registered league players may start an official match."); else if (!bz_isCountDownActive() && playerData->team != eObservers && bz_hasPerm(playerID,"spawn") && playerData->verified && !officialMatch) { funMatch = true; //It's a fun match bz_debugMessagef(DEBUG, "DEBUG :: League Over Seer :: Fun match started by %s (%s).", playerData->callsign.c_str(), playerData->ipAddress.c_str()); bz_sendTextMessagef(BZ_SERVER, BZ_ALLUSERS, "Fun match started by %s.", playerData->callsign.c_str()); if (timeToStart <= 120 && timeToStart > 5) bz_startCountdown (timeToStart, bz_getTimeLimit(), "Server"); //Start the countdown with a custom countdown time limit under 2 minutes else bz_startCountdown (10, bz_getTimeLimit(), "Server"); //Start the countdown for the official match } else bz_sendTextMessage(BZ_SERVER,playerID,"You do not have permission to run the /fm command."); return true; } else if (command == "cancel") { if (bz_hasPerm(playerID,"spawn") && bz_isCountDownActive()) { if (officialMatch) { bz_sendTextMessagef(BZ_SERVER, BZ_ALLUSERS, "Official match ended by %s", playerData->callsign.c_str()); bz_debugMessagef(DEBUG, "DEBUG :: League Over Seer :: Match ended by %s (%s).", playerData->callsign.c_str(),playerData->ipAddress.c_str()); } else { bz_sendTextMessagef(BZ_SERVER, BZ_ALLUSERS, "Fun match ended by %s", playerData->callsign.c_str()); bz_debugMessagef(DEBUG, "DEBUG :: League Over Seer :: Match ended by %s (%s).", playerData->callsign.c_str(),playerData->ipAddress.c_str()); } //Reset the server. Cleanly ends a match officialMatch = false; doNotReportMatch = true; funMatch = false; teamOnePoints = 0; teamTwoPoints = 0; //End the countdown if (bz_isCountDownActive()) bz_gameOver(253, eObservers); } else if (!bz_isCountDownActive()) bz_sendTextMessage(BZ_SERVER, playerID, "There is no match in progress to cancel."); else //Not a league player bz_sendTextMessage(BZ_SERVER, playerID, "You do not have permission to run the /cancel command."); return true; } else if (command == "finish") { if (bz_hasPerm(playerID,"spawn") && bz_isCountDownActive() && officialMatch) { bz_debugMessagef(DEBUG, "DEBUG :: Match Over Seer :: Official match ended early by %s (%s)", playerData->callsign.c_str(), playerData->ipAddress.c_str()); bz_sendTextMessagef(BZ_SERVER, BZ_ALLUSERS, "Official match ended early by %s", playerData->callsign.c_str()); doNotReportMatch = false; //To prevent reporting a canceled match, let plugin know the match was canceled //End the countdown if (bz_isCountDownActive()) bz_gameOver(253, eObservers); } else if (!bz_isCountDownActive()) bz_sendTextMessage(BZ_SERVER, playerID, "There is no match in progress to end."); else if (!officialMatch) bz_sendTextMessage(BZ_SERVER, playerID, "You cannot /finish a fun match. Use /cancel instead."); else //Not a league player bz_sendTextMessage(BZ_SERVER, playerID, "You do not have permission to run the /finish command."); return true; } else if (command == "pause") { if (bz_isCountDownActive() && bz_hasPerm(playerID,"spawn") && playerData->verified) bz_pauseCountdown(playerData->callsign.c_str()); else if (!bz_isCountDownActive()) bz_sendTextMessage(BZ_SERVER, playerID, "There is no active match to pause right now."); else bz_sendTextMessage(BZ_SERVER, playerID, "You are not have permission to run the /pause command."); return true; } else if (command == "resume") { if (bz_hasPerm(playerID,"spawn") && playerData->verified && bz_isCountDownActive()) bz_resumeCountdown(playerData->callsign.c_str()); else if (!bz_isCountDownActive()) bz_sendTextMessage(BZ_SERVER, playerID, "The current match is not paused."); else bz_sendTextMessage(BZ_SERVER, playerID, "You are not have permission to run the /resume command."); return true; } else if (command == "spawn") { if (bz_hasPerm(playerID, "ban")) { if (params->size() > 0) { std::string callsignToLookup; //store the callsign we're going to search for for (unsigned int i = 0; i < params->size(); i++) //piece together the callsign from the slash command parameters { callsignToLookup += params->get(i).c_str(); if (i != params->size() - 1) // so we don't stick a whitespace on the end callsignToLookup += " "; // add a whitespace between each chat text parameter } if (std::string::npos != std::string(params->get(0).c_str()).find("#") && isValidPlayerID(atoi(std::string(params->get(0).c_str()).erase(0, 1).c_str()))) { bz_grantPerm(atoi(std::string(params->get(0).c_str()).erase(0, 1).c_str()), "spawn"); bz_sendTextMessagef(BZ_SERVER, eAdministrators, "%s gave spawn perms to %s", bz_getPlayerByIndex(playerID)->callsign.c_str(), bz_getPlayerByIndex(atoi(std::string(params->get(0).c_str()).substr(0, 1).c_str()))->callsign.c_str()); } else if (isValidCallsign(callsignToLookup) >= 0) { bz_grantPerm(isValidCallsign(callsignToLookup), "spawn"); bz_sendTextMessagef(BZ_SERVER, eAdministrators, "%s gave spawn perms to %s", bz_getPlayerByIndex(playerID)->callsign.c_str(), bz_getPlayerByIndex(isValidCallsign(callsignToLookup))->callsign.c_str()); } else bz_sendTextMessagef(BZ_SERVER, playerID, "player %s not found", params->get(0).c_str()); } else bz_sendTextMessage(BZ_SERVER, playerID, "/spawn <player id or callsign>"); } else if (!playerData->admin) bz_sendTextMessage(BZ_SERVER,playerID,"You do not have permission to use the /spawn command."); return true; } bz_freePlayerRecord(playerData); return false; }
void leagueOverSeer::Event(bz_EventData *eventData) { switch (eventData->eventType) { case bz_eCaptureEvent: //Someone caps { bz_CTFCaptureEventData_V1 *capData = (bz_CTFCaptureEventData_V1*)eventData; if (officialMatch) //Only keep score if it's official { if (capData->teamCapping == teamOne) teamOnePoints++; else if (capData->teamCapping == teamTwo) teamTwoPoints++; } } break; case bz_eGameEndEvent: //A /gameover or a match has ended { //Clear the bool variables funMatch = false; matchStartTime = 0; matchParticipantsRecorded = false; if (doNotReportMatch && officialMatch) //The match was canceled via /gameover or /superkill and we do not want to report these matches { officialMatch = false; //Match is over doNotReportMatch = false; //Reset the variable for next usage teamOnePoints = 0; teamTwoPoints = 0; matchPlayers.clear(); bz_debugMessage(DEBUG, "DEBUG :: League Over Seer :: Official match was not reported."); bz_sendTextMessage(BZ_SERVER, BZ_ALLUSERS, "Official match was not reported."); } else if (officialMatch) { officialMatch = false; //Match is over time_t t = time(NULL); //Get the current time tm * now = gmtime(&t); char match_date[20]; sprintf(match_date, "%02d-%02d-%02d %02d:%02d:%02d", now->tm_year + 1900, now->tm_mon + 1, now->tm_mday, now->tm_hour, now->tm_min, now->tm_sec); //Format the date to -> year-month-day hour:minute:second //Convert ints to std::string with std::ostringstream std::ostringstream teamOnePointsConversion; teamOnePointsConversion << (teamOnePoints); std::ostringstream teamTwoPointsConversion; teamTwoPointsConversion << (teamTwoPoints); std::ostringstream matchTimeConversion; matchTimeConversion << (matchDuration/60); //Keep references to values for quick reference std::string teamOnePointsFinal = teamOnePointsConversion.str(); std::string teamTwoPointsFinal = teamTwoPointsConversion.str(); std::string matchTimeFinal = matchTimeConversion.str(); // Store match data in the logs bz_debugMessagef(DEBUG, "Match Data :: League Over Seer Match Report"); bz_debugMessagef(DEBUG, "Match Data :: -----------------------------"); bz_debugMessagef(DEBUG, "Match Data :: Match Time : %s", match_date); bz_debugMessagef(DEBUG, "Match Data :: Duration : %s", matchTimeFinal.c_str()); bz_debugMessagef(DEBUG, "Match Data :: Team One Score : %s", teamOnePointsFinal.c_str()); bz_debugMessagef(DEBUG, "Match Data :: Team Two Score : %s", teamTwoPointsFinal.c_str()); // Start building POST data to be sent to the league website std::string matchToSend = "query=reportMatch"; matchToSend += "&teamOneWins=" + std::string(bz_urlEncode(teamOnePointsFinal.c_str())); matchToSend += "&teamTwoWins=" + std::string(bz_urlEncode(teamTwoPointsFinal.c_str())); matchToSend += "&duration=" + std::string(bz_urlEncode(matchTimeFinal.c_str())) + "&matchTime=" + std::string(bz_urlEncode(match_date)); if (rotLeague) //Only add this parameter if it's a rotational league such as Open League matchToSend += "&mapPlayed=" + std::string(bz_urlEncode(map.c_str())); matchToSend += "&teamOnePlayers="; bz_debugMessagef(DEBUG, "Match Data :: Team One Players"); for (unsigned int i = 0; i < matchPlayers.size(); i++) //Add all the red players to the match report { if (matchPlayers.at(i).team == teamOne) { matchToSend += std::string(bz_urlEncode(matchPlayers.at(i).bzid.c_str())) + ","; bz_debugMessagef(DEBUG, "Match Data :: %s (%s)", matchPlayers.at(i).callsign.c_str(), matchPlayers.at(i).bzid.c_str()); } } matchToSend.erase(matchToSend.size() - 1); matchToSend += "&teamTwoPlayers="; bz_debugMessagef(DEBUG, "Match Data :: Team Two Players"); for (unsigned int i = 0; i < matchPlayers.size(); i++) //Add all the red players to the match report { if (matchPlayers.at(i).team == teamTwo) { matchToSend += std::string(bz_urlEncode(matchPlayers.at(i).bzid.c_str())) + ","; bz_debugMessagef(DEBUG, "Match Data :: %s (%s)", matchPlayers.at(i).callsign.c_str(), matchPlayers.at(i).bzid.c_str()); } } matchToSend.erase(matchToSend.size() - 1); bz_debugMessagef(DEBUG, "Match Data :: -----------------------------"); bz_debugMessagef(DEBUG, "Match Data :: End of Match Report"); bz_debugMessagef(DEBUG, "DEBUG :: League Over Seer :: Reporting match data..."); bz_sendTextMessage(BZ_SERVER, BZ_ALLUSERS, "Reporting match..."); bz_addURLJob(LEAGUE_URL.c_str(), this, matchToSend.c_str()); //Send the match data to the league website //Clear all the structures and scores for next match matchPlayers.clear(); teamOnePoints = 0; teamTwoPoints = 0; } else bz_debugMessage(DEBUG, "DEBUG :: League Over Seer :: Fun match was not reported."); } break; case bz_eGameStartEvent: //The countdown has started { if (officialMatch) //Don't waste memory if the match isn't official { //Set the team scores to zero just in case teamOnePoints = 0; teamTwoPoints = 0; matchDuration = bz_getTimeLimit(); matchStartTime = bz_getCurrentTime(); doNotReportMatch = false; matchPlayers.clear(); } } break; case bz_eGetPlayerMotto: // Change the motto of a player when they join { bz_GetPlayerMottoData_V2* mottoEvent = (bz_GetPlayerMottoData_V2*)eventData; // Prepare the SQL query with the BZID of the player sqlite3_bind_text(getPlayerMotto, 1, mottoEvent->record->bzID.c_str(), -1, SQLITE_TRANSIENT); if (sqlite3_step(getPlayerMotto) == SQLITE_ROW) // If returns a team name, use it mottoEvent->motto = (const char*)sqlite3_column_text(getPlayerMotto, 0); else mottoEvent->motto = ""; sqlite3_reset(getPlayerMotto); //Clear the prepared statement so it can be reused } case bz_ePlayerJoinEvent: //A player joins { bz_PlayerJoinPartEventData_V1 *joinData = (bz_PlayerJoinPartEventData_V1*)eventData; if (!joinData) return; if ((bz_isCountDownActive() || bz_isCountDownInProgress()) && officialMatch) bz_sendTextMessage(BZ_SERVER, joinData->playerID, "*** There is currently an official match in progress, please be respectful. ***"); else if ((bz_isCountDownActive() || bz_isCountDownInProgress()) && funMatch) bz_sendTextMessage(BZ_SERVER, joinData->playerID, "*** There is currently a fun match in progress, please be respectful. ***"); if (joinData->record->verified) { // Build the POST data for the URL job std::string teamMotto = "query=teamNameQuery"; teamMotto += "&teamPlayers=" + std::string(joinData->record->bzID.c_str()); bz_debugMessagef(DEBUG, "DEBUG :: League Over Seer :: Getting motto for %s...", joinData->record->callsign.c_str()); bz_addURLJob(LEAGUE_URL.c_str(), this, teamMotto.c_str()); //Send the team update request to the league website } } break; case bz_eSlashCommandEvent: //Someone uses a slash command { bz_SlashCommandEventData_V1 *commandData = (bz_SlashCommandEventData_V1*)eventData; bz_BasePlayerRecord *playerData = bz_getPlayerByIndex(commandData->from); std::string command = commandData->message.c_str(); //Use std::string for quick reference if (strncmp("/gameover", commandData->message.c_str(), 9) == 0) bz_sendTextMessagef(BZ_SERVER, commandData->from, "** '/gameover' is disabled, please use /finish or /cancel instead **"); else if (strncmp("/countdown pause", commandData->message.c_str(), 16) == 0) bz_sendTextMessagef(BZ_SERVER, commandData->from, "** '/countdown pause' is disabled, please use /pause instead **"); else if (strncmp("/countdown resume", commandData->message.c_str(), 17 ) == 0) bz_sendTextMessagef(BZ_SERVER, commandData->from, "** '/countdown resume' is disabled, please use /resume instead **"); else if (isdigit(atoi(commandData->message.c_str()) + 12)) bz_sendTextMessage(BZ_SERVER, commandData->from, "** '/countdown TIME' is disabled, please use /official or /fm instead **"); bz_freePlayerRecord(playerData); } break; case bz_eTickEvent: //Tick tock tick tock... { int totaltanks = bz_getTeamCount(eRogueTeam) + bz_getTeamCount(eRedTeam) + bz_getTeamCount(eGreenTeam) + bz_getTeamCount(eBlueTeam) + bz_getTeamCount(ePurpleTeam); if (totaltanks == 0) { //Incase a boolean gets messed up in the plugin, reset all the plugin variables when there are no players (Observers excluded) officialMatch = false; doNotReportMatch = false; funMatch = false; teamOnePoints = 0; teamTwoPoints = 0; //This should never happen but just incase the countdown is going when there are no tanks if (bz_isCountDownActive()) bz_gameOver(253, eObservers); } if (matchStartTime > 0 && matchStartTime + matchRollCall < bz_getCurrentTime() && officialMatch && !matchParticipantsRecorded) { bool invalidateRollCall = false; bz_APIIntList *playerList = bz_newIntList(); bz_getPlayerIndexList(playerList); for (unsigned int i = 0; i < playerList->size(); i++) { bz_BasePlayerRecord *playerRecord = bz_getPlayerByIndex(playerList->get(i)); if (bz_getPlayerTeam(playerList->get(i)) != eObservers) //If player is not an observer { playersInMatch currentPlayer; currentPlayer.team = playerRecord->team; //Add team to structure currentPlayer.callsign = playerRecord->callsign.c_str(); //Add team to structure currentPlayer.bzid = playerRecord->bzID.c_str(); //Add bzid to structure if (std::string(playerRecord->bzID.c_str()).empty()) invalidateRollCall = true; matchPlayers.push_back(currentPlayer); } bz_freePlayerRecord(playerRecord); } bz_deleteIntList(playerList); if (invalidateRollCall && matchRollCall < matchDuration) { bz_debugMessagef(DEBUG, "DEBUG :: League Over Seer :: Invalid player found on field at %i:%i.", (int)(matchRollCall/60), (int)(fmod(matchRollCall,60.0))); matchParticipantsRecorded = false; matchRollCall += 30; matchPlayers.clear(); } else matchParticipantsRecorded = true; } } break; default: break; } }