Esempio n. 1
0
void RegFlag::Event ( bz_EventData *eventData )
{
  bz_BasePlayerRecord *player = NULL;
  int playerID = -1;

  switch (eventData->eventType)
    {
    case bz_ePlayerUpdateEvent:
      playerID = ((bz_PlayerUpdateEventData_V1*)eventData)->playerID;
      break;

    case bz_eShotFiredEvent:
      playerID = ((bz_PlayerUpdateEventData_V1*)eventData)->playerID;
      break;

    default:
      return;
    }

  player = bz_getPlayerByIndex(playerID);
  if (!player) return;
  if (player->globalUser) {
    bz_freePlayerRecord(player);
    return;
  }
  bz_freePlayerRecord(player);

  const char* flagAbrev = bz_getPlayerFlag(playerID);
  if (!flagAbrev)
    return;

  bz_removePlayerFlag(playerID);
  bz_sendTextMessage(BZ_SERVER,playerID, "Flags are for registered players only");

}
Esempio n. 2
0
  virtual bool SlashCommand ( int playerID, bz_ApiString /*command*/, bz_ApiString /*message*/, bz_APIStringList* /*params*/ )
  {
    bz_BasePlayerRecord *player = bz_getPlayerByIndex(playerID);
    if (!player)
      return true;

    if ( !player->admin )
    {
      bz_sendTextMessage(BZ_SERVER,playerID,"You do not have permission to run /killall");
      bz_freePlayerRecord(player);
      return true;
    }

    std::string msg = player->callsign.c_str();
    msg += " has killed everyone";

    bz_sendTextMessage(BZ_SERVER,BZ_ALLUSERS,msg.c_str());

    bz_APIIntList *playerList = bz_newIntList();

    bz_getPlayerIndexList ( playerList );

    for ( unsigned int i = 0; i < playerList->size(); i++ )
      bz_killPlayer(playerList->get(i),false);

    bz_freePlayerRecord(player);
    bz_deleteIntList(playerList);

    return true;
  }
Esempio n. 3
0
void killPlayers(int safeid, std::string kothcallsign)
{
  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->playerID != safeid) {
	bz_killPlayer(player->playerID, true, koth.id);
	if (koth.soundEnabled)
	  bz_sendPlayCustomLocalSound(player->playerID, "flag_lost");
      } else if (koth.soundEnabled) {
	bz_sendPlayCustomLocalSound(player->playerID, "flag_won");
      }
    }

    bz_freePlayerRecord(player);
  }

  bz_deleteIntList(playerList);

  bz_sendTextMessagef(BZ_SERVER, BZ_ALLUSERS, "%s IS KING OF THE HILL!", kothcallsign.c_str());

  return;
}
Esempio n. 4
0
void KeepAwayPlayerPaused( bz_EventData *eventData )
{
	if (eventData->eventType != bz_ePlayerPausedEvent || !keepaway.enabled || keepaway.flagToKeep == "")
		return;

	bz_PlayerPausedEventData_V1 *PauseData = (bz_PlayerPausedEventData_V1*)eventData;

	bz_BasePlayerRecord *player = bz_getPlayerByIndex(PauseData->playerID);

	if (player)
	{
		const char* flagHeld = bz_getPlayerFlag(player->playerID);

		if (flagHeld)
		{
			if (flagHeld == keepaway.flagToKeep)
			{
				bz_removePlayerFlag (player->playerID);
				bz_sendTextMessage (BZ_SERVER, PauseData->playerID, "Flag removed - cannot pause while holding flag.");
				keepaway.id = -1;
				keepaway.team = eNoTeam;
				keepaway.toldFlagFree = false;
			}
		}
	}
	bz_freePlayerRecord(player);

	return;
}
Esempio n. 5
0
	void buildHTMLPlayer ( std::string &params, int playerID, int index )
	{
		bz_BasePlayerRecord	*player = bz_getPlayerByIndex(playerID);
		if (player)
		{
			params += format("&callsign%d=%s",index,bz_urlEncode(player->callsign.c_str()));

			params += format("&team%d=%s",index,bz_urlEncode(getTeamName(player->team)));

			std::string BZID = player->bzID.c_str();
			if (!BZID.size())
				BZID = "none";
			params += format("&bzID%d=%s",index,bz_urlEncode(BZID.c_str()));

			params += format("&token%d=V2",index);

			if (player->team != eObservers)
			{
				params += format("&wins%d=%d",index,player->wins);
				params += format("&losses%d=%d",index,player->losses);
				params += format("&teamkills%d=%d",index,player->teamKills);
			}
			params += format("&version%d=2.0.x",index);
			bz_freePlayerRecord(player);
		}
	}
