Пример #1
0
void ResetZeroTeams()
{

    if (bz_getTeamCount(eRedTeam) == 0)
    {
        tctf.redLastTime = bz_getCurrentTime ();
        tctf.redLastWarn = bz_getCurrentTime ();
    }
    if (bz_getTeamCount(eGreenTeam) == 0)
    {
        tctf.greenLastTime = bz_getCurrentTime ();
        tctf.greenLastWarn = bz_getCurrentTime ();
    }
    if (bz_getTeamCount(eBlueTeam) == 0)
    {
        tctf.blueLastTime = bz_getCurrentTime ();
        tctf.blueLastWarn = bz_getCurrentTime ();
    }
    if (bz_getTeamCount(ePurpleTeam) == 0)
    {
        tctf.purpleLastTime = bz_getCurrentTime ();
        tctf.purpleLastWarn = bz_getCurrentTime ();
    }
    return;
}
Пример #2
0
bool fairCTF::isEven(bz_eTeamType teamLeaving)
{

  int teamsizes[4]; 

  teamsizes[0] = bz_getTeamCount (eRedTeam);
  teamsizes[1] = bz_getTeamCount (eGreenTeam);
  teamsizes[2] = bz_getTeamCount (eBlueTeam);
  teamsizes[3] = bz_getTeamCount (ePurpleTeam);
  
  int leavingTeamIndex = (int)teamLeaving;
  if (leavingTeamIndex >= 1 && leavingTeamIndex <= 4)
  {
    // Decrement the team count for the player that's leaving the game.
    teamsizes[leavingTeamIndex - 1]--;
  }


  //check fairness

  int smallestTeam = 10000; //impossibly high
  int largestTeam = 0;

  for (int x = 0; x < 4; x++)
  {
    if (teamsizes[x] > largestTeam)
    {
      largestTeam = teamsizes[x];
    }
    if (teamsizes[x] != 0 && teamsizes[x] < smallestTeam)
    {
      smallestTeam = teamsizes[x];
    }
  }

  //check differences and ratios

  if (smallestTeam == 10000 || largestTeam == smallestTeam) //equal, or server has no team tanks
  {
    return true;
  }
  if (smallestTeam <= max_gap_by_1) // user-defined cap on a difference of 1
  {
    return false;
  }
  if (largestTeam - smallestTeam == 1) //after UD limit
  {
    return true;
  }
  if ((static_cast<float> (largestTeam - smallestTeam)) / smallestTeam > max_ratio) //greater than specified gap
  {
    return false;
  }
  if (largestTeam - smallestTeam >= max_gap) 
  {
    return false;
  }

  return true; 
}
Пример #3
0
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
}
Пример #4
0
void killAllHunters(std::string messagepass)
{
  bz_APIIntList *playerList = bz_newIntList();
  bz_getPlayerIndexList(playerList);


  for (unsigned int i = 0; i < playerList->size(); i++){

    bz_BasePlayerRecord *player = bz_getPlayerByIndex(playerList->operator[](i));

    if (player) {
      if (player->team != eRabbitTeam) {
	bz_killPlayer(player->playerID, true, BZ_SERVER);
	bz_sendTextMessage(BZ_SERVER, player->playerID, messagepass.c_str());
	if (rrzoneinfo.soundEnabled)
	  bz_sendPlayCustomLocalSound(player->playerID,"flag_lost");
      }
      if (player->team == eRabbitTeam &&
	  rrzoneinfo.soundEnabled &&
	  bz_getTeamCount(eHunterTeam) > 0)
	bz_sendPlayCustomLocalSound(player->playerID,"flag_won");

      bz_freePlayerRecord(player);
    }
  }

  bz_deleteIntList(playerList);

  return;
}
Пример #5
0
bool OnlyOneTeamPlaying()
{
  int R = bz_getTeamCount(eRedTeam);
  int G = bz_getTeamCount(eGreenTeam);
  int B = bz_getTeamCount(eBlueTeam);
  int P = bz_getTeamCount(ePurpleTeam);

  if (R == 0 && G == 0 && B == 0 && P > 0)
    return true;
  if (R == 0 && G == 0 && P == 0 && B > 0)
    return true;
  if (R == 0 && B == 0 && P == 0 && G > 0)
    return true;
  if (G == 0 && B == 0 && P == 0 && R > 0)
    return true;

  return false;
}
Пример #6
0
void autoTime()
{
	int numPlayers = bz_getTeamCount(eRedTeam) + bz_getTeamCount(eGreenTeam) + bz_getTeamCount(eBlueTeam) + bz_getTeamCount(ePurpleTeam) + bz_getTeamCount(eRogueTeam);

	if (!keepaway.autoTimeOn || numPlayers < 3)
	{
		keepaway.adjustedTime = keepaway.TTH;
		return;
	}

	double timeDown = ( 1 - ((double)numPlayers - 2) * keepaway.timeMult);

	if (timeDown < keepaway.timeMultMin)
		timeDown = keepaway.timeMultMin;

	keepaway.adjustedTime = (int)(keepaway.TTH * timeDown);

	return;
}
Пример #7
0
bool onePlayer()
{
  int numPlayers =
      bz_getTeamCount(eRedTeam) + bz_getTeamCount(eGreenTeam) + bz_getTeamCount(eBlueTeam) + bz_getTeamCount(ePurpleTeam) +
      bz_getTeamCount(eRogueTeam);

  if (numPlayers <= 1) {
    if (!koth.onePlayerWarn)
      bz_sendTextMessage(BZ_SERVER, BZ_ALLUSERS, "King of the Hill disabled: less than 2 players.");

    koth.onePlayerWarn = true;
    return true;
  } else {
    if (koth.onePlayerWarn)
      bz_sendTextMessage(BZ_SERVER, BZ_ALLUSERS, "King of the Hill enabled: more than 1 player.");

    koth.onePlayerWarn = false;
    return false;
  }
}
Пример #8
0
inline bool oneTeam(bz_eTeamType leavingPlayerTeam)
{
	int RT = bz_getTeamCount(eRedTeam);
	int GT = bz_getTeamCount(eGreenTeam);
	int BT = bz_getTeamCount(eBlueTeam);
	int PT = bz_getTeamCount(ePurpleTeam);
	int RGT = bz_getTeamCount(eRogueTeam);

	if (leavingPlayerTeam == eRedTeam)
		RT--;
	if (leavingPlayerTeam == eGreenTeam)
		GT--;
	if (leavingPlayerTeam == eBlueTeam)
		BT--;
	if (leavingPlayerTeam == ePurpleTeam)
		PT--;
	if (leavingPlayerTeam == eRogueTeam)
		RGT--;

	int Test1 = (RT * GT) + (RT * BT) + (RT * PT) + (GT * BT) + (GT * PT) + (BT * PT);
	int Test2 = RT + GT + BT + PT + RGT;

	if (Test1 < 1 && Test2 < 2)
	{
		if (!keepaway.oneTeamWarn)
			bz_sendTextMessage (BZ_SERVER, BZ_ALLUSERS, "Keep Away disabled: less than 2 teams.");

		keepaway.oneTeamWarn = true;
		return true;
	}
	else
	{
		if (keepaway.oneTeamWarn)
			bz_sendTextMessage (BZ_SERVER, BZ_ALLUSERS, "Keep Away enabled: more than 1 team.");

		keepaway.oneTeamWarn = false;
		return false;
	}
}
Пример #9
0
int TeamCheck(bz_eTeamType Team, const char* Color, double LastWarn, double LastTime)
{

    if (bz_getTeamCount(Team) != 0 && tctf.timerRunning)
    {

        tctf.timeElapsed = bz_getCurrentTime() - LastTime;
        tctf.timeRemaining = tctf.timeLimit - tctf.timeElapsed;

        if (bz_getCurrentTime() - LastWarn > 60)
        {
            tctf.adjTime = (int)(tctf.timeRemaining / 60);
            bz_sendTextMessagef (BZ_SERVER, Team, "%s Team: less than %i minute(s) left to capture a flag!", Color,
                                 tctf.adjTime + 1);
            return 1; // 1 = reset team's LastWarn
        }
        if (bz_getCurrentTime() - LastWarn > 30 && tctf.timeRemaining < 30)
        {
            bz_sendTextMessagef (BZ_SERVER, Team, "%s Team: less than 30 seconds left to capture a flag!", Color);
            return 1; // 1 = reset team's LastWarn
        }
        if (bz_getCurrentTime() - LastWarn > 10 && tctf.timeRemaining < 20 && tctf.timeRemaining > 10)
        {
            bz_sendTextMessagef (BZ_SERVER, Team, "%s Team: less than 20 seconds left to capture a flag!", Color);
            return 1; // 1 = reset team's LastWarn
        }
        if (bz_getCurrentTime() - LastWarn > 10 && tctf.timeRemaining < 10 && tctf.timeRemaining > 1)
        {
            bz_sendTextMessagef (BZ_SERVER, Team, "%s Team: less than 10 seconds left to capture a flag!", Color);
            return 1; // 1 = reset team's LastWarn
        }

        if (tctf.timeElapsed >= tctf.timeLimit)
        {

            KillTeam(Team);
            bz_sendTextMessagef (BZ_SERVER, BZ_ALLUSERS, "%s team did not capture any other team flags in time.", Color);
            tctf.adjTime = (int)(tctf.timeLimit / 60 + 0.5);
            bz_sendTextMessagef (BZ_SERVER, Team, "CTF timer is reset to %i minutes for the %s team.", tctf.adjTime, Color);
            return 2; // 2 = reset team's LastWarn and LastTime
        }
    }

    return 0; // 0 = no need to reset teams LastWarn or LastTime
}
Пример #10
0
void rabbitTimer::Event(bz_EventData *eventData)
{
	if (eventData->eventType == bz_eTickEvent)
	{
		bz_TickEventData_V1* tickdata = (bz_TickEventData_V1*)eventData;

		if (currentRabbit != -1 && tickdata->eventTime >= rabbitDeathTime)
		{
			//kill the wabbit!
			bz_killPlayer(currentRabbit, false, BZ_SERVER);

			//stopgap. the kill event should do this, really...
			currentRabbit = -1;
			rabbitDeathTime = (float)tickdata->eventTime + rabbitKillTimeLimit;

			bz_sendTextMessage (BZ_SERVER, BZ_ALLUSERS, "Time's up! Selecting new rabbit.");
		}
		else if (currentRabbit == -1 && bz_getTeamCount(eHunterTeam) >= 3) //make sure we've got enough people before reactivating the timer
		{
			//find the new rabbit
			bz_APIIntList pl;
			bz_getPlayerIndexList(&pl);

			for (unsigned int i = 0; i < pl.size() && currentRabbit == -1; i++)
			{
				bz_BasePlayerRecord* pr = bz_getPlayerByIndex(pl.get(i));

				if (pr != NULL)
				{
					if (pr->team == eRabbitTeam)
					{
						currentRabbit = pr->playerID;
						int limit = (int)rabbitKillTimeLimit;
						bz_sendTextMessage(BZ_SERVER, currentRabbit, bz_format("You have %d seconds to make a kill!", limit));
					}
					bz_freePlayerRecord(pr);
				}
			}
		}
	}
	else if (eventData->eventType == bz_ePlayerDieEvent)
	{

		bz_PlayerDieEventData_V1* killdata = (bz_PlayerDieEventData_V1*)eventData;

		if (killdata->team == eRabbitTeam)
		{
			currentRabbit = -1; //we will sort this out on the next tick

			rabbitDeathTime = (float)killdata->eventTime + rabbitKillTimeLimit;
		}
		else if (killdata->killerTeam == eRabbitTeam && currentRabbit != -1)
		{
			if (rollOver)
			{
				rabbitDeathTime += rabbitKillTimeLimit;

				int limit = (int)rabbitKillTimeLimit;
				int timeremaining = (int)(rabbitDeathTime - killdata->eventTime);

				bz_sendTextMessage(BZ_SERVER, currentRabbit, bz_format("+%d seconds: %d seconds remaining.", limit, timeremaining));
			}
			else
			{
				rabbitDeathTime = (float)killdata->eventTime + rabbitKillTimeLimit;

				int limit = (int)rabbitKillTimeLimit;
				bz_sendTextMessage(BZ_SERVER, currentRabbit, bz_format("%d seconds remaining.", limit));
			}
		}
	}
	else if (eventData->eventType == bz_ePlayerDieEvent)
	{
		bz_PlayerJoinPartEventData_V1* partdata = (bz_PlayerJoinPartEventData_V1*)eventData;

		if (partdata->record->team == eRabbitTeam) //we need to select a new rabbit if the rabbit leaves.
		{
			currentRabbit = -1; //we will sort this out on the next tick

			rabbitDeathTime = (float)partdata->eventTime + rabbitKillTimeLimit;
		}
	}
}
void LeagueOverseer::Event (bz_EventData *eventData)
{
    switch (eventData->eventType)
    {
        case bz_eAllowFlagGrab: // This event is called each time a player attempts to grab a flag
        {
            bz_AllowFlagGrabData_V1* allowFlagGrabData = (bz_AllowFlagGrabData_V1*)eventData;
            std::string              flagAbbr          = allowFlagGrabData->flagType;
            int                      playerID          = allowFlagGrabData->playerID;

            if (isPcProtectionEnabled()) // Is the server configured to protect against Pass Camping
            {
                // Check if the last capture was within the 'PC_PROTECTION_DELAY' amount of seconds
                if (LAST_CAP + getPcProtectionDelay() > bz_getCurrentTime())
                {
                    // Check to see if the flag being grabbed belongs to the team that just had their flag captured AND check
                    // to see if someone not from the victim team grabbed it
                    if ((getTeamTypeFromFlag(flagAbbr) == CAP_VICTIM_TEAM && bz_getPlayerTeam(playerID) != CAP_VICTIM_TEAM))
                    {
                        // Disallow the flag grab if it's being grabbed by an enemy right after a flag capture
                        allowFlagGrabData->allow = false;
                    }
                }
            }
        }
        break;

        case bz_eAllowSpawn: // This event is called before a player respawns
        {
            bz_AllowSpawnData_V2* allowSpawnData = (bz_AllowSpawnData_V2*)eventData;
            int                   playerID       = allowSpawnData->playerID;

            if (!pluginSettings.isGuestSpawningEnabled(getCurrentGameMode()) && !isLeagueMember(playerID))
            {
                // Disable their spawning privileges
                allowSpawnData->handled    = true;
                allowSpawnData->allow      = false;
                allowSpawnData->kickPlayer = false;

                sendPluginMessage(playerID, pluginSettings.getGuestSpawningMessage(getCurrentGameMode()));
            }
        }
        break;

        case bz_eBZDBChange: // This event is called each time a BZDB variable is changed
        {
            bz_BZDBChangeData_V1* bzdbData = (bz_BZDBChangeData_V1*)eventData;

            if (bzdbData->key == "_pcProtectionDelay")
            {
                // Save the proposed value in a variable for easy access
                int proposedValue = std::stoi(bzdbData->value.c_str());

                // Our PC protection delay should be between 3 and 30 seconds only, otherwise set it to the default 5 seconds
                if (proposedValue < 3 || proposedValue > 30)
                {
                    bz_setBZDBInt("_pcProtectionDelay", 5);
                }
            }
        }
        break;

        case bz_eCaptureEvent: // This event is called each time a team's flag has been captured
        {
            if (isMatchInProgress())
            {
                bz_CTFCaptureEventData_V1* captureData = (bz_CTFCaptureEventData_V1*)eventData;
                std::shared_ptr<bz_BasePlayerRecord> capperData(bz_getPlayerByIndex(captureData->playerCapping));

                // Keep score
                (captureData->teamCapping == TEAM_ONE) ? currentMatch.incrementTeamOneScore() : currentMatch.incrementTeamTwoScore();

                // Store data for PC Protection
                CAP_VICTIM_TEAM = captureData->teamCapped;
                CAP_WINNER_TEAM = captureData->teamCapping;
                LAST_CAP        = captureData->eventTime;

                logMessage(pluginSettings.getDebugLevel(), "debug", "%s captured the flag at %s",
                        capperData->callsign.c_str(), getMatchTime().c_str());
                logMessage(pluginSettings.getDebugLevel(), "debug", "Match Score %s [%i] vs %s [%i]",
                        currentMatch.getTeamOneName().c_str(), currentMatch.getTeamOneScore(),
                        currentMatch.getTeamTwoName().c_str(), currentMatch.getTeamTwoScore());

                CaptureMatchEvent capEvent = CaptureMatchEvent().setBZID(capperData->bzID.c_str())
                                                                .setTime(getMatchTime());

                // If it's an official match, save the team ID
                if (isOfficialMatch())
                {
                    int teamID = (captureData->teamCapping == TEAM_ONE) ? currentMatch.getTeamOneID() : currentMatch.getTeamTwoID();

                    capEvent.setTeamID(teamID);
                }

                capEvent.save();

                currentMatch.saveEvent(capEvent.getJsonObject());
                currentMatch.stats_flagCapture(captureData->playerCapping);

                logMessage(pluginSettings.getVerboseLevel(), "debug", "CaptureMatchEvent JSON -> %s", capEvent.toString());
            }
        }
        break;

        case bz_eGameEndEvent: // This event is called each time a game ends
        {
            logMessage(pluginSettings.getVerboseLevel(), "debug", "A match has ended.");

            // Get the current standard UTC time
            bz_Time stdTime;
            bz_getUTCtime(&stdTime);
            std::string recordingFileName;

            // Only save the recording buffer if we actually started recording when the match started
            if (RECORDING)
            {
                logMessage(pluginSettings.getVerboseLevel(), "debug", "Recording was in progress during the match.");

                std::stringstream recordingName;

                std::string _matchType = (isOfficialMatch()) ? "offi" : "fm",
                            _teamOneName = currentMatch.getTeamOneName(),
                            _teamTwoName = currentMatch.getTeamTwoName();

                // (offi|fm)-YYYYMMDD
                recordingName << _matchType << "-" << stdTime.year << formatInt("%02d", stdTime.month) << formatInt("%02d", stdTime.day);

                if (!currentMatch.isRosterEmpty())
                {
                    std::replace(_teamOneName.begin(), _teamOneName.end(), ' ', '_');
                    std::replace(_teamTwoName.begin(), _teamTwoName.end(), ' ', '_');

                    // Team_A-vs-Team_B
                    recordingName << "-" << _teamOneName << "-vs-" << _teamTwoName;
                }

                // -HHMM
                recordingName << "-" << formatInt("%02d", stdTime.hour) << formatInt("%02d", stdTime.minute);

                const std::string nameForHash = recordingName.str();
                std::string hash = bz_MD5(nameForHash.c_str());

                // -ACBD123
                recordingName << "-" << hash.substr(0, 7);

                if (currentMatch.matchCanceled())
                {
                    // -Canceled
                    recordingName << "-Canceled";
                }

                recordingName << ".rec";

                recordingFileName = recordingName.str();
                logMessage(pluginSettings.getVerboseLevel(), "debug", "Replay file will be named: %s", recordingFileName.c_str());

                // Save the recording buffer and stop recording
                bz_saveRecBuf(recordingFileName.c_str(), 0);
                bz_stopRecBuf();
                logMessage(pluginSettings.getVerboseLevel(), "debug", "Replay file has been saved and recording has stopped.");

                // We're no longer recording, so set the boolean and announce to players that the file has been saved
                RECORDING = false;
                bz_sendTextMessagef(BZ_SERVER, BZ_ALLUSERS, "Match saved as: %s", recordingFileName.c_str());
            }

            // Format the date to -> year-month-day hour:minute:second
            char matchDate[20];
            sprintf(matchDate, "%02d-%02d-%02d %02d:%02d:%02d", stdTime.year, stdTime.month, stdTime.day, stdTime.hour, stdTime.minute, stdTime.second);

            currentMatch.save(matchDate, recordingFileName);

            if (pluginSettings.isMatchReportEnabled())
            {
                if (!currentMatch.isRosterEmpty())
                {
                    MatchUrlRepo.set("query", "matchReport")
                                .set("data", bz_urlEncode(currentMatch.toString().c_str()))
                                .submit();

                    if (currentMatch.isFM())
                    {
                        // It was a fun match, so there is no need to do anything

                        logMessage(pluginSettings.getVerboseLevel(), "debug", "Fun match has completed.");
                    }
                    else if (currentMatch.matchCanceled())
                    {
                        // The match was canceled for some reason so output the reason to both the players and the server logs

                        logMessage(pluginSettings.getDebugLevel(), "debug", "%s", currentMatch.getCancelation().c_str());
                        bz_sendTextMessage(BZ_SERVER, BZ_ALLUSERS, currentMatch.getCancelation().c_str());
                    }
                    else
                    {
                        logMessage(pluginSettings.getDebugLevel(), "debug", "Reporting match data...");
                        bz_sendTextMessage(BZ_SERVER, BZ_ALLUSERS, "Reporting match...");

                        // Send the match data to the league website
                        MATCH_INFO_SENT = true;
                    }
                }
            }

            // Reset our match data
            currentMatch = Match();

            // Empty our list of players since we don't need a history
            activePlayerList.clear();
        }
        break;

        case bz_eGamePauseEvent:
        {
            bz_GamePauseResumeEventData_V2* gamePauseData = (bz_GamePauseResumeEventData_V2*)eventData;

            // Get the current UTC time
            MATCH_PAUSED = time(NULL);

            // Send the messages
            bz_sendTextMessagef(BZ_SERVER, BZ_ALLUSERS, "    with %s remaining.", getMatchTime().c_str());
            logMessage(pluginSettings.getVerboseLevel(), "debug", "Match paused at %s by %s.", getMatchTime().c_str(), bz_getPlayerCallsign(gamePauseData->playerID));

            PauseResumeMatchEvent pauseEvent = PauseResumeMatchEvent();

            pauseEvent.setState(true)
                      .setTime(getMatchTime())
                      .setBZID(getPlayerBZID(gamePauseData->playerID))
                      .save();

            currentMatch.saveEvent(pauseEvent.getJsonObject());

            logMessage(pluginSettings.getVerboseLevel(), "debug", "PauseResumeMatchEvent JSON -> %s", pauseEvent.toString());
        }
        break;

        case bz_eGameResumeEvent:
        {
            bz_GamePauseResumeEventData_V2* gameResumeData = (bz_GamePauseResumeEventData_V2*)eventData;

            // Get the current UTC time
            time_t now = time(NULL);

            // Do the math to determine how long the match was paused
            double timePaused = difftime(now, MATCH_PAUSED);

            // Create a temporary variable to store and manipulate the match start time
            struct tm modMatchStart = *localtime(&MATCH_START);

            // Manipulate the time by adding the amount of seconds the match was paused in order to be able to accurately
            // calculate the amount of time remaining with LeagueOverseer::getMatchTime()
            modMatchStart.tm_sec += timePaused;

            // Save the manipulated match start time
            MATCH_START = mktime(&modMatchStart);
            logMessage(pluginSettings.getVerboseLevel(), "debug", "Match paused for %.f seconds. Match continuing at %s.", timePaused, getMatchTime().c_str());

            PauseResumeMatchEvent resumeEvent = PauseResumeMatchEvent();

            resumeEvent.setState(false)
                       .setTime(getMatchTime())
                       .setBZID(getPlayerBZID(gameResumeData->playerID))
                       .save();

            currentMatch.saveEvent(resumeEvent.getJsonObject());

            logMessage(pluginSettings.getVerboseLevel(), "debug", "PauseResumeMatchEvent JSON -> %s", resumeEvent.toString());
        }
        break;

        case bz_eGameStartEvent: // This event is triggered when a timed game begins
        {
            logMessage(pluginSettings.getVerboseLevel(), "debug", "A match has started");

            // Empty our list of players since we don't need a history
            activePlayerList.clear();

            // We started recording a match, so save the status
            RECORDING = bz_startRecBuf();

            // We want to notify the logs if we couldn't start recording just in case an issue were to occur and the server
            // owner needs to check to see if players were lying about there no replay
            if (RECORDING)
            {
                logMessage(pluginSettings.getVerboseLevel(), "debug", "Match recording has started successfully");
            }
            else
            {
                logMessage(0, "error", "This match could not be recorded");
            }

            currentMatch.setMatchDuration((int) bz_getTimeLimit());

            MATCH_START = time(NULL);
        }
        break;

        case bz_eGetAutoTeamEvent: // This event is called for each new player is added to a team
        {
            bz_GetAutoTeamEventData_V1* autoTeamData = (bz_GetAutoTeamEventData_V1*)eventData;

            int playerID = autoTeamData->playerID;
            std::shared_ptr<bz_BasePlayerRecord> playerData(bz_getPlayerByIndex(playerID));

            // Only force new players to observer if a match is in progress
            if (isMatchInProgress())
            {
                // Automatically move non-league members or players who just joined to the observer team
                if (!isLeagueMember(playerID) || !playerAlreadyJoined(playerData->bzID.c_str()))
                {
                    autoTeamData->handled = true;
                    autoTeamData->team    = eObservers;
                }
            }
        }
        break;

        case bz_eGetPlayerMotto: // This event is called when the player joins. It gives us the motto of the player
        {
            bz_GetPlayerMottoData_V2* mottoData = (bz_GetPlayerMottoData_V2*)eventData;

            if (pluginSettings.isMottoFetchEnabled())
            {
                std::map<std::string, std::string> parameters;

                parameters["{motto}"] = mottoData->motto;
                parameters["{team}"]  = getPlayerTeamNameByBZID(mottoData->record->bzID.c_str());

                mottoData->motto = formatMotto(parameters);
            }
        }
        break;

        case bz_ePlayerDieEvent: // This event is called each time a tank is killed
        {
            bz_PlayerDieEventData_V1* dieData = (bz_PlayerDieEventData_V1*)eventData;
            std::shared_ptr<bz_BasePlayerRecord> victimData(bz_getPlayerByIndex(dieData->playerID));
            std::shared_ptr<bz_BasePlayerRecord> killerData(bz_getPlayerByIndex(dieData->killerID));

            if (isMatchInProgress())
            {
                KillMatchEvent killEvent = KillMatchEvent();

                killEvent.setKiller(killerData->bzID.c_str())
                         .setVictim(victimData->bzID.c_str())
                         .setTime(getMatchTime())
                         .save();

                currentMatch.saveEvent(killEvent.getJsonObject());

                logMessage(pluginSettings.getVerboseLevel(), "debug", "KillMatchEvent JSON -> %s", killEvent.toString());
            }
        }
        break;

        case bz_ePlayerJoinEvent: // This event is called each time a player joins the game
        {
            bz_PlayerJoinPartEventData_V1* joinData = (bz_PlayerJoinPartEventData_V1*)eventData;

            int playerID = joinData->playerID;
            std::shared_ptr<bz_BasePlayerRecord> playerData(bz_getPlayerByIndex(playerID));

            setLeagueMember(playerID);
            storePlayerInfo(playerID, playerData->bzID.c_str());

            JoinMatchEvent joinEvent = JoinMatchEvent().setCallsign(playerData->callsign.c_str())
                                                       .setVerified(playerData->verified)
                                                       .setIpAddress(playerData->ipAddress.c_str())
                                                       .setBZID(playerData->bzID.c_str());
            joinEvent.save();

            // Only notify a player if they exist, have joined the observer team, and there is a match in progress
            if (isMatchInProgress() && isValidPlayerID(joinData->playerID) && playerData->team == eObservers)
            {
                bz_sendTextMessagef(BZ_SERVER, joinData->playerID, "*** There is currently %s match in progress, please be respectful. ***",
                                    ((isOfficialMatch()) ? "an official" : "a fun"));
            }

            if (pluginSettings.isMottoFetchEnabled())
            {
                // Only send a URL job if the user is verified
                if (playerData->verified)
                {
                    requestTeamName(playerData->callsign.c_str(), playerData->bzID.c_str());
                }
            }
        }
        break;

        case bz_ePlayerPartEvent: // This event is called each time a player leaves a game
        {
            bz_PlayerJoinPartEventData_V1* partData = (bz_PlayerJoinPartEventData_V1*)eventData;

            int playerID = partData->playerID;
            std::shared_ptr<bz_BasePlayerRecord> playerData(bz_getPlayerByIndex(playerID));

            removePlayerInfo(partData->record->bzID.c_str());

            // Only keep track of the parting player if they are a league member and there is a match in progress
            if (isLeagueMember(playerID) && isMatchInProgress())
            {
                if (!playerAlreadyJoined(playerData->bzID.c_str()))
                {
                    // Create a record for the player who just left
                    Player partingPlayer(playerData->bzID.c_str(), playerData->team, bz_getCurrentTime());

                    // Push the record to our vector
                    activePlayerList.push_back(partingPlayer);
                }
            }
        }
        break;

        case bz_eRawChatMessageEvent: // This event is called for each chat message the server receives. It is called before any filtering is done.
        {
            bz_ChatEventData_V1* chatData  = (bz_ChatEventData_V1*)eventData;

            bz_eTeamType target    = chatData->team;
            int          playerID  = chatData->from,
                         recipient = chatData->to;

            // The server is always allowed to talk
            if (playerID == BZ_SERVER)
            {
                break;
            }

            // A non-league player is attempting to talk
            if (!isLeagueMember(playerID))
            {
                std::string allowedChatTarget = pluginSettings.getAllowedTargetChat(getCurrentGameMode());
                bool ignoreMessage = true;

                if (allowedChatTarget == "Observers")
                {
                    if (recipient == eObservers || bz_getPlayerTeam(recipient) == eObservers)
                    {
                        ignoreMessage = false;
                    }
                }
                else if (allowedChatTarget == "ObvserverAdmins")
                {
                    if (bz_getPlayerTeam(recipient) == eObservers && isVisibleAdmin(recipient))
                    {
                        ignoreMessage = false;
                    }
                }
                else if (allowedChatTarget == "Admins")
                {
                    if (target == eAdministrators || isVisibleAdmin(recipient))
                    {
                        ignoreMessage = false;
                    }
                }
                else if (allowedChatTarget == "All")
                {
                    ignoreMessage = false;
                }

                if (ignoreMessage)
                {
                    chatData->message = "";
                    sendPluginMessage(playerID, pluginSettings.getGuestMessagingMessage(getCurrentGameMode()));
                }
            }
        }
        break;

        case bz_eTickEvent: // This event is called once for each BZFS main loop
        {
            // Get the total number of tanks playing
            int totalTanks = bz_getTeamCount(eRedTeam) + bz_getTeamCount(eGreenTeam) + bz_getTeamCount(eBlueTeam) + bz_getTeamCount(ePurpleTeam);

            // If there are no tanks playing, then we need to do some clean up
            if (totalTanks == 0)
            {
                // If there is an official match and no tanks playing, we need to cancel it
                if (isOfficialMatch())
                {
                    currentMatch.cancelMatch("Official match automatically canceled due to all players leaving the match.");
                }

                // If we have players recorded and there's no one around, empty the list
                if (!activePlayerList.empty())
                {
                    activePlayerList.clear();
                }

                // If there is a countdown active an no tanks are playing, then cancel it
                if (bz_isCountDownActive())
                {
                    bz_gameOver(253, eObservers);
                    logMessage(pluginSettings.getVerboseLevel(), "debug", "Game ended because no players were found playing with an active countdown.");
                }
            }

            // Let's get the roll call only if there is an official match
            if (isOfficialMatch())
            {
                // Check if the start time is not negative since our default value for the approxTimeProgress is -1. Also check
                // if it's time to do a roll call, which is defined as 90 seconds after the start of the match by default,
                // and make sure we don't have any match participants recorded and the match isn't paused
                if (getMatchProgress() > currentMatch.getMatchRollCall() && currentMatch.isRosterEmpty() &&
                    !bz_isCountDownPaused() && !bz_isCountDownInProgress())
                {
                    logMessage(pluginSettings.getVerboseLevel(), "debug", "Processing roll call...");

                    // @TODO Make sure all of these variables are used
                    std::shared_ptr<bz_APIIntList> playerList(bz_getPlayerIndexList());
                    bool invalidateRollCall, teamOneError, teamTwoError;
                    std::string teamOneMotto, teamTwoMotto;
                    int teamOneID, teamTwoID;

                    invalidateRollCall = teamOneError = teamTwoError = false;
                    teamOneMotto = teamTwoMotto = "";

                    // We can't do a roll call if the player list wasn't created
                    if (!playerList)
                    {
                        logMessage(pluginSettings.getVerboseLevel(), "error", "Failure to create player list for roll call.");
                        return;
                    }

                    for (unsigned int i = 0; i < playerList->size(); i++)
                    {
                        bz_BasePlayerRecord* playerRecord = bz_getPlayerByIndex(playerList->get(i));

                        if (playerRecord && isLeagueMember(playerRecord->playerID) && bz_getPlayerTeam(playerList->get(i)) != eObservers) // If player is not an observer
                        {
                            currentMatch.savePlayer(playerRecord, getTeamIdFromBZID(playerRecord->bzID.c_str()));

                            // @TODO Rewrite this function to be updated
                            // Check if there is any need to invalidate a roll call from a team
                            //validateTeamName(invalidateRollCall, teamOneError, currentPlayer, teamOneMotto, TEAM_ONE);
                            //validateTeamName(invalidateRollCall, teamTwoError, currentPlayer, teamTwoMotto, TEAM_TWO);
                        }

                        bz_freePlayerRecord(playerRecord);
                    }

                    // We were asked to invalidate the roll call because of some issue so let's check if there is still time for
                    // another roll call
                    if (invalidateRollCall && currentMatch.incrementMatchRollCall(60) < currentMatch.getMatchDuration())
                    {
                        logMessage(pluginSettings.getDebugLevel(), "debug", "Invalid player found on field at %s.", getMatchTime().c_str());

                        // There was an error with one of the members of either team, so request a team name update for all of
                        // the team members to try to fix any inconsistencies of different team names
                        //if (teamOneError) { requestTeamName(TEAM_ONE); }
                        //if (teamTwoError) { requestTeamName(TEAM_TWO); }

                        // Delay the next roll call by 60 seconds
                        logMessage(pluginSettings.getVerboseLevel(), "debug", "Match roll call time has been delayed by 60 seconds.");

                        // Clear the struct because it's useless data
                        currentMatch.clearPlayerRoster();
                        logMessage(pluginSettings.getVerboseLevel(), "debug", "Match participants have been cleared.");
                    }

                    // There is no need to invalidate the roll call so the team names must be right so save them in the struct
                    if (!invalidateRollCall)
                    {
                        currentMatch.setTeamOneID(teamOneID).setTeamOneName(teamOneMotto)
                                    .setTeamTwoID(teamTwoID).setTeamTwoName(teamTwoMotto);

                        logMessage(pluginSettings.getVerboseLevel(), "debug", "Team One set to: %s", currentMatch.getTeamOneName().c_str());
                        logMessage(pluginSettings.getVerboseLevel(), "debug", "Team Two set to: %s", currentMatch.getTeamTwoName().c_str());
                    }
                }
            }
        }
        break;

        default: break;
    }
}
Пример #12
0
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;
}
Пример #13
0
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;
    }
}
Пример #14
0
bool TeamsBalanced()
{

    // if not enough team players - no need to check any further:

    if (bz_getTeamCount(eRedTeam) + bz_getTeamCount(eGreenTeam) + bz_getTeamCount(eBlueTeam) + bz_getTeamCount(
                ePurpleTeam) <= 1)
        return false;

    // check for fair ctf - only need 2 teams close (TeamRatioTolerance or better)
    // this is crude - can be done better I'm sure:

    float TeamRatioTolerance = 0.75; // if not same size, at least 3 versus 4 or better
    float RatioRG = 0;
    float RatioRB = 0;
    float RatioRP = 0;
    float RatioGB = 0;
    float RatioBP = 0;
    float RatioGP = 0;
    float RS = (float)bz_getTeamCount(eRedTeam);
    // "GS" is a macro defined in /usr/include/sys/regset.h on Solaris x86
    float _GS = (float)bz_getTeamCount(eGreenTeam);
    float BS = (float)bz_getTeamCount(eBlueTeam);
    float PS = (float)bz_getTeamCount(ePurpleTeam);

    if (RS >= _GS && RS !=0)
        RatioRG = (_GS / RS);
    if (_GS > RS && _GS !=0)
        RatioRG = (RS / _GS);

    if (RS >= BS && RS !=0)
        RatioRB = (BS / RS);
    if (BS > RS && BS !=0)
        RatioRB = (RS / BS);

    if (RS >= PS && RS !=0)
        RatioRP = (PS / RS);
    if (PS > RS && PS !=0)
        RatioRP = (RS / PS);

    if (_GS >= BS && _GS !=0)
        RatioGB = (BS / _GS);
    if (BS > _GS && BS !=0)
        RatioGB = (_GS / BS);

    if (PS >= _GS && PS !=0)
        RatioGP = (_GS / PS);
    if (_GS > PS && _GS !=0)
        RatioGP = (PS / _GS);

    if (BS >= PS && BS !=0)
        RatioBP = (PS / BS);
    if (PS > BS && PS !=0)
        RatioBP = (BS / PS);

    if (RatioRG >= TeamRatioTolerance || RatioRB >= TeamRatioTolerance || RatioRP >= TeamRatioTolerance
            || RatioGB >= TeamRatioTolerance || RatioGP >= TeamRatioTolerance || RatioBP >= TeamRatioTolerance)

        return true;
    else

        return false;
}
Пример #15
0
bool TeamsBalanced()
{
  // if not enough team players - no need to check any further:

  if (bz_getTeamCount(eRedTeam) + bz_getTeamCount(eGreenTeam) +
      bz_getTeamCount(eBlueTeam) + bz_getTeamCount(ePurpleTeam) <= 1)
    return false;

  // check for fair ctf - only need 2 teams close (TeamRatioTolerance or better)
  // this is crude - can be done better I'm sure:

  float TeamRatioTolerance = 0.75;	// if not same size, at least 3 versus 4 or better
  float RatioRG = 0;
  float RatioRB = 0;
  float RatioRP = 0;
  float RatioGB = 0;
  float RatioBP = 0;
  float RatioGP = 0;
  float RS = (float) bz_getTeamCount(eRedTeam);
  float GS = (float) bz_getTeamCount(eGreenTeam);
  float BS = (float) bz_getTeamCount(eBlueTeam);
  float PS = (float) bz_getTeamCount(ePurpleTeam);

  if (RS >= GS && RS != 0)
    RatioRG = (GS / RS);
  if (GS > RS && GS != 0)
    RatioRG = (RS / GS);

  if (RS >= BS && RS != 0)
    RatioRB = (BS / RS);
  if (BS > RS && BS != 0)
    RatioRB = (RS / BS);

  if (RS >= PS && RS != 0)
    RatioRP = (PS / RS);
  if (PS > RS && PS != 0)
    RatioRP = (RS / PS);

  if (GS >= BS && GS != 0)
    RatioGB = (BS / GS);
  if (BS > GS && BS != 0)
    RatioGB = (GS / BS);

  if (PS >= GS && PS != 0)
    RatioGP = (GS / PS);
  if (GS > PS && GS != 0)
    RatioGP = (PS / GS);

  if (BS >= PS && BS != 0)
    RatioBP = (PS / BS);
  if (PS > BS && PS != 0)
    RatioBP = (BS / PS);

  if (RatioRG >= TeamRatioTolerance || RatioRB >= TeamRatioTolerance ||
      RatioRP >= TeamRatioTolerance || RatioGB >= TeamRatioTolerance ||
      RatioGP >= TeamRatioTolerance || RatioBP >= TeamRatioTolerance) {

    return true;
  } else {

    return false;
  }
}
Пример #16
0
void TeamFlagResetHandler::Event ( bz_EventData *eventData )
{
	if (eventData->eventType != bz_eTickEvent)
		return;

	if (tfr.timerOff == true)
		return;

	bz_APIIntList *playerList = bz_newIntList();
	bz_getPlayerIndexList ( playerList );

	// check to see if anyone has picked up a team flag & count players per team

	for ( unsigned int i = 0; i < playerList->size(); i++ ){

		bz_BasePlayerRecord *player = bz_getPlayerByIndex(playerList->operator[](i));

		if (player) {

			tfr.flagTouched = bz_getPlayerFlag(player->playerID);

			if (tfr.flagTouched){

				if (strcmp(tfr.flagTouched, "R*") == 0){
					tfr.redLastTouched = bz_getCurrentTime();
					tfr.redFlagWasHeld = true;
				}
				if (strcmp(tfr.flagTouched, "G*") == 0){
					tfr.greenLastTouched = bz_getCurrentTime();
					tfr.greenFlagWasHeld = true;
				}
				if (strcmp(tfr.flagTouched, "B*") == 0){
					tfr.blueLastTouched = bz_getCurrentTime();
					tfr.blueFlagWasHeld = true;
				}
				if (strcmp(tfr.flagTouched, "P*") == 0){
					tfr.purpleLastTouched = bz_getCurrentTime();
					tfr.purpleFlagWasHeld = true;
				}
			}

			bz_freePlayerRecord(player);
		}
	}

	bz_deleteIntList(playerList);

	// if no teamplay, no need to reset flags

	tfr.OKToReset = false;

	if (bz_getTeamCount(eRedTeam) * bz_getTeamCount(eGreenTeam) > 0)
		tfr.OKToReset = true;
	if (bz_getTeamCount(eRedTeam) * bz_getTeamCount(eBlueTeam) > 0)
		tfr.OKToReset = true;
	if (bz_getTeamCount(eRedTeam) * bz_getTeamCount(ePurpleTeam) > 0)
		tfr.OKToReset = true;
	if (bz_getTeamCount(eGreenTeam) * bz_getTeamCount(eBlueTeam) > 0)
		tfr.OKToReset = true;
	if (bz_getTeamCount(eGreenTeam) * bz_getTeamCount(ePurpleTeam) > 0)
		tfr.OKToReset = true;
	if (bz_getTeamCount(eBlueTeam) * bz_getTeamCount(ePurpleTeam) > 0)
		tfr.OKToReset = true;

	if (tfr.OKToReset == false){
		ResetFlagData();
		return;
	}

	// check if time's up on flags and reset (if they were held at least once after last reset)

	if (bz_getCurrentTime() - tfr.redLastTouched > tfr.idleTime && tfr.redFlagWasHeld){
		if (bz_getTeamCount(eRedTeam) > 0){
			resetTeamFlag ("R*");
			bz_sendTextMessagef (BZ_SERVER, BZ_ALLUSERS, "Red flag sat idle too long - reset by server.");
		}
		tfr.redFlagWasHeld = false;
		tfr.redLastTouched = bz_getCurrentTime();
	}

	if (bz_getCurrentTime() - tfr.greenLastTouched > tfr.idleTime && tfr.greenFlagWasHeld){
		if (bz_getTeamCount(eGreenTeam) > 0){
			resetTeamFlag ("G*");
			bz_sendTextMessagef (BZ_SERVER, BZ_ALLUSERS, "Green flag sat idle too long - reset by server.");
		}
		tfr.greenLastTouched = bz_getCurrentTime();
		tfr.greenFlagWasHeld = false;
	}

	if (bz_getCurrentTime() - tfr.blueLastTouched > tfr.idleTime && tfr.blueFlagWasHeld){
		if (bz_getTeamCount(eBlueTeam) > 0){
			resetTeamFlag ("B*");
			bz_sendTextMessagef (BZ_SERVER, BZ_ALLUSERS, "Blue flag sat idle too long - reset by server.");
		}
		tfr.blueLastTouched = bz_getCurrentTime();
		tfr.blueFlagWasHeld = false;
	}

	if (bz_getCurrentTime() - tfr.purpleLastTouched > tfr.idleTime && tfr.purpleFlagWasHeld){
		if (bz_getTeamCount(ePurpleTeam) > 0){
			resetTeamFlag ("P*");
			bz_sendTextMessagef (BZ_SERVER, BZ_ALLUSERS, "Purple flag sat idle too long - reset by server.");
		}
		tfr.purpleLastTouched = bz_getCurrentTime();
		tfr.purpleFlagWasHeld = false;
	}
	return;
}
Пример #17
0
void RabidRabbitEventHandler::Event(bz_EventData *eventData)
{

  if (eventData->eventType == bz_ePlayerDieEvent)
  {
    bz_PlayerDieEventData_V1 *DieData = (bz_PlayerDieEventData_V1*)eventData;

    if (rrzoneinfo.cycleOnDie && DieData->team == eRabbitTeam) {
      unsigned int i = rrzoneinfo.currentKillZone;
      if (i == (zoneList.size() - 1))
	rrzoneinfo.currentKillZone = 0;
      else
	rrzoneinfo.currentKillZone++;
    }
    return;
  }

  if ((eventData->eventType != bz_eTickEvent) || (zoneList.size() < 2))
    return;

  for (unsigned int i = 0; i < zoneList.size(); i++) {
    if (!zoneList[i].WWFired && rrzoneinfo.currentKillZone == i) {
      bz_fireWorldWep(zoneList[i].WW.c_str(),
		      zoneList[i].WWLifetime,
		      BZ_SERVER,zoneList[i].WWPosition,
		      zoneList[i].WWTilt,
		      zoneList[i].WWDirection,
		      zoneList[i].WWShotID,
		      zoneList[i].WWDT);
      zoneList[i].WWFired = true;
      zoneList[i].WWLastFired = bz_getCurrentTime();
    } else {
      if ((bz_getCurrentTime() - zoneList[i].WWLastFired) > zoneList[i].WWRepeat)
	zoneList[i].WWFired = false;
    }
  }

  bz_APIIntList *playerList = bz_newIntList();
  bz_getPlayerIndexList(playerList);

  for (unsigned int h = 0; h < playerList->size(); h++) {
    bz_BasePlayerRecord *player = bz_getPlayerByIndex(playerList->operator[](h));

    if (player) {

      for (unsigned int i = 0; i < zoneList.size(); i++) {
	if (zoneList[i].pointIn(player->lastKnownState.pos) &&
	    player->spawned && player->team == eRabbitTeam &&
	    rrzoneinfo.currentKillZone != i && !rrzoneinfo.rabbitNotifiedWrongZone) {
	  bz_sendTextMessage(BZ_SERVER,player->playerID,
			     "You are not in the current Rabid Rabbit zone - try another.");
	  rrzoneinfo.rabbitNotifiedWrongZone = true;
	  rrzoneinfo.rabbitNotifiedWrongZoneNum = i;
	}

	if (!zoneList[i].pointIn(player->lastKnownState.pos) &&
	    player->spawned && player->team == eRabbitTeam &&
	    rrzoneinfo.rabbitNotifiedWrongZone &&
	    rrzoneinfo.rabbitNotifiedWrongZoneNum == i)
	  rrzoneinfo.rabbitNotifiedWrongZone = false;

	if (zoneList[i].pointIn(player->lastKnownState.pos) &&
	    player->spawned &&
	    player->team == eRabbitTeam &&
	    rrzoneinfo.currentKillZone == i &&
	    bz_getTeamCount(eHunterTeam) > 0) {
	  killAllHunters(zoneList[i].servermessage);

	  rrzoneinfo.rabbitNotifiedWrongZone = true;
	  rrzoneinfo.rabbitNotifiedWrongZoneNum = i;

	  if (i == (zoneList.size() - 1))
	    rrzoneinfo.currentKillZone = 0;
	  else
	    rrzoneinfo.currentKillZone++;

	  rrzoneinfo.rabbitNotifiedWrongZone = true;
	  rrzoneinfo.rabbitNotifiedWrongZoneNum = i;
	}

	if (zoneList[i].pointIn(player->lastKnownState.pos) &&
	    player->spawned &&
	    player->team != eRabbitTeam &&
	    zoneList[i].zonekillhunter) {
	  bz_killPlayer(player->playerID, true, BZ_SERVER);
	  bz_sendTextMessage (BZ_SERVER, player->playerID, zoneList[i].playermessage.c_str());
	}
      }
      bz_freePlayerRecord(player);
    }
  }

  bz_deleteIntList(playerList);
  return;
}