/*-------------------------------------------------------------------------
 * AnnounceExit
 *-------------------------------------------------------------------------
 * Purpose:
 *    Somebody left. Let everybody know.
 * 
 * Returns:
 *    nothing
 */
void CFSShip::AnnounceExit(IclusterIGC* pclusterOld, ShipDeleteReason sdr)
{
  if ((SDR_DOCKED == sdr || SDR_LEFTSECTOR == sdr) && (m_pShip->GetParentShip() != NULL))
    return;

  BEGIN_PFM_CREATE(g.fm, pfmShipDelete, S, SHIP_DELETE)
  END_PFM_CREATE
  pfmShipDelete->shipID = GetShipID();
  pfmShipDelete->sdr = sdr;
  CFMRecipient * prcp = NULL;
  if (SDR_DOCKED == sdr || SDR_LEFTSECTOR == sdr)
  {
    assert (pclusterOld);
    prcp = GetGroupSectorFlying(pclusterOld);
  }
  else
  {
    ImissionIGC*    pm = GetIGCShip()->GetMission();
    
    if (pm && pm->GetPrivateData())
    {
      CFSMission * pfsMission = (CFSMission *)(pm->GetPrivateData());
      prcp = pfsMission->GetGroupMission();
    }
  }

  if (prcp)
    g.fm.SendMessages(prcp, FM_GUARANTEED, FM_FLUSH);
  else
    g.fm.PurgeOutBox();
}
Пример #2
0
/*-------------------------------------------------------------------------
 * CAdminGame::get_GameOwnerUser()
 *-------------------------------------------------------------------------
 * Purpose:
 *   Returns the user that owns the game.   
 * 
 */
STDMETHODIMP CAdminGame::get_GameOwnerUser(/*[out, retval]*/ IAdminUser** ppUser)
{
  // Initialize the [out] parameter
  *ppUser = NULL;
  // CLEAROUT(ppUser, (IAdminUser*)NULL);

  ImissionIGC * pMission = GetIGC();

  if (!pMission || !(pMission->GetShips()) || pMission->GetShips()->n() == 0)
    return S_OK;

  CFSMission * pCFSMission = GetHostIGC();

  if (!pCFSMission)
    return S_OK;

  CFSPlayer* pfsPlayer = pCFSMission->GetOwner();

  if (!pfsPlayer)
    return S_OK;

  RETURN_FAILED(pfsPlayer->CAdminSponsor<CAdminUser>::Make(IID_IAdminUser, (void**)ppUser));

  // finish construction
  pfsPlayer->CAdminSponsor<CAdminUser>::GetLimb()->Init(pfsPlayer);

  return S_OK;
}
Пример #3
0
/*-------------------------------------------------------------------------
 * get_GameParameters()
 *-------------------------------------------------------------------------
 */
STDMETHODIMP CAdminGame::get_GameParameters(IAGCGameParameters** ppParams) // overrides IAGCGameImpl
{
  // Perform default processing
  RETURN_FAILED(IAGCGameImplBase::get_GameParameters(ppParams));
  assert(*ppParams);

  // Get the IGC pointer
  ImissionIGC * pIGCMission = GetIGC();
  assert(pIGCMission);

  // Populate the team names
  for (SideLinkIGC*   psl = pIGCMission->GetSides()->first(); (psl != NULL); psl = psl->next())
  {
    IsideIGC*   pside = psl->data();

    if (pside)
    {
      CComBSTR bstrTemp(pside->GetName()); 
      RETURN_FAILED((*ppParams)->put_TeamName(pside->GetObjectID(), bstrTemp));
    }
  }

  // Get the CFSMission pointer
  CFSMission* pFSMission = GetHostIGC();

  // Set the StoryText property
  CComBSTR bstrStoryText(pFSMission->GetStoryText());
  RETURN_FAILED((*ppParams)->put_StoryText(bstrStoryText));

  // Set the starting tech bits
  if (pFSMission->m_pttbmAltered && pFSMission->m_pttbmNewSetting)
  {
    // Loop through the techbit masks for each team
    for (int iSide = 0; iSide < c_cSidesMax; ++iSide)
    {
      // Loop through each techbit
      for (short iBit = 0; iBit < c_ttbMax; ++iBit)
      {
        if (pFSMission->m_pttbmAltered[iSide].GetBit(iBit))
        {
          bool bBit = pFSMission->m_pttbmNewSetting[iSide].GetBit(iBit);
          (*ppParams)->put_OverriddenTechBit(iSide, iBit, VARBOOL(bBit));
        }
      }
    }
  }

  // Indicate success
  return S_OK;
}
void          CFSShip::ShipStatusHidden(IsideIGC* pside)
{
    SideID  sideID = pside->GetObjectID();
    m_rgShipStatus[sideID].SetUnknown();

    IsideIGC*   mySide = GetSide();
    SideID      mySideID = mySide->GetObjectID();

    //Does anyone see us?
    bool    detectedF = false;
    {
        CFSMission* pmission = this->GetMission();
        if (pmission)  
        {
            for (SideLinkIGC*   psl = pmission->GetIGCMission()->GetSides()->first();
                 (psl != NULL);
                 psl = psl->next())
            {
				if (psl->data() != mySide && !mySide->AlliedSides(psl->data(), mySide)) //#ALLY -was: != (Imago fixed 7/8/09)
                {
                    ShipStatus* pss = GetShipStatus(psl->data()->GetObjectID());
                    if (!pss->GetUnknown())
                    {
                        detectedF = true;
                        break;
                    }
                }
            }
        }
    }

    m_rgShipStatus[mySideID].SetDetected(detectedF);

    //Adjust the ship status for all of the children as well
    {
        for (ShipLinkIGC*   psl = GetIGCShip()->GetChildShips()->first();
             (psl != NULL);
             psl = psl->next())
        {
            IshipIGC*   pship = psl->data();
            CFSShip*    pfsShip = ((CFSShip*)(pship->GetPrivateData()));
            ShipStatus* pss = pfsShip->GetShipStatus(sideID);

            pss->SetUnknown();

            pfsShip->GetShipStatus(mySideID)->SetDetected(detectedF);
        }
    }
}
Пример #5
0
/*-------------------------------------------------------------------------
 * OverrideTechBit()
 *-------------------------------------------------------------------------
 */