Esempio n. 6
0
void killTeams(bz_eTeamType safeteam, std::string keepawaycallsign)
{
	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 != safeteam)
				{
					bz_killPlayer(player->playerID, true, BZ_SERVER);
					if (keepaway.soundEnabled)
						bz_sendPlayCustomLocalSound(player->playerID,"flag_lost");
				}
				else if (keepaway.soundEnabled)
					bz_sendPlayCustomLocalSound(player->playerID,"flag_won");
			}

		bz_freePlayerRecord(player);
	}
	bz_deleteIntList(playerList);

	bz_sendTextMessagef (BZ_SERVER, BZ_ALLUSERS, "%s (%s) Kept the Flag Away!", getTeamColor(safeteam), keepawaycallsign.c_str());

	if (keepaway.flagResetEnabled)
		bz_resetFlags(true);

	return;
}
Esempio n. 7
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;
}
Esempio n. 8
0
void KillTeam(bz_eTeamType TeamToKill)
{
  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 == TeamToKill) {
	bz_killPlayer(player->playerID, true, BZ_SERVER);
	if (tctf.soundEnabled)
	  bz_sendPlayCustomLocalSound(player->playerID, "flag_lost");
      } else if (tctf.soundEnabled) {
	bz_sendPlayCustomLocalSound(player->playerID, "flag_won");
      }
      bz_freePlayerRecord(player);
    }

  }
  bz_deleteIntList(playerList);

  return;
}
Esempio n. 9
0
bool teamClear(bz_eTeamType teamToCheck)
{
  if (teamToCheck == eRogueTeam || teamToCheck == eNoTeam || !koth.teamPlay)
    return true;

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

  bool isOut = true;

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

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

    if (player) {
      if (player->team == teamToCheck && kothzone.pointIn(player->currentState.pos) && player->spawned)
	isOut = false;
    }

    bz_freePlayerRecord(player);
  }

  bz_deleteIntList(playerList);

  return isOut;
}
Esempio n. 10
0
inline void checkKeepAwayHolder()
{
	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)
			{
				const char* flagHeld = bz_getPlayerFlag(player->playerID);
				if (flagHeld)
				{
					if (flagHeld == keepaway.flagToKeep && keepaway.id == -1) // gotta a new one; initiate
					{
						initiatekeepaway(player->team, player->callsign, player->playerID);
						bz_freePlayerRecord(player);
						bz_deleteIntList(playerList);
						return;
					}
					if (flagHeld == keepaway.flagToKeep && keepaway.id == player->playerID) // someone still has it; leave
					{
						bz_freePlayerRecord(player);
						bz_deleteIntList(playerList);
						return;
					}
					if (flagHeld == keepaway.flagToKeep && keepaway.id != player->playerID) // must have stolen it
					{
						initiatekeepaway(player->team, player->callsign, player->playerID);
						bz_freePlayerRecord(player);
						bz_deleteIntList(playerList);
						return;
					}
				}
			}

		bz_freePlayerRecord(player);
	}

	keepaway.id = -1;  // no one has flag
	keepaway.team = eNoTeam;

	bz_deleteIntList(playerList);

	return;
}
Esempio n. 11
0
void killmsg::Event ( bz_EventData *eventData )
{
    if(eventData->eventType==bz_ePlayerDieEvent)
    {
      bz_PlayerDieEventData_V1* data = (bz_PlayerDieEventData_V1*)eventData;

      bz_BasePlayerRecord *playerdata; //create a playerrecord for the dead player.
      playerdata = bz_getPlayerByIndex(data->playerID); //get data

      bz_BasePlayerRecord *killerdata; //another playerrecord for the killer
      killerdata = bz_getPlayerByIndex(data->killerID); //get data
     
      if(killerdata&&playerdata)
      {
                //now we create a message to send to the killer
                std::string killermessage = std::string("You killed ") +
                playerdata->callsign.c_str();

                        if(data->killerID==data->playerID && killmyself==1)
                        {
                                //This kill is the kill you get after a teamkill...
                                killmyself=0;
                        }
                        else if(data->killerID==data->playerID)
                        {
                                bz_sendTextMessage(BZ_SERVER,data->killerID,"You commited suicide! Don't do that again!");
                        }
                        else if(killerdata->team==playerdata->team && killerdata->team!=eRogueTeam)
                        {
                                //Here we check whether the kill was a team kill
                                if(triti)killmyself=1; //The plugin gets confused if you get killed after a teamkill
                                std::string tkmessage = std::string("You killed teamate ") +
                                playerdata->callsign.c_str() +
                                std::string("! Don't do that again!") ;
                                bz_sendTextMessage(BZ_SERVER,data->killerID,tkmessage.c_str());
                        }
                        else
                        {
                                //Send the first message if no TK or suicide
                                bz_sendTextMessage(BZ_SERVER,data->killerID,killermessage.c_str());
                        }
      }
      //free the records here
      bz_freePlayerRecord(playerdata);
      bz_freePlayerRecord(killerdata);
    }
}
Esempio n. 12
0
void LogDetail::listPlayers( action act , bz_PlayerJoinPartEventData_V1 *data )
{
  bz_APIIntList *playerList = bz_newIntList();
  bz_BasePlayerRecord *player = NULL;
  std::ostringstream msg;
  char playerStatus;
  int numPlayers;

  bz_getPlayerIndexList( playerList );

  bz_debugMessage( 4 , "Players:" );
  //
  // Count number of players
  //
  numPlayers = 0;
  for ( unsigned int i = 0; i < playerList->size(); i++ ) {
    player = bz_getPlayerByIndex( playerList->get(i));
    if (player) {
      if ((player->callsign != "") && (act == join || act == auth || (data && (player->playerID != data->playerID))))
	numPlayers++;
      bz_freePlayerRecord( player );
    }
  }

  //
  // Display number of players, callsign, and motto string in the following format:
  //
  // PLAYERS (nn) [G]cc:callsign(ee:mottostring)
  // nn - number of players
  // G	- global auth identifier (+|-| |@)
  // cc - count of characters in player callsign
  // callsign - player callsign
  // ee - count of characters in motto string
  // mottostring - player motto string
  //
  // eg.
  // PLAYERS (2) [@]7:Thumper(16:[email protected]) [ ]3:xxx()
  //
  msg.str("");
  msg << "PLAYERS (" << numPlayers << ")";
  for ( unsigned int i = 0; i < playerList->size(); i++ ) {
    player = bz_getPlayerByIndex( playerList->get(i));
    if (player) {
      if ((player->callsign != "") && (act == join || act == auth || (data && (player->playerID != data->playerID)))) {
	playerStatus = ' ';
	if (player->globalUser) playerStatus = '+';
	if (player->verified) playerStatus = '+';
	if (player->admin && !bz_hasPerm(player->playerID, bz_perm_hideAdmin)) playerStatus = '@';
	msg << " [" << playerStatus << "]";
	msg << player->callsign.size() << ':';
	msg << player->callsign.c_str() << "(" << bz_getPlayerMotto(player->playerID) << ")";
      }
    }
  }
  bz_debugMessage(0, msg.str().c_str());

  bz_deleteIntList(playerList);
}
Esempio n. 13
0
void initiatekeepaway(bz_eTeamType plyrteam, bz_ApiString plyrcallsign, int plyrID)
{
	keepaway.team = plyrteam;
	keepaway.callsign = plyrcallsign.c_str();

	if (keepaway.callsign.size() > 16)
	{
		std::string tofix = truncate(keepaway.callsign, 16);
		keepaway.callsign = tofix;
	}

	keepaway.id = plyrID;
	keepaway.startTime = bz_getCurrentTime();
	keepaway.TTHminutes = (int)(keepaway.adjustedTime/60 + 0.5);
	keepaway.TTHseconds = 30;
	keepaway.toldFlagFree = false;
	bool multipleof30 = false;

	if ((int)((keepaway.adjustedTime / 30) + 0.5) != (double)(keepaway.adjustedTime / 30))
		multipleof30 = false;
	else
		multipleof30 = true;

	if (!multipleof30)
	{
		if ((!keepaway.teamPlay || keepaway.team == eRogueTeam))
			bz_sendTextMessagef (BZ_SERVER, BZ_ALLUSERS, "%s has %s flag; %i secs left!", keepaway.callsign.c_str(), keepaway.flagToKeep.c_str(), (int)keepaway.adjustedTime);
		else
			bz_sendTextMessagef (BZ_SERVER, BZ_ALLUSERS, "%s (%s) has %s flag; %i secs left!", getTeamColor(keepaway.team), keepaway.callsign.c_str(), keepaway.flagToKeep.c_str(), (int)keepaway.adjustedTime);
	}

	if (keepaway.soundEnabled)
	{
		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 != keepaway.team || player->team == eRogueTeam) && player->playerID != keepaway.id)
					bz_sendPlayCustomLocalSound(player->playerID,"flag_alert");
				else
					bz_sendPlayCustomLocalSound(player->playerID,"teamgrab");
			}

			bz_freePlayerRecord(player);
		}
		bz_deleteIntList(playerList);
	}

	return;
}
Esempio n. 14
0
	void buildStateHash(std::string &params)
	{
		int hash = sumString(mapFile);

		int i = 0;
		i += bz_getTeamScore(eRedTeam);
		i += bz_getTeamScore(eGreenTeam);
		i += bz_getTeamScore(eBlueTeam);
		i += bz_getTeamScore(ePurpleTeam);
		i += bz_getTeamWins(eRedTeam);
		i += bz_getTeamWins(eGreenTeam);
		i += bz_getTeamWins(eBlueTeam);
		i += bz_getTeamWins(ePurpleTeam);
		i += bz_getTeamLosses(eRedTeam);
		i += bz_getTeamLosses(eGreenTeam);
		i += bz_getTeamLosses(eBlueTeam);
		i += bz_getTeamLosses(ePurpleTeam);

		hash += (i * 1000);

		i = 0;
		bz_APIIntList *players = bz_newIntList();
		bz_getPlayerIndexList(players);;
		if (players && players->size())
		{
			for (unsigned int p = 0; p < players->size(); p++ )
			{
				bz_BasePlayerRecord	*player = bz_getPlayerByIndex(players->get(p));

				//int playerID = players->get(p);
				if (player)
				{
					std::string BZID = player->bzID.c_str();
					if (BZID.size())
						i += sumString(BZID);
					else
						i += sumString(std::string(player->callsign.c_str()));

					i += sumString("NONE");

					i += player->wins;
					i += player->losses;
					i += player->teamKills;

					bz_freePlayerRecord(player);
				}
			}
		}
		bz_deleteIntList(players);

		hash += (i * 100000);

		params += format("&hash=%d",hash);
	}