STDMETHODIMP CAdminGame::OverrideTechBit(int iSideID, int nTechBitID, BOOL bSetting)
{
    assert(GetIGC());
    if (GetIGC()->GetMissionStage() == STAGE_NOTSTARTED && iSideID < c_cSidesMax && iSideID >= 0)
    {
        CFSMission * pfsmission = GetHostIGC();

        pfsmission->MakeOverrideTechBits();

        (pfsmission->m_pttbmAltered)[iSideID].SetBit(nTechBitID);

        if (bSetting)
          (pfsmission->m_pttbmNewSetting)[iSideID].SetBit(nTechBitID);
        else
          (pfsmission->m_pttbmNewSetting)[iSideID].ClearBit(nTechBitID);

        debugf("\nBits: %d %d\n", int((pfsmission->m_pttbmAltered)[iSideID].GetBit(nTechBitID)), int((pfsmission->m_pttbmNewSetting)[iSideID].GetBit(nTechBitID)));
    }
    return S_OK;
}
Пример #6
0
/*-------------------------------------------------------------------------
 * get__NewEnum()
 *-------------------------------------------------------------------------
 * Purpose:
 *    Provide iteration support for things (like VB/Javascript languages) 
 *    that use this COM object.
 */
STDMETHODIMP CAdminUsers :: get__NewEnum(IUnknown** ppunkEnum)
{
  // Clear the [out] parameter
  CLEAROUT(ppunkEnum, (IUnknown*)NULL);

  // Create a new CComEnum enumerator object
  typedef CComObject<CComEnum<IEnumVARIANT, &IID_IEnumVARIANT, VARIANT,
    _Copy<VARIANT> > > CEnum;
  CEnum* pEnum = new CEnum;
  assert(NULL != pEnum);

  //
  // Copy the pCAdminGame elements into to a temporary CComVariant vector
  //

  long cTotal;
  get_Count(&cTotal);

  CComVariant* pargTemp = new CComVariant[cTotal];

  long i = 0;

  if (m_pIGCmission)
  {
    //
    // Iterate thru all ships in mission
    //
    for(ShipLinkIGC * plinkShip = m_pIGCmission->GetShips()->first(); plinkShip; plinkShip = plinkShip->next())
    {
      CFSShip * pfsShip = (CFSShip *) plinkShip->data()->GetPrivateData();
      if (pfsShip->IsPlayer())
      {
        CFSPlayer * pfsPlayer = pfsShip->GetPlayer();

        IAdminUser *pIAdminUser;

        RETURN_FAILED (pfsPlayer->CAdminSponsor<CAdminUser>::Make(IID_IAdminUser, (void**)&pIAdminUser));

        pfsPlayer->CAdminSponsor<CAdminUser>::GetLimb()->Init(pfsPlayer);

        pargTemp[i] = pIAdminUser;

        ++i;

        // at this point we now we are done.  This is not only an optimization but
        // a safeguard incase IGC is flawed.
        if (i >= cTotal) 
            break;
      }
    }
  }
  else
  {
      //
      // Iterate thru all missions
      //
      const ListFSMission * plistMission = CFSMission::GetMissions();
      for (LinkFSMission * plinkMission = plistMission->first(); plinkMission; plinkMission = plinkMission->next())
      {
            CFSMission * pfsMission = plinkMission->data();

            ImissionIGC * pIGCmission = pfsMission->GetIGCMission();

            const ShipListIGC * plistShip = pIGCmission->GetShips();

            //
            // Iterate thru all ships in mission
            //
            for(ShipLinkIGC * plinkShip = plistShip->first(); plinkShip; plinkShip = plinkShip->next())
            {
              CFSShip * pfsShip = (CFSShip *) plinkShip->data()->GetPrivateData();
              if (pfsShip->IsPlayer())
              {
                CFSPlayer * pfsPlayer = pfsShip->GetPlayer();

                IAdminUser *pIAdminUser;

                RETURN_FAILED (pfsPlayer->CAdminSponsor<CAdminUser>::Make(IID_IAdminUser, (void**)&pIAdminUser));

                pfsPlayer->CAdminSponsor<CAdminUser>::GetLimb()->Init(pfsPlayer);

                pargTemp[i] = pIAdminUser;

                ++i;

                // at this point we now we are done.  This is not only an optimization but
                // a safeguard incase IGC is flawed.
                if (i >= cTotal) goto exit_loops;
              }
          }
      }
  }

exit_loops:


  // Initialize enumerator object with the temporary CComVariant vector
  HRESULT hr = pEnum->Init(&pargTemp[0], &pargTemp[cTotal], NULL, AtlFlagCopy);

  delete [] pargTemp;

  if (SUCCEEDED(hr))
    hr = pEnum->QueryInterface(IID_IEnumVARIANT, (void**)ppunkEnum);
  if (FAILED(hr))
    delete pEnum;


  // Return the last result
  return hr;
}
Пример #7
0
HRESULT FedSrvLobbySite::OnAppMessage(FedMessaging * pthis, CFMConnection & cnxnFrom, FEDMESSAGE * pfm)
{
	HRESULT hr = S_OK;
	assert(&g.fmLobby == pthis);

	static CTempTimer timerOnAppMessage("in FedSrvLobbySite::OnAppMessage", .02f);
	timerOnAppMessage.Start();

	switch (pfm->fmid)
	{
		// KGJV #114 - reactivate create mission
	  //#if !defined(ALLSRV_STANDALONE)
	case FM_L_CREATE_MISSION_REQ:
	{
#if !defined(SRV_CHILD)
		CASTPFM(pfmCreateMissionReq, L, CREATE_MISSION_REQ, pfm);
		MissionParams mp;
		Strcpy(mp.strGameName, ZString(FM_VAR_REF(pfmCreateMissionReq, GameName)));// + "'s game");
		Strcpy(mp.szIGCStaticFile, ZString(FM_VAR_REF(pfmCreateMissionReq, IGCStaticFile)));
		mp.bScoresCount = false;// dont set to true till clients can change this!
		mp.iMaxImbalance = 0x7ffe;// added
		assert(!mp.Invalid());
#endif

		//Imago - give birth right here, feed it and off it goes...

#if defined(SRV_PARENT)
		//start missions as thier own process
		STARTUPINFO si;
		PROCESS_INFORMATION pi;
		ZeroMemory(&si, sizeof(si));
		si.cb = sizeof(si);
		ZeroMemory(&pi, sizeof(pi));
		char szCmd[255]; char szName[32]; char szFile[32];
		ZString strName = mp.strGameName;
		ZString strFile = mp.szIGCStaticFile;
		si.lpTitle = mp.strGameName;
		Strcpy(szName, (PCC)strName);
		Strcpy(szFile, (PCC)strFile);
		sprintf(szCmd, "AllSrv.exe \"%s\" %s %x", szName, szFile, pfmCreateMissionReq->dwCookie);

		// Create a NULL dacl to give "everyone" access
		SECURITY_DESCRIPTOR sd;
		SECURITY_ATTRIBUTES sa = { sizeof(sa), &sd, false };
		InitializeSecurityDescriptor(&sd, SECURITY_DESCRIPTOR_REVISION);
		SetSecurityDescriptorDacl(&sd, true, NULL, FALSE);

		if (!CreateProcess(
			NULL,                   // No module name (use command line). 
			szCmd,
			NULL,
			NULL,
			FALSE,                  // Set handle inheritance to FALSE. 
			CREATE_NEW_PROCESS_GROUP | CREATE_NEW_CONSOLE, // we're destined to do amazing things
			NULL,                   // Use parent's environment block. 
			NULL,                   // Use parent's starting directory. 
			&si,                    // Pointer to STARTUPINFO structure.
			&pi)                   // Pointer to PROCESS_INFORMATION structure.
			)
		{
			debugf("CreateProcess failed (%d).\n", GetLastError());
		}

		// check to make sure the child is ready before restart
		char strFilename[10] = "\0";
		sprintf(strFilename, "%d.pid", pi.dwProcessId);
		HANDLE hFile = (HANDLE)CreateFile(strFilename, 0, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_FLAG_NO_BUFFERING, NULL);
		DWORD dwError = GetLastError();
		int i = 0;
		while (hFile == INVALID_HANDLE_VALUE || dwError == ERROR_FILE_NOT_FOUND) {
			if (i >= 14) //30s
				break;

			Sleep(2500);
			hFile = (HANDLE)CreateFile(strFilename, 0, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_FLAG_NO_BUFFERING, NULL);
			dwError = GetLastError();
			i++;
		}
		_Module.AddPID(pi.dwProcessId);
		CloseHandle(hFile);
		CloseHandle(pi.hProcess);
		CloseHandle(pi.hThread);
		g.bRestarting = true;
		PostQuitMessage(0);

#endif 

#if !defined(SRV_CHILD)
#if !defined(SRV_PARENT)
		// pkk 2011-07-24 - Create games only with IGCs from cores.txt
		bool ValidCore = false;
		for (int i = 0; i < g.cStaticCoreInfo; i++)
		{
			if (!strcmpi(mp.szIGCStaticFile, g.vStaticCoreInfo[i].cbIGCFile))
			{
				ValidCore = true;
				break; // quit loop
			}
		}
		if (ValidCore == true)
		{
			//Imago - start the mission in this thread as usual 
			FedSrvSite * psiteFedSrv = new FedSrvSite();
			CFSMission * pfsMissionNew = new CFSMission(mp, "", psiteFedSrv, psiteFedSrv, NULL, NULL);
			pfsMissionNew->SetCookie(pfmCreateMissionReq->dwCookie);
		}
		else
		{
			debugf("Lobby sent invalid core information %s, ignoring message\n", mp.szIGCStaticFile);
		}
		// pkk end
#endif
#endif
	} //Imago 6/22/08
	break;
	//#endif -- reactivate create mission

	case FM_L_NEW_MISSION_ACK:
	{
		CASTPFM(pfmNewMissionAck, L, NEW_MISSION_ACK, pfm);
		CFSMission * pfsm = CFSMission::GetMissionFromIGCMissionID(pfmNewMissionAck->dwIGCMissionID);
		if (pfsm)
		{
			pfsm->SetCookie(pfmNewMissionAck->dwCookie);
			// If we already have players (e.g. reconnect), tell the lobby who's in the game
			const ShipListIGC * plistShip = pfsm->GetIGCMission()->GetShips();
			for (ShipLinkIGC * plinkShip = plistShip->first(); plinkShip; plinkShip = plinkShip->next())
			{
				IshipIGC * pShip = plinkShip->data();
				CFSShip * pfsShip = GETFSSHIP(pShip);
				if (pfsShip->IsPlayer() && !pShip->IsGhost())
				{
					CFSPlayer* pfsPlayer = pfsShip->GetPlayer();
					BEGIN_PFM_CREATE(g.fmLobby, pfmPlayerJoined, S, PLAYER_JOINED)
						FM_VAR_PARM(pfsPlayer->GetName(), CB_ZTS)
						END_PFM_CREATE
						pfmPlayerJoined->dwMissionCookie = pfsm->GetCookie();
				}
			}
			HRESULT hr = pthis->SendMessages(pthis->GetServerConnection(), FM_GUARANTEED, FM_FLUSH);
		}
	}
	break;

	case FM_L_TOKEN:
	{
		CASTPFM(pfmToken, L, TOKEN, pfm);
		Strcpy(g.m_szToken, FM_VAR_REF(pfmToken, Token));
	}
	break;

	case FM_L_REMOVE_PLAYER:
	{
		CASTPFM(pfmRemovePlayer, L, REMOVE_PLAYER, pfm);
		CFSMission * pfsMission = CFSMission::GetMission(pfmRemovePlayer->dwMissionCookie);
		const char* szCharacterName = FM_VAR_REF(pfmRemovePlayer, szCharacterName);
		const char* szMessageParam = FM_VAR_REF(pfmRemovePlayer, szMessageParam);

		// try to find the player in question
		if (!pfsMission)
		{
			debugf("Asked to boot character %s from mission %x by lobby, "
				"but the mission was not found.\n",
				szCharacterName, pfmRemovePlayer->dwMissionCookie);
		}
		else if (!pfsMission->RemovePlayerByName(szCharacterName,
			(pfmRemovePlayer->reason == RPR_duplicateCDKey) ? QSR_DuplicateCDKey : QSR_DuplicateRemoteLogon,
			szMessageParam))
		{
			debugf("Asked to boot character %s from mission %x by lobby, "
				"but the character was not found.\n",
				szCharacterName, pfmRemovePlayer->dwMissionCookie);
		}
	}
	break;

	case FM_L_LOGON_SERVER_NACK:
	{
		char * szReason;

		CASTPFM(pfmLogonNack, L, LOGON_SERVER_NACK, pfm);

		szReason = FM_VAR_REF(pfmLogonNack, Reason);

		OnMessageBox(pthis, szReason ? szReason : "Error while try to log onto server.", "Allegiance Server Error", MB_SERVICE_NOTIFICATION);
		// TODO: consider firing out an event message
		PostQuitMessage(-1);
	}

	// BT - 12/21/2010 ACSS - The lobby server will relay the rank details back to the game server.
	case FM_LS_PLAYER_RANK:
	{
		CQLogonStats * pquery = new CQLogonStats(GotLogonDetails);
		CQLogonStatsData * pqd = pquery->GetData();

		CASTPFM(pfmPlayerRank, LS, PLAYER_RANK, pfm);

		Strcpy(pqd->szCDKey, FM_VAR_REF(pfmPlayerRank, szCDKey));
		Strcpy(pqd->szCharacterName, FM_VAR_REF(pfmPlayerRank, szCharacterName));
		Strcpy(pqd->szPassword, FM_VAR_REF(pfmPlayerRank, szPassword));
		Strcpy(pqd->szReason, FM_VAR_REF(pfmPlayerRank, szReason));

		pqd->characterID = pfmPlayerRank->characterID;
		pqd->fCanCheat = pfmPlayerRank->fCanCheat;
		pqd->fRetry = pfmPlayerRank->fRetry;
		pqd->dwCookie = pfmPlayerRank->dwCookie;
		pqd->fValid = pfmPlayerRank->fValid;
		pqd->dwConnectionID = pfmPlayerRank->dwConnectionID;

		pqd->rank = pfmPlayerRank->rank;
		pqd->sigma = pfmPlayerRank->sigma;
		pqd->mu = pfmPlayerRank->mu;
		pqd->commandRank = pfmPlayerRank->commandRank;
		pqd->commandSigma = pfmPlayerRank->commandSigma;
		pqd->commandMu = pfmPlayerRank->commandMu;

		PostThreadMessage(g.idReceiveThread, wm_sql_querydone, (WPARAM)NULL, (LPARAM)pquery);
		break;
	}

	break;
	}

	timerOnAppMessage.Stop("...for message type %s\n", g_rgszMsgNames[pfm->fmid]);
	return hr;
}
Пример #8
0
/*-------------------------------------------------------------------------
 * CAdminGames::Add()
 *-------------------------------------------------------------------------
 * Purpose:
 *   Add to the collection of Games
 *
 * Parameters:
 *   pGameParameters: a pointer to a CGameParameters interface.
 *                        This houses the mission params.
 *
 */
	STDMETHODIMP CAdminGames::Add(IAGCGameParameters* pGameParameters)
{
	if (!pGameParameters)
		return Error("Creation Parameters was Null");

	// Cannot create a game on a paused server
	if (!g.strLobbyServer.IsEmpty() && !g.fmLobby.IsConnected())
		return Error(IDS_E_GAME_SERVER_PAUSED, IID_IAdminGames);

	IAGCPrivatePtr spPrivate(pGameParameters);
	assert(NULL != spPrivate);

	CGameParamData * pMissionParams = (CGameParamData *)spPrivate->GetIGCVoid();
	assert(pMissionParams);

#if defined(ALLSRV_STANDALONE)
	// Standalone server only supports a single game
	const ListFSMission * plistMission = CFSMission::GetMissions();
	if (plistMission->n())
		return Error(IDS_E_ONE_GAME_PER_SERVER, IID_IAdminGames);

	// Standalone server only support a maximum of c_cMaxPlayersPerGame players total
	if (pMissionParams->nTotalMaxPlayersPerGame > c_cMaxPlayersPerGame)
		pMissionParams->nTotalMaxPlayersPerGame = c_cMaxPlayersPerGame;

	// Standalone games always have a min players per team of 1 and max 
	// players per team of maxPlayerPerGame / nTeams.
	// XXX Note that the training mission #7 uses the server with a
	// XXX nTotalMaxPlayers setting of 1, and we need to handle that.
	pMissionParams->nMinPlayersPerTeam = 1;
	if (pMissionParams->nTotalMaxPlayersPerGame == 1)
		pMissionParams->nMaxPlayersPerTeam = 1;
	else
		pMissionParams->nMaxPlayersPerTeam = pMissionParams->nTotalMaxPlayersPerGame / pMissionParams->nTeams;
#else
	// The maximum players per side must be no more than max per game / nTeams
	if (pMissionParams->nMaxPlayersPerTeam > pMissionParams->nTotalMaxPlayersPerGame / pMissionParams->nTeams)
		pMissionParams->nMaxPlayersPerTeam = pMissionParams->nTotalMaxPlayersPerGame / pMissionParams->nTeams;
	if (pMissionParams->nMinPlayersPerTeam > pMissionParams->nMaxPlayersPerTeam)
		pMissionParams->nMinPlayersPerTeam = pMissionParams->nMaxPlayersPerTeam;
#endif // defined(ALLSRV_STANDALONE)

	// make sure params are valid, if not tell user why
	const char * szInvalid = pMissionParams->Invalid();
	if (szInvalid)
		return Error(szInvalid);

	// Creation through this method always indicates object model created
	// KGJV : hack fix for AllSrvUI created game
	// since bObjectModelCreated isnt exposed thru the AGC interface we use bAllowEmptyTeams
	// so if bAllowEmptyTeams, game will be like a player created game
	pMissionParams->bObjectModelCreated = !pMissionParams->bAllowEmptyTeams;

	// Get the story text of the specified AGCGameParameters object
	CComBSTR bstrStoryText;
	RETURN_FAILED(pGameParameters->get_StoryText(&bstrStoryText));
	USES_CONVERSION;
	const char* pszStoryText = bstrStoryText.Length() ? OLE2CA(bstrStoryText) : NULL;

	//
	// Create a new mission first
	//
	FedSrvSite * psiteFedSrv = new FedSrvSite();
	CFSMission * pfsMissionNew = new CFSMission(*pMissionParams,
		NULL, // NULL means use description in the params
		psiteFedSrv,
		psiteFedSrv,
		pMissionParams,
		pszStoryText);
	if (g.fmLobby.IsConnected())
	{
		BEGIN_PFM_CREATE(g.fmLobby, pfmNewMission, S, NEW_MISSION)
			END_PFM_CREATE
			pfmNewMission->dwIGCMissionID = pfsMissionNew->GetIGCMission()->GetMissionID();

		g.fmLobby.SendMessages(g.fmLobby.GetServerConnection(), FM_GUARANTEED, FM_FLUSH);
	}
	return S_OK;
}
/*-------------------------------------------------------------------------
 * CaptureStation
 *-------------------------------------------------------------------------
 * Purpose:
 *    Handle a station being captured by a ship
 */