Esempio n. 15
0
std::string getFlag()
{
	if (keepaway.flagToKeepIndex < -1) // this should never happen, but save a crash if something goes nuts
		return "";

	// get next flag; if not free take it from player (if forced flags)

	for (unsigned int h = 0; h < keepaway.flagsList.size(); h++) // check all specified flags
	{
		keepaway.flagToKeepIndex++; // get next one in line

		if (keepaway.flagToKeepIndex > ((int)keepaway.flagsList.size() - 1)) // go back to start if at end
			keepaway.flagToKeepIndex = 0;

		std::string flagCandidate = keepaway.flagsList[keepaway.flagToKeepIndex];
		bool flagNotHeld = true;

		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)
			{
				const char* playerFlag = bz_getPlayerFlag(player->playerID);
				if (playerFlag)
				{
					if (playerFlag == flagCandidate && keepaway.forcedFlags) // take it, if forced flags
					{
						bz_removePlayerFlag (player->playerID);
						bz_sendTextMessage (BZ_SERVER, player->playerID, "Sorry, server needs your flag for Keep Away :/");
					}
					if (playerFlag == flagCandidate && !keepaway.forcedFlags) // look for next free flag in list
						flagNotHeld = false;
				}
			}
			bz_freePlayerRecord(player);
		}

		bz_deleteIntList(playerList);

		if (flagNotHeld)
			return flagCandidate;
	}

	if (!keepaway.flagsList.empty())  // we should never get here, but if we do keep going
		return keepaway.flagsList[0];
	else
		return "";
}
Esempio n. 16
0
std::string LogDetail::displayCallsign( int playerID )
{
  std::ostringstream callsign;
  bz_BasePlayerRecord *player = bz_getPlayerByIndex( playerID );
  if (player) {
    callsign << strlen( player->callsign.c_str() ) << ":";
    callsign << player->callsign.c_str();
    bz_freePlayerRecord( player );
  } else {
    callsign << "7:UNKNOWN";
  }
  return callsign.str();
}
Esempio n. 17
0
std::string LogDetail::displayBZid( int playerID )
{
  std::ostringstream bzid;

  bz_BasePlayerRecord *player = bz_getPlayerByIndex( playerID );
  if (player) {
    if (player->globalUser)
      bzid << " BZid:" << player->bzID.c_str();
    bz_freePlayerRecord( player );
  }

  return bzid.str();
}
Esempio n. 18
0
void RogueGenoHandler::Event (bz_EventData *eventData)
{
    switch (eventData->eventType) {
    default:
        // no clue
        break;

    // wait for a tank death and start checking for genocide and rogues
    case bz_ePlayerDieEvent:
    {
        bz_PlayerDieEventData_V1 *dieData = (bz_PlayerDieEventData_V1*)eventData;
        //if its not a genocide kill, dont care
        if (dieData->flagKilledWith != "G")
            break;
        // if the tank killed was not a rogue, let the server/client do the normal killing
        if (dieData->team != eRogueTeam)
            break;
        // option to disallow rogues getting points for shooting themselves
        if (!allowSuicide && dieData->killerID == dieData->playerID)
            break;

        // if the tank killed was a rogue, kill all rogues.
        bz_APIIntList *playerList = bz_newIntList();

        bz_getPlayerIndexList(playerList);

        for (unsigned int i = 0; i < playerList->size(); i++) {
            int targetID = (*playerList)[i];
            bz_BasePlayerRecord *playRec = bz_getPlayerByIndex (targetID);
            if (!playRec)
                continue;

            // the sucker is a spawned rogue, kill him.  This generates another death event,
            // so if you kill another rogue with geno while you are a rogue you end up dead too.
            // and you get both messages (victim and be careful)
            if (playRec->spawned && playRec->team == eRogueTeam) {
                bz_killPlayer(targetID, false, dieData->killerID, "G");
                bz_sendTextMessage(BZ_SERVER, targetID, "You were a victim of Rogue Genocide");

                // oops, I ended up killing myself (directly or indirectly) with Genocide!
                if (targetID == dieData->killerID)
                    bz_sendTextMessage(BZ_SERVER, targetID, "You should be more careful with Genocide!");
            }

            bz_freePlayerRecord(playRec);
        }
        bz_deleteIntList(playerList);
    }
    break;
    }
}
Esempio n. 19
0
std::string LogDetail::displayPlayerPrivs( int playerID )
{
  std::ostringstream playerPrivs;

  bz_BasePlayerRecord *player = bz_getPlayerByIndex( playerID );
  if (player) {
    playerPrivs << "IP:" << player->ipAddress.c_str();
    if (player->verified ) playerPrivs << " VERIFIED";
    if (player->globalUser ) playerPrivs << " GLOBALUSER";
    if (player->admin ) playerPrivs << " ADMIN";
    if (player->op ) playerPrivs << " OPERATOR";
    bz_freePlayerRecord( player );
  } else {
    playerPrivs << "IP:0.0.0.0";
  }

  return playerPrivs.str();
}
Esempio n. 20
0
void KOTHPlayerPaused::process(bz_EventData * eventData)
{
  if (eventData->eventType != bz_ePlayerPausedEvent || !koth.enabled)
    return;

  bz_PlayerPausedEventData_V1 *PauseData = (bz_PlayerPausedEventData_V1 *) eventData;
  bz_BasePlayerRecord *player = bz_getPlayerByIndex(PauseData->playerID);

  if (player) {
    if (kothzone.pointIn(player->currentState.pos)) {
      bz_killPlayer(PauseData->playerID, true, BZ_SERVER);
      bz_sendTextMessage(BZ_SERVER, PauseData->playerID, "Cannot pause while on the Hill.");
    }
  }
  bz_freePlayerRecord(player);

  return;
}
Esempio n. 21
0
void playAlert()
{
	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)
			bz_sendPlayCustomLocalSound(player->playerID,"hunt_select");

		bz_freePlayerRecord(player);
	}
	bz_deleteIntList(playerList);

	return;
}
Esempio n. 22
0
void fairCTF::DropTeamFlag(int playerID)
{
  bz_BasePlayerRecord* droppr = bz_getPlayerByIndex (playerID);
  
  if (droppr != NULL)
  {
    // Are they carrying a team flag?
    if (droppr->currentFlag == "Red team flag" || 
      droppr->currentFlag == "Green team flag" || 
      droppr->currentFlag == "Blue team flag" || 
      droppr->currentFlag == "Purple team flag")
    {
      bz_removePlayerFlag(playerID);
      bz_sendTextMessage (BZ_SERVER, playerID, "CTF play is currently disabled.");
    }
    
    bz_freePlayerRecord(droppr);
  }
}
Esempio n. 23
0
void killAllTeam(int winner, bz_eTeamType teamToKill, bz_eTeamType teamToAward)
{
	bz_APIIntList *playerList = bz_newIntList();
	bz_getPlayerIndexList(playerList);

	for ( unsigned int i = 0; i < playerList->size(); i++ ){
		int player = (*playerList)[i];
		bz_BasePlayerRecord *PlayerRecord = bz_getPlayerByIndex(player);
		if (PlayerRecord->team == teamToKill)
			bz_killPlayer(player,0,winner);
		else if(PlayerRecord->team == teamToAward)
			bz_setPlayerWins(player, (bz_getPlayerWins(player)+2));
		bz_freePlayerRecord(PlayerRecord);
	}	
		
	bz_setTeamWins (teamToAward, (bz_getTeamWins(teamToAward)+1));
	bz_setTeamLosses (teamToKill, (bz_getTeamLosses (teamToKill)+1));
	
}
Esempio n. 24
0
bool Defusal::SlashCommand(int playerID, bz_ApiString command, bz_ApiString /*message*/, bz_APIStringList *params)
{
	bz_BasePlayerRecord *playerdata = bz_getPlayerByIndex(playerID);
	
	if (command == "bomb" && playerdata->currentFlag.c_str()=="Red team flag")
	{	
		bombPlaced = true;
		bombPlacer = playerdata->callsign.c_str();
		bombPlacementTime = bz_getCurrentTime();
		
		bz_removePlayerFlag(playerID); //Take away the flag (bomb), it has been placed
		bz_getFlagPosition(0,bombLocation); //Store the location of the bomb
		
		bz_sendTextMessagef(BZ_SERVER,eBlueTeam,"'%s' has placed the bomb! You have %i minutes to find and defuse it.",bombPlacer.c_str(),detonationTime);
		bz_sendTextMessagef(BZ_SERVER,eRedTeam,"'%s' has placed the bomb! Defend the bomb for %i minutes.",bombPlacer.c_str(),detonationTime);
		bz_sendTextMessagef(BZ_SERVER,eObservers,"'%s' has placed the bomb!",bombPlacer.c_str(),detonationTime);
	}
	
	bz_freePlayerRecord(playerdata);
}
Esempio n. 25
0
void ChatEvents::Event ( bz_EventData *eventData )
{
  bz_ChatEventData_V1	*chatEventData = (bz_ChatEventData_V1*)eventData;

  bz_BasePlayerRecord *fromPlayer = bz_getPlayerByIndex(chatEventData->from);

  std::string message = chatEventData->message.c_str();

  std::string callsign = "";
  if (fromPlayer)
    callsign = fromPlayer->callsign.c_str();

  callsign = tolower(callsign);

  switch( eventData->eventType)
  {
  default:
    break;

  case bz_eRawChatMessageEvent:
    std::map<std::string,tvChatHistory>::iterator itr = chatHistories.find(callsign);
    if (itr == chatHistories.end())
    {
      tvChatHistory h;
      chatHistories[callsign] = h;
    }

    tvChatHistory &history = chatHistories[callsign];

    history.push_back(message);
    if (history.size() > maxChatLines)
      history.erase(history.begin());
    break;

  }

  bz_freePlayerRecord(fromPlayer);

}
Esempio n. 26
0
void SuperUser::Event ( bz_EventData * eventData  )
{
  if (eventData->eventType == bz_eGetPlayerInfoEvent) {
    bz_GetPlayerInfoEventData_V1* playerInfoData = (bz_GetPlayerInfoEventData_V1*)eventData;
    bz_BasePlayerRecord* pr = bz_getPlayerByIndex(playerInfoData->playerID);

    std::vector<std::string> perms = GetUserInfo(pr->bzID.c_str());

    if (std::find(perms.begin(), perms.end(), "ban") != perms.end())
      playerInfoData->admin = true;

    bz_freePlayerRecord(pr);
  }
  else if (eventData->eventType == bz_ePlayerJoinEvent) {
    bz_PlayerJoinPartEventData_V1 *joinData = (bz_PlayerJoinPartEventData_V1*)eventData;

    std::vector<std::string> perms = GetUserInfo(joinData->record->bzID.c_str());

    for (size_t i = 0; i < perms.size(); i++)
      bz_grantPerm(joinData->playerID,perms[i].c_str());
  }
}
Esempio n. 27
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;
		}
	}
}
Esempio n. 28
0
void PlayHistoryTracker::Event(bz_EventData *eventData)
{
  switch (eventData->eventType) {
  default:
    break;

  case bz_ePlayerDieEvent:
    {
      bz_PlayerDieEventData_V1 *deathRecord = (bz_PlayerDieEventData_V1*)eventData;

      // Create variables to store the callsigns
      std::string victimCallsign = "UNKNOWN";
      std::string killerCallsign = "UNKNOWN";

      // Get player records for victim and killer
      bz_BasePlayerRecord *victimData = bz_getPlayerByIndex(deathRecord->playerID);
      bz_BasePlayerRecord *killerData = bz_getPlayerByIndex(deathRecord->killerID);

      // If we have valid data, update the callsigns
      if (victimData)
	victimCallsign = victimData->callsign.c_str();
      if (killerData)
	killerCallsign = killerData->callsign.c_str();

      // Free the player records
      bz_freePlayerRecord(victimData);
      bz_freePlayerRecord(killerData);

      // Handle the victim
      if (spreeCount.find(deathRecord->playerID) != spreeCount.end()) {
	// Store a quick reference to their former spree count
	int spreeTotal = spreeCount[deathRecord->playerID];
	
	std::string message;

	// Generate an appropriate message, if any
	if (spreeTotal >= 5 && spreeTotal < 10)
	  message = victimCallsign + std::string("'s rampage was stopped by ") + killerCallsign;
	else if (spreeTotal >= 10 && spreeTotal < 20)
	  message = victimCallsign + std::string("'s killing spree was halted by ") + killerCallsign;
	else if (spreeTotal >= 20)
	  message = std::string("The unstoppable reign of ") + victimCallsign + std::string(" was ended by ") + killerCallsign;

	// If we have a message to send, then send it
	if (message.size())
	  bz_sendTextMessage(BZ_SERVER, BZ_ALLUSERS, message.c_str());

	// Since they died, release their spree counter
	spreeCount[deathRecord->playerID] = 0;
      }

      // Handle the killer (if it wasn't also the victim)
      if (deathRecord->playerID != deathRecord->killerID && spreeCount.find(deathRecord->killerID) != spreeCount.end()) {
	// Store a quick reference to their newly incremented spree count
	int spreeTotal = ++spreeCount[deathRecord->playerID];

	std::string message;

	// Generate an appropriate message, if any
	if (spreeTotal == 5)
	  message = victimCallsign + std::string(" is on a Rampage!");
	else if (spreeTotal == 10)
	  message = victimCallsign + std::string(" is on a Killing Spree!");
	else if (spreeTotal == 20)
	  message = victimCallsign + std::string(" is Unstoppable!!");
	else if (spreeTotal > 20 && spreeTotal%5 == 0)
	  message = victimCallsign + std::string(" continues to rage on");

	// If we have a message to send, then send it
	if (message.size())
	  bz_sendTextMessage(BZ_SERVER, BZ_ALLUSERS, message.c_str());
      }
    }
    break;

  case  bz_ePlayerJoinEvent:
    {
      // Initialize the spree counter for the player that just joined
      spreeCount[((bz_PlayerJoinPartEventData_V1*)eventData)->playerID] = 0;
    }
    break;

  case  bz_ePlayerPartEvent:
    {
      // Erase the spree counter for the player that just left
      std::map<int, int >::iterator itr = spreeCount.find(((bz_PlayerJoinPartEventData_V1*)eventData)->playerID);
      if (itr != spreeCount.end())
	spreeCount.erase(itr);
    }
    break;
  }
}
Esempio n. 29
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;
    }
}
Esempio n. 30
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;
}