void CFSShip::CaptureStation(IstationIGC * pstation)
{
  {
    //Fudge the hitpoints of the station
    //All those guns inside damage the hull
    pstation->SetFraction(pstation->GetFraction() * 0.5f);

    //But the heroic engineer's get the shields up.
    pstation->SetShieldFraction(0.8f); //pstation->GetShieldFraction() + 0.5f);
  }

  {
      GetPlayerScoreObject()->CaptureBase(true);
      for (ShipLinkIGC* psl = GetIGCShip()->GetChildShips()->first();
           (psl != NULL);
           psl = psl->next())
      {
         CFSShip*      ps = (CFSShip*)(psl->data()->GetPrivateData());
         ps->GetPlayerScoreObject()->CaptureBase(false);
      }
  }

  IsideIGC * pside = GetSide();
  pside->AddBaseCapture();

  SideID iSide = pside->GetObjectID();
  IsideIGC* psideOld = pstation->GetSide();

  StationID stationID = pstation->GetObjectID();
  BEGIN_PFM_CREATE(g.fm, pfmStationCapture, S, STATION_CAPTURE)
  END_PFM_CREATE
  pfmStationCapture->stationID = stationID;
  pfmStationCapture->sidOld = psideOld->GetObjectID();
  pfmStationCapture->sidNew = iSide;
  pfmStationCapture->shipIDCredit = GetIGCShip()->GetObjectID();
  g.fm.SendMessages(GetMission()->GetGroupRealSides(), FM_GUARANTEED, FM_FLUSH);

  pstation->SetSide(pside);
  // TE: Fire AGCEvent when base is captured
  CFSMission * pfsMission = this->GetMission();
  LPCSTR pszContext = pfsMission->GetIGCMission() ? pfsMission->GetIGCMission()->GetContextName() : NULL;
  _AGCModule.TriggerContextEvent(NULL, EventID_StationChangesSides, pszContext,
    GetName(), GetShipID(), pside->GetUniqueID(), -1, 4,
	"GameID"	 , VT_I4   , pfsMission->GetMissionID(),
	"OldTeam"    , VT_I4   , psideOld->GetUniqueID(),
    "OldTeamName", VT_LPSTR, psideOld->GetName(),
	"StationName", VT_LPSTR, pstation->GetName());
  // TE end

	// yp: Add event for players who were involved in the capture of an enemy base.
    // mmf commented this out for now pending additional testing
#if 0
	 ZString pszPlayerList = ""; // this creates a new ZString object and set its value to "", it's not a pointer to ""
	 if(m_pfsMission->GetIGCMission() && m_pfsMission->GetIGCMission()->GetShips())
	 {
		ShipLinkIGC * pShiplink = m_pfsMission->GetIGCMission()->GetShips()->first();
		while (pShiplink)
		{
			CFSShip * pfsShip = (CFSShip *) pShiplink->data()->GetPrivateData();
			if (pfsShip && pfsShip->IsPlayer())
			{
				// this logic might need to be tweeked to include the ship that did the capture if its
				if(pfsShip->GetSide()		&& pfsShip->GetSide()->GetObjectID()	== iSide && // if they are on the side that did the Capture. and..
					pfsShip->GetPlayer()->GetIGCShip()->GetObjectID() == GetIGCShip()->GetObjectID() ||	// they are the ship that did the caputure. or
				   pfsShip->GetCluster()	&& pstation->GetCluster()	&& pfsShip->GetCluster()->GetObjectID() == pstation->GetCluster()->GetObjectID()) // they are in this sector
				{
					pszPlayerList = pszPlayerList + ";" + ZString(pfsShip->GetPlayer()->GetName()); // players name
					// The distance the player is from the station that was destroyed.
					if(pfsShip->GetPlayer()->GetIGCShip() )
					{
						pszPlayerList = pszPlayerList +  ":" + ZString( (pstation->GetPosition() - pfsShip->GetPlayer()->GetIGCShip()->GetPosition()).Length()); // the distance
					}
				}
			}
			pShiplink = pShiplink->next();
		}
	 }
	 
	 // Fire AGCEvent listing players in the sector
	// TODO: Might want to add into the event weither or not this was a VICTORY capture.. should we track that as well?
	_AGCModule.TriggerContextEvent(NULL, EventID_StationChangesSides, pszContext,
						GetName(), GetShipID(), pside->GetUniqueID(), -1, 4,
						"GameID"	 , VT_I4   , pfsMission->GetMissionID(),
						"OldTeam"    , VT_I4   , psideOld->GetUniqueID(),
						"OldTeamName", VT_LPSTR, psideOld->GetName(),
						"zPlayerList", VT_LPSTR, pszPlayerList); // pszPlayerList should look like ";player@squad:1500;player2@squad:500"
 // yp:end
#endif



  //Possibly the built themselves to a victory
  IsideIGC*   psideWin = m_pfsMission->CheckForVictoryByStationCapture(pside, psideOld);
  if (psideWin)
  {
      static char szReason[100];     //Make this static so we only need to keep a pointer to it around
      sprintf(szReason, "%s won because %s captured %s", psideWin->GetName(), GetIGCShip()->GetName(), pstation->GetName());
      m_pfsMission->GameOver(psideWin, szReason);
  }
  else if (psideOld->GetActiveF())						//RESET OUR EYE HERE?  IMAGO CAPTURE EYE BUG FIX?  REVIEW 7/23/09
      m_pfsMission->VacateStation(pstation);
}
void CFSPlayer::SetSide(CFSMission * pfsMission, IsideIGC * pside)
{
  CFSMission * pfsmOld = GetMission();
  IsideIGC* psideOld = GetSide();
  CFSShip::SetSide(pfsMission, pside);

  // Their persist score now becomes their current score, and other stuff is reset
  if (pside)
  {
    PlayerScoreObject* ppso = GetPlayerScoreObject();
    ppso->SetPersist(GetPersistPlayerScore(pside->GetCivilization()->GetObjectID()));

    memset(m_ptDesiredLoadout, 0, sizeof(m_ptDesiredLoadout));
  }

  // can't guarantee success on group changes--dplay player may be already blown away
  if (pside != psideOld)
  {
    if (pfsmOld)
      g.fm.DeleteConnectionFromGroup(CFSSide::FromIGC(psideOld)->GetGroup(), GetConnection());

    if (pfsMission)
    {
      bool fLobbySide = SIDE_TEAMLOBBY == pside->GetObjectID();
      CFMGroup * pgrp = CFSSide::FromIGC(pside)->GetGroup();
      g.fm.AddConnectionToGroup(pgrp, GetConnection());
      
      if (fLobbySide)
        g.fm.DeleteConnectionFromGroup(pfsMission->GetGroupRealSides(), GetConnection());
      else
        g.fm.AddConnectionToGroup(pfsMission->GetGroupRealSides(), GetConnection());
    }
  }
  else
    assert (pfsmOld == pfsMission);

  if (!pside && m_pgrp)
  {
    g.fm.DeleteConnectionFromGroup(m_pgrp, GetConnection());
    m_pgrp = NULL;
  }


  //
  // If the user just joined or left the game, consider firing an AGC event
  //
  if (pfsmOld != pfsMission) 
  {

    if (pfsmOld) // if leaving a game
    {
        const char * szName = pfsmOld->GetIGCMission() && pfsmOld->GetIGCMission()->GetMissionParams() ? pfsmOld->GetIGCMission()->GetMissionParams()->strGameName : "?" ;
        int id = pfsmOld->GetIGCMission() ? pfsmOld->GetIGCMission()->GetMissionID() : -1;
        long idShip = (AGC_AdminUser << 16) | CAdminUser::DetermineID(this->GetPlayer());

        LPCSTR pszContext = pfsmOld->GetIGCMission() ? pfsmOld->GetIGCMission()->GetContextName() : NULL;

      _AGCModule.TriggerContextEvent(NULL, EventID_LogoutGame, pszContext,
        GetName(), idShip, -1, -1, 2,
        "GameID",   VT_I4,    id,
        "GameName", VT_LPSTR, szName);
    }

    if (pfsMission) // if joining a game
    {
        const char * szName = pfsMission->GetIGCMission() && pfsMission->GetIGCMission()->GetMissionParams() ? pfsMission->GetIGCMission()->GetMissionParams()->strGameName : "?" ;
        int id = pfsMission->GetIGCMission() ? pfsMission->GetIGCMission()->GetMissionID() : -1;
        long idShip = (AGC_AdminUser << 16) | CAdminUser::DetermineID(this->GetPlayer());

        LPCSTR pszContext = pfsMission->GetIGCMission() ? pfsMission->GetIGCMission()->GetContextName() : NULL;

      _AGCModule.TriggerContextEvent(NULL, EventID_LoginGame, pszContext,
        GetName(), idShip, -1, -1, 2,
        "GameID",   VT_I4,    id,
        "GameName", VT_LPSTR, szName);
    }
  }

  //
  // If the user just joined or left the team, consider firing an AGC event
  //
  if (psideOld  != pside) 
  {
	  //Imago #169
	  if ( (psideOld && psideOld->GetObjectID() == SIDE_TEAMLOBBY) || (pside && pside->GetObjectID() == SIDE_TEAMLOBBY))
		 if (pfsMission)
			 pfsMission->SetLobbyIsDirty();

    long idShip = (AGC_AdminUser << 16) | CAdminUser::DetermineID(this->GetPlayer());

    if (psideOld ) // if leaving a side
    {
      LPCSTR pszContext = GetIGCShip()->GetMission() ? GetIGCShip()->GetMission()->GetContextName() : NULL;
	  // TE Modify LeaveTeam AGCEvent to include MissionID, and change UniqueID to ObjectID
      _AGCModule.TriggerContextEvent(NULL, EventID_LeaveTeam, pszContext,
        GetName(), idShip, psideOld->GetUniqueID(), -1, 3, // Changed UniqueID to ObjectID. Modified ParamCount to 3
        "MissionID", VT_I4	, psideOld->GetMission()->GetMissionID(),	// Added line MissionID as param
	   "Team"    , VT_I4   , psideOld->GetObjectID(), // Changed UniqueID to ObjectID
        "TeamName", VT_LPSTR, psideOld->GetName());

	  // old event
      //_AGCModule.TriggerContextEvent(NULL, EventID_LeaveTeam, pszContext,
      //  GetName(), idShip, psideOld->GetUniqueID(), -1, 2,
      //  "Team"    , VT_I4   , psideOld->GetUniqueID(),
      //  "TeamName", VT_LPSTR, psideOld->GetName());
	}

    if (pside) // if joining a side
    {
        // TE Modify JoinTeam AGCEvent to include MissionID, and change UniqueID to ObjectID
		_AGCModule.TriggerEvent(NULL, EventID_JoinTeam, GetName(), idShip,
         pside->GetUniqueID(), -1, 3, // Changed UniqueID to ObjectID. Modified ParamCount to 3
		 "MissionID", VT_I4	, pfsMission->GetMissionID(),		// Added line MissionID
         "Team"    , VT_I4   , pside->GetObjectID(), // Changed UniqueID to ObjectID.
         "TeamName", VT_LPSTR, pside->GetName());
     
		// old event
		//_AGCModule.TriggerEvent(NULL, EventID_JoinTeam, GetName(), idShip,
        //pside->GetUniqueID(), -1, 2,
        //"Team"    , VT_I4   , pside->GetUniqueID(),
        //"TeamName", VT_LPSTR, pside->GetName());
    }
  }
}