#include "pch.h"
#include <..\TCLib\CoInit.h>
#include <..\TCLib\AutoHandle.h>
#include <agc.h>
#include <zreg.h>
#ifdef _DEBUG
#define SRVLOG
#endif
#ifdef SRVLOG #include "FedSrvApp.h"
#endif
bool ReadFromRegistry(HKEY & hk, bool bIsString, const char * szItem, void * pValue, DWORD dwDefault)
{
char psz[MAX_PATH] = {""};
DWORD dwSize = (bIsString ? sizeof(psz): sizeof(DWORD));
if (RegQueryValueEx(hk, szItem, NULL, NULL, (BYTE *)psz, &dwSize) != ERROR_SUCCESS ||
(bIsString && psz[0] == 0)) {
if (bIsString)
{
if (dwDefault)
{
strcpy((char*)pValue, (char*)dwDefault);
return true;
}
return false;
}
*(DWORD*)pValue = dwDefault;
return true;
}
if (bIsString)
strcpy((char*)pValue, psz);
else
*(DWORD*)pValue = *(DWORD*)psz;
return true;
}
#if !defined(ALLSRV_STANDALONE)
void DoDecrypt(int size, char* pdata)
{
DWORD encrypt = 0;
for (int i = 0; (i < size); i += 4)
{
DWORD* p = (DWORD*)(pdata + i);
encrypt = *p = *p ^ encrypt;
}
}
static void DoEncrypt(int size, char* pdata)
{
DWORD encrypt = 0;
for (int i = 0; (i < size); i += 4)
{
DWORD* p = (DWORD*)(pdata + i);
DWORD old = *p;
*p = *p ^ encrypt;
encrypt = old;
}
}
#endif ALLOC_MSG_LIST;
Global g;
#include "queries.h"
#if defined(ALLSRV_STANDALONE)
int GetNextCharacterID()
{
static int s_nID;
return ++s_nID;
}
#endif #if !defined(ALLSRV_STANDALONE)
#ifdef MOTHBALLED
void htoc(BYTE *c, BYTE b[])
{
*c = b[0] >= '0' && b[0] <= '9' ? b[0] - '0' : 10 + b[0] - 'A';
*c <<= 4;
*c |= b[1] >= '0' && b[1] <= '9' ? b[1] - '0' : 10 + b[1] - 'A';
}
void SzToBlob(BYTE * in, BYTE* pbBlob)
{
BYTE * pin = in;
BYTE* pout = pbBlob;
long i;
int cbBlob = lstrlenA((char*)in) / 2;
for (i = 0; i < cbBlob; i++, pin += 2, pout++)
{
htoc((BYTE *)pout, (BYTE *)pin);
}
}
#endif #endif int TechBitFromToken(const char * szToken)
{
int itoken = 0;
while (lstrcmpi(g.rgTechs[itoken], szToken))
{
if(itoken == cTechs)
return NA;
itoken++;
}
return itoken;
}
void TechsListToBits(BYTE * szTechs, TechTreeBitMask & ttbm)
{
ttbm.ClearAll();
char * token;
token = strtok((char *) szTechs, " ");
while(token)
{
ttbm.SetBit(TechBitFromToken(token));
token = strtok(NULL, " ");
}
}
void LoadTechBits()
{
#if !defined(ALLSRV_STANDALONE)
SQL_GO(TechBitsAll);
while (SQL_SUCCEEDED(SQL_GETROW(TechBitsAll)))
{
assert(TechBitsAll_BitID < cTechs);
SqlStrCpy(g.rgTechs[TechBitsAll_BitID], TechBitsAll_Name, sizeof(TechBitsAll_Name));
}
#endif }
void LoadRankInfo()
{
#if !defined(ALLSRV_STANDALONE)
SQL_GO(GetRankCount);
SQL_GETROW(GetRankCount);
g.cRankInfo = GetRankCount_Count;
if (g.cRankInfo > 0)
{
g.vRankInfo = new RankInfo[g.cRankInfo];
SQL_GO(GetRanks);
for (int i = 0; i < g.cRankInfo; i++)
{
ZVerify(SQL_SUCCEEDED(SQL_GETROW(GetRanks)));
g.vRankInfo[i].civ = GetRanks_CivID;
g.vRankInfo[i].rank = GetRanks_Rank;
g.vRankInfo[i].requiredRanking = GetRanks_Requirement;
strcpy(g.vRankInfo[i].RankName, (char*)GetRanks_Name);
}
}
#else char mapfilename[MAX_PATH + 1];
HRESULT hr = UTL::getFile("ranks", ".txt", mapfilename, true, true);
FILE* file = fopen(mapfilename, "rt"); if (file)
{
int nbranks;
fscanf(file,"%d\n",&nbranks);
g.cRankInfo = nbranks;
g.vRankInfo = new RankInfo[g.cRankInfo];
for (int i=0;i<nbranks;i++)
{
int rank;
fscanf(file,"%d,%[^,\n]\n",&rank,g.vRankInfo[i].RankName);
g.vRankInfo[i].rank = rank;
g.vRankInfo[i].requiredRanking = 0;
g.vRankInfo[i].civ = -1;
}
fclose(file);
}
else
g.cRankInfo = 0;
#endif }
void UnloadRankInfo()
{
delete [] g.vRankInfo;
g.cRankInfo = 0;
}
void LoadStaticCoreInfo()
{
char mapfilename[MAX_PATH + 1];
HRESULT hr = UTL::getFile("cores", ".txt", mapfilename, true, true);
FILE* file = fopen(mapfilename, "rt"); g.cStaticCoreInfo = 0;
g.vStaticCoreInfo = NULL;
if (file)
{
fscanf(file,"%d\n",&g.cStaticCoreInfo);
g.vStaticCoreInfo = new StaticCoreInfo[g.cStaticCoreInfo];
memset(g.vStaticCoreInfo,0,g.cStaticCoreInfo*sizeof(StaticCoreInfo)); for (int i=0;i<g.cStaticCoreInfo;i++)
{
fscanf(file,"%[^\n]\n",g.vStaticCoreInfo[i].cbIGCFile);
}
fclose(file);
}
}
void UnloadStaticCoreInfo()
{
if (g.vStaticCoreInfo)
delete [] g.vStaticCoreInfo;
g.cStaticCoreInfo = 0;
}
void LoadStaticMapInfo()
{
#if !defined(ALLSRV_STANDALONE)
SQL_GO(GetStaticMapCount);
SQL_GETROW(GetStaticMapCount);
g.cStaticMapInfo = GetStaticMapCount_Count;
if (g.cStaticMapInfo > 0)
{
g.vStaticMapInfo = new StaticMapInfo[g.cStaticMapInfo];
SQL_GO(GetStaticMaps);
for (int i = 0; i < g.cStaticMapInfo; i++)
{
ZVerify(SQL_SUCCEEDED(SQL_GETROW(GetStaticMaps)));
SQLSTRCPY(g.vStaticMapInfo[i].cbIGCFile, GetStaticMaps_FileName);
SQLSTRCPY(g.vStaticMapInfo[i].cbFriendlyName, GetStaticMaps_MapName);
g.vStaticMapInfo[i].nNumTeams = GetStaticMaps_NumTeams;
assert(GetStaticMaps_NumTeams > 1 && GetStaticMaps_NumTeams <= c_cSidesMax);
}
}
#else
char mapfilename[MAX_PATH + 1];
HRESULT hr = UTL::getFile("maps", ".txt", mapfilename, true, true);
FILE* file = fopen(mapfilename, "rt"); if (file)
{
int nbmaps;
fscanf(file,"%d\n",&nbmaps);
g.cStaticMapInfo = nbmaps;
g.vStaticMapInfo = new StaticMapInfo[g.cStaticMapInfo];
for (int i=0;i<nbmaps;i++)
{
int nbteams;
fscanf(file,"%d,%[^,],%[^,\n]\n",&nbteams,g.vStaticMapInfo[i].cbFriendlyName,g.vStaticMapInfo[i].cbIGCFile);
g.vStaticMapInfo[i].nNumTeams = nbteams;
}
fclose(file);
}
else
g.cStaticMapInfo = 0;
#endif
}
bool VerifyUserMap(const char* szMapFile, int nTeams)
{
for (int i = 0; i < g.cStaticMapInfo; i++)
{
if (nTeams == g.vStaticMapInfo[i].nNumTeams
&& 0 == strcmp(szMapFile, g.vStaticMapInfo[i].cbIGCFile))
return true;
}
return false;
}
void UnloadStaticMapInfo()
{
delete [] g.vStaticMapInfo;
g.cStaticMapInfo = 0;
}
void AddNamedValue(char ** ppNext, const char * szName, const char * szValue)
{
lstrcpy(*ppNext, szName);
(*ppNext) += lstrlen(szName);
*((*ppNext)++) = '\t';
lstrcpy(*ppNext, szValue);
(*ppNext) += lstrlen(szValue);
*((*ppNext)++) = '\n';
}
void SetSessionDetails()
{
static char rgchBuf[10<<10]; char * pNext = rgchBuf;
static CTimer tt("setting session details", .01f);
tt.Start();
const ListFSMission * plistMission = CFSMission::GetMissions();
for (LinkFSMission * plinkMission = plistMission->first(); plinkMission; plinkMission = plinkMission->next())
{
CFSMission * pfsMission = plinkMission->data();
AddNamedValue(&pNext, "GAM", pfsMission->GetMissionDef()->misparms.strGameName);
char szPlayers[5];
_itoa(pfsMission->GetCountOfPlayers(NULL, false), szPlayers, 10);
AddNamedValue(&pNext, "PLR", szPlayers);
char szMaxPlayers[6]; _itoa(pfsMission->GetMissionDef()->misparms.nTotalMaxPlayersPerGame, szMaxPlayers, 10);
AddNamedValue(&pNext, "LIM", szMaxPlayers);
}
g.fm.SetSessionDetails(rgchBuf);
tt.Stop();
}
void UnloadDbCache()
{
#if !defined(ALLSRV_STANDALONE)
if (g.trekCore)
{
g.trekCore->Terminate();
delete g.trekCore;
g.trekCore = NULL;
}
#endif }
HRESULT pascal FedSrv_Terminate(void)
{
if (g.hReceiveThread)
{
SetEvent(g.hKillReceiveEvent);
WaitForSingleObject(g.hReceiveThread, INFINITE);
CloseHandle(g.hReceiveThread);
g.hReceiveThread = NULL;
}
if (g.hKillReceiveEvent)
{
CloseHandle(g.hKillReceiveEvent);
g.hKillReceiveEvent = NULL;
}
if (g.hPlayerEvent)
{
CloseHandle(g.hPlayerEvent);
g.hPlayerEvent = NULL;
}
SWMRGDelete(&g.swmrg);
g.fm.Shutdown();
DisconnectFromLobby();
#if !defined(ALLSRV_STANDALONE)
ShutDownSQL();
#endif timeEndPeriod(1);
if (NULL != g.pServerCounters)
{
g.perfshare.FreeCounters(g.pServerCounters);
g.pServerCounters = NULL;
}
g.perfshare.Terminate(); _AGCModule.TriggerEvent(NULL, AllsrvEventID_Terminate, "", -1, -1, -1, 0);
g.pzas = NULL;
return(S_OK);
}
void FetchGlobalAttributeSet(GlobalAttributeID gaid, GlobalAttributeSet& gas)
{
#if !defined(ALLSRV_STANDALONE)
gas.Initialize();
if (gaid)
{
GlobalAttrs_ID = gaid;
SQL_GO(GetGlobalAttrs);
SQLRETURN sqlret = SQL_GETROW(GetGlobalAttrs);
assert(SQL_SUCCEEDED(sqlret));
#define DBTOGAS(attr) (1.0f + (float) (attr) / 100.0f)
#define DBGSA(x) gas.SetAttribute(c_ga##x, DBTOGAS(GlobalAttrs_##x));
DBGSA(MaxSpeed);
DBGSA(Thrust);
DBGSA(TurnRate);
DBGSA(TurnTorque);
DBGSA(MaxArmorStation);
DBGSA(ArmorRegenerationStation);
DBGSA(MaxShieldStation);
DBGSA(ShieldRegenerationStation);
DBGSA(MaxArmorShip);
DBGSA(MaxShieldShip);
DBGSA(ShieldRegenerationShip);
DBGSA(ScanRange);
DBGSA(Signature);
DBGSA(MaxEnergy);
DBGSA(SpeedAmmo);
DBGSA(LifespanEnergy);
DBGSA(TurnRateMissile);
DBGSA(MiningRate);
DBGSA(MiningYield);
DBGSA(RipcordTime);
DBGSA(DamageGuns);
DBGSA(DamageMissiles);
DBGSA(DevelopmentCost);
DBGSA(DevelopmentTime);
DBGSA(MiningCapacity);
}
#endif }
void JoinMission(CFSPlayer * pfsPlayer, DWORD dwCookie, const char * szPW)
{
CFSMission * pfsMission;
if (NA == (int)dwCookie && CFSMission::GetMissions()->n() > 0)
pfsMission = CFSMission::GetMissions()->first()->data();
else
pfsMission = CFSMission::GetMission(dwCookie);
if (!pfsMission)
{
debugf("%s trying to join mission=%x that doesn't exist\n", pfsPlayer->GetName(), dwCookie);
BEGIN_PFM_CREATE(g.fm, pfmDelPosReq, CS, DELPOSITIONREQ)
END_PFM_CREATE
pfmDelPosReq->shipID = pfsPlayer->GetShipID();
pfmDelPosReq->iSide = NA;
pfmDelPosReq->reason = DPR_NoMission;
g.fm.SendMessages(pfsPlayer->GetConnection(), FM_GUARANTEED, FM_FLUSH);
return;
}
if (pfsMission->GetStage() == STAGE_OVER)
{
BEGIN_PFM_CREATE(g.fm, pfmDelPosReq, CS, DELPOSITIONREQ)
END_PFM_CREATE
pfmDelPosReq->shipID = pfsPlayer->GetShipID();
pfmDelPosReq->iSide = NA;
pfmDelPosReq->reason = DPR_ServerPaused;
g.fm.SendMessages(pfsPlayer->GetConnection(), FM_GUARANTEED, FM_FLUSH);
return;
}
if(pfsPlayer->PrivilegedUser()){ ImissionIGC * pMission = pfsMission->GetIGCMission();
OldPlayerLink* popi = pfsMission->GetOldPlayerLink(pfsPlayer->GetName());
const MissionParams* pmp = pMission->GetMissionParams();
SideID iSide=SIDE_TEAMLOBBY;
unsigned char bannedSideMask;
if (popi)
{
bannedSideMask = popi->data().bannedSideMask;
if ((popi->data().sideID < 0) || (bannedSideMask & SideMask(popi->data().sideID))
|| ((pfsMission->GetStage() == STAGE_STARTED) && pmp->bAllowDefections)
|| (popi->data().sideID >= pmp->nTeams))
{
iSide = SIDE_TEAMLOBBY;
}
else
{
iSide = popi->data().sideID;
}
}
pfsMission->AddPlayerToMission(pfsPlayer);
IsideIGC* psideReq = pMission->GetSide(iSide);
if (psideReq->GetObjectID() != SIDE_TEAMLOBBY)
pfsMission->RequestPosition(pfsPlayer, psideReq, popi != NULL);
return;
}
if (pfsMission->RequiresInvitation())
{
if (!pfsMission->IsInvited(pfsPlayer))
{
BEGIN_PFM_CREATE(g.fm, pfmDelPosReq, CS, DELPOSITIONREQ)
END_PFM_CREATE
pfmDelPosReq->shipID = pfsPlayer->GetShipID();
pfmDelPosReq->iSide = NA;
pfmDelPosReq->reason = DPR_PrivateGame;
g.fm.SendMessages(pfsPlayer->GetConnection(), FM_GUARANTEED, FM_FLUSH);
return;
}
}
ImissionIGC * pMission = pfsMission->GetIGCMission();
#if defined(ALLSRV_STANDALONE)
if (g.fm.GetHostApplicationGuid() == FEDSRV_STANDALONE_PRIVATE_GUID)
{
ShipLinkIGC* psl;
for (psl = pMission->GetShips()->first(); (psl != NULL); psl = psl->next())
{
CFSShip* pfsShip = (CFSShip *)(psl->data()->GetPrivateData());
if (pfsShip->IsPlayer())
{
CFSPlayer* pfsPlayerOther = pfsShip->GetPlayer();
if (_stricmp(pfsPlayer->GetName(), pfsPlayerOther->GetName()) == 0)
{
BEGIN_PFM_CREATE(g.fm, pfmDelPosReq, CS, DELPOSITIONREQ)
END_PFM_CREATE
pfmDelPosReq->shipID = pfsPlayer->GetShipID();
pfmDelPosReq->iSide = NA;
pfmDelPosReq->reason = DPR_DuplicateLogin;
g.fm.SendMessages(pfsPlayer->GetConnection(), FM_GUARANTEED, FM_FLUSH);
return;
}
}
}
}
else
#endif {
#ifdef USEAUTH
pfsMission->RemovePlayerByName(pfsPlayer->GetName(), QSR_DuplicateLocalLogon);
#endif
}
const MissionParams* pmp = pMission->GetMissionParams();
if (pmp->nTotalMaxPlayersPerGame != 0x7fff
&& pfsMission->GetCountOfPlayers(NULL, true) >= pmp->nTotalMaxPlayersPerGame)
{
BEGIN_PFM_CREATE(g.fm, pfmDelPosReq, CS, DELPOSITIONREQ)
END_PFM_CREATE
pfmDelPosReq->shipID = pfsPlayer->GetShipID();
pfmDelPosReq->iSide = NA;
pfmDelPosReq->reason = DPR_GameFull;
g.fm.SendMessages(pfsPlayer->GetConnection(), FM_GUARANTEED, FM_FLUSH);
return;
}
const char* szPassword = pmp->strGamePassword;
if (szPassword[0] != '\0'
&& Strcmp(szPassword, szPW) != 0)
{
BEGIN_PFM_CREATE(g.fm, pfmDelPosReq, CS, DELPOSITIONREQ)
END_PFM_CREATE
pfmDelPosReq->shipID = pfsPlayer->GetShipID();
pfmDelPosReq->iSide = NA;
pfmDelPosReq->reason = DPR_BadPassword;
g.fm.SendMessages(pfsPlayer->GetConnection(), FM_GUARANTEED, FM_FLUSH);
return;
}
if (!pfsPlayer->CanCheat() && !pfsPlayer->PrivilegedUser())
{
RankID rank = pfsPlayer->GetPersistPlayerScore(NA)->GetRank();
if (pfsMission->GetMissionDef()->misparms.iMinRank > rank
|| pfsMission->GetMissionDef()->misparms.iMaxRank < rank)
{
BEGIN_PFM_CREATE(g.fm, pfmDelPosReq, CS, DELPOSITIONREQ)
END_PFM_CREATE
pfmDelPosReq->shipID = pfsPlayer->GetShipID();
pfmDelPosReq->iSide = NA;
pfmDelPosReq->reason = DPR_InvalidRank;
g.fm.SendMessages(pfsPlayer->GetConnection(), FM_GUARANTEED, FM_FLUSH);
return;
}
}
OldPlayerLink* popi = pfsMission->GetOldPlayerLink(pfsPlayer->GetName());
SideID iSide;
unsigned char bannedSideMask;
if (popi)
{
if (popi->data().pso.GetDeaths() > pmp->iLives)
{
BEGIN_PFM_CREATE(g.fm, pfmDelPosReq, CS, DELPOSITIONREQ)
END_PFM_CREATE
pfmDelPosReq->shipID = pfsPlayer->GetShipID();
pfmDelPosReq->iSide = NA;
pfmDelPosReq->reason = DPR_OutOfLives;
g.fm.SendMessages(pfsPlayer->GetConnection(), FM_GUARANTEED, FM_FLUSH);
return;
}
bannedSideMask = popi->data().bannedSideMask;
unsigned char legalSideMask = SideMask(pMission->GetSides()->n()) - 1;
if ((bannedSideMask & legalSideMask) == legalSideMask)
{
BEGIN_PFM_CREATE(g.fm, pfmDelPosReq, CS, DELPOSITIONREQ)
END_PFM_CREATE
pfmDelPosReq->shipID = pfsPlayer->GetShipID();
pfmDelPosReq->iSide = NA;
pfmDelPosReq->reason = DPR_Banned;
g.fm.SendMessages(pfsPlayer->GetConnection(), FM_GUARANTEED, FM_FLUSH);
return;
}
if ((popi->data().sideID < 0) || (bannedSideMask & SideMask(popi->data().sideID))
|| ((pfsMission->GetStage() == STAGE_STARTED) && pmp->bAllowDefections)
|| (popi->data().sideID >= pmp->nTeams))
{
iSide = SIDE_TEAMLOBBY;
}
else
{
iSide = popi->data().sideID;
}
}
else
{
if (((!pmp->bAllowJoiners) && (pfsMission->GetStage() != STAGE_NOTSTARTED))
|| pmp->bLockLobby)
{
BEGIN_PFM_CREATE(g.fm, pfmDelPosReq, CS, DELPOSITIONREQ)
END_PFM_CREATE
pfmDelPosReq->shipID = pfsPlayer->GetShipID();
pfmDelPosReq->iSide = NA;
pfmDelPosReq->reason = pmp->bLockLobby ? DPR_LobbyLocked : DPR_NoJoiners;
g.fm.SendMessages(pfsPlayer->GetConnection(), FM_GUARANTEED, FM_FLUSH);
return;
}
bannedSideMask = 0;
if (pfsMission->GetStage() == STAGE_NOTSTARTED)
iSide = NA; else
iSide = SIDE_TEAMLOBBY;
}
if ((iSide == NA) || ((iSide == SIDE_TEAMLOBBY) && pmp->bLockSides))
{
iSide = SIDE_TEAMLOBBY; assert (iSide != NA);
}
pfsMission->AddPlayerToMission(pfsPlayer);
IsideIGC* psideReq = pMission->GetSide(iSide);
if (!psideReq)
{
assert(false);
psideReq = pMission->GetSide(SIDE_TEAMLOBBY);
}
if (psideReq->GetObjectID() != SIDE_TEAMLOBBY)
pfsMission->RequestPosition(pfsPlayer, psideReq, popi != NULL);
}
void GotInvitationList(CQGetInvitationList * pquery)
{
CQGetInvitationListData * pqd = pquery->GetData();
CFSMission * pfsMission = CFSMission::GetMissionFromIGCMissionID(pqd->missionID);
int cRows = 0;
if (pfsMission) {
CQGetInvitationListData * pRows = pquery->GetOutputRows(&cRows); while (cRows--)
{
pfsMission->AddInvitation(SideID(pRows->iTeam), pRows->szSubject);
}
}
}
void GotCharSquads(CQCharSquads * pquery)
{
CQCharSquadsData * pqd = pquery->GetData();
CFMConnection * pcnxn = g.fm.GetConnectionFromId(pqd->dwConnectionID);
if (!pcnxn)
return; CFSPlayer * pfsPlayer = CFSPlayer::GetPlayerFromConnection(*pcnxn);
if (!pfsPlayer)
return; int cRows;
CQCharSquadsData * pRows = pquery->GetOutputRows(&cRows); while (cRows--)
{
pfsPlayer->GetSquadMembershipList()->last(
new SquadMembership(
pRows->squadID,
(const char*)pRows->szSquadName,
0 == pRows->status,
1 == pRows->status && 1 == pRows->detailedStatus
));
pRows++;
}
int nNumSquads = pfsPlayer->GetSquadMembershipList()->n();
SquadMembership* vsquadmembership =
(SquadMembership*)_alloca(sizeof(SquadMembership) * nNumSquads + 1);
SquadMembershipLink* pSquadLink = pfsPlayer->GetSquadMembershipList()->first();
for (int iSquad = 0; iSquad < nNumSquads; ++iSquad, pSquadLink = pSquadLink->next())
{
vsquadmembership[iSquad] = *(pSquadLink->data());
}
BEGIN_PFM_CREATE(g.fm, pfmSquadMemberships, LS, SQUAD_MEMBERSHIPS)
FM_VAR_PARM(nNumSquads ? vsquadmembership : NULL, sizeof(SquadMembership) * nNumSquads)
END_PFM_CREATE
pfmSquadMemberships->cSquadMemberships = nNumSquads;
g.fm.SendMessages(pcnxn, FM_GUARANTEED, FM_FLUSH);
if (pqd->fJoin) JoinMission(pfsPlayer, pqd->dwCookie, pqd->szPassword);
}
void GotLogonDetails(CQLogonStats * pquery)
{
CQLogonStatsData * pqd = pquery->GetData();
CFMConnection * pcnxn = g.fm.GetConnectionFromId(pqd->dwConnectionID);
bool fJoinNow = true; if (!pcnxn)
return; CFSPlayer * pfsPlayer = CFSPlayer::GetPlayerFromConnection(*pcnxn);
bool fValid = pqd->fValid;
bool fRetry = pqd->fRetry;
g.cMsgsToOthers =
g.cBytesToOthers = 0;
float flDTime;
int cMsgsOdometer;
int cBytesOdometer;
g.fm.CheckOdometer(flDTime, cMsgsOdometer, cBytesOdometer);
if (fValid) {
lstrcpy(pqd->szReason, pqd->szCharacterName);
if (NULL != g.pServerCounters)
{
g.pServerCounters->cLogins++;
g.pServerCounters->cPlayersOnline++;
}
DataShipIGC dataship;
ZeroMemory(&dataship, sizeof(dataship));
dataship.shipID = NA;
dataship.sideID = NA;
dataship.hullID = NA;
dataship.pilotType = pqd->fCanCheat ? c_ptCheatPlayer : c_ptPlayer;
dataship.abmOrders = 0;
dataship.baseObjectID = NA;
lstrcpy(dataship.name, pqd->szReason);
TRef<IshipIGC> pship = (IshipIGC *) g.trekCore->CreateObject(g.timeNow,
OT_ship, &dataship, sizeof(dataship));
pfsPlayer = new CFSPlayer(pcnxn, pqd->characterID, pqd->szCDKey, pship, !! pqd->fCanCheat);
assert(pfsPlayer);
#if !defined(ALLSRV_STANDALONE)
PlayerScoreObject * plrsc = pfsPlayer->GetPlayerScoreObject();
int cRows;
CQLogonStatsData * pRows = pquery->GetOutputRows(&cRows); while (cRows--)
{
PersistPlayerScoreObject * ppso = new PersistPlayerScoreObject(
pRows->score,
RATING_EXT2INT(pRows->rating),
pRows->rank,
pRows->civID);
pfsPlayer->GetPersistPlayerScoreObjectList()->last(ppso);
pRows++;
}
#endif
DWORD dw; HKEY hk;
DWORD dwASGS_RANKS_ON=0;
if (RegCreateKeyEx(HKEY_LOCAL_MACHINE, HKLM_FedSrv, 0, "", REG_OPTION_NON_VOLATILE, KEY_READ | KEY_WRITE, NULL, &hk, &dw) == ERROR_SUCCESS)
{
bool bSuccess = ReadFromRegistry(hk, false, "ASGS_RANKS_ON", &dwASGS_RANKS_ON, 0);
RegCloseKey(hk);
}
if (dwASGS_RANKS_ON) {
char szRank[64];
char newName[64];
int leftParen; int strLen;
ZString strName = pfsPlayer->GetName();
strLen = strName.GetLength();
leftParen = strName.ReverseFind('(',0);
if (leftParen>=1) {
Strncpy(szRank,(PCC)strName+leftParen+1,(strLen-leftParen)-1);
RankID myRank = atoi(szRank);
if (!((myRank>0) && (myRank<100))) {
debugf("Rank out of range rank=%d\n",myRank);
myRank=0; }
const CivilizationListIGC * pctlist = g.trekCore->GetCivilizations();
PersistPlayerScoreObject * ppso = new PersistPlayerScoreObject(0.0f,0.0f,myRank,NA); pfsPlayer->GetPersistPlayerScoreObjectList()->last(ppso);
for (CivilizationLinkIGC * pcl = pctlist->first(); (pcl != NULL); pcl = pcl->next())
{
PersistPlayerScoreObject * ppso = new PersistPlayerScoreObject(0.0f,0.0f,myRank,pcl->data()->GetObjectID());
pfsPlayer->GetPersistPlayerScoreObjectList()->last(ppso);
}
if (myRank>4) {
Strncpy(newName,(PCC)strName,leftParen);
Strncpy(newName+leftParen,"\0",1); pship->SetName(newName);
}
fValid = true;
} else {
fValid = true; debugf("No rank found in callsign %s\n",(PCC)strName);
}
#if 0 MaClient *http_client; int contentLen;
char *szContent;
char szURL[255]; char szName[64]; char szResponse[255];
ZString strName = pfsPlayer->GetName();
Strcpy(szURL,"http://asgs.alleg.net/asgs/services.asmx/GetPlayerRank?Callsign=");
Strcpy(szName,(PCC)strName);
if ((isalnum(szName[0]) == 0) && (strName.Left(1) != "_")) strcpy(szName,strName.RightOf(1));
strcat(szURL,szName);
Mpr mpr("AllSrv");
mpr.start(MPR_SERVICE_THREAD);
http_client = new MaClient();
http_client->getRequest(szURL);
if (szContent = http_client->getResponseContent(&contentLen)) {
ZString strContent = szContent;
strContent = strContent.RightOf(88);
strContent = strContent.LeftOf("<");
debugf("sent asgs %s and asgs sent %s\n",szURL, (PCC)strContent);
Strcpy(szResponse,(PCC)strContent);
mpr.stop(0);
delete http_client;
if (strcmp(strtok(szResponse,"|"),"0") != 0 ) {
strtok(NULL,"|");
Strcpy(pqd->szReason,strtok(NULL,"|"));
fValid = false;
debugf("Lobby possibly validated ASGS user but Server did not!\n");
} else { RankID myRank = atoi(strtok(NULL,"|"));
const CivilizationListIGC * pctlist = g.trekCore->GetCivilizations();
PersistPlayerScoreObject * ppso = new PersistPlayerScoreObject(0.0f,0.0f,myRank,NA); pfsPlayer->GetPersistPlayerScoreObjectList()->last(ppso);
for (CivilizationLinkIGC * pcl = pctlist->first(); (pcl != NULL); pcl = pcl->next())
{
PersistPlayerScoreObject * ppso = new PersistPlayerScoreObject(0.0f,0.0f,myRank,pcl->data()->GetObjectID());
pfsPlayer->GetPersistPlayerScoreObjectList()->last(ppso);
}
fValid = true;
}
} else {
fValid = true; debugf("ASGS Server did not respond!\n");
}
#endif } else {
fValid = true; debugf("Not using ASGS (ASGS_RANKS_ON regkey not set), rank query not done\n");
}
}
else
{
if (NULL != g.pServerCounters)
g.pServerCounters->cLoginsFailed++;
}
BEGIN_PFM_CREATE(g.fm, pfmLogonAck, S, LOGONACK)
FM_VAR_PARM(pqd->szReason, CB_ZTS)
END_PFM_CREATE
pfmLogonAck->shipID = fValid ? pfsPlayer->GetShipID() : 0;
pfmLogonAck->fValidated = fValid;
pfmLogonAck->fRetry = fRetry;
pfmLogonAck->cookie = fValid ? pfsPlayer->GetCookie() : 0;
pfmLogonAck->timeServer = g.timeNow;
if (fValid)
{
BEGIN_PFM_CREATE(g.fm, pfmStaticMapInfo, S, STATIC_MAP_INFO)
FM_VAR_PARM(g.vStaticMapInfo, sizeof(StaticMapInfo) * g.cStaticMapInfo)
END_PFM_CREATE
BEGIN_PFM_CREATE(g.fm, pfmRankInfo, S, RANK_INFO)
FM_VAR_PARM(g.vRankInfo, sizeof(RankInfo) * g.cRankInfo)
END_PFM_CREATE
pfmRankInfo->cRanks = g.cRankInfo;
#if !defined(ALLSRV_STANDALONE)
CQCharSquads * pqueryCharSquads = new CQCharSquads(GotCharSquads);
CQCharSquadsData * pqdSquads = pqueryCharSquads->GetData();
pqdSquads->characterID = pqd->characterID;
pqdSquads->dwConnectionID = pqd->dwConnectionID;
CFSMission * pfsMission = CFSMission::GetMission(pqd->dwCookie);
if (pfsMission) {
pqdSquads->fJoin = pfsMission->IsSquadGame();
fJoinNow = !pqdSquads->fJoin; pqdSquads->dwCookie = pqd->dwCookie;
lstrcpy(pqdSquads->szPassword, pqd->szPassword);
g.sql.PostQuery(pqueryCharSquads);
}
#endif
}
g.fm.SendMessages(pcnxn, FM_GUARANTEED, FM_FLUSH);
g.fm.CheckOdometer(flDTime, cMsgsOdometer, cBytesOdometer);
debugf("Player %s logon %s. Sent %d msgs and %dB to them in %1.3fs, "
"and %d msgs and %dB to others in the process.\n",
pqd->szCharacterName, fValid ? "succeeded" : "failed",
cMsgsOdometer, cBytesOdometer, flDTime, g.cMsgsToOthers, g.cBytesToOthers);
if (fValid && fJoinNow)
JoinMission(pfsPlayer, pqd->dwCookie, pqd->szPassword);
}
void SetCharStats(int characterID,
CFSPlayer* pfsPlayer,
IsideIGC * pSide,
PlayerScoreObject& pso,
CFSMission* pfsMission)
{
#if !defined(ALLSRV_STANDALONE) if (0.0f == pso.GetTimePlayed())
{
return;
}
assert(pso.GetScore() >= 0.0f);
assert (pSide);
CivID civID = pSide->GetCivilization()->GetObjectID();
PersistPlayerScoreObject& ppso = pso.GetPersist();
RankID newRank = ppso.GetRank();
if (pfsMission->GetScoresCount())
{
float score = ppso.GetScore() + pso.GetScore();
int iScore = int(score);
for (int i = g.cRankInfo - 1; (i >= 0); i--)
{
RankInfo& ri = g.vRankInfo[i];
if ((ri.civ == civID) && (ri.requiredRanking < iScore))
{
newRank = ri.rank;
break;
}
}
ppso.Set(score,
pso.GetCombatRating(),
newRank);
if (pfsPlayer)
{
pfsPlayer->GetPersistPlayerScore(civID)->Set(score, pso.GetCombatRating(), newRank);
PersistPlayerScoreObject* ppsoNA = pfsPlayer->GetPersistPlayerScore(NA);
float s = ppsoNA->GetScore() + pso.GetScore();
int is = int(s);
for (int i = g.cRankInfo - 1; (i >= 0); i--)
{
RankInfo& ri = g.vRankInfo[i];
if ((ri.civ == NA) && (ri.requiredRanking < is))
{
ppsoNA->Set(s, 0.0f, ri.rank);
break;
}
}
}
}
CQCharStats * pquery = new CQCharStats(NULL); CQCharStatsData * pdq = pquery->GetData();
pdq->CharacterID = characterID;
pdq->CivID = civID;
pdq->Rating = RATING_INT2EXT(pso.GetCombatRating());
pdq->WarpsSpotted = pso.GetWarpsSpotted();
pdq->AsteroidsSpotted = pso.GetAsteroidsSpotted();
pdq->TechsRecovered = pso.GetTechsRecovered();
pdq->MinerKills = pso.GetMinerKills();
pdq->BuilderKills = pso.GetBuilderKills();
pdq->LayerKills = pso.GetLayerKills();
pdq->PlayerKills = pso.GetPlayerKills();
pdq->BaseKills = pso.GetBaseKills();
pdq->BaseCaptures = pso.GetBaseCaptures();
pdq->Deaths = pso.GetDeaths();
pdq->PilotBaseKills = pso.GetPilotBaseKills();
pdq->PilotBaseCaptures = pso.GetPilotBaseCaptures();
pdq->Minutes = pso.GetTimePlayed() / 60.0f;
pdq->bWin = pso.GetWinner();
pdq->bLose = pso.GetLoser();
pdq->bWinCmd = pso.GetCommandWinner();
pdq->bLoseCmd = pso.GetCommandLoser();
pdq->Score = pso.GetScore();
pdq->bScoresCount = pfsMission->GetScoresCount();
pdq->RankOld = newRank;
debugf("SetCharStats: bScoresCount=%d, CharacterID=%d, CivID=%d, Rating=%d,\n",
pdq->bScoresCount,pdq->CharacterID, pdq->CivID, pdq->Rating);
debugf(" WarpsSpotted=%.2f, AsteroidsSpotted=%.2f, TechsRecovered=%.2f,\n",
pdq->WarpsSpotted, pdq->AsteroidsSpotted, pdq->TechsRecovered);
debugf(" MinerKills=%.2f, BuilderKills=%.2f, LayerKills=%.2f, PlayerKills=%.2f,\n",
pdq->MinerKills, pdq->BuilderKills, pdq->LayerKills, pdq->PlayerKills);
debugf(" BaseKills=%.2f, BaseCaptures=%.2f, Deaths=%d, PilotBaseKills=%d, BaseCaptures=%d,\n",
pdq->BaseKills, pdq->BaseCaptures, pdq->Deaths, pdq->PilotBaseKills, pdq->PilotBaseCaptures);
debugf(" Minutes=%d, bWin=%d, bLose=%d, bWinCmd=%d, bLoseCmd=%d, RankOld=%d, Score=%.2f.\n",
pdq->Minutes, pdq->bWin, pdq->bLose, pdq->bWinCmd, pdq->bLoseCmd, pdq->RankOld, pdq->Score);
g.sql.PostQuery(pquery);
#endif #ifdef DEBUG
if (0.0f == pso.GetTimePlayed())
{ return; }
assert(pso.GetScore() >= 0.0f);
assert(pSide);
PersistPlayerScoreObject& ppso = pso.GetPersist();
RankID Rank = ppso.GetRank();
if (pfsPlayer != NULL) debugf("PlayerName =%s, ",pfsPlayer->GetName());
debugf("CharacterID=%d, Rank=%d, bScoresCount=%d, CivID=%d, Rating=%d,\n",
characterID, Rank ,pfsMission->GetScoresCount(), pSide->GetCivilization()->GetObjectID(),
RATING_INT2EXT(pso.GetCombatRating()));
debugf(" WarpsSpotted=%.2f, AsteroidsSpotted=%.2f, TechsRecovered=%.2f,\n",
pso.GetWarpsSpotted(), pso.GetAsteroidsSpotted(), pso.GetTechsRecovered());
debugf(" MinerKills=%.2f, BuilderKills=%.2f, LayerKills=%.2f, PlayerKills=%.2f,\n",
pso.GetMinerKills(), pso.GetBuilderKills(), pso.GetLayerKills(), pso.GetPlayerKills());
debugf(" BaseKills=%.2f, BaseCaptures=%.2f, Deaths=%d, PilotBaseKills=%d, BaseCaptures=%d,\n",
pso.GetBaseKills(), pso.GetBaseCaptures(), pso.GetDeaths(), pso.GetPilotBaseKills(), pso.GetPilotBaseCaptures());
debugf(" Minutes=%.2f, bWin=%d, bLose=%d, bWinCmd=%d, bLoseCmd=%d, Score=%.2f.\n",
(pso.GetTimePlayed() / 60.0f), pso.GetWinner(), pso.GetLoser(), pso.GetCommandWinner(), pso.GetCommandLoser(),
pso.GetScore());
#endif
}
void RecordSquadGame(const SideListIGC* psides, IsideIGC* psideWon)
{
#if !defined(ALLSRV_STANDALONE)
CQReportSquadGame * pquery = new CQReportSquadGame(NULL);
CQReportSquadGameData * pqd = pquery->GetData();
pqd->squadIDWon = psideWon->GetSquadID();
SideLinkIGC* linkSide = psides->first();
{
while (linkSide
&& (linkSide->data() == psideWon || linkSide->data()->GetSquadID() == NA))
{
linkSide = linkSide->next();
}
if (linkSide)
{
pqd->squadIDLost1 = linkSide->data()->GetSquadID();
linkSide = linkSide->next();
}
else
pqd->squadIDLost1 = NA;
}
{
while (linkSide
&& (linkSide->data() == psideWon || linkSide->data()->GetSquadID() == NA))
{
linkSide = linkSide->next();
}
if (linkSide)
{
pqd->squadIDLost2 = linkSide->data()->GetSquadID();
linkSide = linkSide->next();
}
else
pqd->squadIDLost2 = NA;
}
{
while (linkSide
&& (linkSide->data() == psideWon || linkSide->data()->GetSquadID() == NA))
{
linkSide = linkSide->next();
}
if (linkSide)
{
pqd->squadIDLost3 = linkSide->data()->GetSquadID();
linkSide = linkSide->next();
}
else
pqd->squadIDLost3 = NA;
}
{
while (linkSide
&& (linkSide->data() == psideWon || linkSide->data()->GetSquadID() == NA))
{
linkSide = linkSide->next();
}
if (linkSide)
{
pqd->squadIDLost4 = linkSide->data()->GetSquadID();
linkSide = linkSide->next();
}
else
pqd->squadIDLost4 = NA;
}
{
while (linkSide
&& (linkSide->data() == psideWon || linkSide->data()->GetSquadID() == NA))
{
linkSide = linkSide->next();
}
if (linkSide)
{
pqd->squadIDLost5 = linkSide->data()->GetSquadID();
linkSide = linkSide->next();
}
else
pqd->squadIDLost5 = NA;
}
assert(linkSide == NULL || linkSide->data() == psideWon && linkSide->next() == NULL);
g.sql.PostQuery(pquery);
#endif }
void GetInvitations(int nInvitationID, MissionID missionID)
{
#if !defined(ALLSRV_STANDALONE)
CQGetInvitationList * pquery = new CQGetInvitationList(GotInvitationList);
CQGetInvitationListData * pdq = pquery->GetData();
pdq->listid = nInvitationID;
pdq->missionID = missionID;
g.sql.PostQuery(pquery);
#endif
}
void LoadDbCache()
{
#if !defined(ALLSRV_STANDALONE)
SQLRETURN sqlret = 0;
int i = 0;
int nCount;
g.trekCore = CreateMission(); g.trekCore->Initialize(Time::Now(), &g.siteFedSrv);
g.trekCore->SetStaticCore(NULL);
#pragma warning(disable : 4244)
LoadTechBits();
SQL_GO(ShipsCount);
SQL_GETROW(ShipsCount);
ShipID* vnShipIdList = (ShipID*)_alloca(g_cShipTypes * sizeof(ShipID));
nCount = 0;
SQL_GO(ShipTypeIDs);
while (SQL_SUCCEEDED(sqlret = SQL_GETROW(ShipTypeIDs)))
{
vnShipIdList[nCount] = ShipTypeIDs_ShipTypeID;
++nCount;
assert(nCount <= g_cShipTypes);
}
SQL_GO(Projectiles);
while (SQL_SUCCEEDED(SQL_GETROW(Projectiles)))
{
DataProjectileTypeIGC dpt;
dpt.projectileTypeID = Projectiles_ProjectileID;
dpt.power = Projectiles_HitPointsInflict;
dpt.blastPower = Projectiles_BlastPower;
dpt.blastRadius = Projectiles_BlastRadius;
dpt.speed = Projectiles_SpeedMax;
dpt.absoluteF = false != Projectiles_IsAbsoluteSpeed;
dpt.modelName[0] = '\0';
SQLSTRCPY(dpt.textureName, Projectiles_FileTexture);
SQLSTRCPY(dpt.modelName, Projectiles_FileModel);
dpt.lifespan = Projectiles_TimeDuration / 1000.0f;
dpt.radius = Projectiles_Size_cm / 100.0f; dpt.rotation = Projectiles_RateRotation * pi / 180.0f;
dpt.color.r = Projectiles_Red / 100.0f;
dpt.color.g = Projectiles_Green / 100.0f;
dpt.color.b = Projectiles_Blue / 100.0f;
dpt.color.a = Projectiles_Alpha / 100.0f;
dpt.damageType = Projectiles_DamageType;
;
dpt.bDirectional = !!Projectiles_IsDirectional;
dpt.width = Projectiles_WidthOverHeight;
dpt.ambientSound = Projectiles_AmbientSound;
IprojectileTypeIGC * pprojtype = (IprojectileTypeIGC *)
g.trekCore->CreateObject(g.timeNow, OT_projectileType, &dpt, sizeof(dpt));
pprojtype->Release();
}
SQL_GO(Weapons);
while (SQL_SUCCEEDED(SQL_GETROW(Weapons)))
{
DataWeaponTypeIGC dwt;
CopyMemory(dwt.modelName, Weapons_FileModel, sizeof(Weapons_FileModel));
SET_PARTS(dwt, Weapons)
dwt.dtimeReady = (float) Weapons_dTimeReady / 1000.0f;
dwt.dtimeBurst = Weapons_dTimeBurstShots / 1000.0f;
dwt.energyPerShot = Weapons_EnergyPerShot;
dwt.dispersion = Weapons_Dispersion;
dwt.projectileTypeID = Weapons_ProjectileID1;
dwt.cAmmoPerShot = Weapons_cBulletsPerShot;
dwt.activateSound = Weapons_ActivateSound;
dwt.singleShotSound = Weapons_SingleShotSound;
dwt.burstSound = Weapons_BurstShotSound;
IweaponIGC * pweapon = (IweaponIGC *) g.trekCore->CreateObject(
g.timeNow, OT_partType, &dwt, sizeof(dwt));
pweapon->Release();
}
SQL_GO(Missiles);
while (SQL_SUCCEEDED(SQL_GETROW(Missiles)))
{
DataMissileTypeIGC missile;
SET_EXPEND(missile, Missiles)
missile.maxLock = Missiles_MaxLock;
missile.chaffResistance = Missiles_Resistance;
missile.acceleration = Missiles_Acceleration;
missile.turnRate = RadiansFromDegrees(Missiles_TurnRate);
missile.initialSpeed = Missiles_InitialSpeed;
missile.lockTime = Missiles_LockTime;
missile.readyTime = Missiles_ReadyTime;
missile.dispersion = Missiles_Dispersion;
missile.lockAngle = RadiansFromDegrees(Missiles_LockAngle);
missile.power = Missiles_Power;
missile.damageType = Missiles_DamageType;
missile.blastPower = Missiles_BlastPower;
missile.blastRadius = Missiles_BlastRadius;
missile.bDirectional = !!Missiles_IsDirectional;
missile.width = Missiles_WidthOverHeight;
missile.launchSound = Missiles_LaunchSound;
missile.ambientSound = Missiles_FlightSound;
ImissileIGC * pmissile = (ImissileIGC *) g.trekCore->CreateObject(g.timeNow, OT_missileType,
&missile, sizeof(missile));
pmissile->Release();
}
SQL_GO(Chaff);
while (SQL_SUCCEEDED(SQL_GETROW(Chaff)))
{
DataChaffTypeIGC chaff;
SET_EXPEND(chaff, Chaff)
chaff.chaffStrength = Chaff_Strength;
IObject* u = g.trekCore->CreateObject(g.timeNow, OT_chaffType,
&chaff, sizeof(chaff));
u->Release();
}
SQL_GO(Shields);
while (SQL_SUCCEEDED(SQL_GETROW(Shields)))
{
DataShieldTypeIGC dst;
SET_PARTS(dst, Shields)
dst.rateRegen = Shields_RegenRate;
dst.maxStrength = Shields_MaxHitPoints;
dst.defenseType = Shields_DefenseType;
dst.activateSound = Shields_ActivateSound;
dst.deactivateSound = Shields_DeactivateSound;
IpartTypeIGC * pparttype = (IpartTypeIGC *) g.trekCore->CreateObject(
g.timeNow, OT_partType, &dst, sizeof(dst));
pparttype->Release();
}
SQL_GO(Cloaks);
while (SQL_SUCCEEDED(SQL_GETROW(Cloaks)))
{
DataCloakTypeIGC dct;
SET_PARTS(dct, Cloaks)
dct.energyConsumption = Cloaks_EnergyConsumption;
dct.maxCloaking = Cloaks_MaxCloaking;
dct.onRate = Cloaks_OnRate;
dct.offRate = Cloaks_OffRate;
dct.engageSound = Cloaks_EngageSound;
dct.disengageSound = Cloaks_DisengageSound;
IpartTypeIGC * pparttype = (IpartTypeIGC *) g.trekCore->CreateObject(
g.timeNow, OT_partType, &dct, sizeof(dct));
pparttype->Release();
}
SQL_GO(Afterburners);
while (SQL_SUCCEEDED(SQL_GETROW(Afterburners)))
{
DataAfterburnerTypeIGC dab;
SET_PARTS(dab, Afterburners)
dab.fuelConsumption = Afterburners_RateBurn;
dab.maxThrust = Afterburners_ThrustMax;
dab.onRate = Afterburners_RateOn;
dab.offRate = Afterburners_RateOff;
dab.interiorSound = Afterburners_InteriorSound;
dab.exteriorSound = Afterburners_ExteriorSound;
IpartTypeIGC * pparttype = (IpartTypeIGC *) g.trekCore->CreateObject(
g.timeNow, OT_partType, &dab, sizeof(dab));
pparttype->Release();
}
SQL_GO(Ammo);
while (SQL_SUCCEEDED(SQL_GETROW(Ammo)))
{
DataPackTypeIGC dpt;
SET_PARTS(dpt, Ammo)
dpt.amount = Ammo_Qty;
dpt.packType = Ammo_AmmoType;
IpartTypeIGC * pparttype = (IpartTypeIGC *) g.trekCore->CreateObject(
g.timeNow, OT_partType, &dpt, sizeof(dpt));
pparttype->Release();
}
SQL_GO(Mines);
while (SQL_SUCCEEDED(SQL_GETROW(Mines)))
{
DataMineTypeIGC dmt;
SET_EXPEND(dmt, Mines)
dmt.endurance = float(Mines_MunitionCount) * Mines_Power;
dmt.power = Mines_Power;
dmt.radius = Mines_PlacementRadius;
dmt.damageType = Mines_DamageType;
IObject* u = g.trekCore->CreateObject(g.timeNow, OT_mineType,
&dmt, sizeof(dmt));
u->Release();
}
SQL_GO(Probes);
while (SQL_SUCCEEDED(SQL_GETROW(Probes)))
{
DataProbeTypeIGC dpt;
SET_EXPEND(dpt, Probes)
dpt.scannerRange = Probes_ScanRange;
dpt.projectileTypeID = Probes_ProjectileTypeID;
dpt.accuracy = float(Probes_accuracy) / 100.0f;
dpt.dtimeBurst = float(Probes_dtimeBurst) / 1000.0f;
dpt.dispersion = Probes_dispersion;
dpt.ammo = Probes_ammo;
dpt.ambientSound = Probes_AmbientSound;
dpt.dtRipcord = (Probes_dtRipcord != 255)? float(Probes_dtRipcord) : -1.0f;
IObject* u = g.trekCore->CreateObject(g.timeNow, OT_probeType,
&dpt, sizeof(dpt));
u->Release();
}
SQL_GO(Magazines);
while (SQL_SUCCEEDED(SQL_GETROW(Magazines)))
{
DataLauncherTypeIGC magazine;
magazine.partID = Magazine_PartID;
magazine.expendabletypeID = Magazine_ExpendableID;
magazine.amount = Magazine_Amount;
magazine.launchCount = Magazine_LaunchCount;
magazine.successorPartID = Magazine_SuccessorID;
SQLSTRCPY(magazine.inventoryLineMDL, Magazine_InventoryLineMDL);
IpartTypeIGC * pparttype = (IpartTypeIGC *) g.trekCore->CreateObject(
g.timeNow, OT_partType, &magazine, sizeof(magazine));
pparttype->Release();
}
for (i = 0; i < nCount; i++)
{
ShipTypes_ShipTypeID = vnShipIdList[i];
SQL_GO(ShipTypes);
if (SQL_SUCCEEDED(sqlret = SQL_GETROW(ShipTypes)))
{
AttachPointsCount_ShipTypeID = ShipTypes_ShipTypeID;
SQL_GO(AttachPointsCount);
SQL_GETROW(AttachPointsCount);
CB cbHull = sizeof(DataHullTypeIGC) + g_cAttachPoints * sizeof(HardpointData);
DataHullTypeIGC * pdht = (DataHullTypeIGC *) GlobalAllocPtr(GMEM_MOVEABLE | GMEM_ZEROINIT, cbHull);
SQLSTRCPY(pdht->modelName, ShipTypes_ShipModelName);
SQLSTRCPY(pdht->iconName, ShipTypes_ShipIconName);
SQLSTRCPY(pdht->name, ShipTypes_Name);
SQLSTRCPY(pdht->description, ShipTypes_Description);
#define defaultPart(x) pdht->preferredPartsTypes[x-1] = ShipTypes_PreferredPart##x > 0 ? ShipTypes_PreferredPart##x : NA;
defaultPart(1)
defaultPart(2)
defaultPart(3)
defaultPart(4)
defaultPart(5)
defaultPart(6)
defaultPart(7)
defaultPart(8)
defaultPart(9)
defaultPart(10)
defaultPart(11)
defaultPart(12)
defaultPart(13)
defaultPart(14)
#undef defaultPart
pdht->hardpointOffset = sizeof(DataHullTypeIGC);
pdht->price = ShipTypes_Price;
pdht->mass = ShipTypes_flWeight;
pdht->hullID = ShipTypes_ShipTypeID;
pdht->length = ShipTypes_flLength;
pdht->speed = ShipTypes_SpeedMax;
pdht->maxTurnRates[c_axisYaw] = ShipTypes_flRateYaw * pi / 180.0f;
pdht->maxTurnRates[c_axisPitch] = ShipTypes_flRatePitch * pi / 180.0f;
pdht->maxTurnRates[c_axisRoll] = ShipTypes_flRateRoll * pi / 180.0f;
float fYaw = ShipTypes_flRateYaw * ShipTypes_flRateYaw / (2.0f * ShipTypes_flDriftYaw);
float fPitch = ShipTypes_flRatePitch * ShipTypes_flRatePitch / (2.0f * ShipTypes_flDriftPitch);
float fRoll = ShipTypes_flRateRoll * ShipTypes_flRateRoll / (2.0f * ShipTypes_flDriftPitch);
pdht->turnTorques[c_axisYaw] = pdht->mass * fYaw * pi / 180.0f;
pdht->turnTorques[c_axisPitch] = pdht->mass * fPitch * pi / 180.0f;
pdht->turnTorques[c_axisRoll] = pdht->mass * fRoll * pi / 180.0f;
pdht->thrust = pdht->mass * ShipTypes_flAcceleration;
pdht->sideMultiplier = ShipTypes_flAccelSideMult;
pdht->backMultiplier = ShipTypes_flAccelBackMult;
pdht->signature = (float)ShipTypes_BaseSignature / 100.0f;
pdht->scannerRange = ShipTypes_RangeScanner;
pdht->hitPoints = ShipTypes_HitPoints;
pdht->defenseType = ShipTypes_DefenseType;
pdht->maxEnergy = ShipTypes_EnergyMax;
pdht->habmCapabilities = ShipTypes_Capabilities;
pdht->rechargeRate = ShipTypes_RateRechargeEnergy;
pdht->ecm = ShipTypes_ecm;
pdht->ripcordSpeed = ShipTypes_ripcordSpeed * g.trekCore->GetFloatConstant(c_fcidRipcordTime);
pdht->ripcordCost = ShipTypes_ripcordCost;
pdht->maxFuel = float(ShipTypes_MaxFuel);
pdht->maxAmmo = ShipTypes_MaxAmmo;
pdht->pmEquipment[ET_ChaffLauncher] = ShipTypes_ChaffPartMask;
pdht->pmEquipment[ET_Shield] = ShipTypes_ShieldPartMask;
pdht->pmEquipment[ET_Afterburner] = ShipTypes_AfterburnerPartMask;
pdht->pmEquipment[ET_Cloak] = ShipTypes_CloakPartMask;
pdht->pmEquipment[ET_Magazine] = ShipTypes_MagazinePartMask;
pdht->pmEquipment[ET_Dispenser] = ShipTypes_DispenserPartMask;
pdht->capacityMagazine = ShipTypes_MagazineCapacity;
pdht->capacityDispenser = ShipTypes_DispenserCapacity;
pdht->capacityChaffLauncher = ShipTypes_ChaffCapacity;
pdht->successorHullID = ShipTypes_SuccessorID;
pdht->interiorSound = ShipTypes_InteriorSound;
pdht->exteriorSound = ShipTypes_ExteriorSound;
pdht->mainThrusterInteriorSound = ShipTypes_ThrustInteriorSound;
pdht->mainThrusterExteriorSound = ShipTypes_ThrustExteriorSound;
pdht->manuveringThrusterInteriorSound = ShipTypes_TurnInteriorSound;
pdht->manuveringThrusterExteriorSound = ShipTypes_TurnExteriorSound;
TechsListToBits(ShipTypes_TechBitsReqd, pdht->ttbmRequired);
TechsListToBits(ShipTypes_TechBitsEffect, pdht->ttbmEffects);
assert (pdht->ttbmEffects <= pdht->ttbmRequired);
AttachPoints_ShipTypeID = ShipTypes_ShipTypeID;
pdht->maxWeapons = 0;
pdht->maxFixedWeapons = 0;
pdht->timeToBuild = ShipTypes_TimeToBuild;
pdht->groupID = ShipTypes_GroupID;
SQL_GO(AttachPoints);
{
HardpointData * phpd = (HardpointData*)((char*)pdht + pdht->hardpointOffset);
while (SQL_SUCCEEDED(sqlret = SQL_GETROW(AttachPoints)))
{
SQLSTRCPY(phpd->frameName, AttachPoints_FrameName);
SQLSTRCPY(phpd->locationAbreviation, AttachPoints_LocationAbreviation);
phpd->bFixed = (AttachPoints_PartTypeID == ET_Weapon);
assert ((!phpd->bFixed) ||
(( (char*)phpd - ((char*)pdht + pdht->hardpointOffset) ) <
c_maxUnmannedWeapons * sizeof(HardpointData)));
phpd->interiorSound = AttachPoints_InteriorSound;
phpd->turnSound = AttachPoints_TurnSound;
phpd->partMask = AttachPoints_PartMask;
pdht->maxWeapons++;
if (phpd->bFixed)
pdht->maxFixedWeapons++;
phpd++;
}
}
IhullTypeIGC * phulltype = (IhullTypeIGC *) g.trekCore->CreateObject(g.timeNow, OT_hullType,
pdht, cbHull);
phulltype->Release();
}
}
SQL_GO(DevelopmentsCount);
SQL_GETROW(DevelopmentsCount);
DevelopmentID* vnDevelopmentIdList = (DevelopmentID*)_alloca(g_cDevelopments * sizeof(DevelopmentID));
nCount = 0;
SQL_GO(DevelopmentsIDs);
while (SQL_SUCCEEDED(sqlret = SQL_GETROW(DevelopmentsIDs)))
{
vnDevelopmentIdList[nCount] = DevelopmentIDs_DevelopmentID;
++nCount;
assert(nCount <= g_cDevelopments);
}
for (i = 0; i < nCount; i++)
{
Developments_ID = vnDevelopmentIdList[i];
SQL_GO(Developments);
if (SQL_SUCCEEDED(sqlret = SQL_GETROW(Developments)))
{
DataDevelopmentIGC dd;
dd.price = Developments_Price;
SQLSTRCPY(dd.modelName, Developments_Bitmap);
SQLSTRCPY(dd.name, Developments_Name);
SQLSTRCPY(dd.iconName, Developments_IconName);
SQLSTRCPY(dd.description, Developments_Description);
TechsListToBits(Developments_TechBitsReqd, dd.ttbmRequired);
TechsListToBits(Developments_TechBitsEffect, dd.ttbmEffects);
dd.timeToBuild = Developments_SecondsToBuild;
dd.completionSound = Developments_CompletedSound;
dd.groupID = Developments_GroupID;
assert (dd.timeToBuild > 0);
dd.developmentID = Developments_ID;
if (NA == Developments_GlobalAttribute)
Developments_GlobalAttribute = 0; FetchGlobalAttributeSet(Developments_GlobalAttribute, dd.gas);
IdevelopmentIGC * pdev = (IdevelopmentIGC *) g.trekCore->CreateObject(
g.timeNow, OT_development, &dd, sizeof(dd));
pdev->Release();
}
}
SQL_GO(Drones);
while (SQL_SUCCEEDED(SQL_GETROW(Drones)))
{
DataDroneTypeIGC ddt;
ddt.price = Drones_Price;
lstrcpy(ddt.modelName, g.trekCore->GetHullType(Drones_ShipTypeID)->GetModelName());
ddt.iconName[0] = '\0'; SQLSTRCPY(ddt.name, Drones_Name);
SQLSTRCPY(ddt.description, Drones_Description);
TechsListToBits(Drones_TechBitsReqd, ddt.ttbmRequired);
TechsListToBits(Drones_TechBitsEffect, ddt.ttbmEffects);
ddt.timeToBuild = Drones_SecToBuild;
ddt.pilotType = (PilotType)Drones_DroneType;
ddt.hullTypeID = Drones_ShipTypeID;
ddt.droneTypeID = Drones_ID;
ddt.shootSkill = 0.5f; ddt.moveSkill = 0.5f;
ddt.bravery = 0.5f;
ddt.groupID = Drones_GroupID;
ddt.etidLaid = Drones_ExpendableID;
IdroneTypeIGC * pdronetype = (IdroneTypeIGC *) g.trekCore->CreateObject(
g.timeNow, OT_droneType, &ddt, sizeof(ddt));
pdronetype->Release();
}
SQL_GO(StationTypes);
while(SQL_SUCCEEDED(SQL_GETROW(StationTypes)))
{
DataStationTypeIGC st;
memset(&st, 0, sizeof(st)); SQLSTRCPY(st.name, Stations_Name);
SQLSTRCPY(st.description, Stations_Description);
SQLSTRCPY(st.modelName, Stations_Model);
SQLSTRCPY(st.iconName, Stations_IconName);
st.textureName[0] = '\0';
SQLSTRCPY(st.builderName, Stations_BuilderName);
TechsListToBits(Stations_TBReqd, st.ttbmRequired);
TechsListToBits(Stations_TBEffect, st.ttbmEffects);
TechsListToBits(Stations_TBLocal, st.ttbmLocal);
st.price = Stations_Price;
st.signature = float(Stations_Signature) / 100.0f;
st.maxArmorHitPoints = Stations_HPArmor;
st.defenseTypeArmor = Stations_DTArmor;
st.maxShieldHitPoints = Stations_HPShield;
st.defenseTypeShield = Stations_DTShield;
st.armorRegeneration = Stations_RateRegenArmor;
st.shieldRegeneration = Stations_RateRegenShield;
st.timeToBuild = Stations_SecondsToBuild;
assert (st.timeToBuild > 0);
st.radius = Stations_Radius;
st.income = Stations_Income;
st.stationTypeID = Stations_ID;
st.sabmCapabilities = Stations_Capabilities;
st.scannerRange = Stations_ScanRange;
st.aabmBuild = Stations_AsteroidDiscountMask;
st.successorStationTypeID = Stations_UpgradeStationTypeID;
st.classID = Stations_ClassID;
st.groupID = Stations_GroupID;
st.constructionDroneTypeID = Stations_ConstructionDroneTypeID;
st.constructorNeedRockSound = Stations_BuildLocationSound;
st.constructorUnderAttackSound = Stations_ConstructorAttackedSound;
st.constructorDestroyedSound = Stations_ConstructorDestroyedSound;
st.completionSound = Stations_CompletedSound;
st.exteriorSound = Stations_ExteriorSound;
st.interiorSound = Stations_InteriorSound;
st.interiorAlertSound = Stations_InteriorAlertSound;
st.underAttackSound = Stations_UnderAttackSound;
st.criticalSound = Stations_CriticalSound;
st.destroyedSound = Stations_DestroyedSound;
st.capturedSound = Stations_CapturedSound;
st.enemyDestroyedSound = Stations_EnemyDestroyedSound;
st.enemyCapturedSound = Stations_EnemyCapturedSound;
IObject* punk = g.trekCore->CreateObject(g.timeNow, OT_stationType,
&st, sizeof(st));
punk->Release();
}
SQL_GO(CivsCount);
SQL_GETROW(CivsCount);
for (i = 0; i < g_cCivs; i++)
{
Civs_ID = i;
SQL_GO(Civs);
if (SQL_SUCCEEDED(sqlret = SQL_GETROW(Civs)))
{
DataCivilizationIGC c;
SQLSTRCPY(c.name, Civs_Name);
SQLSTRCPY(c.iconName, Civs_IconName);
SQLSTRCPY(c.hudName, Civs_HUDName);
c.lifepod = Civs_DefaultShipType;
c.initialStationTypeID = Civs_InitialStationTypeID;
c.civilizationID = Civs_ID;
c.bonusMoney = Civs_BonusMoney;
c.incomeMoney = Civs_IncomeMoney;
TechsListToBits(Civs_TechBits, c.ttbmBaseTechs);
TechsListToBits(Civs_TechBitsNoDev, c.ttbmNoDevTechs);
FetchGlobalAttributeSet(Civs_GlobalAttr, c.gasBaseAttributes);
IcivilizationIGC * pciv = (IcivilizationIGC *) g.trekCore->CreateObject(
g.timeNow, OT_civilization, &c, sizeof(c));
pciv->Release();
}
}
SQL_GO(TreasureSets);
while (SQL_SUCCEEDED(SQL_GETROW(TreasureSets)))
{
DataTreasureSetIGC dts;
SQLSTRCPY(dts.name, TreasureSets_Name);
dts.treasureSetID = TreasureSets_ID;
dts.bZoneOnly = (TreasureSets_IsZoneOnly != 0);
dts.nTreasureData = 0;
IbaseIGC* pb = g.trekCore->CreateObject(g.timeNow, OT_treasureSet,
&dts, sizeof(DataTreasureSetIGC));
pb->Release();
}
assert (g.trekCore->GetTreasureSets()->n() > 0); SQL_GO(TreasureChance);
while (SQL_SUCCEEDED(SQL_GETROW(TreasureChance)))
{
ItreasureSetIGC* pts = g.trekCore->GetTreasureSet(TreasureChance_SetID);
assert (pts);
pts->AddTreasureData(TreasureChance_TreasureCode, TreasureChance_ObjectID, TreasureChance_Chance);
}
#pragma warning(default : 4244)
#endif }
CFMGroup * GetGroupSectorDocked(IclusterIGC * pCluster)
{
ClusterGroups * pcg = ((CFSCluster*) pCluster->GetPrivateData())->GetClusterGroups();
return pcg->pgrpClusterDocked;
}
CFMGroup * GetGroupSectorFlying(IclusterIGC * pCluster)
{
ClusterGroups * pcg = ((CFSCluster*) pCluster->GetPrivateData())->GetClusterGroups();
return pcg->pgrpClusterFlying;
}
void ExportObj(IbaseIGC * pIGC, ObjectType ot, FMD_S_EXPORT ** ppfmExport)
{
int cbExport = pIGC->Export(NULL);
if (ppfmExport)
{
BEGIN_PFM_CREATE_ALLOC(g.fm, pfmExport, S, EXPORT)
FM_VAR_PARM(NULL, cbExport)
END_PFM_CREATE
pfmExport->objecttype = ot;
pIGC->Export(FM_VAR_REF(pfmExport, exportData));
*ppfmExport = pfmExport;
}
else
{
BEGIN_PFM_CREATE(g.fm, pfmExport, S, EXPORT)
FM_VAR_PARM(NULL, cbExport)
END_PFM_CREATE
pfmExport->objecttype = ot;
pIGC->Export(FM_VAR_REF(pfmExport, exportData));
}
}
void SendPlayerInfo(CFSPlayer * pfsPlayer, CFSShip * pfsShip, CFSMission* pfsMission, bool bSend)
{
const int cCivsMax = 20; int cCivs = 0;
PersistPlayerScoreObject rgperplrScore[cCivsMax];
if (pfsShip->IsPlayer()) {
CFSPlayer * pfsPlayerSent = pfsShip->GetPlayer(); PersistPlayerScoreObjectList * pperplrscoList = pfsPlayerSent->GetPersistPlayerScoreObjectList();
cCivs = pperplrscoList->n();
assert(cCivsMax >= cCivs);
PersistPlayerScoreObjectLink * pl = NULL;
int i = 0;
for (pl = pperplrscoList->first(); pl; pl = pl->next())
{
rgperplrScore[i++] = *pl->data();
}
}
else {
cCivs = 1;
rgperplrScore[0] = pfsShip->GetPlayerScoreObject()->GetPersist();
}
BEGIN_PFM_CREATE(g.fm, pfmPlayerInfo, S, PLAYERINFO)
FM_VAR_PARM(rgperplrScore, cCivs * sizeof(rgperplrScore[0]))
END_PFM_CREATE
lstrcpy(pfmPlayerInfo->CharacterName, pfsShip->GetName());
pfmPlayerInfo->fExperience = pfsShip->GetIGCShip()->GetExperience();
pfmPlayerInfo->nKills = pfsShip->GetIGCShip()->GetKills();
pfmPlayerInfo->nDeaths = pfsShip->GetIGCShip()->GetDeaths();
pfmPlayerInfo->nEjections = pfsShip->GetIGCShip()->GetEjections();
pfmPlayerInfo->dtidDrone = pfsShip->IsPlayer()
? NA
: ((CFSDrone*)pfsShip)->GetDroneTypeID();
pfmPlayerInfo->pilotType = pfsShip->GetIGCShip()->GetPilotType();
pfmPlayerInfo->abmOrders = pfsShip->GetIGCShip()->GetOrdersABM();
{
IbaseIGC* pbase = pfsShip->GetIGCShip()->GetBaseData();
pfmPlayerInfo->baseObjectID = pbase
? pbase->GetObjectID() : NA;
}
IsideIGC* pside = pfsShip->GetIGCShip()->GetSide();
if (pside)
{
assert (pfsMission);
pfmPlayerInfo->iSide = pside->GetObjectID();
}
else
{
pfmPlayerInfo->iSide = NA;
}
pfmPlayerInfo->shipID = pfsShip->GetShipID();
pfmPlayerInfo->rankID = 0; pfmPlayerInfo->fReady = pfsShip->IsPlayer() ? pfsShip->GetPlayer()->GetReady() : true; pfmPlayerInfo->money = 0; if (pfsShip->IsPlayer() && pfsMission && pside && pfmPlayerInfo->iSide != SIDE_TEAMLOBBY)
{
CFSPlayer* pfsPlayerNew = pfsShip->GetPlayer();
pfmPlayerInfo->fTeamLeader = pfsMission->GetLeader(pfmPlayerInfo->iSide) == pfsPlayerNew;
pfmPlayerInfo->fMissionOwner = pfsMission->GetOwner() == pfsPlayerNew;
}
else
{
pfmPlayerInfo->fTeamLeader = false;
pfmPlayerInfo->fMissionOwner = false;
}
if (bSend)
{
CFMRecipient* prcp;
if (pfsPlayer)
prcp = pfsPlayer->GetConnection();
else
prcp = pfsMission->GetGroupMission();
g.fm.SendMessages(prcp, FM_GUARANTEED, FM_FLUSH);
debugf("Sending PlayerInfo for %s to %s(%u)\n", pfsShip->GetName(),
prcp->GetName(), prcp->GetID());
}
}
CFSDrone * CreateStockDrone(IdroneTypeIGC * pdronetype, IsideIGC* pSide, IbaseIGC* pbase)
{
PilotType pt = pdronetype->GetPilotType();
ImissionIGC* pmission = pSide->GetMission();
IshipIGC* pship = CreateDrone(pmission,
-2,
pt,
NULL,
pdronetype->GetHullTypeID(),
pSide,
(pt == c_ptMiner) ? c_aabmMineHe3 : 0,
pdronetype->GetShootSkill(),
pdronetype->GetMoveSkill(),
pdronetype->GetBravery());
assert (pship);
if (pbase)
pship->SetBaseData(pbase);
pship->CreateDamageTrack();
CFSDrone * pfsDrone = new CFSDrone(pship);
pfsDrone->SetDroneTypeID(pdronetype->GetObjectID());
{
char bfr[c_cbName + 10];
const char* pszName;
if (pt == c_ptBuilder)
{
assert (pbase);
assert (pbase->GetObjectType() == OT_stationType);
pszName = ((IstationTypeIGC*)pbase)->GetBuilderName();
}
else
{
pszName = pdronetype->GetName();
}
assert (strlen(pszName) < c_cbName - 4);
strcpy(bfr, pszName);
_itoa(pship->GetObjectID(), bfr + strlen(bfr), 10);
pship->SetName(bfr);
}
pfsDrone->SetDroneTypeID(pdronetype->GetObjectID());
SendPlayerInfo(NULL, pfsDrone, (CFSMission *)(pmission->GetPrivateData()));
pfsDrone->ShipStatusStart(NULL);
pfsDrone->SetLastDamageReport(pship->GetLastUpdate());
return pfsDrone;
}
bool LeaveShip(CFSShip* pfsShip, IshipIGC* pshipParent)
{
assert (pfsShip);
assert (pfsShip->IsPlayer());
assert (pshipParent);
bool bLeft = false;
if (pshipParent->GetCluster() == NULL)
{
IshipIGC* pship = pfsShip->GetIGCShip();
assert (pship != pshipParent);
assert (pship->GetParentShip() == pshipParent);
assert (pship->GetCluster() == NULL);
CFSShip* pfsShipParent = (CFSShip*)(pshipParent->GetPrivateData());
assert (pfsShipParent->IsPlayer());
pship->SetParentShip(NULL);
bLeft = true;
IsideIGC* pside = pship->GetSide();
IhullTypeIGC* pht = pside->GetCivilization()->GetLifepod();
pship->SetBaseHullType(pht);
ShipStatus* pss = pfsShip->GetShipStatus(pside->GetObjectID());
pss->SetState(c_ssDocked);
pss->SetParentID(NA);
pss->SetHullID(pht->GetObjectID());
assert (pship->GetStation());
assert (pss->GetStationID() == pship->GetStation()->GetObjectID());
BEGIN_PFM_CREATE(g.fm, pfmLeave, S, LEAVE_SHIP)
END_PFM_CREATE
pfmLeave->sidChild = pship->GetObjectID();
g.fm.SendMessages(CFSSide::FromIGC(pside)->GetGroup(), FM_GUARANTEED, FM_FLUSH);
}
return bLeft;
}
bool BoardShip(CFSShip* pfsShip, IshipIGC* pshipBoard)
{
assert (pfsShip);
assert (pfsShip->IsPlayer());
assert (pshipBoard);
bool bBoarded = false;
IshipIGC* pship = pfsShip->GetIGCShip();
if (pship != pshipBoard)
{
IhullTypeIGC* phtBoard = pshipBoard->GetBaseHullType();
if (phtBoard)
{
IshipIGC* pshipOldParent = pship->GetParentShip();
CFSShip* pfsShipBoard = (CFSShip*)(pshipBoard->GetPrivateData());
IstationIGC* pstationBoard = pshipBoard->GetStation();
if (pfsShipBoard->IsPlayer() &&
((pshipBoard == pshipOldParent) || ((pship->GetCluster() == NULL) && (pship->GetStation() != NULL) &&
(pshipBoard->GetCluster() == NULL) &&
(pstationBoard != NULL))))
{
Mount turret;
{
Mount minMount = phtBoard->GetMaxFixedWeapons();
Mount maxMount = phtBoard->GetMaxWeapons();
if (minMount == maxMount)
turret = NA;
else
{
Mount startMount = pship->GetTurretID();
if (startMount == NA)
startMount = maxMount - 1;
else
assert (pship->GetParentShip() != NULL);
turret = startMount;
while (true)
{
turret++;
if (turret >= maxMount)
turret = minMount;
ShipLinkIGC* psl;
for (psl = pshipBoard->GetChildShips()->first();
(psl != NULL);
psl = psl->next())
{
if (psl->data()->GetTurretID() == turret)
break;
}
if (psl == NULL)
{
break;
}
if (turret == startMount)
{
turret = NA;
break;
}
}
}
}
if ((turret != NA) || pfsShip->GetPlayer()->CanCheat())
{
{
const ShipListIGC* pchildren = pship->GetChildShips();
assert ((pchildren->n() == 0) || (pship->GetCluster() == NULL));
ShipLinkIGC* psl;
while (psl = pchildren->first()) {
LeaveShip((CFSShip*)(psl->data()->GetPrivateData()), pship);
}
}
IsideIGC* pside = pship->GetSide();
{
Money refund = pship->GetValue();
assert(refund >= 0);
if (refund > 0)
{
pfsShip->SetMoney(pfsShip->GetMoney() + refund);
BEGIN_PFM_CREATE(g.fm, pfmMoney, S, MONEY_CHANGE)
END_PFM_CREATE
pfmMoney->sidTo = pfsShip->GetShipID();
pfmMoney->sidFrom = NA;
pfmMoney->dMoney = refund;
g.fm.SendMessages(CFSSide::FromIGC(pside)->GetGroup(), FM_GUARANTEED, FM_FLUSH);
}
}
pship->SetParentShip(pshipBoard);
pship->SetTurretID(turret);
bBoarded = true;
ShipStatus* pss = pfsShip->GetShipStatus(pside->GetObjectID());
pss->SetState(turret == NA ? c_ssObserver : c_ssTurret);
pss->SetParentID(pshipBoard->GetObjectID());
pss->SetHullID(NA);
if (pstationBoard)
pship->SetStation(pstationBoard);
pfsShipBoard->QueueLoadoutChange();
IclusterIGC* pcluster = pship->GetCluster();
if (pcluster)
{
assert (pshipOldParent == pshipBoard);
g.fm.SendMessages(GetGroupSectorFlying(pcluster), FM_GUARANTEED, FM_FLUSH);
}
else
{
g.fm.SendMessages(CFSSide::FromIGC(pside)->GetGroup(), FM_GUARANTEED, FM_FLUSH);
}
}
}
}
}
return bBoarded;
}
bool CheatCreateDrones(CFSShip * pfsShip, ZString & strCheat)
{
IclusterIGC* pcluster = pfsShip->GetIGCShip()->GetCluster();
if (!pcluster)
return false;
CFSMission * pfsMission = pfsShip->GetMission();
bool fIsCheat = true;
ZString strDroneType(strCheat.GetToken());
ZString strNumDrones(strCheat.GetToken());
ZString strDroneSide(strCheat.GetToken());
ZString strMessage(strCheat.GetToken());
ZString strShipTypeID(strCheat.GetToken());
if (strDroneType.IsEmpty())
fIsCheat = false;
else
{
short iBucket = 0;
IhullTypeIGC * phull = NULL;
PilotType ptPilotType;
IdroneTypeIGC * pdronetype = NULL;
IsideIGC* psideDrone;
int iNumDrones;
if (!lstrcmpi(strDroneType, "carrier"))
ptPilotType = c_ptCarrier;
else if (!lstrcmpi(strDroneType, "miner"))
ptPilotType = c_ptMiner;
else if (!lstrcmpi(strDroneType, "wingman"))
ptPilotType = c_ptWingman;
else
{
pfsMission->GetSite()->SendChatf(NULL, CHAT_INDIVIDUAL_NOFILTER, pfsShip->GetIGCShip()->GetObjectID(),
NA, "%s is not a valid drone type. Aborting cheat code.", (PCC) strDroneType);
fIsCheat = false;
}
if (fIsCheat)
{
const DroneTypeListIGC * pdronelist = pfsMission->GetIGCMission()->GetDroneTypes();
DroneTypeLinkIGC * pdronelink;
for (pdronelink = pdronelist->first(); pdronelink; pdronelink = pdronelink->next())
{
pdronetype = pdronelink->data();
if (pdronetype->GetPilotType() == ptPilotType)
break;
}
if (!pdronetype)
{
pfsMission->GetSite()->SendChatf(NULL, CHAT_INDIVIDUAL_NOFILTER, pfsShip->GetIGCShip()->GetObjectID(),
NA, "There are not any %s type drones defined. Aborting cheat code.", (const char*)strDroneType);
fIsCheat = false;
}
}
if (fIsCheat)
{
iNumDrones = strNumDrones.IsEmpty() ? 1 : atoi(strNumDrones);
if (!strDroneSide.IsEmpty())
{
psideDrone = pfsMission->GetIGCMission()->GetSide(atoi(strDroneSide));
if (!psideDrone)
fIsCheat = false;
}
else
{
psideDrone = pfsShip->GetSide();
}
}
if (fIsCheat)
{
{
Vector p = Vector::GetZero();
if (!pfsShip->GetStation()) p = pfsShip->GetIGCShip()->GetSourceShip()->GetPosition();
for (int i=0; i < iNumDrones; i++)
{
p.x += random(-200.0f, 200.0f);
p.y += random(-200.0f, 200.0f);
p.z += random(-200.0f, 200.0f);
CFSDrone* pdrone = CreateStockDrone(pdronetype, psideDrone);
assert (pdrone);
pdrone->GetIGCShip()->SetAmmo(0x7fff);
pdrone->GetIGCShip()->SetPosition(p);
pdrone->GetIGCShip()->SetCluster(pcluster);
pdrone->ShipStatusLaunched();
}
}
}
}
return fIsCheat;
}
#ifdef MOVE_TO_FEDMESSAGING
BOOL FAR PASCAL EnumPlayersCallback(DPID dpId, DWORD dwPlayerType,
LPCDPNAME lpName, DWORD dwFlags, LPVOID lpContext)
{
DataEnumPlayers * pdep = (DataEnumPlayers *) lpContext;
CFSMission * pfsMission = pdep->pfsShip->GetMission();
char rgchdpn[256]; char szIndent[15];
assert (pdep->indent < sizeof(szIndent));
szIndent[pdep->indent] = '\0';
int i = pdep->indent;
while (i--)
szIndent[i] = ' ';
if (DPPLAYERTYPE_GROUP == dwPlayerType)
{
DPNAME * pdpn = (DPNAME *) rgchdpn;
DWORD dwSize = sizeof(rgchdpn);
ZSucceeded(g.fm.GetDPlay()->GetGroupName(dpId, rgchdpn, &dwSize));
if (pdep->pfsShip)
pfsMission->GetSite()->SendChatf(NULL, CHAT_INDIVIDUAL_NOFILTER, pdep->pfsShip->GetIGCShip()->GetObjectID(),
NA, "%s%s%s (%u): ",
szIndent, pdpn->lpszShortNameA, pdpn->lpszLongNameA, dpId);
debugf("%s%s%s (%u): ", szIndent, pdpn->lpszShortNameA, pdpn->lpszLongNameA, dpId);
DataEnumPlayers depNew = *pdep;
depNew.indent += 2;
ZSucceeded(g.fm.GetDPlay()->EnumGroupPlayers( dpId, NULL, EnumPlayersCallback, (LPVOID) &depNew, DPENUMPLAYERS_ALL));
debugf("\n");
ZSucceeded(g.fm.GetDPlay()->EnumGroupsInGroup(dpId, NULL, EnumPlayersCallback, (LPVOID) &depNew, DPENUMGROUPS_LOCAL));
}
else
{
CFSShip * pfsShip = NULL;
DWORD dwSize = sizeof(CFSShip);
ZSucceeded(g.fm.GetDPlay()->GetPlayerData(dpId, &pfsShip, &dwSize, DPGET_LOCAL));
if (pdep->pfsShip)
pfsMission->GetSite()->SendChatf(NULL, CHAT_INDIVIDUAL_NOFILTER, pdep->pfsShip->GetIGCShip()->GetObjectID(), NA, "%s%s", szIndent, pfsShip->GetName());
debugf("%s, ", pfsShip->GetName());
}
return TRUE;
}
void CheatDPGroups(CFSShip * pfsShip)
{
DataEnumPlayers dep;
dep.pfsShip = pfsShip;
dep.indent = 0;
g.fm.GetDPlay()->EnumGroups(NULL, EnumPlayersCallback, &dep, DPENUMGROUPS_LOCAL);
if (pfsShip && pfsShip->IsPlayer())
{
CFSPlayer * pfsPlayer = pfsShip->GetPlayer();
char rgchdpn[128];
DPNAME * pdpn = (DPNAME *) rgchdpn;
DWORD dwSize = sizeof(rgchdpn);
DPID dpidGroup = pfsPlayer->GetGroup();
ZSucceeded(g.fm.GetDPlay()->GetGroupName(dpidGroup, rgchdpn, &dwSize));
pfsShip->GetMission()->GetSite()->SendChatf(NULL, CHAT_INDIVIDUAL_NOFILTER, pfsShip->GetIGCShip()->GetObjectID(),
NA, "You're in group %s%s (%u)", pdpn->lpszShortNameA, pdpn->lpszLongNameA, dpidGroup);
}
}
#endif void CheatJPD(CFSShip * pfsShip)
{
IclusterIGC* pcluster = pfsShip->GetIGCShip()->GetCluster();
if (!pcluster) return;
IdroneTypeIGC * pdronetype = NULL;
CFSMission * pfsMission = pfsShip->GetMission();
const DroneTypeListIGC * pdronelist = pfsMission->GetIGCMission()->GetDroneTypes();
DroneTypeLinkIGC * pdronelink;
for (pdronelink = pdronelist->first(); pdronelink && !pdronetype; pdronelink = pdronelink->next())
{
IdroneTypeIGC * pdronetypeT = pdronelink->data();
if (pdronetypeT->GetPilotType() == c_ptWingman)
pdronetype = pdronetypeT;
}
if (!pdronetype)
{
pfsMission->GetSite()->SendChatf(NULL, CHAT_INDIVIDUAL_NOFILTER, pfsShip->GetIGCShip()->GetObjectID(),
NA, "There are not any wingman type drones defined. Aborting cheat code.");
return;
}
IshipIGC * pship = pfsShip->GetIGCShip();
const Orientation& o = pship->GetOrientation();
const float flDistanceFromCenter = 200.0f;
const float flDistanceFromShip = 600.0f;
Vector p = pship->GetPosition() - o.GetBackward() * flDistanceFromShip +
o.GetRight() * flDistanceFromCenter;
CFSDrone * pfsDrone = CreateStockDrone(pdronetype, pship->GetSide());
pfsDrone->GetIGCShip()->SetAmmo(0x7fff);
pfsDrone->GetIGCShip()->SetPosition(p);
pfsDrone->GetIGCShip()->SetCluster(pship->GetCluster());
pfsDrone->ShipStatusLaunched();
const SideListIGC * plistSide = pfsMission->GetIGCMission()->GetSides();
IsideIGC * psideEnemy = NULL;
IsideIGC * psideMe = pship->GetSide();
for (SideLinkIGC * plinkSide = plistSide->first();
plinkSide && NULL == psideEnemy;
plinkSide = plinkSide->next())
{
IsideIGC * psideT = plinkSide->data();
if (psideT != psideMe) psideEnemy = psideT;
}
if (psideEnemy)
{
p += o.GetRight() * (-2 * flDistanceFromCenter); pfsDrone = CreateStockDrone(pdronetype, psideEnemy);
pfsDrone->GetIGCShip()->SetAmmo(0x7fff);
pfsDrone->GetIGCShip()->SetPosition(p);
pfsDrone->GetIGCShip()->SetCluster(pship->GetCluster());
pfsDrone->ShipStatusLaunched();
}
else
{
pfsMission->GetSite()->SendChatf(NULL, CHAT_INDIVIDUAL_NOFILTER, pfsShip->GetIGCShip()->GetObjectID(),
NA, "Cannot create enemy ship because an enemy side does not exist.");
}
}
void LogTrapHack(AGCEventID idEvent, CFSPlayer* pfsPlayer,
CFMConnection* pcnxnFrom, const char* pExpr, UINT nLine)
{
LPCSTR pszContext = NULL;
const char* pszSubject = NULL;
AGCUniqueID idSource = -1;
if (pfsPlayer)
{
pszContext = pfsPlayer->GetIGCShip() ?
pfsPlayer->GetIGCShip()->GetMission()->GetContextName() : NULL;
pszSubject = pfsPlayer->GetName();
idSource =
static_cast<USHORT>(CAdminUser::DetermineID(pfsPlayer))
| static_cast<DWORD>(AGC_AdminUser << 16);
}
switch (idEvent)
{
case EventID_HackLog:
assert(pfsPlayer);
assert(pszSubject);
assert(pcnxnFrom);
retailf("HackLog %s: %s %d\n", pszSubject, pExpr, nLine);
break;
case EventID_HackBoot:
assert(pfsPlayer);
assert(pszSubject);
assert(pcnxnFrom);
retailf("HackBoot %s: %s %d\n", pszSubject, pExpr, nLine);
g.fm.DeleteConnection(*pfsPlayer->GetConnection());
break;
case EventID_HackBootNoPlayer:
assert(!pfsPlayer);
assert(!pszSubject);
assert(pcnxnFrom);
retailf("HackBootNoPlayer %s %d\n", pExpr, nLine);
g.fm.DeleteConnection(*pcnxnFrom);
break;
default:
ZError("Unexpected AGCEventID passed to LogTrapHack.");
}
_AGCModule.TriggerContextEvent(NULL, idEvent, pszContext,
pszSubject, idSource, -1, -1, 2,
"Expr", VT_LPSTR, pExpr,
"Line", VT_I4 , nLine);
}
bool DoCheatCode(CFSShip * pfsShip, const char * szMessage)
{
CFSMission * pfsMission = pfsShip->GetMission();
bool fIsCheat = true;
ZString strCheat(szMessage);
ZString strToken = strCheat.GetToken();
if (!lstrcmpi(strToken, "bootme"))
{
Sleep(1000); LogTrapHack(EventID_HackBoot, pfsShip->GetPlayer(), pfsShip->GetPlayer()->GetConnection(), "bootme cheat code", __LINE__);
}
else if (!lstrcmpi(strToken, "spew"))
{
debugf("===> %s\n", (PCC) strCheat);
}
else if (!lstrcmpi(strToken, "stations"))
{
pfsMission->GetSite()->SendChatf(NULL, CHAT_INDIVIDUAL_NOFILTER, pfsShip->GetIGCShip()->GetObjectID(),
NA, "Station ID: Name, Side (yours is %d), HP, Sector", pfsShip->GetSide()->GetObjectID());
const StationListIGC * pstations = pfsMission->GetIGCMission()->GetStations();
StationLinkIGC * pstationLink = NULL;
for (pstationLink = pstations->first(); pstationLink; pstationLink = pstationLink->next())
{
IstationIGC * pStation = pstationLink->data();
pfsMission->GetSite()->SendChatf(NULL, CHAT_INDIVIDUAL_NOFILTER, pfsShip->GetIGCShip()->GetObjectID(),
NA, "%d: %s%s, %d-%s, %d%%/%d%%HP, in %s",
pStation->GetObjectID(), pStation->GetName(), (pStation->GetStationType()->GetCapabilities() & c_sabmFlag) ? " (flag)" : "",
pStation->GetSide()->GetObjectID(), pStation->GetSide()->GetName(),
(int)(100.0f * pStation->GetFraction()), (int)(100.0f * pStation->GetShieldFraction()), pStation->GetCluster()->GetName());
}
}
else if (!lstrcmpi(strToken, "exile"))
{
ZString strPlayer(strCheat.GetToken());
if (strPlayer.IsEmpty()) fIsCheat = false;
else
{
for (ShipLinkIGC* psl = pfsMission->GetIGCMission()->GetShips()->first(); (psl != NULL); psl = psl->next())
{
CFSShip* pfsShip = (CFSShip*)(psl->data()->GetPrivateData());
if (pfsShip->IsPlayer() && (lstrcmpi(strPlayer, psl->data()->GetName()) == 0))
{
pfsMission->RemovePlayerFromMission(pfsShip->GetPlayer(), QSR_AdminBooted);
break;
}
}
}
}
else if (!lstrcmpi(strToken, "OhSayCanYouSee"))
{
IclusterIGC* pcluster = pfsShip->GetIGCShip()->GetCluster();
if (pcluster)
{
IsideIGC* pside = pfsShip->GetIGCShip()->GetSide();
for (ModelLinkIGC* pml = pcluster->GetModels()->first(); (pml != NULL); pml = pml->next())
{
ImodelIGC* pmodel = pml->data();
if ((pmodel->GetAttributes() & c_mtStatic) != 0)
pmodel->SetSideVisibility(pside, true);
}
}
else
fIsCheat = false;
}
else if (!lstrcmpi(strToken, "IfYouBuildIt"))
{
ZString strTech;
if (pfsMission->GetStage() != STAGE_STARTED)
pfsMission->GetSite()->SendChatf(NULL, CHAT_INDIVIDUAL_NOFILTER, pfsShip->GetIGCShip()->GetObjectID(),
NA, "Trying to steal a tech before the game even starts??? Sheesh--what a loser!");
else
{
IsideIGC * pside = pfsShip->GetSide();
SideID sideid = pside->GetObjectID();
while (!(strTech = strCheat.GetToken()).IsEmpty()) {
int ibit = TechBitFromToken(strTech);
if (NA != ibit)
{
TechTreeBitMask ttbm;
ttbm.ClearAll();
ttbm.SetBit(ibit);
pside->ApplyDevelopmentTechs(ttbm);
}
else
{
pfsMission->GetSite()->SendChatf(NULL, CHAT_INDIVIDUAL_NOFILTER, pfsShip->GetIGCShip()->GetObjectID(),
NA, "Sorry, no tech found named %s.", (const char*)strTech);
}
}
}
}
else if (!lstrcmpi(strToken, "IfYouWishUponAStar"))
{
ZString strTech;
if (pfsMission->GetStage() != STAGE_STARTED)
pfsMission->GetSite()->SendChatf(NULL, CHAT_INDIVIDUAL_NOFILTER, pfsShip->GetIGCShip()->GetObjectID(),
NA, "Trying to steal a tech before the game even starts??? Sheesh--what a loser!");
else
{
IsideIGC * pside = pfsShip->GetSide();
SideID sideid = pside->GetObjectID();
TechTreeBitMask ttbm;
ttbm.SetAll();
pside->ApplyDevelopmentTechs(ttbm);
}
}
else if (!lstrcmpi(strToken, "fourteen"))
{
CFSMission * pfsMission = pfsShip->GetMission();
if (STAGE_NOTSTARTED == pfsMission->GetStage() || STAGE_STARTING == pfsMission->GetStage())
pfsMission->StartGame();
}
else if (!lstrcmpi(strToken, "fifteen"))
{
CFSMission * pfsMission = pfsShip->GetMission();
if (STAGE_NOTSTARTED == pfsMission->GetStage() || STAGE_STARTING == pfsMission->GetStage())
pfsMission->StartCountdown(15);
}
else if (!lstrcmpi(strToken, "ragnarok"))
{
assert(false);
}
else if (!lstrcmpi(strToken, "gimme"))
{
ZString strMoney(strCheat.GetToken());
if (strMoney.IsEmpty()) fIsCheat = false;
else
{
BEGIN_PFM_CREATE(g.fm, pfmMoney, S, MONEY_CHANGE)
END_PFM_CREATE
pfmMoney->sidTo = pfsShip->GetShipID();
pfmMoney->sidFrom = NA;
pfmMoney->dMoney = max(-pfsShip->GetMoney(), atoi(strMoney));
pfsShip->SetMoney(pfsShip->GetMoney() + pfmMoney->dMoney);
g.fm.SendMessages(CFSSide::FromIGC(pfsShip->GetSide())->GetGroup(), FM_GUARANTEED, FM_FLUSH);
}
}
else if (!lstrcmpi(strToken, "winwinwin"))
pfsMission->GameOver(pfsShip->GetSide(), "By a cheat");
else if (!lstrcmpi(strToken, "checkbank"))
pfsMission->GetSite()->SendChatf(NULL, CHAT_INDIVIDUAL_NOFILTER, pfsShip->GetIGCShip()->GetObjectID(),
NA, "You have %d in your bank account.", pfsShip->GetMoney());
else if (!lstrcmpi(strToken, "capture"))
{
ZString strStation(strCheat.GetToken());
if (strStation.IsEmpty()) fIsCheat = false;
else
{
StationID stationID = atoi(strStation);
IstationIGC * pstation = pfsMission->GetIGCMission()->GetStation(stationID);
if (pstation)
pfsShip->CaptureStation(pstation);
else
pfsMission->GetSite()->SendChatf(NULL, CHAT_INDIVIDUAL_NOFILTER, pfsShip->GetIGCShip()->GetObjectID(),
NA, "Cannot capture station %d because it does not exist.", stationID);
}
}
else if (!lstrcmpi(strToken, "createdrones"))
fIsCheat = CheatCreateDrones(pfsShip, strCheat);
#ifdef OUT_OF_ORDER
else if (!lstrcmpi(strToken, "dpgroups"))
CheatDPGroups(pfsShip);
#endif else if (!lstrcmpi(strToken, "jpd"))
{
CheatJPD(pfsShip);
}
else if (!lstrcmpi(strToken, "fireaway"))
{
int cChats = 0;
Time timeStart = Time::Now();
while (Time::Now() - timeStart < 3.0) {
pfsMission->GetSite()->SendChatf(NULL, CHAT_INDIVIDUAL_NOFILTER, pfsShip->GetIGCShip()->GetObjectID(),
NA, "firing away: %05d", cChats);
cChats++;
}
printf("%d chats sent in 3 seconds.\n", cChats);
pfsMission->GetSite()->SendChatf(NULL, CHAT_INDIVIDUAL_NOFILTER, pfsShip->GetIGCShip()->GetObjectID(),
NA, "%d chats sent in 3 seconds.", cChats);
}
#if defined(ALLOW_TESTAGCEVENTS_CHEAT)
else if (!lstrcmpi(strToken, "testagcevents"))
{
AGCEventID idEvent = EventID_ChatMessage;
HAGCLISTENERS hListeners = GetAGCGlobal()->EventListeners(idEvent, -1, -1, -1);
if (!hListeners)
return true;
IAGCVectorPtr spVector1, spVector2;
ZSucceeded(GetAGCGlobal()->MakeAGCVector(&Vector(10, 20, 30), &spVector1));
ZSucceeded(GetAGCGlobal()->MakeAGCVector(&Vector(100, 200, 300), &spVector2));
DATE date = GetLocalVariantDateTime();
CY cy = {99, 12};
LPCSTR pszContext = pfsShip->GetIGCShip() ?
pfsShip->GetIGCShip()->GetMission()->GetContextName() : NULL;
_AGCModule.TriggerContextEvent(hListeners, idEvent, pszContext,
"TestAGCEvents cheat", -1, -1, -1, 19,
"VT_LPWSTR" , VT_LPWSTR , L"I'm a wide string",
"VT_BSTR" , VT_BSTR , (BSTR)CComBSTR(L"I'm a BSTR"),
"VT_UNKNOWN" , VT_UNKNOWN , (IAGCVector*)spVector2,
"VT_DISPATCH", VT_DISPATCH, (IAGCVector*)spVector1,
"VT_BOOL" , VT_BOOL , VARIANT_TRUE,
"VT_I1" , VT_I1 , 0x69,
"VT_I2" , VT_I2 , 0xF00D,
"VT_UI1" , VT_UI1 , 0x96,
"VT_UI2" , VT_UI2 , 0xD00F,
"VT_ERROR" , VT_ERROR , E_NOTIMPL,
"VT_R4" , VT_R4 , 1.56f,
"VT_R8" , VT_R8 , pi,
"VT_CY" , VT_CY , cy,
"VT_DATE" , VT_DATE , date,
"Message" , VT_LPSTR , "This is just a test",
"Type" , VT_LPSTR , "Cheat!",
"Target" , VT_LPSTR , "AllSrv",
"Source" , VT_I4 , -1,
"Source Name", VT_LPSTR , "Cheater");
}
#endif else
fIsCheat = false;
return fIsCheat;
}
void HandleCOMChatEvents(const char *szMessage, const char *szDest, ShipID shipidFrom,
CFSMission * pfsMission, int iType, SoundID voiceOver, CommandID commandID)
{
const char * szSource = "Admin"; AGCUniqueID idSource = -1;
AGCUniqueID idTeam = -1;
AGCUniqueID idGame = pfsMission->GetIGCMission()->GetMissionID();
if (shipidFrom != NA)
{
CFSShip * pfsShipFrom = CFSShip::GetShipFromID(shipidFrom);
if (pfsShipFrom)
{
IshipIGC *pShipIGC = pfsShipFrom->GetIGCShip();
assert(pShipIGC);
szSource = pShipIGC->GetName();
idSource = -1;
if (pfsShipFrom->IsPlayer())
idSource = static_cast<USHORT>(CAdminUser::DetermineID(pfsShipFrom->GetPlayer())) | static_cast<DWORD>(AGC_AdminUser << 16);
idTeam = pShipIGC->GetSide()->GetUniqueID();
}
}
AGCEventID idEvent = (CHAT_ADMIN == iType) ?
EventID_AdminPage : EventID_ChatMessage;
static char* s_szChatTypes[CHAT_MAX] =
{
"EVERYONE", "LEADERS", "ADMIN", "SHIP", "TEAM", "INDIVIDUAL", "INDIVIDUAL_NOFILTER" "WING", "INDIVIDUAL_ECHO", "ALL_SECTOR", "FRIENDLY_SECTOR", "GROUP", "GROUP_NOECHO", "NOSELECTION", };
assert(sizeofArray(s_szChatTypes) == CHAT_MAX);
assert(iType >= 0 && iType < sizeofArray(s_szChatTypes));
LPCSTR pszType = s_szChatTypes[iType];
LPCSTR pszContext = pfsMission->GetIGCMission() ?
pfsMission->GetIGCMission()->GetContextName() : NULL;
_AGCModule.TriggerContextEvent(NULL, idEvent, pszContext,
szSource, idSource, idGame, idTeam, 7,
"Message" , VT_LPSTR, szMessage,
"Type" , VT_LPSTR, pszType,
"Target" , VT_LPSTR, szDest,
"GameID" , VT_I4 , idGame,
"TeamID" , VT_I4 , idTeam,
"VoiceID" , VT_I4 , voiceOver,
"CommandID" , VT_I4 , commandID);
}
bool CommandToDrone(CFSMission* pfsMission,
ChatData* pcd,
ObjectType otTarget,
ObjectID oidTarget,
const DataBuoyIGC* pdb,
CFSShip* pfsSender,
IshipIGC* pshipTo,
ImodelIGC** ppmodelTarget)
{
bool bAccepted = false;
assert (pfsSender);
IsideIGC* pside = pshipTo->GetSide();
if ((pcd->commandID != c_cidNone) &&
(pfsSender->GetIGCShip()->GetSide() == pside))
{
if (*ppmodelTarget == NULL)
{
if (pdb)
{
*ppmodelTarget = (ImodelIGC*)(pfsMission->GetIGCMission()->CreateObject(g.timeNow, OT_buoy, pdb, sizeof(*pdb)));
assert (*ppmodelTarget);
((IbuoyIGC*)*ppmodelTarget)->AddConsumer();
}
else
{
*ppmodelTarget = pfsMission->GetIGCMission()->GetModel(otTarget, oidTarget);
}
}
if ((pcd->commandID == c_cidDefault) && (*ppmodelTarget != NULL))
{
pcd->commandID = pshipTo->GetDefaultOrder(*ppmodelTarget);
}
if (pshipTo->LegalCommand(pcd->commandID, *ppmodelTarget))
{
bAccepted = true;
pfsMission->GetSite()->SendChat(pshipTo, CHAT_INDIVIDUAL, pfsSender->GetIGCShip()->GetObjectID(),
voAffirmativeSound, "Affirmative.");
if (pcd->commandID == c_cidJoin)
{
assert ((*ppmodelTarget)->GetObjectType() == OT_ship);
WingID wid = ((IshipIGC*)*ppmodelTarget)->GetWingID();
pshipTo->SetWingID(wid);
BEGIN_PFM_CREATE(g.fm, pfmWingChange, CS, SET_WINGID)
END_PFM_CREATE
pfmWingChange->shipID = pshipTo->GetObjectID();
pfmWingChange->wingID = wid;
pfmWingChange->bCommanded = true;
g.fm.SendMessages(CFSSide::FromIGC(pside)->GetGroup(), FM_GUARANTEED, FM_FLUSH);
}
else
{
pshipTo->SetCommand(c_cmdCurrent,
*ppmodelTarget,
pcd->commandID);
pshipTo->SetCommand(c_cmdAccepted,
*ppmodelTarget,
pcd->commandID);
}
}
else
{
}
}
return bAccepted;
}
void ForwardChatMessageToWing(CFSMission* pfsMission,
CFSShip* pfsSender,
FEDMESSAGE* pfm,
WingID wid,
IshipIGC* pshipSkip)
{
for (ShipLinkIGC* psl = pfsSender->GetIGCShip()->GetSide()->GetShips()->first();
(psl != NULL);
psl = psl->next())
{
IshipIGC* pship = psl->data();
if ((pship->GetWingID() == wid) && (pship != pshipSkip))
{
CFSShip* pfsShipTo = (CFSShip*)(pship->GetPrivateData());
if (pfsShipTo->IsPlayer())
{
g.fm.ForwardMessage(pfsShipTo->GetPlayer()->GetConnection(), pfm, FM_GUARANTEED);
}
}
}
}
void ForwardChatMessage(CFSMission* pfsMission,
CFSShip* pfsSender,
FEDMESSAGE* pfm,
ChatData* pcd,
const char* pszMsg,
ObjectType otTarget = NA,
ObjectID oidTarget = NA,
const DataBuoyIGC* pdb = NULL)
{
if (((pcd->commandID == c_cidNone) && (pcd->voiceOver == NA) && ((pszMsg == NULL) || (*pszMsg == '\0'))) ||
(pcd->commandID < c_cidNone) ||
(pcd->commandID >= c_cidMax))
return; if (pfsSender &&
pfsSender->IsPlayer() &&
!pfsSender->GetPlayer()->DecrementChatBudget(pcd->chatTarget != CHAT_GROUP_NOECHO))
{
return;
}
char szDestBfr[20];
const char* pszDest = "UNKNOWN";
switch (pcd->chatTarget)
{
case CHAT_EVERYONE:
{
pszDest = pfsMission->GetMissionDef()->misparms.strGameName;
if (pcd->commandID == c_cidNone)
{
g.fm.ForwardMessage(pfsMission->GetGroupMission(), pfm, FM_GUARANTEED);
}
}
break;
case CHAT_FRIENDLY_SECTOR: {
assert (pfsSender); IclusterIGC* pcluster = pfsMission->GetIGCMission()->GetCluster(pcd->oidRecipient);
if (pcluster)
{
pszDest = pcluster->GetName();
IsideIGC* pside = pfsSender->GetIGCShip()->GetSide();
for (ShipLinkIGC* psl = pcluster->GetShips()->first();
(psl != NULL);
psl = psl->next())
{
IshipIGC* pship = psl->data();
if (pship->GetSide() == pside)
{
CFSShip* pfsShipTo = (CFSShip*)(pship->GetPrivateData());
if (pfsShipTo->IsPlayer())
{
g.fm.ForwardMessage(pfsShipTo->GetPlayer()->GetConnection(), pfm, FM_GUARANTEED);
}
else
{
}
}
}
}
}
break;
case CHAT_ALL_SECTOR: {
assert (pfsSender); IclusterIGC* pcluster = pfsMission->GetIGCMission()->GetCluster(pcd->oidRecipient);
if (pcluster && (pcd->commandID == c_cidNone))
{
pszDest = pcluster->GetName();
g.fm.ForwardMessage(GetGroupSectorDocked(pcluster), pfm, FM_GUARANTEED);
g.fm.ForwardMessage(GetGroupSectorFlying(pcluster), pfm, FM_GUARANTEED);
}
}
break;
case CHAT_LEADERS:
{
pszDest = "LEADERS";
int iSide = pfsMission->GetMissionDef()->misparms.nTeams;
while (iSide-- > 0)
{
CFSPlayer* pfsLeader = pfsMission->GetLeader(iSide);
if (pfsLeader && (pcd->commandID == c_cidNone))
g.fm.ForwardMessage(pfsLeader->GetConnection(), pfm, FM_GUARANTEED);
}
}
break;
case CHAT_ADMIN:
{
pszDest = "ADMIN";
}
break;
case CHAT_SHIP:
{
pszDest = "ship";
IshipIGC* pshipSource = pfsSender->GetIGCShip()->GetSourceShip();
if (pshipSource != pfsSender->GetIGCShip())
{
CFSShip* pfsShipTo = (CFSShip*)(pshipSource->GetPrivateData());
assert (pfsShipTo->IsPlayer());
g.fm.ForwardMessage(pfsShipTo->GetPlayer()->GetConnection(), pfm, FM_GUARANTEED);
}
for (ShipLinkIGC* psl = pshipSource->GetChildShips()->first();
(psl != NULL);
psl = psl->next())
{
IshipIGC* pship = psl->data();
if (pship != pfsSender->GetIGCShip())
{
CFSShip* pfsShipTo = (CFSShip*)(pship->GetPrivateData());
assert (pfsShipTo->IsPlayer());
g.fm.ForwardMessage(pfsShipTo->GetPlayer()->GetConnection(), pfm, FM_GUARANTEED);
}
}
}
break;
case CHAT_TEAM:
{
pszDest = pfsMission->GetMissionDef()->rgszName[pcd->oidRecipient];
IsideIGC* pside = pfsMission->GetIGCMission()->GetSide(pcd->oidRecipient);
if (pside && ((pcd->commandID == c_cidNone) || (pfsSender == NULL) || (pside == pfsSender->GetSide())))
{
g.fm.ForwardMessage(CFSSide::FromIGC(pside)->GetGroup(),
pfm, FM_GUARANTEED);
}
}
break;
case CHAT_GROUP:
case CHAT_GROUP_NOECHO:
{
pcd->chatTarget = CHAT_INDIVIDUAL;
}
case CHAT_INDIVIDUAL_NOFILTER:
case CHAT_INDIVIDUAL:
{
CFSShip * pfsShipTo = CFSShip::GetShipFromID(pcd->oidRecipient);
if (pfsShipTo) {
assert(pfsShipTo->GetIGCShip());
pszDest = pfsShipTo->GetIGCShip()->GetName();
if (pfsShipTo->IsPlayer())
{
if ((pcd->commandID == c_cidNone) || (pfsSender == NULL) ||
(pfsShipTo->GetSide() == pfsSender->GetSide()))
{
CFSPlayer *pfsPlayer = pfsShipTo->GetPlayer();
assert(pfsPlayer);
g.fm.ForwardMessage(pfsPlayer->GetConnection(), pfm, FM_GUARANTEED);
}
}
else
{
ImodelIGC* pmodel = NULL;
if (CommandToDrone(pfsMission, pcd, otTarget, oidTarget, pdb, pfsSender, pfsShipTo->GetIGCShip(), &pmodel))
{
pcd->chatTarget = CHAT_INDIVIDUAL_ECHO;
ForwardChatMessageToWing(pfsMission, pfsSender, pfm, 0, pfsSender->GetIGCShip()); ForwardChatMessageToWing(pfsMission, pfsSender, pfm, 7, pfsSender->GetIGCShip()); ForwardChatMessageToWing(pfsMission, pfsSender, pfm, 8, pfsSender->GetIGCShip()); ForwardChatMessageToWing(pfsMission, pfsSender, pfm, 9, pfsSender->GetIGCShip()); }
if (pdb && pmodel)
{
assert (pmodel->GetObjectType() == OT_buoy);
((IbuoyIGC*)pmodel)->ReleaseConsumer();
pmodel->Release();
}
}
}
}
break;
case CHAT_WING:
{
pszDest = szDestBfr;
strcpy(szDestBfr, "Wing");
_itoa(pcd->oidRecipient, &szDestBfr[4], 10);
ForwardChatMessageToWing(pfsMission, pfsSender, pfm, pcd->oidRecipient, NULL);
}
break;
}
HandleCOMChatEvents(pszMsg, pszDest, pcd->sidSender, pfsMission, pcd->chatTarget, pcd->voiceOver, pcd->commandID);
}
int __cdecl CmpShipDeviation (const void *elem1, const void *elem2)
{
CFSShip * pship1 = * (CFSShip **) elem1;
CFSShip * pship2 = * (CFSShip **) elem2;
return (pship1->GetDeviation() < pship2->GetDeviation()) ? 1 : -1;
}
void AddUpdate(Time timeReference,
const Vector& positionReference,
CFSShip* pfsShip, ServerHeavyShipUpdate* pHeavy)
{
IshipIGC* pship = pfsShip->GetIGCShip();
pHeavy->shipID = pship->GetObjectID();
if (pfsShip->IsPlayer())
{
const ClientShipUpdate& su = pfsShip->GetPlayer()->GetShipUpdate();
pHeavy->time.Set(timeReference, su.time);
pHeavy->position.Set(positionReference, su.position);
pHeavy->controls = su.controls;
pHeavy->orientation = su.orientation;
pHeavy->stateM = su.stateM;
pHeavy->turnRates = su.turnRates;
pHeavy->velocity = su.velocity;
pHeavy->power = su.power;
pship->ExportFractions(&(pHeavy->fractions));
}
else
{
pship->ExportShipUpdate(timeReference, positionReference, pHeavy);
}
}
void SendShipUpdates(CFSMission * pfsMission)
{
DWORD nFrame = pfsMission->IncrementFrame();
if (nFrame % 2 == 0)
return;
{
ShipLinkIGC* pshipsFirst = pfsMission->GetIGCMission()->GetShips()->first();
for (SideLinkIGC* psidelink = pfsMission->GetIGCMission()->GetSides()->first();
(psidelink != NULL);
psidelink = psidelink->next())
{
IsideIGC* pside = psidelink->data();
assert(0 == g.fm.CbUsedSpaceInOutbox());
SideID sid = pside->GetObjectID();
for (ShipLinkIGC* pshiplink = pshipsFirst;
(pshiplink != NULL);
pshiplink = pshiplink->next())
{
IshipIGC* pship = pshiplink->data();
if (pship->GetSide()->GetObjectID() >= 0)
{
CFSShip* pfsShip = (CFSShip*)(pship->GetPrivateData());
ShipStatus* pss = pfsShip->GetShipStatus(sid);
ShipStatus* pssOld = pfsShip->GetOldShipStatus(sid);
if (*pss != *pssOld)
{
BEGIN_PFM_CREATE(g.fm, pfmShipStatus, S, SHIP_STATUS)
END_PFM_CREATE
pfmShipStatus->shipID = pship->GetObjectID();
pfmShipStatus->status = *pssOld = *pss; }
}
}
g.fm.SendMessages(CFSSide::FromIGC(pside)->GetGroup(), FM_GUARANTEED, FM_FLUSH);
}
}
const ClusterListIGC* pclstlist = pfsMission->GetIGCMission()->GetClusters();
for (ClusterLinkIGC* pcl = pfsMission->GetIGCMission()->GetClusters()->first(); (pcl != NULL); pcl = pcl->next())
{
IclusterIGC* pcluster = pcl->data();
const ShipListIGC* pshiplist = pcluster->GetShips();
const PlayerList* pplayerList = ((CFSCluster*)(pcluster->GetPrivateData()))->GetFlyingPlayers();
if ((pplayerList->n() > 0) && (pshiplist->n() > 0))
{
assert (pshiplist->n() < c_cShipsPerSectorMax);
static CFSShip* rgShips[c_cShipsPerSectorMax];
static CFSShip* rgActiveTurrets[c_cShipsPerSectorMax];
static CFSShip* rgInactiveTurrets[c_cShipsPerSectorMax];
int cShipUpdates = 0;
int cActiveTurretUpdates = 0;
int cInactiveTurretUpdates = 0;
int cShips = 0;
int cTurrets = 0;
for (ShipLinkIGC * pshiplink = pshiplist->first(); (pshiplink != NULL); pshiplink = pshiplink->next())
{
IshipIGC* pship = pshiplink->data();
CFSShip* pfsShip = (CFSShip *) pship->GetPrivateData();
assert (!pfsShip->GetHasUpdate());
if (pfsShip->IsPlayer())
{
CFSPlayer* pfsPlayer = pfsShip->GetPlayer();
unsigned char ucLastUpdate = pfsPlayer->GetLastUpdate();
if (pship->GetParentShip() == NULL)
{
cShips++;
if (ucLastUpdate == c_ucShipUpdate)
{
const ClientShipUpdate& su = pfsPlayer->GetShipUpdate();
float dt = su.time - g.timeNow;
if ((dt >= -1.5f) && (dt <= 1.5f))
{
rgShips[cShipUpdates++] = pfsShip;
pfsShip->SetHasUpdate();
}
}
}
else if (pship->GetTurretID() != NA)
{
cTurrets++;
if (ucLastUpdate == c_ucActiveTurretUpdate)
{
const ClientActiveTurretUpdate& atu = pfsPlayer->GetActiveTurretUpdate();
float dt = atu.time - g.timeNow;
if ((dt >= -1.5f) && (dt <= 1.5f))
rgActiveTurrets[cActiveTurretUpdates++] = pfsShip;
}
else if ((pship->GetStateM() & (oneWeaponIGC | allWeaponsIGC)) == 0) rgInactiveTurrets[cInactiveTurretUpdates++] = pfsShip;
}
pfsPlayer->ResetLastUpdate();
}
else
{
cShips++;
static const DWORD c_updateFrequency = 2;
float dt = pfsShip->GetIGCShip()->GetLastUpdate() - g.timeNow;
if ((dt >= -1.5f) && (dt <= 1.5f))
{
rgShips[cShipUpdates++] = pfsShip;
pfsShip->SetHasUpdate();
}
}
}
assert (cShips > 0);
if (cShipUpdates + cActiveTurretUpdates + cInactiveTurretUpdates > 0)
{
const int cbAvailable = int(1600.0f * c_dsecUpdateClient);
const int cHeavyPerInterval = 2;
const int cLightPerInterval = 2;
const int cActivePerInterval = 2;
assert (cbAvailable > cHeavyPerInterval * sizeof(ServerHeavyShipUpdate) +
cLightPerInterval * sizeof(ServerLightShipUpdate) +
cActivePerInterval * sizeof(ServerActiveTurretUpdate));
int cLightUpdates;
int cHeavyUpdates;
if (cShipUpdates <= 2)
{
cHeavyUpdates = cShipUpdates;
cLightUpdates = 0;
}
else
{
cHeavyUpdates = 2;
cLightUpdates = (cShipUpdates * cLightPerInterval) / cShips;
if (cHeavyUpdates + cLightUpdates > cShipUpdates)
cLightUpdates = cShipUpdates - cHeavyUpdates;
}
int cTurretUpdates;
if (cActiveTurretUpdates <= 1)
{
if ((cLightUpdates > 0) && (cActiveTurretUpdates == 0))
{
cHeavyUpdates++;
cLightUpdates--;
}
cTurretUpdates = cActiveTurretUpdates;
}
else
{
cTurretUpdates = (cActiveTurretUpdates == cTurrets) ? 2 : 1;
}
if (cHeavyUpdates != cShipUpdates)
{
qsort(rgShips, cShipUpdates, sizeof(rgShips[0]), CmpShipDeviation);
}
{
int effectiveHeavy = (cHeavyUpdates < cShipUpdates) ? cHeavyUpdates - 1 : cHeavyUpdates;
int effectiveLight = cHeavyUpdates +
(cHeavyUpdates + cLightUpdates < cShipUpdates)
? (cLightUpdates - 1)
: cLightUpdates;
for (int i = 0; (i < cShipUpdates); i++)
{
if (i < effectiveHeavy)
rgShips[i]->SetDeviation(0.0f);
else
{
float r = random(0.0f, 0.25f);
rgShips[i]->SetDeviation(rgShips[i]->GetDeviation() +
random(0.0f, 0.25f) +
((i < effectiveLight)
? 0.70f
: 1.00f));
}
}
}
if (cTurretUpdates < cActiveTurretUpdates)
{
qsort(rgActiveTurrets, cActiveTurretUpdates, sizeof(rgActiveTurrets[0]), CmpShipDeviation);
}
{
for (int i = 0; (i < cActiveTurretUpdates); i++)
{
if (i < cTurretUpdates)
rgActiveTurrets[i]->SetDeviation(0.0f);
else
rgActiveTurrets[i]->SetDeviation(rgActiveTurrets[i]->GetDeviation() + random(0.5f, 0.75f));
}
}
{
for (int i = 0; (i < cInactiveTurretUpdates); i++)
{
rgInactiveTurrets[i]->SetDeviation(0.0f);
}
}
#define CB_HSU_VARDATA(elems) ((elems) * sizeof(ServerHeavyShipUpdate))
#define CB_LSU_VARDATA(elems) ((elems) * sizeof(ServerLightShipUpdate))
#define CB_ATU_VARDATA(elems) ((elems) * sizeof(ServerActiveTurretUpdate))
#define CB_ITU_VARDATA(elems) ((elems) * sizeof(ShipID))
static char bfrHeavy[sizeof(FMD_S_HEAVY_SHIPS_UPDATE) +
CB_HSU_VARDATA(c_cShipsPerSectorMax) +
CB_ATU_VARDATA(c_cShipsPerSectorMax) +
sizeof(FMD_S_LIGHT_SHIPS_UPDATE) + CB_LSU_VARDATA(c_cShipsPerSectorMax) +
CB_ITU_VARDATA(c_cShipsPerSectorMax)];
static FMD_S_HEAVY_SHIPS_UPDATE* pfmHeavy = (FMD_S_HEAVY_SHIPS_UPDATE*)bfrHeavy;
pfmHeavy->fmid = FM_S_HEAVY_SHIPS_UPDATE;
pfmHeavy->timeReference = g.timeNow;
pfmHeavy->ibrgActiveTurretUpdates = sizeof(FMD_S_HEAVY_SHIPS_UPDATE);
static char bfrLight[sizeof(FMD_S_LIGHT_SHIPS_UPDATE) +
CB_LSU_VARDATA(c_cShipsPerSectorMax) +
CB_ITU_VARDATA(c_cShipsPerSectorMax)];
static FMD_S_LIGHT_SHIPS_UPDATE* pfmLight = (FMD_S_LIGHT_SHIPS_UPDATE*)bfrLight;
pfmLight->fmid = FM_S_LIGHT_SHIPS_UPDATE;
ShipID* pInactive = (ShipID*)(pfmLight + 1);
pfmLight->ibrgInactiveTurretUpdates = sizeof(FMD_S_LIGHT_SHIPS_UPDATE);
pfmLight->cbrgInactiveTurretUpdates = CB_ITU_VARDATA(cInactiveTurretUpdates);
{
for (int i = 0; (i < cInactiveTurretUpdates); i++)
{
assert (rgInactiveTurrets[i]->IsPlayer());
*(pInactive++) = rgInactiveTurrets[i]->GetShipID();
}
}
pfmLight->ibrgLightShipUpdates = pfmLight->ibrgInactiveTurretUpdates + pfmLight->cbrgInactiveTurretUpdates;
for (PlayerLink* pplayerLink = pplayerList->first(); (pplayerLink != NULL); pplayerLink = pplayerLink->next())
{
CFSPlayer* pfsPlayer = pplayerLink->data();
IshipIGC* pshipPlayer = pfsPlayer->GetIGCShip();
{
IshipIGC* pshipSource = pshipPlayer->GetSourceShip();
pshipSource->ExportFractions(&(pfmHeavy->fractions));
}
ServerActiveTurretUpdate* pActive = (ServerActiveTurretUpdate*)(pfmHeavy + 1);
{
ServerActiveTurretUpdate* pActiveMax = pActive + cTurretUpdates;
for (int i = 0; ((pActive < pActiveMax) && (i < cActiveTurretUpdates)); i++)
{
assert (i < cActiveTurretUpdates);
assert (rgActiveTurrets[i]->IsPlayer());
CFSShip* pfsShip = rgActiveTurrets[i];
if (pfsShip != pfsPlayer)
{
const ClientActiveTurretUpdate& atu = pfsShip->GetPlayer()->GetActiveTurretUpdate();
pActive->time.Set(g.timeNow, atu.time);
pActive->controls = atu.controls;
pActive->orientation = atu.orientation;
(pActive++)->shipID = pfsShip->GetShipID();
}
}
}
pfmHeavy->cbrgActiveTurretUpdates = short((DWORD)pActive - (DWORD)(pfmHeavy + 1));
pfmHeavy->ibrgHeavyShipUpdates = pfmHeavy->ibrgActiveTurretUpdates + pfmHeavy->cbrgActiveTurretUpdates;
IshipIGC* pshipTarget = NULL;
CFSShip* pfsTarget;
{
pfmHeavy->bpTargetHull.SetChar(255);
ImodelIGC* pmodelTarget = pshipPlayer->GetCommandTarget(c_cmdCurrent);
if (pmodelTarget && (pmodelTarget->GetCluster() == pcluster))
{
switch (pmodelTarget->GetObjectType())
{
case OT_ship:
{
IshipIGC* pship = ((IshipIGC*)pmodelTarget)->GetSourceShip();
if (pship != pshipPlayer)
{
assert (pship->GetParentShip() == NULL);
pfmHeavy->bpTargetHull = pship->GetFraction();
{
IshieldIGC* pshield = (IshieldIGC*)(pship->GetMountedPart(ET_Shield, 0));
if (pshield)
pfmHeavy->bpTargetShield = pshield->GetFraction();
}
pfsTarget = (CFSShip*)(pship->GetPrivateData());
if (pfsTarget->GetHasUpdate())
pshipTarget = pship;
}
}
break;
case OT_station:
{
IstationIGC* pstation = (IstationIGC*)pmodelTarget;
pfmHeavy->bpTargetHull = pstation->GetFraction();
pfmHeavy->bpTargetShield = pstation->GetShieldFraction();
}
break;
case OT_probe:
case OT_asteroid:
case OT_missile:
{
pfmHeavy->bpTargetHull = ((IdamageIGC*)pmodelTarget)->GetFraction();
}
}
}
}
{
IshipIGC* pshipSource = pshipPlayer->GetSourceShip();
pfmHeavy->positionReference = (pshipSource->GetCluster() == pcluster)
? pshipSource->GetPosition()
: Vector::GetZero();
}
ServerHeavyShipUpdate* pHeavy = (ServerHeavyShipUpdate*)pActive;
ServerLightShipUpdate* pLight = (ServerLightShipUpdate*)pInactive;
{
ServerHeavyShipUpdate* pHeavyMax = pHeavy + cHeavyUpdates;
ServerLightShipUpdate* pLightMax = pLight + cLightUpdates;
if (pshipTarget)
{
assert (cHeavyUpdates > 0);
AddUpdate(g.timeNow, pfmHeavy->positionReference,
pfsTarget, pHeavy++);
}
for (int index = 0; (index < cShipUpdates); index++)
{
CFSShip* pfsShip = rgShips[index];
if (pfsShip != pfsPlayer)
{
IshipIGC* pship = pfsShip->GetIGCShip();
if (pship != pshipTarget)
{
if (pHeavy < pHeavyMax)
{
AddUpdate(g.timeNow, pfmHeavy->positionReference, pfsShip, pHeavy++);
}
else if (pLight < pLightMax)
{
pship->ExportShipUpdate(pLight++);
}
else
break;
}
}
}
}
pfmLight->cbrgLightShipUpdates = short((DWORD)pLight - (DWORD)pInactive);
pfmHeavy->cbrgHeavyShipUpdates = short((DWORD)pHeavy - (DWORD)pActive);
pfmLight->cbmsg = sizeof(FMD_S_LIGHT_SHIPS_UPDATE) + pfmLight->cbrgInactiveTurretUpdates + pfmLight->cbrgLightShipUpdates;
pfmHeavy->cbmsg = sizeof(FMD_S_HEAVY_SHIPS_UPDATE) + pfmHeavy->cbrgActiveTurretUpdates + pfmHeavy->cbrgHeavyShipUpdates;
if ((pfmHeavy->cbmsg != sizeof(FMD_S_HEAVY_SHIPS_UPDATE)) || (pshipPlayer->GetCluster() != NULL))
{
CB cbMsg = pfmHeavy->cbmsg;
if (pfmLight->cbmsg != sizeof(FMD_S_LIGHT_SHIPS_UPDATE))
{
memcpy(((char*)pfmHeavy) + cbMsg, pfmLight, pfmLight->cbmsg);
cbMsg += pfmLight->cbmsg;
}
g.fm.GenericSend(pfsPlayer->GetConnection(), pfmHeavy, cbMsg, FM_NOT_GUARANTEED);
}
else if (pfmLight->cbmsg != sizeof(FMD_S_LIGHT_SHIPS_UPDATE))
{
g.fm.ForwardMessage(pfsPlayer->GetConnection(), pfmLight, FM_NOT_GUARANTEED);
}
}
for (int i = 0; (i < cShipUpdates); i++)
{
assert (rgShips[i]->GetHasUpdate());
rgShips[i]->ClearHasUpdate();
}
}
}
}
if (NULL != g.pServerCounters)
{
g.pServerCounters->csecAvgUpdateLatency = CFSPlayer::GetAverageLatency();
g.pServerCounters->csecMaxUpdateLatency = CFSPlayer::GetMaxLatency();
}
#undef SUVARDATASIZE
}
DWORD MoveShips(CFSMission * pfsMission, Time timeNow, Time timeLastUpdate)
{
static CTempTimer timerMoveShips("in MoveShips", .1f);
timerMoveShips.Start();
if (pfsMission->GetStage() == STAGE_STARTED)
{
static CTempTimer timerSendShipUpdates("in SendShipUpdates", .1f);
timerSendShipUpdates.Start();
SendShipUpdates(pfsMission);
timerSendShipUpdates.Stop();
}
static CTempTimer timerMissionUpdate("in ImissionIGC->Update", .15f);
timerMissionUpdate.Start();
pfsMission->GetIGCMission()->Update(timeNow);
timerMissionUpdate.Stop();
timerMoveShips.Stop();
return 0;
}
ItreasureIGC* CreateTreasure(Time now, IshipIGC* pship, DataTreasureIGC* pdt, const Vector& position, float dv)
{
assert (pship);
assert (dv > 1.0f);
pdt->objectID = pship->GetMission()->GenerateNewTreasureID();
pdt->p0 = position;
Vector direction = Vector::RandomDirection();
float radius = pship->GetRadius() + 10.0f;
pdt->p0 += radius * direction;
pdt->v0 = direction * dv + pship->GetVelocity();
IclusterIGC* pcluster = pship->GetCluster();
pdt->clusterID = pcluster->GetObjectID();
pdt->time0 = now;
ItreasureIGC* t = (ItreasureIGC *)
pship->GetMission()->CreateObject(now, OT_treasure,
pdt, sizeof(*pdt));
assert (t);
t->Release();
return t;
}
ItreasureIGC* CreateTreasure(Time now, IshipIGC* pship, short amount, IpartTypeIGC* ppt, const Vector& position, float dv, float lifespan = 600.0f)
{
assert (pship);
assert (ppt);
assert (dv > 1.0f);
DataTreasureIGC dt;
dt.treasureCode = c_tcPart;
dt.treasureID = ppt->GetObjectID();
dt.lifespan = lifespan;
dt.amount = amount;
dt.createNow = false;
return CreateTreasure(now, pship, &dt, position, dv);
}
ItreasureIGC* CreateTreasure(Time now, IshipIGC* pship, IpartIGC* p, IpartTypeIGC* ppt, const Vector& position, float dv, float lifespan = 600.0f)
{
assert (p);
short amount;
switch (p->GetObjectType())
{
case OT_magazine:
case OT_dispenser:
case OT_pack:
{
amount = p->GetAmount();
if (amount == 0)
return NULL;
}
break;
default:
amount = 0;
}
return CreateTreasure(now, pship, amount, ppt, position, dv, lifespan);
}
void ExportStaticIGCObjs()
{
{
const StationTypeListIGC * pstlist = g.trekCore->GetStationTypes();
StationTypeLinkIGC * pstlink = NULL;
for (pstlink = pstlist->first(); pstlink; pstlink = pstlink->next())
ExportObj(pstlink->data(), OT_stationType, NULL);
}
{
const ProjectileTypeListIGC * pptlist = g.trekCore->GetProjectileTypes();
ProjectileTypeLinkIGC * pptlink = NULL;
for (pptlink = pptlist->first(); pptlink; pptlink = pptlink->next())
ExportObj(pptlink->data(), OT_projectileType, NULL);
}
{
const ExpendableTypeListIGC* petlist = g.trekCore->GetExpendableTypes();
ExpendableTypeLinkIGC* petlink;
for (petlink = petlist->first(); petlink; petlink = petlink->next())
ExportObj(petlink->data(), petlink->data()->GetObjectType(), NULL);
}
{
const PartTypeListIGC * pptlist = g.trekCore->GetPartTypes();
PartTypeLinkIGC * pptlink = NULL;
for (pptlink = pptlist->first(); pptlink; pptlink = pptlink->next())
ExportObj(pptlink->data(), OT_partType, NULL);
}
{
const HullTypeListIGC * phtlist = g.trekCore->GetHullTypes();
HullTypeLinkIGC * phtlink = NULL;
for (phtlink = phtlist->first(); phtlink; phtlink = phtlink->next())
ExportObj(phtlink->data(), OT_hullType, NULL);
}
{
const DevelopmentListIGC * pdtlist = g.trekCore->GetDevelopments();
DevelopmentLinkIGC * pdtlink = NULL;
for (pdtlink = pdtlist->first(); pdtlink; pdtlink = pdtlink->next())
ExportObj(pdtlink->data(), OT_development, NULL);
}
{
const DroneTypeListIGC * pdtlist = g.trekCore->GetDroneTypes();
DroneTypeLinkIGC * pdtlink = NULL;
for (pdtlink = pdtlist->first(); pdtlink; pdtlink = pdtlink->next())
ExportObj(pdtlink->data(), OT_droneType, NULL);
}
{
const CivilizationListIGC * pctlist = g.trekCore->GetCivilizations();
CivilizationLinkIGC * pctlink = NULL;
for (pctlink = pctlist->first(); pctlink; pctlink = pctlink->next())
ExportObj(pctlink->data(), OT_civilization, NULL);
}
}
int FedSrvSiteBase::OnMessageBox(FedMessaging * pthis, const char * strText, const char * strCaption, UINT nType)
{
return OnMessageBox(strText, strCaption, nType);
}
int FedSrvSiteBase::OnMessageBox(const char * strText, const char * strCaption, UINT nType)
{
printf("%s:\n%s\n\n", strCaption, strText);
_AGCModule.TriggerEvent(NULL, AllsrvEventID_MessageBox, "", -1, -1, -1, 2,
"Caption", VT_LPSTR, strCaption,
"Message", VT_LPSTR, strText);
return 0; }
HRESULT FedSrvSiteBase::OnSysMessage(FedMessaging * pthis)
{
if (g.pServerCounters)
{
g.pServerCounters->cSysMessagesIn++;
g.pServerCounters->cSysMessagesInPerSecond++;
}
return S_OK;
}
void FedSrvSiteBase::OnSQLErrorRecord(SSERRORINFO * perror, OLECHAR * postrError)
{
_AGCModule.TriggerEvent(NULL, AllsrvEventID_DatabaseErrorSQL, "", -1, -1, -1, 5,
"Message" , VT_LPWSTR, perror->pwszMessage,
"Procedure" , VT_LPWSTR, perror->pwszProcedure,
"Native" , VT_I4, perror->lNative,
"Line" , VT_I2, perror->wLineNumber,
"OleDB" , VT_LPWSTR, postrError);
}
void FedSrvSiteBase::OnOLEDBErrorRecord(BSTR bstrDescription, GUID guid, DWORD dwHelpContext,
BSTR bstrHelpFile, BSTR bstrSource)
{
OLECHAR szGUID[48];
StringFromGUID2(guid, szGUID, sizeofArray(szGUID));
_AGCModule.TriggerEvent(NULL, AllsrvEventID_DatabaseErrorOLEDB, "", -1, -1, -1, 5,
"Desc", VT_BSTR, bstrDescription,
"Guid", VT_LPWSTR,szGUID,
"HelpID", VT_I4, dwHelpContext,
"HelpFile", VT_BSTR, bstrHelpFile,
"Source", VT_BSTR, bstrSource);
}
HRESULT FedSrvSiteBase::OnNewConnection(FedMessaging * pthis, CFMConnection & cnxn)
{
return S_OK;
}
HRESULT FedSrvSiteBase::OnDestroyConnection(FedMessaging * pthis, CFMConnection & cnxn)
{
CFSPlayer * pfsPlayer = CFSPlayer::GetPlayerFromConnection(cnxn);
if (pfsPlayer) {
PlaySound("AppGPFault", NULL, SND_ALIAS | SND_PURGE | SND_ASYNC);
_AGCModule.TriggerEvent(NULL, AllsrvEventID_PlayerDropped, "", -1, -1, -1, 2,
"PlayerName", VT_LPSTR, pfsPlayer->GetName(),
"ConxID", VT_I4, cnxn.GetID());
if (NULL != g.pServerCounters)
{
g.pServerCounters->cTimeouts++;
g.pServerCounters->cTimeoutsPerSecond++;
}
delete pfsPlayer;
}
return S_OK;
}
HRESULT FedSrvSiteBase::OnSessionLost(FedMessaging * pthis)
{
_AGCModule.TriggerEvent(NULL, AllsrvEventID_SessionLost, "", -1, -1, -1, 1,
"Time", VT_I4, Time::Now().clock());
return S_OK;
}
#ifndef NO_MSG_CRC
void FedSrvSiteBase::OnBadCRC(FedMessaging * pthis, CFMConnection & cnxn, BYTE * pMsg, DWORD cbMsg)
{
char buf[256];
FEDMESSAGE * pfm = (FEDMESSAGE *) pMsg;
wsprintf(buf, "HEY! We got a corrupt message!\nPlayer=%s(%d), "
"cbmsg=%d, fmid=%d, total packet size=%d.\n"
"Copy the above line to crashplayers.txt on \\\\zoneagga01. Going to drop player now.\n",
cnxn.GetName(), cnxn.GetID(),
cbMsg >= 2 ? pfm->cbmsg : 0, cbMsg >= 4 ? pfm->fmid : 0, cbMsg);
OnMessageBox(buf, "Allegiance", 0);
pthis->DeleteConnection(cnxn); }
#endif
void FedSrvSiteBase::OnMessageSent(FedMessaging * pthis, CFMRecipient * precip, const void * pv, DWORD cb, FMGuaranteed fmg)
{
int cConnections = precip->GetCountConnections();
assert (cConnections >= 0);
DWORD dwBytes = cb * cConnections;
FEDMESSAGE * pfm = (FEDMESSAGE*)pv;
if (FM_GUARANTEED == fmg)
{
if (FM_CS_ORDER_CHANGE == pfm->fmid)
{
CASTPFM(pfmOrderChange, CS, ORDER_CHANGE, pfm);
#ifdef DEBUG
debugf("FM_CS_ORDER_CHANGE: shipID=%d, objectID=%d, objectType=%d, commandID=%d, command=%d.\n",
pfmOrderChange->shipID, pfmOrderChange->objectID, pfmOrderChange->objectType,
pfmOrderChange->commandID, pfmOrderChange->command);
#endif
}
g.pServerCounters->cPacketsOut += cConnections;
g.pServerCounters->cPacketsOutPerSecond += cConnections;
g.pServerCounters->cBytesOut += dwBytes;
g.pServerCounters->cBytesOutPerSecond += dwBytes;
}
else if (FM_NOT_GUARANTEED == fmg)
{
}
}
#define TrapHackLog(x) {if (!(x)) { LogTrapHack(EventID_HackLog , pfsPlayer, &cnxnFrom, #x, __LINE__); break; }}
#define TrapHackBoot(x) {if (!(x)) { LogTrapHack(EventID_HackBoot , pfsPlayer, &cnxnFrom, #x, __LINE__); break; }}
#define TrapHackBootNoPlayer(x) {if (!(x)) { LogTrapHack(EventID_HackBootNoPlayer, NULL, &cnxnFrom, #x, __LINE__); break; }}
static bool DisplaceProbe(ImodelIGC* pmodel, Vector* position, float r)
{
Vector dxy = *position - pmodel->GetPosition();
float l2 = dxy.LengthSquared();
float rOffset = pmodel->GetRadius() + r;
if ((l2 < rOffset * rOffset) && (l2 != 0.0f))
{
*position = pmodel->GetPosition() + dxy * (rOffset / (float)sqrt(l2));
return true;
}
return false;
}
static void DisplaceProbe(IclusterIGC* pcluster, Vector* position, float r)
{
{
for (StationLinkIGC* psl = pcluster->GetStations()->first(); (psl != NULL); psl = psl->next())
{
if (DisplaceProbe(psl->data(), position, r))
return;
}
}
{
for (WarpLinkIGC* psl = pcluster->GetWarps()->first(); (psl != NULL); psl = psl->next())
{
if (DisplaceProbe(psl->data(), position, r))
return;
}
}
{
for (AsteroidLinkIGC* psl = pcluster->GetAsteroids()->first(); (psl != NULL); psl = psl->next())
{
if (DisplaceProbe(psl->data(), position, r))
return;
}
}
}
HRESULT FedSrvSiteBase::OnAppMessage(FedMessaging * pthis, CFMConnection & cnxnFrom, FEDMESSAGE * pfm)
{
CFSPlayer * pfsPlayer = NULL;
CFSMission * pfsMission = NULL;
ImissionIGC * pMission = NULL;
HRESULT hr = S_OK;
static CTempTimer timerOnAppMessage("in OnAppMessage", .02f);
static CTempTimer ttPreHandler("in OnAppMessage (before we actually switch)", .01f);
ttPreHandler.Start();
timerOnAppMessage.Start();
if (NULL != g.pServerCounters)
{
g.pServerCounters->cPacketsIn++;
g.pServerCounters->cPacketsInPerSecond++;
g.pServerCounters->cBytesIn += pfm->cbmsg;
g.pServerCounters->cBytesInPerSecond += pfm->cbmsg;
static Time timeLastQueueCheck = 0;
if (g.timeNow - timeLastQueueCheck > 1.0f)
{
g.fm.GetSendQueue(&(g.pServerCounters->cOutboundQueueLength),
&(g.pServerCounters->cOutboundQueueSize));
g.fm.GetReceiveQueue(&(g.pServerCounters->cInboundQueueLength),
&(g.pServerCounters->cInboundQueueSize));
timeLastQueueCheck = g.timeNow;
}
}
pfsPlayer = CFSPlayer::GetPlayerFromConnection(cnxnFrom);
if (pfsPlayer)
{
assert (pfm->fmid != FM_C_LOGONREQ); cnxnFrom.ResetAbsentCount();
pfsMission = pfsPlayer->GetMission();
if (pfsMission)
pMission = pfsMission->GetIGCMission();
}
ttPreHandler.Stop("...for message type %s from %s", g_rgszMsgNames[pfm->fmid],
pfsPlayer ? pfsPlayer->GetName() : "<unknown>");
if (!pfsPlayer && (pfm->fmid != FM_C_LOGONREQ))
{
_AGCModule.TriggerEvent(NULL, AllsrvEventID_MsgFromUnknownPlayer, "", -1, -1, -1, 2,
"PlayerID", VT_I4, cnxnFrom.GetID(),
"MsgName", VT_LPSTR, g_rgszMsgNames[pfm->fmid]);
}
else
switch(pfm->fmid)
{
case FM_C_SHIP_UPDATE:
{
CASTPFM(pfmShipUpdate, C, SHIP_UPDATE, pfm);
if (pfsPlayer->GetCookie() == pfmShipUpdate->cookie)
{
IshipIGC * pship = pfsPlayer->GetIGCShip();
if (pship->GetCluster() && (pship->GetParentShip() == NULL))
{
assert (pship->GetBaseHullType());
pfsPlayer->SetShipUpdate(pfmShipUpdate->shipupdate);
}
}
}
break;
case FM_C_ACTIVE_TURRET_UPDATE:
{
CASTPFM(pfmATU, C, ACTIVE_TURRET_UPDATE, pfm);
IshipIGC * pship = pfsPlayer->GetIGCShip();
if (pship->GetCluster() &&
(pship->GetParentShip() != NULL) &&
(pship->GetTurretID() != NA))
{
pfsPlayer->SetActiveTurretUpdate(pfmATU->atu);
}
}
break;
case FM_C_INACTIVE_TURRET_UPDATE:
{
CASTPFM(pfmITU, C, INACTIVE_TURRET_UPDATE, pfm);
IshipIGC * pship = pfsPlayer->GetIGCShip();
if (pship->GetCluster() &&
(pship->GetParentShip() != NULL) &&
(pship->GetTurretID() != NA))
{
pfsPlayer->SetInactiveTurretUpdate();
}
}
break;
case FM_CS_PING:
{
CASTPFM(pfmPing, CS, PING, pfm);
pfmPing->timeServer = g.timeNow;
g.fm.ForwardMessage(pfsPlayer->GetConnection(), pfmPing, pfmPing->fmg);
break;
}
case FM_CS_CHATMESSAGE:
{
bool bForward = true;
CASTPFM(pfmChat, CS, CHATMESSAGE, pfm);
if (!pfsMission)
break;
TrapHackBoot(pfmChat->cbMessage >= 0);
TrapHackBoot(pfmChat->ibMessage == sizeof(FMD_CS_CHATMESSAGE));
if (pfmChat->cbMessage > 0)
{
if (pfsPlayer->CanCheat() &&
DoCheatCode(pfsPlayer, FM_VAR_REF(pfmChat, Message)))
{
if (!lstrcmpi(FM_VAR_REF(pfmChat, Message), "bootme"))
break;
bForward = false;
}
else
{
if (pfmChat->cbMessage > 5 && pfsMission->GetOwner() == pfsPlayer)
{
if (_strnicmp(FM_VAR_REF(pfmChat, Message), "#ban ", 5) == 0)
{
for (ShipLinkIGC* psl = pfsMission->GetIGCMission()->GetShips()->first(); (psl != NULL); psl = psl->next())
{
CFSShip* pfsShip = (CFSShip*)(psl->data()->GetPrivateData());
if (pfsShip->IsPlayer() && (_stricmp(FM_VAR_REF(pfmChat, Message) + 5, psl->data()->GetName()) == 0))
{
if (pfsShip->GetSide()->GetObjectID() < 0)
{
debugf("#ban: %s banned by %s\n", pfsShip->GetName(), pfsPlayer->GetName());
LPCSTR pszContext = pfsMission->GetIGCMission()->GetContextName();
_AGCModule.TriggerContextEvent(NULL, EventID_LogoutGame, pszContext, pfsShip->GetName(),
pfsShip->GetShipID(), -1, -1, 3, "GameID", VT_I4, pfsMission->GetMissionID(),
"GameName", VT_LPSTR, pfsMission->GetIGCMission()->GetMissionParams()->strGameName,
"zBooter", VT_LPSTR, pfsPlayer->GetName());
pfsMission->RemovePlayerFromMission(pfsShip->GetPlayer(), QSR_OwnerBooted);
pfmChat->cd.chatTarget = CHAT_EVERYONE;
pfmChat->cd.oidRecipient = NA;
break;
}
}
}
bForward = false;
}
}
if ((pfsPlayer->GetSide()->GetObjectID() >= 0) && (pfsMission->GetStage() == STAGE_STARTED))
{
if (pfmChat->cbMessage > strlen("#resign") && _strnicmp(FM_VAR_REF(pfmChat, Message), "#resign", strlen("#resign")) == 0)
{
if (!pfsMission->HasBallots(BALLOT_RESIGN))
pfsMission->AddBallot(new ResignBallot(pfsPlayer));
else pfsMission->GetSite()->SendChatf(NULL, CHAT_INDIVIDUAL_NOFILTER, pfsPlayer->GetIGCShip()->GetObjectID(),
NA, "Resign vote already in progress...");
bForward = false;
}
else if (pfmChat->cbMessage > strlen("#draw") && _strnicmp(FM_VAR_REF(pfmChat, Message), "#draw", strlen("#draw")) == 0)
{
if (!pfsMission->HasBallots(BALLOT_OFFERDRAW))
pfsMission->AddBallot(new OfferDrawBallot(pfsPlayer));
else pfsMission->GetSite()->SendChatf(NULL, CHAT_INDIVIDUAL_NOFILTER, pfsPlayer->GetIGCShip()->GetObjectID(),
NA, "Draw vote already in progress...");
bForward = false;
}
else if (pfmChat->cbMessage > strlen("#mutiny") && _strnicmp(FM_VAR_REF(pfmChat, Message), "#mutiny", strlen("#mutiny")) == 0)
{
if (pfsMission->GetLeader(pfsPlayer->GetSide()->GetObjectID()) != pfsPlayer)
if (!pfsMission->HasBallots(BALLOT_MUTINY))
pfsMission->AddBallot(new MutinyBallot(pfsPlayer));
else pfsMission->GetSite()->SendChatf(NULL, CHAT_INDIVIDUAL_NOFILTER, pfsPlayer->GetIGCShip()->GetObjectID(),
NA, "Mutiny vote already in progress...");
bForward = false;
}
else if(pfsMission->GetLeader(pfsPlayer->GetSide()->GetObjectID()) == pfsPlayer && pfmChat->cbMessage > strlen("#autoaccept") && _strnicmp(FM_VAR_REF(pfmChat, Message), "#autoaccept", strlen("#autoaccept")) == 0)
{
pfsMission->SetAutoAccept(pfsPlayer->GetSide(),!pfsMission->GetAutoAccept(pfsPlayer->GetSide()));
bForward = true;
}
else if(pfsMission->GetOwner() == pfsPlayer && pfmChat->cbMessage > strlen("#autobalance ") && _strnicmp(FM_VAR_REF(pfmChat, Message), "#autobalance", strlen("#autobalance")) == 0)
{
if (_strnicmp(FM_VAR_REF(pfmChat, Message), "#autobalance 1", strlen("#autobalance 1")) == 0)
pfsMission->SetMaxTeamImbalance(1);
if (_strnicmp(FM_VAR_REF(pfmChat, Message), "#autobalance 2", strlen("#autobalance 2")) == 0)
pfsMission->SetMaxTeamImbalance(2);
if (_strnicmp(FM_VAR_REF(pfmChat, Message), "#autobalance a", strlen("#autobalance a")) == 0)
pfsMission->SetMaxTeamImbalance(0x7ffe);
if (_strnicmp(FM_VAR_REF(pfmChat, Message), "#autobalance n", strlen("#autobalance n")) == 0)
pfsMission->SetMaxTeamImbalance(0x7fff);
pfmChat->cd.chatTarget = CHAT_EVERYONE;
pfmChat->cd.oidRecipient = NA;
bForward = true;
}
else if(pfmChat->cbMessage > strlen("#list") && _strnicmp(FM_VAR_REF(pfmChat, Message), "#list", strlen("#list")) == 0)
{
pfsMission->GetSite()->SendChatf(NULL, CHAT_INDIVIDUAL_NOFILTER, pfsPlayer->GetIGCShip()->GetObjectID(),
NA, "#draw | #resign | #autoaccept | #autobalance [1|2|a|n] | #ban | #mutiny");
bForward = false;
}
}
#ifdef FAZBETA
else
{
if (pfsMission->GetOwner() == pfsPlayer && (_strnicmp(FM_VAR_REF(pfmChat, Message), "#start", strlen("#start")) == 0))
{
CFSMission * pfsMission = pfsPlayer->GetMission();
if (STAGE_NOTSTARTED == pfsMission->GetStage() || STAGE_STARTING == pfsMission->GetStage())
pfsMission->StartCountdown(15);
}
}
#endif
}
}
pfmChat->cd.sidSender = pfsPlayer->GetIGCShip()->GetObjectID();
char* pszMsg = FM_VAR_REF(pfmChat, Message);
#if !defined(ALLSRV_STANDALONE)
if (pszMsg && (0 == _strnicmp("icq,", pszMsg, 4)))
{
char * szName = pszMsg + 4;
char * szColon = szName;
while (*szColon && (':' != *szColon)) szColon++;
if (*szColon)
{
*szColon = '\0';
lstrcpyn((char *)GetICQID_CharName, szName, sizeof(GetICQID_CharName));
SQL_GO(GetICQID);
SQLRETURN sqlret = SQL_GETROW(GetICQID);
if (*(++szColon) && SQL_SUCCESS == sqlret && GetICQID_ID != -1)
{
BEGIN_PFM_CREATE(g.fm, pfmICQChat, S, ICQ_CHAT_ACK)
FM_VAR_PARM(szColon, CB_ZTS)
END_PFM_CREATE
pfmICQChat->icqid = GetICQID_ID;
g.fm.SendMessages(pfsPlayer->GetConnection(), FM_GUARANTEED, FM_FLUSH);
bForward = false;
}
}
}
#endif if (bForward)
ForwardChatMessage(pfsMission, pfsPlayer, pfm,
&(pfmChat->cd),
pszMsg,
pfmChat->otTarget,
pfmChat->oidTarget,
NULL);
}
break;
case FM_CS_CHATBUOY:
{
if (!pfsMission || (pfsMission->GetStage() != STAGE_STARTED))
break;
CASTPFM(pfmBuoy, CS, CHATBUOY, pfm);
pfmBuoy->cd.sidSender = pfsPlayer->GetIGCShip()->GetObjectID();
ForwardChatMessage(pfsMission, pfsPlayer, pfm,
&(pfmBuoy->cd),
FM_VAR_REF(pfmBuoy, Message),
OT_buoy,
NA,
&(pfmBuoy->db));
break;
}
case FM_CS_SET_WINGID:
{
if (!pfsMission)
break;
IsideIGC* pside = pfsPlayer->GetSide();
if (pside->GetObjectID() < 0)
break;
CASTPFM(pfmSW, CS, SET_WINGID, pfm);
TrapHackBoot(pfmSW->wingID >= 0);
TrapHackBoot(pfmSW->wingID < c_widMax);
CFSShip* pfsShip = CFSShip::GetShipFromID(pfmSW->shipID);
if (pfsShip)
{
if (pfsShip != pfsPlayer)
{
if ((pfsShip->GetSide() != pside) ||
(pfsPlayer != pfsMission->GetLeader(pside->GetObjectID())))
{
break;
}
pfmSW->bCommanded = true;
}
else
pfmSW->bCommanded = false; g.fm.ForwardMessage(CFSSide::FromIGC(pside)->GetGroup(), pfmSW, FM_GUARANTEED);
pfsShip->GetIGCShip()->SetWingID(pfmSW->wingID);
}
}
break;
case FM_C_VOTE:
{
if (!pfsMission || pfsPlayer->GetSide()->GetObjectID() < 0)
break;
CASTPFM(pfmVote, C, VOTE, pfm);
pfsMission->TallyVote(pfsPlayer, pfmVote->ballotID, pfmVote->bAgree);
}
break;
case FM_CS_REQUEST_MONEY:
{
if (!pfsMission || (pfsMission->GetStage() != STAGE_STARTED))
break;
CASTPFM(pfmRequest, CS, REQUEST_MONEY, pfm);
TrapHackBoot(pfmRequest->amount > 0);
if (!pfsPlayer->DecrementChatBudget(true))
{
break;
}
IshipIGC* pshipAD = pfsPlayer->GetIGCShip()->GetAutoDonate();
if ((!pshipAD) || (((CFSShip*)(pshipAD->GetPrivateData()))->GetMoney() < pfmRequest->amount))
{
Money moneyMax = pfmRequest->amount - 1;
IsideIGC* pside = pfsPlayer->GetSide();
for (ShipLinkIGC* psl = pside->GetShips()->first(); (psl != NULL); psl = psl->next())
{
IshipIGC* pship = psl->data();
if (pship != pfsPlayer->GetIGCShip())
{
CFSShip* pfsship = (CFSShip*)(pship->GetPrivateData());
if (pfsship->GetMoney() > moneyMax)
{
moneyMax = pfsship->GetMoney();
pshipAD = pship;
}
}
}
}
if (pshipAD)
{
pfmRequest->shipidRequest = pfsPlayer->GetShipID();
CFSShip* pfsAD = (CFSShip*)(pshipAD->GetPrivateData());
g.fm.ForwardMessage(pfsAD->GetPlayer()->GetConnection(), pfmRequest, FM_GUARANTEED);
}
}
break;
case FM_CS_FIRE_MISSILE:
{
if (!pfsMission || (pfsMission->GetStage() != STAGE_STARTED))
break;
CASTPFM(pfmFireMissile, CS, FIRE_MISSILE, pfm);
DataMissileIGC dm;
dm.pLauncher = pfsPlayer->GetIGCShip();
TrapHackBoot(dm.pLauncher->GetParentShip() == NULL);
ImagazineIGC* pmagazine = (ImagazineIGC*)(dm.pLauncher->GetMountedPart(ET_Magazine, 0));
if (pmagazine)
{
TrapHackBoot(pmagazine->GetAmount() > 0);
IclusterIGC* pcluster = pfsPlayer->GetCluster();
if ((!pcluster) || (pcluster->GetObjectID() != pfmFireMissile->clusterID))
pcluster = pMission->GetCluster(pfmFireMissile->clusterID);
TrapHackBoot (pcluster);
Time timeFudge = pfmFireMissile->timeFired + 0.5f;
pfmFireMissile->bDud = (timeFudge < pmagazine->GetTimeLoaded());
{
if (pfmFireMissile->bDud)
debugf("dud missile %d %d %d\n", timeFudge.clock(), pmagazine->GetTimeLoaded().clock());
}
pfmFireMissile->launcherID = pfsPlayer->GetShipID();
dm.pmissiletype = pmagazine->GetMissileType();
assert (dm.pmissiletype);
int iNumMissiles = pfmFireMissile->cbmissileLaunchData / sizeof(MissileLaunchData);
MissileLaunchData* pMissileLaunchData = (MissileLaunchData*) (FM_VAR_REF(pfmFireMissile, missileLaunchData));
pfmFireMissile->missiletypeID = dm.pmissiletype->GetObjectID();
const Orientation& myOrientation = dm.pLauncher->GetOrientation();
Vector position = dm.pLauncher->GetPosition() + (pmagazine->GetEmissionPt() * myOrientation);
const Vector& myVelocity = dm.pLauncher->GetVelocity();
Vector velocity = myVelocity - dm.pmissiletype->GetInitialSpeed() * myOrientation.GetBackward();
if (pfmFireMissile->targetType == NA)
dm.pTarget = NULL;
else
{
dm.pTarget = pMission->GetModel(pfmFireMissile->targetType, pfmFireMissile->targetID);
if (dm.pTarget &&
((dm.pTarget->GetCluster() != pcluster) ||
!pfsPlayer->GetIGCShip()->CanSee(dm.pTarget)))
dm.pTarget = NULL;
}
dm.pCluster = pcluster;
dm.lock = pfmFireMissile->lock;
for (int i = 0; i < iNumMissiles; i++)
{
{
Vector d = position - pMissileLaunchData[i].vecPosition;
float d2 = d * d;
if (d2 > 20.0f) debugf("missile position error %f %s\n", d2, pfsPlayer->GetName());
if ((d2 < 0.0f) || (d2 > 200.0f * 200.0f))
pMissileLaunchData[i].vecPosition = position;
}
{
Vector d = velocity - pMissileLaunchData[i].vecVelocity;
float d2 = d * d;
if (d2 > 20.0f) debugf("missile velocity error %f\n", d2);
if ((d2 < 0.0f) || (d2 > 100.0f * 100.0f))
pMissileLaunchData[i].vecVelocity = velocity;
}
{
float d2 = pMissileLaunchData[i].vecForward * pMissileLaunchData[i].vecForward;
if ((d2 < 0.95f * 0.95f) || (d2 > 1.05f * 1.05f))
pMissileLaunchData[i].vecForward = myOrientation.GetForward();
}
dm.position = pMissileLaunchData[i].vecPosition;
dm.velocity = pMissileLaunchData[i].vecVelocity;
dm.forward = pMissileLaunchData[i].vecForward;
dm.missileID = pMissileLaunchData[i].missileID = pMission->GenerateNewMissileID ();
dm.bDud = pfmFireMissile->bDud;
ImissileIGC * m = (ImissileIGC*)(pMission->CreateObject(pfmFireMissile->timeFired + dm.pmissiletype->GetReadyTime(), OT_missile, &dm, sizeof(dm)));
if (m)
m->Release();
}
g.fm.ForwardMessage(GetGroupSectorFlying(pcluster), pfmFireMissile, FM_GUARANTEED);
pmagazine->SetTimeFired(pfmFireMissile->timeFired);
pmagazine->SetLock(0.0f);
short amount = pmagazine->GetAmount() - iNumMissiles;
pmagazine->SetAmount(amount);
}
}
break;
case FM_C_AUTODONATE:
{
if (!pfsMission || (pfsMission->GetStage() != STAGE_STARTED))
break;
CASTPFM(pfmAutoDonate, C, AUTODONATE, pfm);
TrapHackBoot(pfmAutoDonate >= 0);
TrapHackBoot(pfsPlayer->GetMoney() >= pfmAutoDonate->amount);
IsideIGC* pside = pfsPlayer->GetSide();
SideID sideID = pside->GetObjectID();
if (pfmAutoDonate->amount==-1 && pfsMission->GetLeader(sideID)!=pfsPlayer)
TrapHackBoot(false); CFSPlayer* pfsDonate = NULL;
ShipID shipID = pfsPlayer->GetShipID();
if ((pfmAutoDonate->sidDonateTo != NA) && (pfmAutoDonate->sidDonateTo != shipID))
{
CFSShip* pfsDonateTo = CFSShip::GetShipFromID(pfmAutoDonate->sidDonateTo);
if (pfsDonateTo && pfsDonateTo->IsPlayer() && (pside == pfsDonateTo->GetSide()))
{
pfsDonate = pfsDonateTo->GetPlayer();
}
}
CFSPlayer *pfsPlayerChanged = NULL;
if (pfmAutoDonate->amount == -1)
{
if (!pfsDonate) break; if (pfsDonate->GetAutoDonate() != NULL)
pfsDonate->SetAutoDonate(NULL,0);
else
pfsDonate->SetAutoDonate(pfsPlayer,0);
pfsPlayerChanged = pfsDonate;
}
else
{
pfsPlayer->SetAutoDonate(pfsDonate, pfmAutoDonate->amount);
pfsPlayerChanged = pfsPlayer;
}
assert(pfsPlayerChanged);
if (pMission->GetMissionStage() == STAGE_STARTED)
{
IshipIGC* pshipNewDonate = pfsPlayerChanged->GetIGCShip()->GetAutoDonate();
SideID sideID = pside->GetObjectID();
IshipIGC* pshipLeader = pfsMission->GetLeader(sideID)->GetIGCShip();
if (pshipLeader != pshipNewDonate)
{
const ShipListIGC* pships = pside->GetShips();
int cOther = 0;
int cLeader = 0;
{
for (ShipLinkIGC* psl = pships->first(); (psl != NULL); psl = psl->next())
{
IshipIGC* pshipAD = psl->data()->GetAutoDonate();
if (pshipAD)
{
if (pshipAD == pshipLeader)
cLeader++;
else
cOther++;
}
}
}
if (cLeader < cOther)
{
IshipIGC* pshipNewLeader = PickNewLeader(pships, pshipLeader, cLeader);
if (pshipNewLeader)
{
CFSShip* pfsNewLeader = (CFSShip*)(pshipNewLeader->GetPrivateData());
pfsMission->SetLeader(pfsNewLeader->GetPlayer());
}
}
}
}
}
break;
case FM_C_FIRE_EXPENDABLE:
{
if (!pfsMission || (pfsMission->GetStage() != STAGE_STARTED))
break;
CASTPFM(pfmFireExpendable, C, FIRE_EXPENDABLE, pfm);
IshipIGC* pShip = pfsPlayer->GetIGCShip();
assert (pShip);
TrapHackBoot(pShip->GetParentShip() == NULL);
IdispenserIGC* pdispenser = (IdispenserIGC*)(pShip->GetMountedPart(pfmFireExpendable->et, 0));
if (pdispenser)
{
TrapHackBoot(pdispenser->GetAmount() > 0);
IexpendableTypeIGC* pet = pdispenser->GetExpendableType();
IclusterIGC* pcluster = pShip->GetCluster();
if (pcluster)
{
assert(0 == g.fm.CbUsedSpaceInOutbox());
{
BEGIN_PFM_CREATE(g.fm, pfmSFE, S, FIRE_EXPENDABLE)
END_PFM_CREATE
pfmSFE->launcherID = pShip->GetObjectID();
pfmSFE->equipmentType = pfmFireExpendable->et;
}
const Vector& myPosition = pShip->GetPosition();
const Vector& myVelocity = pShip->GetVelocity();
const Orientation& myOrientation = pShip->GetOrientation();
ObjectType type = pet->GetObjectType();
if (type == OT_chaffType)
{
DataChaffIGC dataChaff;
dataChaff.time0 = g.timeNow;
dataChaff.p0 = myPosition;
dataChaff.v0 = myVelocity + myOrientation.GetUp() * 5.0f;
dataChaff.pcluster = pcluster;
dataChaff.pchafftype = (IchaffTypeIGC*)pet;
{
BEGIN_PFM_CREATE(g.fm, pfmCC, S, CREATE_CHAFF)
END_PFM_CREATE
pfmCC->p0 = dataChaff.p0;
pfmCC->v0 = dataChaff.v0;
pfmCC->time0 = dataChaff.time0;
pfmCC->etid = pet->GetObjectID();
}
IchaffIGC* c = (IchaffIGC*)(pMission->CreateObject(g.timeNow,
OT_chaff,
&dataChaff,
sizeof(dataChaff)));
assert (c != NULL);
for (MissileLinkIGC* pml = pcluster->GetMissiles()->first();
(pml != NULL);
pml = pml->next())
{
ImissileIGC* pmissile = pml->data();
if (pmissile->GetTarget() == pShip)
{
float chaff = ((IchaffTypeIGC*)pet)->GetChaffStrength();
float missile = pmissile->GetMissileType()->GetChaffResistance();
float cm = chaff * missile;
float f = (chaff > missile)
? (cm - 0.5f * missile * missile)
: (0.5f * chaff * chaff);
if (random(0.0f, cm) <= f)
{
pmissile->SetTarget(c);
BEGIN_PFM_CREATE(g.fm, pfmSpoof, S, MISSILE_SPOOFED)
END_PFM_CREATE
pfmSpoof->missileID = pmissile->GetObjectID();
}
}
}
BEGIN_PFM_CREATE(g.fm, pfmSpoof, S, END_SPOOFING)
END_PFM_CREATE
c->Release();
}
else
{
float speed2 = myVelocity.LengthSquared();
float offset = (pet->GetRadius() + pShip->GetRadius()) + 5.0f;
Vector displace = (speed2 < 1.0f)
? (myOrientation.GetBackward() * offset)
: (myVelocity * (-offset / float(sqrt(speed2))));
Vector position = myPosition + displace;
IsideIGC* pside = pShip->GetSide();
if (type == OT_mineType)
{
DataMineIGC dm;
dm.pshipLauncher = pShip;
dm.psideLauncher = pside;
dm.mineID = pMission->GenerateNewMineID();
dm.time0 = pShip->GetLastUpdate() + 3.0f; dm.p0 = position;
dm.pminetype = (ImineTypeIGC*)pet;
assert (dm.pminetype);
dm.pcluster = pcluster;
dm.exportF = false;
ImineIGC * m = (ImineIGC*)(pMission->CreateObject(
g.timeNow, OT_mine, &dm, sizeof(dm)));
if (m)
m->Release();
}
else
{
assert (type == OT_probeType);
DataProbeIGC dp;
dp.pside = pShip->GetSide();
dp.pship = pShip;
dp.probeID = pMission->GenerateNewProbeID();
dp.time0 = pShip->GetLastUpdate();
dp.p0 = position;
dp.pprobetype = (IprobeTypeIGC*)pet;
assert (dp.pprobetype);
dp.pcluster = pcluster;
dp.exportF = false;
dp.pmodelTarget = pShip->GetCommandTarget(c_cmdCurrent);
IprobeIGC * p = (IprobeIGC*)(pMission->CreateObject(
g.timeNow, OT_probe, &dp, sizeof(dp)));
if (p)
p->Release();
}
}
short amount = pdispenser->GetAmount() - 1;
assert (amount >= 0);
pdispenser->SetAmount(amount);
g.fm.SendMessages(GetGroupSectorFlying(pcluster), FM_GUARANTEED, FM_FLUSH);
}
}
}
break;
case FM_CS_LOGOFF:
{
if (NULL != g.pServerCounters)
g.pServerCounters->cLogoffs++;
debugf("Logoff: %s(%u), was on side=%d mission=%x.\n",
pfsPlayer->GetName(), pfsPlayer->GetConnection()->GetID(),
(pfsPlayer->GetSide() ? pfsPlayer->GetSide()->GetObjectID() : NA),
(pfsPlayer->GetMission() ? pfsPlayer->GetMission()->GetCookie() : NA));
g.fm.ForwardMessage(pfsPlayer->GetConnection(), pfm, FM_GUARANTEED);
delete pfsPlayer; }
break;
case FM_C_LOGONREQ:
{
CQLogonStats * pquery = new CQLogonStats(GotLogonDetails);
CQLogonStatsData * pqd = pquery->GetData();
if (NULL != g.pServerCounters)
g.pServerCounters->cLoginAttempts++;
CASTPFM(pfmLogon, C, LOGONREQ, pfm);
char * szReason = "Sorry Charlie. Something \"weird\" happened."; bool fRetry = false;
TrapHackBootNoPlayer(NULL != FM_VAR_REF(pfmLogon, CharacterName)
&& NULL != memchr(FM_VAR_REF(pfmLogon, CharacterName), 0, c_cbName));
TrapHackBootNoPlayer(NULL == FM_VAR_REF(pfmLogon, MissionPassword)
|| NULL != memchr(FM_VAR_REF(pfmLogon, MissionPassword), 0, c_cbGamePassword));
TrapHackBootNoPlayer(NULL != FM_VAR_REF(pfmLogon, CDKey)
&& NULL != memchr(FM_VAR_REF(pfmLogon, CDKey), 0, c_cbCDKey));
if (pfmLogon->fedsrvVer == MSGVER)
{ bool fValid = false; LPBYTE pZoneTicket = (LPBYTE) FM_VAR_REF(pfmLogon, ZoneTicket);
#ifdef USEAUTH
if (pZoneTicket) {
hr = g.pzas->DecryptTicket(pZoneTicket, pfmLogon->cbZoneTicket);
switch (hr)
{
case ZT_NO_ERROR:
{
if (lstrcmpi(g.strAuthServer, g.pzas->GetAuthServer())) {
szReason = "Your account authentication did not go through the expected server.";
break;
}
bool fValidNow = false;
fValid = g.pzas->HasToken(g.m_szToken, &fValidNow);
if (!fValid)
szReason = "Your Allegiance Zone subscription has expired.";
else if (!fValidNow)
{
fValid = false; szReason = "This account is not authorized to play on the Allegiance Zone.";
fRetry = true;
}
break;
}
case ZT_E_BUFFER_TOO_SMALL:
_AGCModule.TriggerEvent(NULL, AllsrvEventID_IncreaseTokensMax, "", -1, -1, -1, 0);
break;
case ZT_E_AUTH_INVALID_TICKET:
_AGCModule.TriggerEvent(NULL, AllsrvEventID_InvalidZoneTicket, "", -1, -1, -1, 0);
szReason = "Could not validate Zone ID.";
break;
default:
_AGCModule.TriggerEvent(NULL, AllsrvEventID_DecryptTicketFailed, "", -1, -1, -1, 0);
}
}
else
{
_AGCModule.TriggerEvent(NULL, AllsrvEventID_NoTicket, "", -1, -1, -1, 0);
szReason = "No login credentials found.";
}
lstrcpy(pqd->szCharacterName, g.pzas->GetName());
pqd->characterID = g.pzas->GetAccountID();
#else if (0 < pfmLogon->cbCharacterName && pfmLogon->cbCharacterName <= c_cbName)
{
fValid = true;
lstrcpy(pqd->szCharacterName, FM_VAR_REF(pfmLogon, CharacterName));
pqd->characterID = GetNextCharacterID();
pqd->fCanCheat = false;
}
else
{
_AGCModule.TriggerEvent(NULL, AllsrvEventID_NoTicket, "", -1, -1, -1, 0);
szReason = "No player name found.";
lstrcpy(pqd->szCharacterName, "<invalid>");
}
#endif lstrcpy(pqd->szReason, szReason);
pqd->fRetry = fRetry;
pqd->dwCookie = pfmLogon->dwCookie;
if(FM_VAR_REF(pfmLogon, MissionPassword))
lstrcpy(pqd->szPassword, FM_VAR_REF(pfmLogon, MissionPassword));
else
pqd->szPassword[0] = 0;
lstrcpy(pqd->szCDKey, FM_VAR_REF(pfmLogon, CDKey));
pqd->fValid = fValid;
pqd->dwConnectionID = cnxnFrom.GetID();
#if !defined(ALLSRV_STANDALONE)
if (fValid)
g.sql.PostQuery(pquery);
else #endif
pquery->DataReady();
} else
{
if (NULL != g.pServerCounters)
g.pServerCounters->cLoginsFailed++;
char szVerError[350];
if (pfmLogon->fedsrvVer < MSGVER)
wsprintf(szVerError, "The server you are trying to play on has a newer version than you. "
"Please go play online to get the latest auto-update. If this doesn't work, try deleting "
"the file 'filelist.txt' from the install directory and restarting the application.");
else {
#if defined(ALLSRV_STANDALONE)
wsprintf(szVerError, "The server you are trying to play on is out-of-date. Find another server "
"or contact the server's owner and tell them to auto-update by connecting to the zone match-making "
"service. If that doesn't work, have the server's owner try deleting "
"the file 'filelist.txt' from the install directory and restarting the server.");
#else
wsprintf(szVerError, "The server you are trying to play on is out-of-date. The Zone needs to update their game server(s). Please try again later.");
#endif
}
assert(lstrlen(szVerError) < sizeof(szVerError));
_AGCModule.TriggerEvent(NULL, AllsrvEventID_BadClientVersion, "", -1, -1, -1, 2,
"ServerVer", VT_I4, MSGVER,
"ClientVer", VT_I4, pfmLogon->fedsrvVer);
BEGIN_PFM_CREATE(g.fm, pfmLogonAck, S, LOGONACK)
FM_VAR_PARM(szVerError, CB_ZTS)
FM_VAR_PARM(NULL, CB_ZTS)
END_PFM_CREATE
pfmLogonAck->fValidated = false;
pfmLogonAck->fRetry = false;
g.fm.SendMessages(&cnxnFrom, FM_GUARANTEED, FM_FLUSH);
}
#ifdef DEBUG
DWORD cMsgs, cbData;
ZSucceeded(g.fm.GetSendQueue(&cMsgs, &cbData));
debugf("GetSendQueue reports %d msgs, %d bytes.\n", cMsgs, cbData);
#endif
break;
}
case FM_C_TREASURE_ACK:
{
if (!pfsMission || (pfsMission->GetStage() != STAGE_STARTED))
break;
if (pfsPlayer->GetTreasureObjectID() != NA)
{
IsideIGC* pside = pfsPlayer->GetSide();
if (pside->GetObjectID() >= 0)
{
TrapHackBoot(pfsPlayer->GetIGCShip()->GetParentShip() == NULL);
CASTPFM(pfmTA, C, TREASURE_ACK, pfm);
ObjectID oid = pfsPlayer->GetTreasureObjectID();
IpartTypeIGC* ppt = pMission->GetPartType(oid);
assert(ppt);
short amount = pfsPlayer->GetTreasureAmount();
if (pfmTA->mountID != c_mountNA)
{
TrapHackBoot(pfsPlayer->GetIGCShip()->GetHullType()->CanMount(ppt, pfmTA->mountID));
IpartIGC* ppart = pfsPlayer->GetIGCShip()->GetMountedPart(ppt->GetEquipmentType(), pfmTA->mountID);
if (ppart)
{
TrapHackBoot(ppart->GetPartType() == ppt);
ppart->SetAmount(ppart->GetAmount() + amount);
}
else
pfsPlayer->GetIGCShip()->CreateAndAddPart(ppt, pfmTA->mountID, amount);
IclusterIGC* pcluster = pfsPlayer->GetIGCShip()->GetCluster();
if (pcluster)
{
BEGIN_PFM_CREATE(g.fm, pfmAddPart, S, ADD_PART)
END_PFM_CREATE
pfmAddPart->shipID = pfsPlayer->GetShipID();
pfmAddPart->newPartData.partID = oid;
pfmAddPart->newPartData.mountID = pfmTA->mountID;
pfmAddPart->newPartData.amount = amount;
g.fm.SendMessages(GetGroupSectorFlying(pcluster), FM_GUARANTEED, FM_FLUSH);
}
}
else if (pfsPlayer->GetIGCShip()->GetCluster())
{
CreateTreasure(g.timeNow, pfsPlayer->GetIGCShip(), amount, ppt,
pfsPlayer->GetIGCShip()->GetPosition(), 25.0f, 120.0f);
}
}
pfsPlayer->SetTreasureObjectID(NA);
}
}
break;
case FM_C_BUY_LOADOUT:
{
if (!pfsMission
|| (pfsPlayer->GetIGCShip()->GetCluster() != NULL)
|| (pfsPlayer->GetIGCShip()->GetStation() == NULL)
|| pfsPlayer->GetIGCShip()->IsGhost())
break;
IsideIGC* pside = pfsPlayer->GetSide();
if (pside->GetObjectID() < 0)
break;
TrapHackBoot(pfsPlayer->GetIGCShip()->GetParentShip() == NULL);
CASTPFM(pfmBuyLoadout, C, BUY_LOADOUT, pfm);
TrapHackBoot(pfmBuyLoadout->ibloadout == sizeof(FMD_C_BUY_LOADOUT));
TrapHackBoot(pfmBuyLoadout->cbloadout >= sizeof(ShipLoadout));
TrapHackBoot((pfmBuyLoadout->cbloadout - sizeof(ShipLoadout)) % sizeof(ExpandedPartData) >= 0);
TrapHackBoot(pfmBuyLoadout->cbloadout <= c_cbLoadout);
Money cost = -pfsPlayer->GetIGCShip()->GetValue();
IhullTypeIGC* phtOld = pfsPlayer->GetIGCShip()->GetBaseHullType();
bool bBoughtEverything = pfsPlayer->GetIGCShip()->PurchaseShipLoadout(pfmBuyLoadout->cbloadout,
(const ShipLoadout*)(FM_VAR_REF(pfmBuyLoadout, loadout)));
cost += pfsPlayer->GetIGCShip()->GetValue();
if (cost != 0)
{
TrapHackBoot(pfsPlayer->GetMoney() >= cost);
pfsPlayer->SetMoney(pfsPlayer->GetMoney() - cost);
BEGIN_PFM_CREATE(g.fm, pfmMoneyChange, S, MONEY_CHANGE)
END_PFM_CREATE
pfmMoneyChange->dMoney = -cost;
pfmMoneyChange->sidTo = pfsPlayer->GetShipID();
pfmMoneyChange->sidFrom = NA;
g.fm.SendMessages(CFSSide::FromIGC(pside)->GetGroup(), FM_GUARANTEED, FM_FLUSH);
}
const ShipListIGC* pshipsChildren = pfsPlayer->GetIGCShip()->GetChildShips();
IhullTypeIGC* phtNew = pfsPlayer->GetIGCShip()->GetBaseHullType();
if (phtOld != phtNew)
{
ShipLinkIGC* pslNext;
for (ShipLinkIGC* psl = pshipsChildren->first(); (psl != NULL); psl = pslNext)
{
pslNext = psl->next();
if (psl->data()->GetTurretID() < 0)
LeaveShip(((CFSShip*)(psl->data()->GetPrivateData()))->GetPlayer(), pfsPlayer->GetIGCShip());
}
}
bool bLaunch = pfmBuyLoadout->fLaunch && bBoughtEverything;
BEGIN_PFM_CREATE(g.fm, pfmBuyLoadoutAck, S, BUY_LOADOUT_ACK)
FM_VAR_PARM(NULL, pfsPlayer->GetIGCShip()->ExportShipLoadout(NULL))
END_PFM_CREATE
pfsPlayer->GetIGCShip()->ExportShipLoadout((ShipLoadout*)(FM_VAR_REF(pfmBuyLoadoutAck, loadout)));
pfsPlayer->SaveDesiredLoadout();
pfmBuyLoadoutAck->fBoughtEverything = bBoughtEverything;
pfmBuyLoadoutAck->fLaunch = bLaunch;
g.fm.SendMessages(pfsPlayer->GetConnection(), FM_GUARANTEED, FM_FLUSH);
pfsPlayer->QueueLoadoutChange();
{
SideID sid = pfsPlayer->GetSide()->GetObjectID();
pfsPlayer->GetShipStatus(sid)->SetHullID(pfsPlayer->GetIGCShip()->GetBaseHullType()->GetObjectID());
for (ShipLinkIGC* psl = pshipsChildren->first(); (psl != NULL); psl = psl->next())
{
CFSShip* pfsChild = (CFSShip*)(psl->data()->GetPrivateData());
pfsChild->GetShipStatus(sid)->SetState(psl->data()->GetTurretID() == NA ? c_ssObserver : c_ssTurret);
g.fm.SendMessages(pfsChild->GetPlayer()->GetConnection(), FM_GUARANTEED, FM_DONT_FLUSH);
}
}
g.fm.PurgeOutBox();
if (bLaunch)
{
for (ShipLinkIGC* psl = pshipsChildren->first();
(psl != NULL);
psl = psl->next())
{
psl->data()->SetStation(NULL);
}
pfsPlayer->GetIGCShip()->SetStation(NULL);
}
}
break;
case FM_CS_DROP_PART:
{
if (!pfsMission || (pfsMission->GetStage() != STAGE_STARTED) || (pfsPlayer->GetIGCShip()->GetSide()->GetObjectID() < 0))
break;
TrapHackBoot (pfsPlayer->GetIGCShip()->GetParentShip() == NULL);
IclusterIGC* pcluster = pfsPlayer->GetIGCShip()->GetCluster();
if (pcluster)
{
TrapHackBoot (pfsPlayer->GetSide()->GetObjectID() >= 0);
CASTPFM(pfmDropPart, CS, DROP_PART, pfm);
TrapHackBoot ((pfmDropPart->et >= NA) && (pfmDropPart->et < ET_MAX));
TrapHackBoot ((pfmDropPart->mount >= -c_maxCargo) && (pfmDropPart->mount < c_maxMountedWeapons));
TrapHackBoot ((pfmDropPart->mount <= 0) || (pfmDropPart->et == ET_Weapon));
TrapHackBoot ((pfmDropPart->mount < 0) || (pfmDropPart->et >= 0));
IpartIGC* ppart = pfsPlayer->GetIGCShip()->GetMountedPart(pfmDropPart->et, pfmDropPart->mount);
if (ppart)
{
pfmDropPart->shipID = pfsPlayer->GetShipID();
g.fm.ForwardMessage(GetGroupSectorFlying(pcluster), pfmDropPart, FM_GUARANTEED);
ObjectType type = ppart->GetObjectType();
if (((type != OT_pack) && !IlauncherIGC::IsLauncher(type)) ||
(ppart->GetAmount() != 0))
{
CreateTreasure(g.timeNow, pfsPlayer->GetIGCShip(), ppart, ppart->GetPartType(),
pfsPlayer->GetIGCShip()->GetPosition(), 25.0f, 120.0f);
}
ppart->Terminate();
}
}
}
break;
case FM_C_SUICIDE:
{
if (!(pfsPlayer->GetIGCShip()->GetParentShip() || pfsPlayer->CanCheat()))
break;
if (!pfsMission || (pfsMission->GetStage() != STAGE_STARTED))
break;
if (pfsPlayer->GetIGCShip()->GetCluster()) pfsMission->GetSite()->KillShipEvent(g.timeNow, pfsPlayer->GetIGCShip(), NULL, 1.0f,
pfsPlayer->GetIGCShip()->GetSourceShip()->GetPosition(), Vector::GetZero());
break;
}
case FM_C_PROMOTE:
{
if (!pfsMission || (pfsMission->GetStage() != STAGE_STARTED) || pfsPlayer->GetIGCShip()->IsGhost())
break;
CASTPFM(pfmPromoteC, C, PROMOTE, pfm);
for (ShipLinkIGC* psl = pfsPlayer->GetIGCShip()->GetChildShips()->first(); (psl != NULL); psl = psl->next())
{
IshipIGC* pship = psl->data();
if (pship->GetTurretID() == pfmPromoteC->mountidPromoted)
{
pship->Promote();
((CFSShip*)(pship->GetPrivateData()))->ShipStatusRecalculate();
BEGIN_PFM_CREATE(g.fm, pfmPromote, S, PROMOTE)
END_PFM_CREATE
pfmPromote->shipidPromoted = pship->GetObjectID();
IclusterIGC* pcluster = pfsPlayer->GetIGCShip()->GetCluster();
if (pcluster)
g.fm.SendMessages(GetGroupSectorFlying(pcluster), FM_GUARANTEED, FM_FLUSH); else
g.fm.SendMessages(CFSSide::FromIGC(pfsPlayer->GetSide())->GetGroup(), FM_GUARANTEED, FM_FLUSH);
break;
}
}
}
break;
case FM_C_BOARD_SHIP:
{
if (!pfsMission || (pfsMission->GetStage() != STAGE_STARTED) || pfsPlayer->GetIGCShip()->IsGhost())
break;
CASTPFM(pfmBoardShip, C, BOARD_SHIP, pfm);
if (pfmBoardShip->sidParent == NA)
{
IshipIGC* pship = pfsPlayer->GetIGCShip()->GetParentShip();
if (pship)
{
if (LeaveShip(pfsPlayer, pship))
break;
}
}
else
{
IshipIGC* pship = pfsPlayer->GetIGCShip()->GetSide()->GetShip(pfmBoardShip->sidParent);
if (pship && !pship->IsGhost())
{
if (BoardShip(pfsPlayer, pship))
break;
}
}
BEGIN_PFM_CREATE(g.fm, pfmBoardNack, S, BOARD_NACK)
END_PFM_CREATE
pfmBoardNack->sidRequestedParent;
g.fm.SendMessages(pfsPlayer->GetConnection(), FM_GUARANTEED, FM_FLUSH);
}
break;
case FM_C_VIEW_CLUSTER:
{
if (pfsPlayer->GetIGCShip()->GetStation())
{
CASTPFM(pfmViewCluster, C, VIEW_CLUSTER, pfm);
IclusterIGC* pcluster;
if (pfmViewCluster->clusterID != NA)
{
pcluster = pMission->GetCluster(pfmViewCluster->clusterID);
TrapHackBoot(pcluster);
BEGIN_PFM_CREATE(g.fm, pfmVC, S, VIEW_CLUSTER)
END_PFM_CREATE
pfmVC->clusterID = pfmViewCluster->clusterID;
pfmVC->bUsePosition = false;
if (pfmViewCluster->otTarget != NA)
{
ImodelIGC* ptarget = pMission->GetModel(pfmViewCluster->otTarget, pfmViewCluster->oidTarget);
if (ptarget && (ptarget->GetCluster() == pcluster) && ptarget->SeenBySide(pfsPlayer->GetSide()))
{
pfmVC->bUsePosition = true;
pfmVC->position = ptarget->GetPosition();
}
}
g.fm.SendMessages(pfsPlayer->GetConnection(), FM_GUARANTEED, FM_FLUSH);
}
else
pcluster = NULL;
pfsPlayer->SetCluster(pcluster, true);
}
}
break;
case FM_CS_SWAP_PART:
{
if (!pfsMission || (pfsMission->GetStage() != STAGE_STARTED) || (pfsPlayer->GetIGCShip()->GetSide()->GetObjectID() < 0))
break;
TrapHackBoot (pfsPlayer->GetIGCShip()->GetParentShip() == NULL);
IclusterIGC* pcluster = pfsPlayer->GetIGCShip()->GetCluster();
if (pcluster)
{
CASTPFM(pfmSwapPart, CS, SWAP_PART, pfm);
assert (pfsPlayer->GetIGCShip()->GetBaseHullType());
TrapHack (pfmSwapPart->mountNew >= -c_maxCargo);
TrapHackBoot ((pfmSwapPart->etOld >= NA) && (pfmSwapPart->etOld < ET_MAX));
TrapHackBoot ((pfmSwapPart->mountOld >= -c_maxCargo) && (pfmSwapPart->mountOld < c_maxMountedWeapons));
TrapHackBoot ((pfmSwapPart->mountOld <= 0) || (pfmSwapPart->etOld == ET_Weapon));
TrapHackBoot ((pfmSwapPart->mountOld < 0) || (pfmSwapPart->etOld >= 0));
TrapHackBoot ((pfmSwapPart->mountNew >= -c_maxCargo) && (pfmSwapPart->mountNew < c_maxMountedWeapons));
TrapHackBoot ((pfmSwapPart->mountNew <= 0) || (pfmSwapPart->etOld == ET_Weapon));
TrapHackBoot ((pfmSwapPart->mountNew < 0) || (pfmSwapPart->etOld >= 0));
IpartIGC* ppart = pfsPlayer->GetIGCShip()->GetMountedPart(pfmSwapPart->etOld, pfmSwapPart->mountOld);
if (ppart)
{
IpartIGC* ppartNew = pfsPlayer->GetIGCShip()->GetMountedPart(pfmSwapPart->etOld, pfmSwapPart->mountNew);
if (ppartNew)
{
ppart->SetMountID(c_mountNA);
ppartNew->SetMountID(pfmSwapPart->mountOld);
}
ppart->SetMountID(pfmSwapPart->mountNew);
pfmSwapPart->shipID = pfsPlayer->GetShipID();
g.fm.ForwardMessage(GetGroupSectorFlying(pcluster), pfmSwapPart, FM_GUARANTEED);
}
}
break;
}
case FM_CS_RELOAD:
{
if (!pfsMission || (pfsMission->GetStage() != STAGE_STARTED) || (pfsPlayer->GetIGCShip()->GetSide()->GetObjectID() < 0))
break;
TrapHackBoot (pfsPlayer->GetIGCShip()->GetParentShip() == NULL);
CASTPFM(pfmReload, CS, RELOAD, pfm);
TrapHackBoot(pfmReload->ibrgReloads == sizeof(FMD_CS_RELOAD));
IclusterIGC* pcluster = pfsPlayer->GetIGCShip()->GetCluster();
if (pcluster && (pfsPlayer->GetIGCShip()->GetParts()->n() != 0)) {
const PartListIGC * ppartlist = pfsPlayer->GetIGCShip()->GetParts();
ReloadData* prlNext = (ReloadData*)FM_VAR_REF(pfmReload, rgReloads);
int nReloads = pfmReload->cbrgReloads / sizeof(ReloadData);
TrapHackBoot((nReloads > 0) && (nReloads <= 5)); ReloadData* prlStop = prlNext + nReloads;
bool bBoot = false;
while (prlNext < prlStop)
{
if ((prlNext->mount >= 0) || (prlNext->mount < -c_maxCargo))
{
bBoot = true;
break;
}
IpartIGC* ppart = pfsPlayer->GetIGCShip()->GetMountedPart(NA, prlNext->mount);
if (!ppart)
{
bBoot = true;
break;
}
ObjectType type = ppart->GetObjectType();
if (type == OT_pack)
{
IpackIGC* ppack = (IpackIGC*)ppart;
PackType packtype = ppack->GetPackType();
short amount = ppack->GetAmount();
if (prlNext->amountTransfered == NA)
{
ppack->Terminate();
}
else
{
if ((prlNext->amountTransfered < 0) || (prlNext->amountTransfered >= amount))
{
bBoot = true;
break;
}
ppack->SetAmount(amount - prlNext->amountTransfered);
amount = prlNext->amountTransfered;
}
if (packtype == c_packAmmo)
{
pfsPlayer->GetIGCShip()->SetAmmo(pfsPlayer->GetIGCShip()->GetAmmo() + amount);
Mount maxWeapons = pfsPlayer->GetIGCShip()->GetHullType()->GetMaxWeapons();
for (Mount i = 0; (i < maxWeapons); i++)
{
IweaponIGC* pw = (IweaponIGC*)(pfsPlayer->GetIGCShip()->GetMountedPart(ET_Weapon, i));
if (pw && (pw->GetAmmoPerShot() != 0))
pw->SetMountedFraction(0.0f);
}
}
else
{
assert (packtype == c_packFuel);
pfsPlayer->GetIGCShip()->SetFuel(pfsPlayer->GetIGCShip()->GetFuel() + float(amount));
IpartIGC* pa = pfsPlayer->GetIGCShip()->GetMountedPart(ET_Afterburner, 0);
if (pa)
pa->SetMountedFraction(0.0f);
}
}
else
{
if (!IlauncherIGC::IsLauncher(type))
{
bBoot = true;
break;
}
IlauncherIGC* plauncher = (IlauncherIGC*)ppart;
IlauncherIGC* plauncherMounted = (IlauncherIGC*)(pfsPlayer->GetIGCShip()->GetMountedPart(plauncher->GetEquipmentType(), 0));
if (prlNext->amountTransfered == NA)
{
if ((plauncherMounted != NULL) && (plauncherMounted->GetAmount() != 0))
{
bBoot = true;
break;
}
if (plauncherMounted)
plauncherMounted->Terminate();
plauncher->SetMountID(0);
}
else
{
short amount = plauncher->GetAmount();
if ((!plauncherMounted) ||
(prlNext->amountTransfered <= 0) ||
(prlNext->amountTransfered > amount))
{
bBoot = true;
break;
}
if (amount == prlNext->amountTransfered)
plauncher->Terminate();
else
plauncher->SetAmount(amount - prlNext->amountTransfered);
plauncherMounted->SetAmount(plauncherMounted->GetAmount() + prlNext->amountTransfered);
plauncherMounted->SetMountedFraction(0.0f);
plauncherMounted->ResetTimeLoaded();
}
}
prlNext++;
}
if (bBoot)
{
TrapHackBoot(!bBoot);
}
else
{
pfmReload->shipID = pfsPlayer->GetShipID();
g.fm.ForwardMessage(GetGroupSectorFlying(pcluster), pfmReload, FM_GUARANTEED);
}
}
}
break;
case FM_C_POSITIONREQ:
{
if (!pfsMission)
break;
CASTPFM(pfmPositionReq, C, POSITIONREQ, pfm);
SideID iSide = pfmPositionReq->iSide;
TrapHackBoot(iSide >= SIDE_TEAMLOBBY && iSide < c_cSidesMax);
if (NA == iSide)
iSide = pfsMission->PickNewSide(pfsPlayer, false, 0);
IsideIGC* psideReq = pMission->GetSide(iSide);
if (psideReq)
pfsMission->RequestPosition(pfsPlayer, psideReq, false);
else
{
BEGIN_PFM_CREATE(g.fm, pfmDelPosReq, CS, DELPOSITIONREQ)
END_PFM_CREATE
pfmDelPosReq->shipID = pfsPlayer->GetShipID();
pfmDelPosReq->iSide = iSide;
pfmDelPosReq->reason = DPR_SideGone;
g.fm.SendMessages(pfsPlayer->GetConnection(), FM_GUARANTEED, FM_FLUSH);
break;
}
break;
}
case FM_C_POSITIONACK:
{
if (!pfsMission)
break;
CASTPFM(pfmPositionAck, C, POSITIONACK, pfm);
CFSShip * pfssAck = CFSShip::GetShipFromID(pfmPositionAck->shipID);
IsideIGC * pside = pfsPlayer->GetSide(); TrapHackBoot(pfmPositionAck->iSide >= 0 && pfmPositionAck->iSide < c_cSidesMax);
if (pfmPositionAck->iSide != pside->GetObjectID()
|| pfmPositionAck->iSide == SIDE_TEAMLOBBY
|| pfsPlayer != pfsMission->GetLeader(pfmPositionAck->iSide))
break;
if (!pfssAck || pfssAck->GetMission() != pfsMission) break;
CFSPlayer * pfspAck = pfssAck->GetPlayer();
if (pfmPositionAck->fAccepted)
{
if (pfsMission->CheckPositionRequest(pfssAck->GetPlayer(), pside) == NA
&& pfsMission->RemoveJoinRequest(pfssAck->GetPlayer(), pside))
{
pfsMission->AddPlayerToSide(pfspAck, pside);
}
}
else
{
pfsMission->RemoveJoinRequest(pfspAck, NULL);
}
break;
}
case FM_CS_QUIT_MISSION:
{
if (!pfsMission)
break;
IsideIGC* pside = pfsPlayer->GetSide(); assert (pside);
SideID sideID = pside->GetObjectID();
if (sideID < 0 && sideID != SIDE_TEAMLOBBY)
break;
CASTPFM(pfmQuitMission, CS, QUIT_MISSION, pfm);
CFSShip * pfssAck = CFSShip::GetShipFromID(pfmQuitMission->shipID);
if (!pfssAck) break;
if ((pfsPlayer == pfssAck) ||
((pfsPlayer == pfsMission->GetLeader(sideID)) &&
(pfssAck->GetSide() == pside)))
{
CFSPlayer * pfspAck = pfssAck->GetPlayer();
bool bIsBoot = (pfsPlayer->GetShipID() != pfmQuitMission->shipID);
TrapHackBoot(pfmQuitMission->reason == (bIsBoot ? QSR_LeaderBooted : QSR_Quit));
if (!bIsBoot || !pfsMission->GetMissionDef()->misparms.bLockTeamSettings)
{
if (bIsBoot)
{
LPCSTR pszContext = pfsMission->GetIGCMission() ? pfsMission->GetIGCMission()->GetContextName() : NULL;
_AGCModule.TriggerContextEvent(NULL, EventID_LeaveTeam, pszContext,
pfssAck->GetName(), pfssAck->GetShipID(), pside->GetObjectID(), pfsPlayer->GetCharacterID(), 4,
"MissionID", VT_I4, pfsMission->GetMissionID(),
"Team" , VT_I4 , pside->GetObjectID(),
"TeamName", VT_LPSTR, pside->GetName(),
"zBooter", VT_LPSTR, pfsPlayer->GetName());
}
pfsMission->RemovePlayerFromMission(pfspAck, pfmQuitMission->reason);
}
}
break;
}
case FM_CS_QUIT_SIDE:
{
if (!pfsMission)
break;
IsideIGC* pside = pfsPlayer->GetSide(); assert (pside);
SideID sideID = pside->GetObjectID();
if (sideID < 0)
break;
CASTPFM(pfmQuitSide, CS, QUIT_SIDE, pfm);
CFSShip * pfssAck = CFSShip::GetShipFromID(pfmQuitSide->shipID);
if (!pfssAck) break;
TrapHackBoot(pfssAck->IsPlayer());
if ((pfsPlayer == pfssAck) ||
((pfsPlayer == pfsMission->GetLeader(sideID)) &&
(pfssAck->GetSide() == pside)))
{
CFSPlayer * pfspAck = pfssAck->GetPlayer();
bool bIsBoot = (pfsPlayer->GetShipID() != pfmQuitSide->shipID);
TrapHackBoot(pfmQuitSide->reason == (bIsBoot ? QSR_LeaderBooted : QSR_Quit));
if (!bIsBoot && pfsMission->GetMissionDef()->misparms.bLockSides)
{
BEGIN_PFM_CREATE(g.fm, pfmDelPosReq, CS, DELPOSITIONREQ)
END_PFM_CREATE
pfmDelPosReq->shipID = pfsPlayer->GetShipID();
pfmDelPosReq->iSide = sideID;
pfmDelPosReq->reason = DPR_SidesLocked;
g.fm.SendMessages(pfsPlayer->GetConnection(), FM_GUARANTEED, FM_FLUSH);
}
else
{
if (!bIsBoot || !pfsMission->GetMissionDef()->misparms.bLockTeamSettings)
{
pfsMission->RemovePlayerFromSide(pfspAck, pfmQuitSide->reason);
if (bIsBoot)
{
unsigned char bannedSideMask = pfspAck->GetBannedSideMask();
unsigned char legalSideMask = SideMask(pfsMission->GetCountSides()) - 1;
if ((bannedSideMask & legalSideMask) == legalSideMask)
pfsMission->RemovePlayerFromMission(pfspAck, pfmQuitSide->reason);
}
}
} }
break;
}
case FM_CS_AUTO_ACCEPT:
{
if (!pfsMission)
break;
CASTPFM(pfmAutoAccept, CS, AUTO_ACCEPT, pfm);
SideID sid = pfsPlayer->GetSide()->GetObjectID();
if (sid == SIDE_TEAMLOBBY)
break;
TrapHackBoot(sid >= 0 && sid < c_cSidesMax);
if (pfsPlayer != pfsMission->GetLeader(sid))
break;
TrapHackBoot(pfmAutoAccept->iSide == sid);
if (pfsMission->GetMissionDef()->misparms.bLockGameOpen)
break;
g.fm.ForwardMessage(pfsMission->GetGroupMission(), pfmAutoAccept, FM_GUARANTEED);
IsideIGC * pside = pMission->GetSide(pfmAutoAccept->iSide);
pfsMission->SetAutoAccept(pside, pfmAutoAccept->fAutoAccept);
break;
}
case FM_CS_LOCK_LOBBY:
{
if ((!pfsMission) || (pfsMission->GetOwner() != pfsPlayer))
break;
if (pfsMission->GetMissionDef()->misparms.bLockGameOpen)
break;
CASTPFM(pfmLockLobby, CS, LOCK_LOBBY, pfm);
g.fm.ForwardMessage(pfsMission->GetGroupMission(), pfmLockLobby, FM_GUARANTEED);
pfsMission->SetLockLobby(pfmLockLobby->fLock);
break;
}
case FM_CS_LOCK_SIDES:
{
if ((!pfsMission) || (pfsMission->GetOwner() != pfsPlayer))
break;
CASTPFM(pfmLockSides, CS, LOCK_SIDES, pfm);
g.fm.ForwardMessage(pfsMission->GetGroupMission(), pfmLockSides, FM_GUARANTEED);
pfsMission->SetLockSides(pfmLockSides->fLock);
break;
}
case FM_C_RANDOMIZE_TEAMS:
{
if ((!pfsMission) || (pfsMission->GetOwner() != pfsPlayer))
break;
if (pfsMission->GetStage() != STAGE_NOTSTARTED)
break;
if (pfsMission->GetMissionDef()->misparms.iMaxImbalance == 0x7ffe)
{
pfsMission->RandomizeSides();
}
else
{
pfsMission->FlushSides();
}
break;
}
case FM_CS_PLAYER_READY:
case FM_CS_FORCE_TEAM_READY:
{
if (!pfsMission)
break;
bool fIsForce = FM_CS_FORCE_TEAM_READY == pfm->fmid;
IsideIGC * pside = pfsPlayer->GetSide();
int iSide = pside->GetObjectID();
bool fReady = false;
bool fForceReady = false;
FEDMESSAGE * pfmForward = NULL;
if (fIsForce)
{
if (pfsPlayer != pfsMission->GetLeader(iSide))
break;
CASTPFM(pfmForceReady, CS, FORCE_TEAM_READY, pfm);
TrapHackBoot(iSide >= 0 && iSide < c_cSidesMax);
TrapHackBoot(pfmForceReady->iSide == iSide);
g.fm.ForwardMessage(pfsMission->GetGroupMission(), pfm, FM_GUARANTEED);
pfsMission->SetForceReady(iSide, pfmForceReady->fForceReady);
pfmForward = (FEDMESSAGE *) pfmForceReady;
}
else {
CASTPFM(pfmPlayerReady, CS, PLAYER_READY, pfm);
TrapHackBoot(pfmPlayerReady->shipID == pfsPlayer->GetShipID());
fReady = pfmPlayerReady->fReady;
pfsPlayer->SetReady(pfmPlayerReady->fReady);
pfmForward = (FEDMESSAGE *) pfmPlayerReady;
g.fm.ForwardMessage(pfsMission->GetGroupMission(), pfm, FM_GUARANTEED);
}
break;
}
case FM_C_DOCKED:
{
if (!pfsMission || (pfsMission->GetStage() != STAGE_STARTED))
break;
IsideIGC* pside = pfsPlayer->GetSide();
if (pside->GetObjectID() < 0)
break;
if (pfsPlayer->GetIGCShip()->GetStation() != NULL)
{
CASTPFM(pfmDocked, C, DOCKED, pfm);
IshipIGC* pshipParent = pfsPlayer->GetIGCShip()->GetParentShip();
if (pshipParent == NULL)
{
const ShipListIGC* pshipsChildren = pfsPlayer->GetIGCShip()->GetChildShips();
IstationIGC* pstation;
if ((pfmDocked->stationID == NA) && !pfsPlayer->GetIGCShip()->IsGhost())
{
pstation = NULL;
}
else
{
pstation = pfsMission->GetIGCMission()->GetStation(pfmDocked->stationID);
BEGIN_PFM_CREATE(g.fm, pfmAck, S, TELEPORT_ACK)
END_PFM_CREATE
if ((pstation == NULL) ||
(pstation->GetSide() != pside) ||
(!pstation->GetStationType()->HasCapability(c_sabmRestart)))
{
pfmAck->stationID = NA;
pfmAck->bNewHull = false;
g.fm.SendMessages(pfsPlayer->GetConnection(), FM_GUARANTEED, FM_FLUSH);
break;
}
pfmAck->stationID = pfmDocked->stationID;
pfmAck->bNewHull = !pstation->CanBuy(pfsPlayer->GetIGCShip()->GetBaseHullType());
g.fm.SendMessages(pfsPlayer->GetConnection(), FM_GUARANTEED, FM_FLUSH);
if (pfmAck->bNewHull)
{
{
ShipLinkIGC* psl;
while (psl = pshipsChildren->first()) LeaveShip((CFSShip*)(psl->data()->GetPrivateData()), pfsPlayer->GetIGCShip());
}
Money refund = pfsPlayer->GetIGCShip()->GetValue();
assert(refund >= 0);
if (refund > 0)
{
BEGIN_PFM_CREATE(g.fm, pfmMoney, S, MONEY_CHANGE)
END_PFM_CREATE
pfmMoney->sidTo = pfsPlayer->GetShipID();
pfmMoney->sidFrom = NA;
pfmMoney->dMoney = refund;
pfsPlayer->SetMoney(pfsPlayer->GetMoney() + refund);
g.fm.SendMessages(CFSSide::FromIGC(pside)->GetGroup(), FM_GUARANTEED, FM_FLUSH);
}
{
const PartListIGC* ppartsList = pfsPlayer->GetIGCShip()->GetParts();
PartLinkIGC* ppl;
while (ppl = ppartsList->first()) ppl->data()->Terminate();
}
IhullTypeIGC* pht = pside->GetCivilization()->GetLifepod();
pfsPlayer->GetIGCShip()->SetBaseHullType(pht);
ShipStatus* pss = pfsPlayer->GetShipStatus(pside->GetObjectID());
pss->SetHullID(pht->GetObjectID());
}
}
for (ShipLinkIGC* psl = pshipsChildren->first();
(psl != NULL);
psl = psl->next())
{
psl->data()->SetStation(pstation);
}
pfsPlayer->GetIGCShip()->SetStation(pstation);
}
}
}
break;
case FM_C_BUCKET_DONATE:
{
if (!pfsMission || (pfsMission->GetStage() != STAGE_STARTED))
break;
CASTPFM(pfmBucketDonate, C, BUCKET_DONATE, pfm);
IsideIGC* pside = pfsPlayer->GetSide();
IbucketIGC* pbucket = pside->GetBucket(pfmBucketDonate->iBucket);
TrapHackBoot(pbucket);
TrapHackBoot(pbucket->GetGroupID() >= 0);
TrapHackBoot(pfsPlayer->GetMoney() >= pfmBucketDonate->moneyGiven);
TrapHackBoot(pfmBucketDonate->moneyGiven >= 0);
Money mnyRefund = pfmBucketDonate->moneyGiven;
if (pside->CanBuy(pbucket))
{
Money mnySpent = pbucket->AddMoney(pfmBucketDonate->moneyGiven);
assert(mnySpent <= mnyRefund); mnyRefund -= mnySpent;
pfsPlayer->SetMoney(pfsPlayer->GetMoney() - mnySpent);
BEGIN_PFM_CREATE(g.fm, pfmMoneyChange, S, MONEY_CHANGE)
END_PFM_CREATE
pfmMoneyChange->dMoney = -mnySpent;
pfmMoneyChange->sidTo = pfsPlayer->GetShipID();
pfmMoneyChange->sidFrom = pfmMoneyChange->sidTo;
g.fm.SendMessages(CFSSide::FromIGC(pside)->GetGroup(), FM_GUARANTEED, FM_FLUSH);
if (pfsPlayer->GetMoney() < 0)
{
LPCSTR pszContext = pfsPlayer->GetIGCShip() ?
pfsPlayer->GetIGCShip()->GetMission()->GetContextName() : NULL;
_AGCModule.TriggerContextEvent(NULL, AllsrvEventID_MoneyError,
pszContext, pfsPlayer->GetName(), -1, -1, -1, 3,
"PlayerName", VT_LPSTR, pfsPlayer->GetName(),
"MoneyGiven", VT_I4, pfmBucketDonate->moneyGiven,
"MoneyLeft", VT_I4, pfsPlayer->GetMoney());
}
SideID sid = pside->GetObjectID();
BEGIN_PFM_CREATE(g.fm, pfmBucketStatus, S, BUCKET_STATUS)
END_PFM_CREATE
pfmBucketStatus->timeTotal = pbucket->GetTime();
pfmBucketStatus->moneyTotal = pbucket->GetMoney();
pfmBucketStatus->iBucket = pfmBucketDonate->iBucket;
pfmBucketStatus->sideID = sid;
IbuyableIGC* b = pbucket->GetBuyable();
CFMGroup * pgrp = ((b->GetObjectType() == OT_development) && (b->GetObjectID() == c_didTeamMoney)) ?
pfsMission->GetGroupMission() :
CFSSide::FromIGC(pside)->GetGroup();
g.fm.SendMessages(pgrp, FM_GUARANTEED, FM_FLUSH);
}
if (mnyRefund)
{
assert (mnyRefund > 0);
BEGIN_PFM_CREATE(g.fm, pfmMoneyChange, S, MONEY_CHANGE)
END_PFM_CREATE
pfmMoneyChange->dMoney = mnyRefund;
pfmMoneyChange->sidTo = pfsPlayer->GetShipID();
pfmMoneyChange->sidFrom = NA;
g.fm.SendMessages(pfsPlayer->GetConnection(), FM_GUARANTEED, FM_FLUSH);
}
break;
}
case FM_C_PLAYER_DONATE:
{
if (!pfsMission || (pfsMission->GetStage() != STAGE_STARTED))
break;
CASTPFM(pfmPlayerDonate, C, PLAYER_DONATE, pfm);
TrapHackBoot(pfmPlayerDonate->moneyGiven > 0);
TrapHackBoot(pfsPlayer->GetMoney() >= pfmPlayerDonate->moneyGiven);
CFSShip * pfssTo = CFSShip::GetShipFromID(pfmPlayerDonate->shipID);
CFMRecipient * prcp = NULL;
if (pfmPlayerDonate->moneyGiven > 0)
{
BEGIN_PFM_CREATE(g.fm, pfmMoneyChange, S, MONEY_CHANGE)
END_PFM_CREATE
pfmMoneyChange->dMoney = pfmPlayerDonate->moneyGiven;
if (pfssTo && (pfsPlayer->GetSide() == pfssTo->GetSide()) && (pfsPlayer->GetMoney() >= pfmPlayerDonate->moneyGiven))
{
pfmMoneyChange->sidTo = pfmPlayerDonate->shipID;
pfmMoneyChange->sidFrom = pfsPlayer->GetShipID();
pfsPlayer->SetMoney(pfsPlayer->GetMoney() - pfmMoneyChange->dMoney);
pfssTo->SetMoney(pfssTo->GetMoney() + pfmMoneyChange->dMoney);
prcp = CFSSide::FromIGC(pfsPlayer->GetSide())->GetGroup();
}
else
{
debugf("%s tried to donate money to ship %d, which doesn't exist in mission.\n",
pfsPlayer->GetName(), pfmPlayerDonate->shipID);
assert (pfmPlayerDonate->moneyGiven > 0);
pfmMoneyChange->sidTo = pfsPlayer->GetShipID();
pfmMoneyChange->sidFrom = NA;
prcp = pfsPlayer->GetConnection();
}
g.fm.SendMessages(prcp, FM_GUARANTEED, FM_FLUSH);
}
}
break;
case FM_CS_ORDER_CHANGE:
{
if (!pfsMission || (pfsMission->GetStage() != STAGE_STARTED))
break;
CASTPFM(pfmOC, CS, ORDER_CHANGE, pfm);
IshipIGC* pship = pfsPlayer->GetIGCShip();
assert (pship);
IsideIGC* pside = pship->GetSide();
if (pside->GetObjectID() >= 0)
{
ImodelIGC* pmodel = pMission->GetModel(pfmOC->objectType, pfmOC->objectID);
pship->SetCommand(pfmOC->command, pmodel, pfmOC->commandID);
}
}
break;
case FM_CS_CHANGE_TEAM_CIV:
{
if (!pfsMission)
break;
IsideIGC * pside = pfsPlayer->GetSide();
SideID sid = pside->GetObjectID();
if (sid == SIDE_TEAMLOBBY || pfsPlayer != pfsMission->GetLeader(sid))
break;
CASTPFM(pfmChangeTeamCiv, CS, CHANGE_TEAM_CIV, pfm);
TrapHackBoot(NA != pfmChangeTeamCiv->civID);
TrapHackBoot(sid == pfmChangeTeamCiv->iSide);
if (pfsMission->GetStage() == STAGE_NOTSTARTED)
{
IcivilizationIGC * pciv = pMission->GetCivilization(pfmChangeTeamCiv->civID);
TrapHackBoot(pciv);
g.fm.ForwardMessage(pfsMission->GetGroupMission(), pfmChangeTeamCiv, FM_GUARANTEED);
pfsMission->SetSideCiv(pside, pciv);
}
}
break;
case FM_CS_SIDE_INACTIVE:
{
TrapHackBoot(pfsMission);
TrapHackBoot(pfsMission->GetOwner() == pfsPlayer);
TrapHackBoot(pfsMission->GetStage() == STAGE_NOTSTARTED);
TrapHackBoot(!pfsMission->GetMissionDef()->misparms.bObjectModelCreated);
CASTPFM(pfmSideInactive, CS, SIDE_INACTIVE, pfm);
SideID sid = pfmSideInactive->sideID;
if (!pfsMission->HasPlayers(pfsMission->GetIGCMission()->GetSide(sid),true))
pfsMission->SetSideActive(sid,pfmSideInactive->bActive); else pfmSideInactive->bActive = pfsMission->GetSideActive(sid);
bool bAET = pfsMission->GetAllowEmptyTeams();
bool bAllActive = true;
for (SideID i = 0; i < pfsMission->GetCountSides() ; i++) {
if (!pfsMission->GetSideActive(i))
bAllActive = false;
}
bool bMustChangeAET = false;
if (bAllActive && bAET) bMustChangeAET = true; if (!bAllActive && !bAET) bMustChangeAET = true; if (bMustChangeAET)
{
pfsMission->SetAllowEmptyTeams(!bAET); pfmSideInactive->bChangeAET = true;
pfmSideInactive->bAET = pfsMission->GetAllowEmptyTeams();
}
else
pfmSideInactive->bChangeAET = false;
g.fm.ForwardMessage(pfsMission->GetGroupMission(), pfmSideInactive, FM_GUARANTEED); }
break;
case FM_CS_SET_TEAM_INFO:
{
if (!pfsMission)
break;
if (pfsMission->GetStage() == STAGE_NOTSTARTED
&& !pfsMission->GetMissionDef()->misparms.bLockTeamSettings)
{
CASTPFM(pfmSetTeamInfo, CS, SET_TEAM_INFO, pfm);
TrapHackBoot(pfmSetTeamInfo->sideID >= 0);
TrapHackBoot(pfmSetTeamInfo->sideID < c_cSidesMax);
TrapHackBoot(NULL != memchr(pfmSetTeamInfo->SideName, 0, c_cbName));
TrapHackBoot(pfsPlayer->GetIsMemberOfSquad(pfmSetTeamInfo->squadID));
if (pfmSetTeamInfo->sideID >= pfsMission->GetCountSides()
|| pfsMission->GetLeader(pfmSetTeamInfo->sideID) != pfsPlayer
|| pfsPlayer->GetSide()->GetObjectID() != pfmSetTeamInfo->sideID)
break;
if (pfsMission->GetMissionDef()->misparms.bSquadGame)
{
TrapHackBoot(pfsPlayer->GetCanLeadSquad(pfmSetTeamInfo->squadID)
|| pfsPlayer->GetSide()->GetSquadID() == pfmSetTeamInfo->squadID);
if (pfmSetTeamInfo->squadID != NA)
pfsMission->SetSideSquad(pfmSetTeamInfo->sideID, pfmSetTeamInfo->squadID);
}
else
{
if (pfmSetTeamInfo->squadID == NA)
pfsMission->SetSideName(pfmSetTeamInfo->sideID, pfmSetTeamInfo->SideName);
}
}
}
break;
case FM_CS_DELPOSITIONREQ:
{
if (!pfsMission)
break;
CASTPFM(pfmDelPositionReq, CS, DELPOSITIONREQ, pfm);
ShipID shipID = pfsPlayer->GetShipID();
if (pfmDelPositionReq->shipID == shipID)
{
TrapHackBoot(pfmDelPositionReq->reason == DPR_Canceled);
}
else
{
TrapHackBoot(pfmDelPositionReq->reason == DPR_Rejected);
}
TrapHackBoot(pfmDelPositionReq->iSide >= 0 && pfmDelPositionReq->iSide < c_cSidesMax);
if (pfmDelPositionReq->iSide >= pfsMission->GetCountSides())
break;
if (pfmDelPositionReq->shipID != shipID
&& pfsPlayer != pfsMission->GetLeader(pfmDelPositionReq->iSide))
break;
g.fm.ForwardMessage(pfsMission->GetGroupMission(), pfm, FM_GUARANTEED);
pfsMission->RemoveJoinRequest(pfsPlayer, pfsMission->GetIGCMission()->GetSide(SIDE_TEAMLOBBY));
}
break;
case FM_CS_MISSIONPARAMS:
{
if (!pfsMission)
break;
CASTPFM(pfmMissionParams, CS, MISSIONPARAMS, pfm);
if (pfsMission->GetOwner() != pfsPlayer)
break;
TrapHackBoot(pfmMissionParams->missionparams.Invalid(true) == NULL);
pfmMissionParams->missionparams.bObjectModelCreated =
!!pfsMission->GetMissionDef()->misparms.bObjectModelCreated;
#if !defined(ALLSRV_STANDALONE)
TrapHackBoot(pfmMissionParams->missionparams.bClubGame == true);
#else TrapHackBoot(pfmMissionParams->missionparams.bClubGame == false);
#endif TrapHackBoot(pfmMissionParams->missionparams.bLockGameOpen
== pfsMission->GetMissionDef()->misparms.bLockGameOpen);
TrapHackBoot(pfmMissionParams->missionparams.nTotalMaxPlayersPerGame
== pfsMission->GetMissionDef()->misparms.nTotalMaxPlayersPerGame);
if (pfsMission->GetMissionDef()->misparms.bLockGameOpen)
{
TrapHackBoot(
pfmMissionParams->missionparams.nMaxPlayersPerTeam
== pfsMission->GetMissionDef()->misparms.nMaxPlayersPerTeam
|| pfmMissionParams->missionparams.nMaxPlayersPerTeam
>= pfmMissionParams->missionparams.nTotalMaxPlayersPerGame
/ pfmMissionParams->missionparams.nTeams);
}
if (pfsMission->GetStage() == STAGE_NOTSTARTED)
{
#if defined(ALLSRV_STANDALONE)
if (pfmMissionParams->missionparams.bObjectModelCreated)
{
strcpy(pfmMissionParams->missionparams.strGamePassword,
pfsMission->GetMissionDef()->misparms.strGamePassword);
strcpy(pfmMissionParams->missionparams.strGameName,
pfsMission->GetMissionDef()->misparms.strGameName);
}
#endif pfsMission->SetMissionParams(pfmMissionParams->missionparams);
g.fm.ForwardMessage(pfsMission->GetGroupMission(), pfsMission->GetMissionDef(), FM_GUARANTEED);
pfsMission->SetLobbyIsDirty();
LPCSTR pszContext = pfsMission->GetIGCMission()->GetContextName();
_AGCModule.TriggerContextEvent(NULL, EventID_GameStateChange, pszContext,
pfsMission->GetMissionDef()->misparms.strGameName,
pfsMission->GetMissionID(), -1, -1, 0);
}
else
{
}
}
break;
case FM_C_START_GAME:
{
TrapHackBoot(pfsMission);
TrapHackBoot(pfsMission->GetOwner() == pfsPlayer);
if (pfsMission->GetStage() == STAGE_NOTSTARTED)
{
if (pfsMission->FAllReady())
{
pfsMission->StartCountdown(c_fMissionBriefingCountdown);
}
}
}
break;
case FM_CS_SET_TEAM_LEADER:
{
if (!pfsMission)
break;
CASTPFM(pfmSetTeamLeader, CS, SET_TEAM_LEADER, pfm);
IsideIGC* psidePlayer = pfsPlayer->GetSide();
SideID sid = psidePlayer->GetObjectID();
TrapHackBoot(sid >= 0 && sid < c_cSidesMax);
if (pfsPlayer == pfsMission->GetLeader(sid))
{
TrapHackBoot(sid == pfmSetTeamLeader->sideID);
CFSShip* pfssNewLeader = CFSShip::GetShipFromID(pfmSetTeamLeader->shipID);
if (pfssNewLeader && pfssNewLeader->IsPlayer()
&& pfssNewLeader->GetSide() == psidePlayer)
{
CFSPlayer * pfspNewLeader = pfssNewLeader->GetPlayer();
if (pfspNewLeader->GetSide() == psidePlayer)
pfsMission->SetLeader(pfspNewLeader);
}
}
}
break;
case FM_C_RIPCORD_REQUEST:
{
if (!pfsMission || (pfsMission->GetStage() != STAGE_STARTED) || (pfsPlayer->GetIGCShip()->GetSide()->GetObjectID() < 0) ||
pfsPlayer->GetIGCShip()->GetParentShip() ||
(pfsPlayer->GetIGCShip()->GetCluster() == NULL) ||
(pfsPlayer->GetIGCShip()->GetFlag() != NA) ||
pfsPlayer->GetIGCShip()->GetBaseHullType()->HasCapability(c_habmNoRipcord))
{
break;
}
CASTPFM(pfmRipcord, C, RIPCORD_REQUEST, pfm);
RequestRipcord(pfsPlayer->GetIGCShip(), pfsMission->GetIGCMission()->GetCluster(pfmRipcord->sidRipcord));
}
break;
case FM_C_REQPINGDATA:
{
CFMConnection * cnxn = pfsPlayer->GetConnection();
if(cnxn->PingQuery()) { ListConnections::Iterator iterCnxn(*g.fm.GetConnections());
while (!iterCnxn.End())
{
CFMConnection & cnxn = *iterCnxn.Value();
iterCnxn.Next();
CFSPlayer * pfsTempPlayer = CFSPlayer::GetPlayerFromConnection(cnxn);
if(pfsTempPlayer) {
BEGIN_PFM_CREATE(g.fm, pfmPingData, S, PINGDATA)
END_PFM_CREATE
pfmPingData->shipID = pfsTempPlayer->GetShipID();
DPN_CONNECTION_INFO Connection_Info;
Connection_Info.dwSize = sizeof(DPN_CONNECTION_INFO);
if(g.fm.GetConnectionInfo(&cnxn, Connection_Info) == S_OK) {
pfmPingData->ping = Connection_Info.dwRoundTripLatencyMS;
DWORD m_lastLost;
DWORD m_lastPackets;
cnxn.GetPacketLossData(&m_lastPackets,&m_lastLost);
DWORD packets_now = Connection_Info.dwPacketsSentGuaranteed + Connection_Info.dwPacketsSentNonGuaranteed;
DWORD lost_now = Connection_Info.dwPacketsRetried + Connection_Info.dwPacketsDropped;
float fLossPercentage;
if ((packets_now-m_lastPackets) > 0) fLossPercentage = (float)((float)(lost_now - m_lastLost)/(float)(packets_now-m_lastPackets))*100;
else
fLossPercentage = 0.0;
pfmPingData->loss = (unsigned int)fLossPercentage;
} else {
pfmPingData->ping = 0;
pfmPingData->loss = 0;
}
}
}
BEGIN_PFM_CREATE(g.fm, pfmPingDataOpenWindow, S, PINGDATA)
END_PFM_CREATE
pfmPingDataOpenWindow->shipID = -1;
pfmPingDataOpenWindow->ping = 1;
g.fm.SendMessages(pfsPlayer->GetConnection(),FM_GUARANTEED, FM_FLUSH);
} else {
BEGIN_PFM_CREATE(g.fm, pfmPingData, S, PINGDATA)
END_PFM_CREATE
pfmPingData->shipID = -1;
pfmPingData->ping = 1;
g.fm.SendMessages(pfsPlayer->GetConnection(),FM_GUARANTEED, FM_FLUSH);
}
}
break;
default:
{
TrapHackBoot(false);
}
break;
} assert(0 == g.fm.CbUsedSpaceInOutbox());
timerOnAppMessage.Stop("...for message type %s\n", g_rgszMsgNames[pfm->fmid]);
return(S_OK);
}
HANDLE CreateUniqueMutex()
{
SECURITY_ATTRIBUTES* psa = NULL;
SECURITY_DESCRIPTOR sd;
SECURITY_ATTRIBUTES sa = {sizeof(sa), &sd, false};
if (IsWinNT())
{
InitializeSecurityDescriptor(&sd, SECURITY_DESCRIPTOR_REVISION);
SetSecurityDescriptorDacl(&sd, true, NULL, FALSE);
psa = &sa;
}
HANDLE hMutex = ::CreateMutex(psa, false, szAllSrvRunningGlobal);
if (!hMutex)
hMutex = ::CreateMutex(psa, false, szAllSrvRunning);
return hMutex;
}
void CheckForNoShows()
{
const ListFSMission * plistMission = CFSMission::GetMissions();
for (LinkFSMission * plinkMission = plistMission->first(); plinkMission; plinkMission = plinkMission->next())
{
CFSMission * pfsMission = plinkMission->data();
if (!pfsMission->GetMissionDef()->misparms.bObjectModelCreated && !strcmp(pfsMission->GetMissionDef()->misparms.szIGCStaticFile,IGC_ENCRYPT_CORE_FILENAME) && pfsMission->GetCountOfPlayers(NULL, true) == 0)
{
SYSTEMTIME stNow;
FILETIME ftNow;
FILETIME ftStart;
::GetSystemTime(&stNow);
SystemTimeToFileTime(&stNow, &ftNow);
SystemTimeToFileTime(pfsMission->GetStartTime(), &ftStart);
ULONGLONG ullStart;
ULONGLONG ullNow;
CopyMemory(&ullStart, &ftStart, sizeof(ullStart));
CopyMemory(&ullNow, &ftNow, sizeof(ullNow));
if ((ULONG) (ullNow - ullStart) > 300000000) {
debugf("No one showed up for mission %x, killing it.\n", pfsMission->GetCookie());
delete pfsMission;
break; }
}
}
}
void DisconnectFromLobby()
{
if (g.fmLobby.IsConnected())
{
_AGCModule.TriggerEvent(NULL, AllsrvEventID_DisconnectingLobby,
"", -1, -1, -1, 1,
"LobbyServer", VT_LPSTR, (LPCTSTR)g.strLobbyServer);
g.fmLobby.Shutdown();
_AGCModule.TriggerEvent(NULL, AllsrvEventID_DisconnectedLobby,
"", -1, -1, -1, 1,
"LobbyServer", VT_LPSTR, (LPCTSTR)g.strLobbyServer);
}
}
void ProcessNetworkMessages()
{
static CTimer timerReceiveMessages("in ReceiveMessages()", .1f);
static CTimer timerReceiveLobbyMessages("in lobby ReceiveMessages()", .1f);
static CTimer timerClientRollCall("doing client roll call", .1f);
timerReceiveMessages.Start();
g.fm.ReceiveMessages();
timerReceiveMessages.Stop();
if (g.fmLobby.IsConnected())
{
timerReceiveLobbyMessages.Start();
g.fmLobby.ReceiveMessages();
timerReceiveLobbyMessages.Stop();
}
static Time timeRollCall = Time::Now();
if (g.timeNow.clock() - timeRollCall.clock() > (CLOCKS_PER_SEC*10)) {
timerClientRollCall.Start();
ListConnections::Iterator iterCnxn(*g.fm.GetConnections());
while (!iterCnxn.End())
{
CFMConnection & cnxn = *iterCnxn.Value();
iterCnxn.Next(); DWORD m_lastLost;
DWORD m_lastPackets;
cnxn.GetPacketLossData(&m_lastPackets,&m_lastLost);
DPN_CONNECTION_INFO Connection_Info;
Connection_Info.dwSize = sizeof(DPN_CONNECTION_INFO);
if(g.fm.GetConnectionInfo(&cnxn, Connection_Info) == S_OK) {
m_lastLost = Connection_Info.dwPacketsDropped + Connection_Info.dwPacketsRetried;
m_lastPackets = Connection_Info.dwPacketsSentNonGuaranteed + Connection_Info.dwPacketsSentGuaranteed;
cnxn.SetPacketLossData(m_lastPackets,m_lastLost);
}
DWORD cMsgs;
DWORD cbMsgs;
HRESULT hr = g.fm.GetConnectionSendQueue(&cnxn, &cMsgs, &cbMsgs);
const DWORD cMaxQ = 100; int cMsgPayload;
CFSPlayer * pfsPlayer = CFSPlayer::GetPlayerFromConnection(cnxn);
if (pfsPlayer && pfsPlayer->GetJustJoined() == true) {
cMsgPayload = cMsgs;
cnxn.SetQueuePayload(cMsgPayload);
pfsPlayer->SetJustJoined(false);
} else {
cMsgPayload = cnxn.GetQueuePayload();
}
if (cMsgPayload > cMsgs) {
cMsgPayload = cMsgs;
cnxn.SetQueuePayload(cMsgPayload);
}
if ((cnxn.IncAbsentCount() > 6) || FAILED(hr) ||
((cMsgs-cMsgPayload) > cMaxQ)) {
char szBuff[128];
int cb = wsprintf(szBuff, "Nuking %s(%u) because ", cnxn.GetName(), cnxn.GetID());
if (FAILED(hr))
{
wsprintf(szBuff + cb, "GetConnectionSendQueue returned 0x%08x.\n", hr);
debugf(szBuff);
}
else
{
DWORD dwHundredbpsG, dwmsLatencyG, dwHundredbpsU, dwmsLatencyU;
hr = g.fm.GetLinkDetails(&cnxn, &dwHundredbpsG, &dwmsLatencyG, &dwHundredbpsU, &dwmsLatencyU);
float kbpsG = (float) dwHundredbpsG / 10.0f;
float kbpsU = (float) dwHundredbpsU / 10.0f;
if (cMsgs > cMaxQ)
wsprintf(szBuff + cb, "they had too many messages (%u) queued up to them.\n", cMsgs);
else
wsprintf(szBuff + cb, "they missed roll call, with messages (%u) queued up to them.\n", cMsgs);
debugf(szBuff);
debugf("DPlay's view of the link was: %.1fkbps, %ums.\n", kbpsG, dwmsLatencyG);
}
float flTimeDiff = ((float) (timeRollCall.clock() - cnxn.GetLastComplete())) / 1000.0f;
debugf("The last completion was %.2f seconds ago.\n", flTimeDiff);
g.fm.DeleteConnection(cnxn);
}
}
timeRollCall = g.timeNow;
timerClientRollCall.Stop();
if (g.pServerCounters)
g.pServerCounters->timeNetworkMessages =
timerReceiveMessages.LastInterval() +
timerReceiveLobbyMessages.LastInterval() +
timerClientRollCall.LastInterval();
}
else if (g.pServerCounters)
g.pServerCounters->timeNetworkMessages = timerReceiveMessages.LastInterval() + timerReceiveLobbyMessages.LastInterval();
bool bSupposedToConnectToLobby;
bool bServerStartedByUI = false;
#if defined(ALLSRV_STANDALONE)
bServerStartedByUI = _Module.WasCOMStarted();
bSupposedToConnectToLobby = !(FEDSRV_GUID != g.fm.GetHostApplicationGuid()); #else
bSupposedToConnectToLobby = !g.strLobbyServer.IsEmpty();
#endif
if (bSupposedToConnectToLobby) {
if (g.fmLobby.IsConnected())
{
static Time timeRollCallLobby = Time::Now();
if (g.timeNow.clock() - timeRollCallLobby.clock() > 4000) {
BEGIN_PFM_CREATE(g.fmLobby, pfmHeartbeat, S, HEARTBEAT)
END_PFM_CREATE
g.fmLobby.SendMessages(g.fmLobby.GetServerConnection(), FM_GUARANTEED, FM_FLUSH);
timeRollCallLobby = g.timeNow;
CheckForNoShows(); }
}
else {
static Time timeLastTry = Time::Now();
if (g.timeNow.clock() - timeLastTry.clock() > 60000)
{
const ListFSMission * plistMission = CFSMission::GetMissions();
bool fAnyRunning = false;
for (LinkFSMission * plinkMission = plistMission->first(); !fAnyRunning && plinkMission; plinkMission = plinkMission->next())
{
CFSMission * pfsMission = plinkMission->data();
if (pfsMission->GetStage() == STAGE_STARTED)
fAnyRunning = true;
}
if (!fAnyRunning)
ConnectToLobby(NULL);
timeLastTry = g.timeNow;
}
}
}
}
void UpdateMissions(Time timeStart, Time timePrevious)
{
static CTimer timerIGC("updating all IGC missions", .1f);
timerIGC.Start();
static Time timLastStationUpdate(Time::Now());
const float dtimStationUpdateInterval = 0.75f;
const ListFSMission * plistMission = CFSMission::GetMissions();
LinkFSMission * plinkMissionNext;
for (LinkFSMission * plinkMission = plistMission->first(); plinkMission; plinkMission = plinkMissionNext)
{
plinkMissionNext = plinkMission->next();
CFSMission * pfsMission = plinkMission->data();
if (pfsMission->GetStage() < STAGE_OVER &&
pfsMission->GetIGCMission() != g.trekCore) {
float dtTimeTillStart = pfsMission->GetMissionDef()->misparms.timeStart - timeStart;
float dtPreviousTimeTillStart = pfsMission->GetMissionDef()->misparms.timeStart - timePrevious;
if (pfsMission->GetStage() == STAGE_NOTSTARTED)
{
if (pfsMission->GetMissionDef()->misparms.bAutoRestart)
{
if (dtTimeTillStart <= c_fMissionBriefingCountdown)
{
if (pfsMission->GetMissionDef()->misparms.bAllowEmptyTeams)
{
pfsMission->StartCountdown(max(0.0f, dtTimeTillStart));
}
else
{
for (SideID sideId = 0; sideId < pfsMission->GetMissionDef()->misparms.nTeams; sideId++)
pfsMission->SetForceReady(sideId, true);
if (pfsMission->FAllReady()) pfsMission->StartCountdown(max(0.0f, dtTimeTillStart));
else
{
if (dtTimeTillStart <= 0)
{
pfsMission->SetStage(STAGE_OVER);
pfsMission->GetSite()->SendChat(NULL, CHAT_EVERYONE, NA, NA,
"Game canceled due to lack of players", c_cidNone, NA, NA, NULL, true);
}
}
}
}
else if (dtTimeTillStart <= 2 * c_fMissionBriefingCountdown
&& dtPreviousTimeTillStart > 2 * c_fMissionBriefingCountdown)
{
if (!pfsMission->GetMissionDef()->misparms.bAllowEmptyTeams
&& !pfsMission->FAllReady())
{
char szMessage[100];
sprintf(szMessage,
"Warning: Game will be canceled if all teams are not ready in %d seconds.",
int(2 * c_fMissionBriefingCountdown));
pfsMission->GetSite()->SendChat(NULL, CHAT_EVERYONE, NA, NA,
szMessage, c_cidNone, NA, NA, NULL, true);
}
}
}
else if (pfsMission->GetMissionDef()->misparms.bAutoStart && pfsMission->FAllReady())
{
pfsMission->StartCountdown(pfsMission->GetMissionDef()->misparms.fStartCountdown);
}
}
if (pfsMission->GetStage() == STAGE_STARTING
&& timeStart > pfsMission->GetMissionDef()->misparms.timeStart
&& (pfsMission->HasPlayers(NULL, true)
|| pfsMission->GetMissionDef()->misparms.bAllowEmptyTeams)
)
{
pfsMission->StartGame();
}
pfsMission->UpdateLobby(timeStart);
MoveShips(pfsMission, timeStart, timePrevious);
if (pfsMission->GetStage() == STAGE_STARTED)
{
if (timeStart - timLastStationUpdate > dtimStationUpdateInterval)
{
for (ShipLinkIGC* psl = pfsMission->GetIGCMission()->GetShips()->first(); (psl != NULL); psl = psl->next())
{
IshipIGC* pship = psl->data();
IstationIGC* pstation = pship->GetStation();
if (pstation != NULL)
{
CFSShip* pfsship = (CFSShip*)(pship->GetPrivateData());
if (pfsship->IsPlayer())
{
BEGIN_PFM_CREATE(g.fm, pfmStationsUpdate, S, STATIONS_UPDATE)
FM_VAR_PARM(NULL, sizeof(StationState))
END_PFM_CREATE
StationState* pss = (StationState*)(FM_VAR_REF(pfmStationsUpdate, rgStationStates));
pss->stationID = pstation->GetObjectID();
pss->bpHullFraction = pstation->GetFraction();
pss->bpShieldFraction = pstation->GetShieldFraction();
g.fm.SendMessages(pfsship->GetPlayer()->GetConnection(), FM_NOT_GUARANTEED, FM_FLUSH);
}
}
}
}
pfsMission->DoTick(timeStart);
}
{
for (ShipLinkIGC* psl = pfsMission->GetIGCMission()->GetShips()->first(); (psl != NULL); psl = psl->next())
{
IshipIGC* pship = psl->data();
CFSShip* pfsship = (CFSShip*)(pship->GetPrivateData());
if (pfsship->IsPlayer())
pfsship->GetPlayer()->IncrementChatBudget();
}
}
}
if (pfsMission->ShouldDelete())
delete pfsMission;
}
timLastStationUpdate = timeStart;
timerIGC.Stop();
if (g.pServerCounters)
g.pServerCounters->timeIGCWork= timerIGC.LastInterval();
}
#if defined(ALLSRV_STANDALONE)
void GetExePath(char * szEXEPath)
{
::GetModuleFileName(NULL, szEXEPath, MAX_PATH);
char* p = strrchr(szEXEPath, '\\');
if (p)
{
p++;
*p = 0; }
else
{
szEXEPath[0] = '\\';
szEXEPath[1] = '\0';
}
}
bool IsCFGFileValid(const char * szFileName)
{
const char * c_szValidCfg = "THIS IS A VALID CONFIG FILE";
ZFile file(szFileName);
int n = file.GetLength(); if (n != -1 && n != 0)
{
char* pData = new char[n+1];
memcpy(pData, file.GetPointer(), n);
pData[n] = 0;
bool bValid = strstr(pData, c_szValidCfg) != NULL;
delete [] pData;
if (!bValid)
{
debugf("File %s is not a valid config file.\n", szFileName);
return false;
}
}
else
{
debugf("File %s error while trying to load downloaded config file.\n", szFileName);
return false;
}
return true;
}
IHTTPSession * BeginConfigDownload()
{
ZVersionInfo vi;
ZString strBuild(vi.GetFileBuildNumber());
char szConfig[MAX_PATH];
lstrcpy(szConfig, "http://Allegiance.zone.com/Allegiance.cfg");
CRegKey key;
if (ERROR_SUCCESS == key.Open(HKEY_LOCAL_MACHINE, HKLM_FedSrv, KEY_READ))
{
ZString strConfig;
if (SUCCEEDED(LoadRegString(key, "cfgfile", strConfig)))
{
strcpy(szConfig, PCC(strConfig));
}
}
DeleteFile(".\\temp.cfg") ; if (ZString(szConfig).Find("http://") == -1)
{
CopyFile(szConfig, ".\\temp.cfg", FALSE); debugf("Using local config file due to registry setting for ConfigFile because \"http://\" was missing from it. %s\n", szConfig);
return NULL; }
else
{
IHTTPSession * pHTTPSession = CreateHTTPSession(NULL);
const char * szFileList[] = { szConfig, "temp.cfg", NULL };
pHTTPSession->InitiateDownload(szFileList, "."); return pHTTPSession;
}
}
bool OnAutoUpdateEXEDownloadDone(const char * szFilelistCRC, int nFilelistCRC, int nFilelistSize, const char * szSite, const char * szDirectory, int nAutoUpdateCRC, const char * szEXEPath)
{
char szPath[MAX_PATH + 16];
strcpy(szPath, szEXEPath);
strcat(szPath, "AutoUpdate.exe");
if (nAutoUpdateCRC != FileCRC(szPath, NULL))
{
char * szMsg = "ERROR: AutoUpdate was aborted. CRC for AutoUpdate.exe downloaded did not match CRC found in cfg file. You will not be able to host a public game.\n";
printf(szMsg);
MessageBox(NULL, szMsg, "Allegiance Server", MB_SERVICE_NOTIFICATION);
debugf("AutoUpdate.exe CRC mismatch\n");
return false;
}
char * szLaunchPostUpdate;
if (_Module.WasCOMStarted())
{
szLaunchPostUpdate = "AllSrvUI.exe";
}
else
{
szLaunchPostUpdate = _Module.IsInstalledAsService() ? "S:AllSrv" : "AllSrv.exe"; }
char szCommandLine[MAX_PATH * 10];
_snprintf (szCommandLine, sizeof(szCommandLine)-1, "%s %s %d \"%s\" \"%s\" \"%s\"", szLaunchPostUpdate, szFilelistCRC, nFilelistSize, szSite, szDirectory, PCC(g.strArtPath));
printf("Launching AutoUpdate.exe ... ");
int nErr;
if((nErr = (int)ShellExecute(0,
"Open",
szPath,
szCommandLine,
NULL,
SW_SHOWNORMAL)
) <= 32)
{
printf("failed.\nError launching AutoUpdate.exe (Code = %d). You will not be able to host a public game.\n", nErr);
MessageBox(NULL, "Error launching AutoUpdate.exe. You will not be able to host a public game.", "Allegiance Server", MB_SERVICE_NOTIFICATION);
debugf("Couldn't launch AutoUpdate.exe (Code = %d)\n", nErr);
return false;
}
printf("succeeded.\n");
PostQuitMessage(0); return false;
}
bool DownloadAutoUpdateEXE(const char * szFilelistCRC, int nFilelistCRC, int nFilelistSize, const char * szSite, const char * szDirectory, int nAutoUpdateCRC, const char * szAutoUpdateURL)
{
char szEXEPath[MAX_PATH];
GetExePath(szEXEPath);
char szPath[MAX_PATH];
strcpy(szPath, szEXEPath);
strcat(szPath, "AutoUpdate.exe");
printf("Server is out-of-date.\n");
if (nAutoUpdateCRC != FileCRC(szPath, NULL))
{
IHTTPSession * pHTTPSession = CreateHTTPSession(NULL);
const char * szFileList[] = { szAutoUpdateURL, "AutoUpdate.exe", NULL };
pHTTPSession->InitiateDownload(szFileList, szEXEPath);
debugf("Downloading AutoUpdate.exe file...");
printf("Downloading AutoUpdate.exe file ... ");
while(pHTTPSession->ContinueDownload())
{
Sleep(100);
}
debugf("Done\n");
bool bErrorOccurred = pHTTPSession->GetLastErrorMessage() ? true : false;
char szErrorMsg[512];
if (bErrorOccurred)
_snprintf(szErrorMsg, sizeof(szErrorMsg), "\nError Connecting to Zone. You will not be able to host a public game. AutoUpdate.exe download failed. \r\n%s", pHTTPSession->GetLastErrorMessage());
delete pHTTPSession;
if (bErrorOccurred)
{
printf("failed: %s\n", szErrorMsg);
MessageBox(NULL, szErrorMsg, "Allegiance Server", MB_SERVICE_NOTIFICATION);
debugf("%s\n", szErrorMsg);
return false;
}
else
printf("succeeded.\n");
}
return OnAutoUpdateEXEDownloadDone(szFilelistCRC, nFilelistCRC, nFilelistSize, szSite, szDirectory, nAutoUpdateCRC, szEXEPath);
}
bool OnCFGDownloadDone(const char * szConfig) {
char szLobby[_MAX_PATH * 2];
GetPrivateProfileString("Allegiance", "PublicLobby", "",
szLobby, sizeofArray(szLobby), szConfig);
if (*szLobby == '\0')
return false;
g.strLobbyServer = szLobby;
char szPort[8];
GetPrivateProfileString("Allegiance", "LobbyServerPort", "2303",
szPort, sizeofArray(szPort), szConfig);
g.dwLobbyPort = atoi(szPort);
char szFilelistCRC[50];
#ifdef USEAUTH
char szAuthServer[128]; GetPrivateProfileString("Allegiance", "ZAuth", "auth.zone.com",
szAuthServer, sizeof(szAuthServer), szConfig);
g.strAuthServer = szAuthServer;
#endif
GetPrivateProfileString("AllSrvUI", "FilelistCRC", "0",
szFilelistCRC, sizeof(szFilelistCRC), szConfig);
_strupr(szFilelistCRC);
int nFilelistCRC = UTL::hextoi(szFilelistCRC);
if (nFilelistCRC == 0)
return true;
char szEXEPath[MAX_PATH + 16];
GetExePath(szEXEPath);
char szPath[MAX_PATH + 16];
strcpy(szPath, szEXEPath);
strcat(szPath, "Filelist.txt");
if (FileCRC(szPath, NULL) != nFilelistCRC)
{
char szStr[100];
GetPrivateProfileString("AllSrvUI", "FilelistSize", "0",
szStr, sizeof(szStr), szConfig);
int nFilelistSize = atoi(szStr);
if (nFilelistSize == 0)
return true;
char szSite[512];
GetPrivateProfileString("AllSrvUI", "Site", "",
szSite, sizeof(szSite), szConfig);
if (szSite[0] == '\0')
return true;
char szDirectory[512];
GetPrivateProfileString("AllSrvUI", "Directory", "",
szDirectory, sizeof(szDirectory), szConfig);
if (szDirectory[0] == '\0')
return true;
char szAutoUpdateURL[512];
GetPrivateProfileString("AllSrvUI", "AutoUpdateURL", "",
szAutoUpdateURL, sizeof(szAutoUpdateURL), szConfig);
if (szAutoUpdateURL[0] == '\0')
return true;
char szAutoUpdateCRC[30];
GetPrivateProfileString("AllSrvUI", "AutoUpdateCRC", "",
szAutoUpdateCRC, sizeof(szAutoUpdateCRC), szConfig);
_strupr(szAutoUpdateCRC);
int nAutoUpdateCRC = UTL::hextoi(szAutoUpdateCRC);
if (szAutoUpdateCRC[0] == '\0' || nAutoUpdateCRC == 0)
return true;
return DownloadAutoUpdateEXE(szFilelistCRC, nFilelistCRC, nFilelistSize, szSite, szDirectory, nAutoUpdateCRC, szAutoUpdateURL);
}
else
{
return true;
}
}
bool RetrieveCFGFile() {
IHTTPSession * pHTTPSession = BeginConfigDownload();
if (pHTTPSession)
{
debugf("Downloading cfg file...");
while(pHTTPSession->ContinueDownload())
{
Sleep(100);
}
debugf("Done\n");
bool bErrorOccurred = pHTTPSession->GetLastErrorMessage() ? true : false;
char szErrorMsg[512];
if (bErrorOccurred)
_snprintf(szErrorMsg, sizeof(szErrorMsg), "\nError Connecting to Zone. You will not be able to host a public game. \r\n%s", pHTTPSession->GetLastErrorMessage());
delete pHTTPSession;
if (bErrorOccurred)
{
printf("%s\n", szErrorMsg);
debugf("%s\n", szErrorMsg);
if (!_Module.IsInstalledAsService())
MessageBox(NULL, szErrorMsg, "Allegiance Server", MB_SERVICE_NOTIFICATION);
return false;
}
}
PathString pathCurrent(PathString::GetCurrentDirectory());
PathString pathConfig(pathCurrent + PathString(PathString("temp.cfg").GetFilename()));
if (IsCFGFileValid(PCC(pathConfig)))
{
return OnCFGDownloadDone(PCC(pathConfig));
}
else
{
debugf("\nInvalid CFG File.\n");
char * szErrorMsg = "\nError Connecting to Zone. You will not be able to host a public game. (CFG File is invalid.)\n";
printf(szErrorMsg);
if (!_Module.IsInstalledAsService())
MessageBox(NULL, szErrorMsg, "Allegiance Server", MB_SERVICE_NOTIFICATION);
return false;
}
}
#endif void AnnouncePause()
{
BEGIN_PFM_CREATE(g.fmLobby, pfmPause, S, PAUSE)
END_PFM_CREATE
pfmPause->fPause = g.fPaused;
AGCEventID idEvent = g.fPaused ? AllsrvEventID_Pause : AllsrvEventID_Continue;
_AGCModule.TriggerEvent(NULL, idEvent, "", -1, -1, -1, 0);
char * szMode = g.fPaused ? "paused." : "continued.";
printf("Server %s.\n", szMode);
g.fmLobby.SendMessages(g.fmLobby.GetServerConnection(), FM_GUARANTEED, FM_FLUSH);
}
void RestartPausedMissions()
{
const ListFSMission * plistMission = CFSMission::GetMissions();
for (LinkFSMission * plinkMission = plistMission->first(); plinkMission; plinkMission = plinkMission->next())
{
CFSMission * pfsMission = plinkMission->data();
if (pfsMission->GetStage() == STAGE_OVER && pfsMission->GetMissionDef()->misparms.bAllowRestart)
pfsMission->SetStage(STAGE_NOTSTARTED);
}
}
HRESULT ConnectToLobby(const char * pszLobby_OverrideCFG )
{
DisconnectFromLobby();
assert(!g.fmLobby.IsConnected());
#if defined(ALLSRV_STANDALONE)
if (!RetrieveCFGFile())
return HRESULT_FROM_WIN32(ERROR_CRC);
#endif
if(pszLobby_OverrideCFG)
g.strLobbyServer = pszLobby_OverrideCFG;
printf("Connecting to lobby: %s ... ", PCC(g.strLobbyServer));
_AGCModule.TriggerEvent(NULL, AllsrvEventID_Connecting, "", -1, -1, -1, 1,
"LobbyServer", VT_LPSTR, PCC(g.strLobbyServer));
HRESULT hr = g.fmLobby.JoinSession(
#if defined(ALLSRV_STANDALONE)
FEDFREELOBBYSERVERS_GUID,
#else
FEDLOBBYSERVERS_GUID,
#endif
PCC(g.strLobbyServer), PCC(g.strLocalAddress), g.dwLobbyPort); if (FAILED(hr))
{
printf("failed.\n", PCC(g.strLobbyServer));
return hr;
}
printf("succeeded.\n", PCC(g.strLobbyServer));
g.strLobbyServer = PCC(g.strLobbyServer);
_AGCModule.TriggerEvent(NULL, AllsrvEventID_ConnectedLobby,
"", -1, -1, -1, 1,
"LobbyServer", VT_LPSTR, PCC(g.strLobbyServer));
DWORD dwPort = 0; hr = g.fm.GetListeningPort(&dwPort);
if(FAILED(hr))
{
debugf("Cannot discover listening port.\n");
}
BEGIN_PFM_CREATE(g.fmLobby, pfmLogon, S, LOGON_LOBBY)
FM_VAR_PARM(g.cStaticCoreInfo ? g.vStaticCoreInfo : NULL, g.cStaticCoreInfo * c_cbFileName) FM_VAR_PARM(PCC(g.strLocation), CB_ZTS) END_PFM_CREATE
pfmLogon->cStaticCoreInfo = g.cStaticCoreInfo; pfmLogon->MaxGames = g.cMaxGames; pfmLogon->verLobby = LOBBYVER_LS;
pfmLogon->dwPort = dwPort;
g.fmLobby.SendMessages(g.fmLobby.GetServerConnection(), FM_GUARANTEED, FM_FLUSH);
AnnouncePause();
const ListFSMission * plistMission = CFSMission::GetMissions();
for (LinkFSMission * plinkMission = plistMission->first(); plinkMission; plinkMission = plinkMission->next())
{
CFSMission * pfsMission = plinkMission->data();
BEGIN_PFM_CREATE(g.fmLobby, pfmNewMission, S, NEW_MISSION)
END_PFM_CREATE
pfmNewMission->dwIGCMissionID = pfsMission->GetIGCMission()->GetMissionID();
pfsMission->SetCookie(0);
}
hr = g.fmLobby.SendMessages(g.fmLobby.GetServerConnection(), FM_GUARANTEED, FM_FLUSH);
if (SUCCEEDED(hr))
{
#if defined(ALLSRV_STANDALONE)
if (!_Module.WasCOMStarted())
#endif
StartDefaultGames();
}
return hr;
}
DWORD ProcessMsgPump(int dwSleep, DWORD nCount, LPHANDLE pHandles)
{
static bool s_fWinNT = ::IsWinNT();
Time timeBegin = Time::Now();
DWORD dwSleep1 = dwSleep;
DWORD dwEnd = timeBegin.clock() + dwSleep; static CTimer timerMsgPump("in message pump", 0.25f);
static CTempTimer timerSingleMsg("handling single Windows msg", .01f);
timerMsgPump.Start();
DWORD dwWait = WAIT_TIMEOUT;
do
{
#ifdef DEBUG
dwWait = MsgWaitForMultipleObjectsEx(nCount, pHandles, dwSleep, QS_ALLINPUT, MWMO_ALERTABLE);
#else
dwWait = MsgWaitForMultipleObjects(nCount, pHandles, false, dwSleep, QS_ALLINPUT);
#endif
if (WAIT_TIMEOUT == dwWait)
break;
if ((WAIT_OBJECT_0 + nCount) == dwWait)
{
static MSG msg;
while (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE))
{
timerSingleMsg.Start();
TranslateMessage(&msg);
switch (msg.message)
{
case wm_sql_querydone:
{
CSQLQuery * pQuery = (CSQLQuery *) msg.lParam;
pQuery->DataReady();
break;
}
case wm_fs_pause:
AnnouncePause();
if (!g.fPaused)
RestartPausedMissions();
break;
case WM_QUIT:
_Module.StopAllsrv();
break;
default:
DispatchMessage(&msg);
}
timerSingleMsg.Stop();
}
}
dwSleep = dwEnd - Time::Now().clock();
} while (dwSleep <= dwSleep1); timerMsgPump.Stop();
if (g.pServerCounters)
g.pServerCounters->timeMsgPump= timerMsgPump.LastInterval();
return dwWait;
}
void StartDefaultGames()
{
const ListFSMission * plistMission = CFSMission::GetMissions();
if(0 != plistMission->n())
return;
MissionParams mp;
mp.Reset();
MissionParams mpClean;
mpClean.Reset();
HKEY hKey;
DWORD dwType;
DWORD dwValue;
DWORD cbValue;
if (ERROR_SUCCESS == ::RegOpenKeyEx(HKEY_LOCAL_MACHINE, HKLM_FedSrv, 0, KEY_READ, &hKey))
{
cbValue = sizeof(dwValue);
#if defined(ALLSRV_STANDALONE)
if (ERROR_SUCCESS == ::RegQueryValueEx(hKey, "MaxPlayersPerGame", NULL, &dwType, (unsigned char*)&dwValue, &cbValue))
mp.nTotalMaxPlayersPerGame = min(c_cMaxPlayersPerGame, (short)dwValue);
else
mp.nTotalMaxPlayersPerGame = c_cMaxPlayersPerGame;
#endif
#if defined(ALLSRV_STANDALONE)
mp.nMinPlayersPerTeam = 1;
mp.nMaxPlayersPerTeam = (char)(min(100, (int)mp.nTotalMaxPlayersPerGame / (int)mp.nTeams));
mp.bObjectModelCreated = true; #else
mp.bObjectModelCreated = false; #endif
HRESULT hr = S_OK;
int iGame = 1;
while (SUCCEEDED(hr))
{
char cbValueName[24];
ZString strGameName;
wsprintf(cbValueName, "Game%d", iGame);
hr = LoadRegString(hKey, cbValueName, strGameName);
if (SUCCEEDED(hr))
{
strncpy(mp.strGameName, strGameName, c_cbGameName);
mp.strGameName[c_cbGameName - 1] = '\0';
assert(!mp.Invalid());
ZString strCore;
wsprintf(cbValueName, "Core%d", iGame);
LoadRegString(hKey, cbValueName, strCore);
strncpy(mp.szIGCStaticFile, strCore, c_cbFileName);
ZString strMap;
wsprintf(cbValueName, "LockOpen%d", iGame);
cbValue = sizeof(dwValue);
if (ERROR_SUCCESS == ::RegQueryValueEx(hKey, cbValueName, NULL, &dwType, (unsigned char*)&dwValue, &cbValue))
mp.bLockGameOpen = !!dwValue;
else
mp.bLockGameOpen = mpClean.bLockGameOpen; ZString strRankParam;
wsprintf(cbValueName, "MinRank%d", iGame);
if (LoadRegString(hKey, cbValueName, strRankParam) == S_OK)
sscanf(strRankParam,"%hd",&(mp.iMinRank));
else
mp.iMinRank = mpClean.iMinRank; wsprintf(cbValueName, "MaxRank%d", iGame);
if (LoadRegString(hKey, cbValueName, strRankParam) == S_OK)
sscanf(strRankParam,"%hd",&(mp.iMaxRank));
else
mp.iMaxRank = mpClean.iMaxRank;
printf("Starting game \"%s\"(%s) with core: %s - minrank=%d - maxrank=%d\n", mp.strGameName, (mp.bLockGameOpen == 1) ? "LockOpen":"Not LockOpen",mp.szIGCStaticFile,mp.iMinRank,mp.iMaxRank);
FedSrvSite * psiteFedSrv = new FedSrvSite();
CFSMission * pfsMissionNew = new CFSMission(mp, NULL, psiteFedSrv, psiteFedSrv, NULL, NULL);
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);
}
}
++iGame;
}
RegCloseKey(hKey);
}
}
DWORD WINAPI ReceiveThread(LPVOID pThreadParameter)
{
HANDLE rgeventHandles[2];
ZVersionInfo vi;
debugf("Running %s %s\n", (PCC) vi.GetInternalName(), (PCC) vi.GetProductVersionString());
debugf("Entering ReceiveThread\n");
DWORD dwUpdateInterval = g.nUpdatesPerSecond <= 0 ? (1000 / 10) : (1000 / g.nUpdatesPerSecond); if (g.pServerCounters)
g.pServerCounters->timeCycleTarget = dwUpdateInterval;
printf("Preparing server...\n");
HRESULT hr = CoInitialize(NULL);
ZSucceeded(hr);
_Module.Init(g.hInst); CComObject<CAdminServer>* pServer = NULL;
ZSucceeded(pServer->CreateInstance(&pServer));
ZSucceeded(GetAGCGlobal()->RegisterInterfaceInGlobal(pServer->GetUnknown(),
IID_IUnknown, &g.dwServerGITCookie));
TCHandle shMutexRunning = CreateUniqueMutex();
_Module.RegisterCOMObjects();
#if !defined(ALLSRV_STANDALONE)
hr = g.sql.Init(g.strSQLConfig.m_str, g.idReceiveThread, g.csqlSilentThreads, g.csqlNotifyThreads);
if (FAILED(hr))
{
return hr;
}
#endif
UTL::SetArtPath(g.strArtPath);
g.trekCore = CreateMission(); g.trekCore->Initialize (Time::Now(), &g.siteFedSrv);
debugf("trekCore completed\n");
int iStaticCoreVersion;
#if !defined(ALLSRV_STANDALONE)
iStaticCoreVersion = LoadIGCStaticCore (IGC_ENCRYPT_CORE_FILENAME, g.trekCore, false, DoDecrypt);
#else iStaticCoreVersion = LoadIGCStaticCore (IGC_STATIC_CORE_FILENAME, g.trekCore, false);
#endif assert (iStaticCoreVersion != NA);
debugf("iStaticCoreVersion = %d\n",iStaticCoreVersion);
LoadStaticCoreInfo();
#if defined(ALLSRV_STANDALONE)
if (_Module.WasCOMStarted())
{
pServer->put_PublicLobby(false); }
else
{
g.strLobbyServer="?"; pServer->put_PublicLobby(true); }
#else
pServer->put_PublicLobby(true); #endif rgeventHandles[0] = g.hKillReceiveEvent;
LoadRankInfo();
debugf("LoadRankInfo result: #ranks=%d\n",g.cRankInfo);
debugf("calling LoadStaticMapInfo\n");
LoadStaticMapInfo();
debugf("LoadStaticMapInfo result: #maps=%d\n",g.cStaticMapInfo);
CTimer timerReceiveIterations("between iterations in ReceiveThread loop", .25f);
printf("Ready for clients.\n");
timerReceiveIterations.Start();
Time timeStartIteration = Time::Now();
Time timeEndIteration = timeStartIteration;
DWORD dwWait = WAIT_TIMEOUT;
while (dwWait != WAIT_OBJECT_0)
{
timerReceiveIterations.Stop();
timerReceiveIterations.Start();
if (g.pServerCounters)
g.pServerCounters->timeBetweenInnerLoops = timerReceiveIterations.LastInterval();
timeEndIteration = timeStartIteration;
timeStartIteration = Time::Now();
g.timeNow = timeStartIteration;
ProcessNetworkMessages();
UpdateMissions(timeStartIteration, timeEndIteration);
DWORD dwIteration = (Time::Now().clock() - timeStartIteration.clock());
DWORD dwSleep = dwIteration < dwUpdateInterval
? (dwUpdateInterval - dwIteration)
: 0;
dwWait = ProcessMsgPump(dwSleep, 1, rgeventHandles);
}
HAGCLISTENERS hListeners = GetAGCGlobal()->EventListeners(
EventID_ServerShutdown, -1, -1, -1);
if (hListeners)
{
char szName[MAX_COMPUTERNAME_LENGTH + 1];
DWORD cchName = sizeofArray(szName);
GetComputerNameA(szName, &cchName);
_AGCModule.TriggerEvent(hListeners, EventID_ServerShutdown, "", -1, -1, -1, 1,
"Server", VT_LPSTR, szName);
}
printf("Shutting down server...\n");
CoSuspendClassObjects();
_Module.RevokeCOMObjects();
shMutexRunning = NULL;
IUnknownPtr spunkServer;
ZSucceeded(GetAGCGlobal()->GetInterfaceFromGlobal(g.dwServerGITCookie,
IID_IUnknown, (void**)&spunkServer));
ZSucceeded(GetAGCGlobal()->RevokeInterfaceFromGlobal(g.dwServerGITCookie));
CoDisconnectObject(spunkServer, 0);
spunkServer = NULL;
UnloadRankInfo(); UnloadStaticMapInfo();
UnloadStaticCoreInfo();
UnloadDbCache();
_Module.Term();
CoUninitialize();
ExitThread(0);
return 0;
}
void LoadSettings()
{
g.Init();
TCHAR szModule[_MAX_PATH];
TCHAR szDrive[_MAX_DRIVE], szDir[_MAX_DIR];
GetModuleFileName(NULL, szModule, sizeofArray(szModule));
_tsplitpath(szModule, szDrive, szDir, NULL, NULL);
_makepath(szModule, szDrive, szDir, TEXT("Artwork\\"), NULL);
g.strArtPath = szModule;
HKEY hKey;
DWORD dwType;
DWORD dwValue;
DWORD cbValue;
if (ERROR_SUCCESS == ::RegOpenKeyEx(HKEY_LOCAL_MACHINE, HKLM_FedSrv, 0, KEY_READ, &hKey))
{
if (FAILED(LoadRegString(hKey, "AuthServer", g.strAuthServer)))
g.strAuthServer = "Pointweb01"; dwValue=0;
cbValue = sizeof(dwValue);
if (ERROR_SUCCESS == ::RegQueryValueEx(hKey, "nUpdatesPerSecond", NULL, &dwType, (unsigned char*)&dwValue, &cbValue))
g.nUpdatesPerSecond = dwValue;
else
g.nUpdatesPerSecond = 10;
#ifdef _DEBUG
#define SRVLOG
#endif
#ifdef SRVLOG dwValue=0;
cbValue = sizeof(dwValue);
if (ERROR_SUCCESS != ::RegQueryValueEx(hKey, "nDebugMask", NULL, &dwType, (unsigned char*)&dwValue, &cbValue))
dwValue=FED_DEBUG_FILE;
g_app.SetDebug(dwValue);
#endif
#if !defined(ALLSRV_STANDALONE)
LoadRegString(hKey, "LobbyServer", g.strLobbyServer);
#endif if (FAILED(LoadRegString(hKey, "LocalAddress", g.strLocalAddress)))
{
WSADATA WSAData;
char szHostName[20]; WSAStartup(MAKEWORD(1,1), &WSAData);
gethostname(szHostName, sizeof(szHostName));
WSACleanup();
g.strLocalAddress = szHostName;
}
if (FAILED(LoadRegString(hKey, "Location", g.strLocation)))
{
g.strLocation = "unknown";
}
g.cMaxGames = 99; cbValue = sizeof(dwValue);
RegQueryValueEx(hKey, "MaxGames", NULL, &dwType, (unsigned char*)&g.cMaxGames, &cbValue);
ZString strArtPath;
if (SUCCEEDED(LoadRegString(hKey, "ArtPath", strArtPath)))
{
if (strArtPath.Right(1) != "\\")
strArtPath += "\\";
g.strArtPath = strArtPath;
}
dwValue=0;
cbValue = sizeof(dwValue);
if (ERROR_SUCCESS == ::RegQueryValueEx(hKey, "fWantInt3", NULL, &dwType, (unsigned char*)&dwValue, &cbValue))
g.fWantInt3 = !!dwValue;
else g.fWantInt3 = true;
dwValue=0;
cbValue = sizeof(dwValue);
if (ERROR_SUCCESS == ::RegQueryValueEx(hKey, "fProtocol", NULL, &dwType, (unsigned char*)&dwValue, &cbValue))
g.fProtocol = !!dwValue;
else g.fProtocol = true;
dwValue=0;
cbValue = sizeof(dwValue);
if (ERROR_SUCCESS == ::RegQueryValueEx(hKey, "fDoublePrecision", NULL, &dwType, (unsigned char*)&dwValue, &cbValue))
g.fDoublePrecision = !!dwValue;
else g.fDoublePrecision = true;
dwValue=0;
cbValue = sizeof(dwValue);
if (ERROR_SUCCESS == ::RegQueryValueEx(hKey, "fTimeout", NULL, &dwType, (unsigned char*)&dwValue, &cbValue))
g.fTimeOut = !!dwValue;
else g.fTimeOut = true;
#if !defined(ALLSRV_STANDALONE)
dwValue=0;
cbValue = sizeof(dwValue);
if (ERROR_SUCCESS == ::RegQueryValueEx(hKey, "SQLThreadsNotify", NULL, &dwType, (unsigned char*)&dwValue, &cbValue))
g.csqlNotifyThreads = dwValue;
else g.csqlNotifyThreads = 3;
dwValue=0;
cbValue = sizeof(dwValue);
if (ERROR_SUCCESS == ::RegQueryValueEx(hKey, "SQLThreadsSilent", NULL, &dwType, (unsigned char*)&dwValue, &cbValue))
g.csqlSilentThreads = dwValue;
else g.csqlSilentThreads = 2;
if (FAILED(LoadRegString(hKey, "SQLConfig", g.strSQLConfig)))
g.strSQLConfig.Empty(); #endif ::RegCloseKey(hKey);
}
}
bool StringStartsWith (char* src, char* find)
{
int find_length = strlen (find);
for (int i = 0; i < find_length; i++)
if (tolower (src[i]) != tolower (find[i]))
return false;
return true;
}
void BuildIGCFiles (char* szArtworkPath, bool bEncrypt = false, bool bMaps = true)
{
#if !defined(ALLSRV_STANDALONE)
int iPathLastChar = strlen (szArtworkPath) - 1;
if (szArtworkPath[iPathLastChar] == '\\')
szArtworkPath[iPathLastChar] = 0;
UTL::SetArtPath(szArtworkPath);
LoadDbCache();
printf (bEncrypt ? " Writing encrypt core..." : " Writing static core...");
if (DumpIGCStaticCore (bEncrypt ? IGC_ENCRYPT_CORE_FILENAME : IGC_STATIC_CORE_FILENAME, g.trekCore, c_maskStaticTypes, bEncrypt ? DoEncrypt : NULL))
printf (" OK\n");
else
{
printf (" FAILED\n");
exit (1);
}
#pragma warning(push)
#pragma warning(disable : 4244)
if (bMaps)
{
SQL_GO(MapsCount);
SQL_GETROW(MapsCount);
MapDescription* pMaps = new MapDescription[g_cMapsCount];
MapFileSite* pSite = new MapFileSite;
SQL_GO(MapIDs);
for (int i = 0; i < g_cMapsCount; i++)
{
if (SQL_SUCCEEDED(SQL_GETROW(MapIDs)))
{
pMaps[i].mapID = MapIDs_MapID;
SQLSTRCPY (pMaps[i].szFileName, MapIDs_FileName);
}
}
for (i = 0; i < g_cMapsCount; i++)
{
if (StringStartsWith (pMaps[i].szFileName, "template") || StringStartsWith (pMaps[i].szFileName, "t_"))
continue;
printf (" Creating Map %s...\n", pMaps[i].szFileName);
ImissionIGC* pMission = CreateMission();
pMission->Initialize(Time::Now(), pSite);
int iStaticCoreVersion = LoadIGCStaticCore (bEncrypt ? IGC_ENCRYPT_CORE_FILENAME : IGC_STATIC_CORE_FILENAME, pMission, false, bEncrypt ? DoDecrypt : NULL);
assert (iStaticCoreVersion != NA);
SectorInfo_MapID = StationInstance_MapID = Asteroids_MapID = AlephInst_MapID = MineInstance_MapID = ProbeInstance_MapID = TreasureInstance_MapID = pMaps[i].mapID;
printf (" --------------------------------------------------\n");
SQL_GO(SectorInfo);
while(SQL_SUCCEEDED(SQL_GETROW(SectorInfo)))
{
DataClusterIGC obj;
obj.starSeed = SectorInfo_starSeed;
obj.lightDirection = (Vector (SectorInfo_LightX, SectorInfo_LightY, SectorInfo_LightZ)).Normalize ();
obj.lightColor = SectorInfo_LightColor;
obj.screenX = SectorInfo_ScreenX;
obj.screenY = SectorInfo_ScreenY;
obj.clusterID = SectorInfo_SectorID;
obj.nDebris = SectorInfo_DebrisCount;
obj.nStars = SectorInfo_StarsCount;
SQLSTRCPY (obj.name, SectorInfo_Name);
SQLSTRCPY (obj.posterName, SectorInfo_PosterName);
SQLSTRCPY (obj.planetName, SectorInfo_PlanetName);
obj.planetSinLatitude.SetChar (SectorInfo_planetSinLatitude);
obj.planetLongitude.SetChar (SectorInfo_planetLongitude);
obj.planetRadius = SectorInfo_planetRadius;
obj.activeF = true;
obj.bHomeSector = SectorInfo_IsHomeSector ? true : false;
if (StringStartsWith (obj.name, "template") || StringStartsWith (obj.name, "t_"))
continue;
printf (" Creating Sector %s...\n", obj.name);
IObject* punk = pMission->CreateObject(g.timeNow, OT_cluster, &obj, sizeof(obj));
punk->Release();
}
printf (" --------------------------------------------------\n");
SQL_GO(AlephsCount);
SQL_GETROW(AlephsCount);
std::map<int, DataWarpIGC*> alephMap;
SQL_GO(Alephs);
while(SQL_SUCCEEDED(SQL_GETROW(Alephs)))
{
DataWarpIGC* pObj = new DataWarpIGC;
pObj->warpDef.warpID = AlephInst_ID;
pObj->warpDef.destinationID = AlephInst_TargetAlephID;
pObj->warpDef.radius = AlephInst_Radius;
SQLSTRCPY (pObj->warpDef.textureName, AlephInst_Texture);
SQLSTRCPY (pObj->warpDef.iconName, AlephInst_PRIcon);
pObj->position = Vector (AlephInst_xLocation, AlephInst_yLocation, AlephInst_zLocation);
Vector forward (AlephInst_xForward, AlephInst_yForward, AlephInst_zForward);
forward.SetNormalize ();
pObj->forward = forward;
pObj->rotation = Rotation (forward, AlephInst_rRotation);
pObj->signature = AlephInst_Signature;
pObj->clusterID = AlephInst_SectorID;
alephMap[AlephInst_ID] = pObj;
}
std::map<int, DataWarpIGC*>::iterator alephMapIterator = alephMap.begin ();
while (alephMapIterator != alephMap.end ())
{
DataWarpIGC* pPairedAleph = alephMap[alephMapIterator->second->warpDef.destinationID];
IclusterIGC* pCluster = pMission->GetCluster (pPairedAleph->clusterID);
strcpy (alephMapIterator->second->name, pCluster->GetName ());
IObject* punk = pMission->CreateObject(g.timeNow, OT_warp, alephMapIterator->second, sizeof(DataWarpIGC));
punk->Release();
printf (" Creating Aleph from %s to %s...\n", pMission->GetCluster (alephMapIterator->second->clusterID)->GetName (), pCluster->GetName ());
alephMapIterator++;
}
alephMapIterator = alephMap.begin ();
while (alephMapIterator != alephMap.end ())
{
delete alephMapIterator->second;
alephMapIterator++;
}
printf (" --------------------------------------------------\n");
SQL_GO(Asteroids);
while(SQL_SUCCEEDED(SQL_GETROW(Asteroids)))
{
DataAsteroidIGC obj;
obj.signature = Asteroids_Signature;
obj.position = Vector (Asteroids_x, Asteroids_y, Asteroids_z);
Vector up,
forward,
axis;
if ((Asteroids_xUp == NA) && (Asteroids_yUp == NA) && (Asteroids_zUp == NA))
up = Vector::RandomDirection ();
else
up = (Vector (Asteroids_xUp, Asteroids_yUp, Asteroids_zUp)).Normalize ();
if ((Asteroids_xUp == NA) && (Asteroids_yUp == NA) && (Asteroids_zUp == NA))
forward = Vector::RandomDirection ();
else
forward = (Vector (Asteroids_xForward, Asteroids_yForward, Asteroids_zForward)).Normalize ();
if ((Asteroids_xRotation == NA) && (Asteroids_yRotation == NA) && (Asteroids_zRotation == NA))
{
axis = Vector::RandomDirection ();
if (Asteroids_rRotation == NA)
Asteroids_rRotation = random (0.0f, 1.0f) * pi;
}
else
axis = (Vector (Asteroids_xRotation, Asteroids_yRotation, Asteroids_zRotation)).Normalize ();
obj.up = up;
obj.forward = forward;
obj.rotation = Rotation (axis, Asteroids_rRotation);
obj.asteroidDef.ore = obj.asteroidDef.oreMax = Asteroids_Ore;
obj.asteroidDef.aabmCapabilities = Asteroids_Abilities;
obj.asteroidDef.asteroidID = Asteroids_AsteroidID;
obj.asteroidDef.hitpoints = Asteroids_HitPoints;
obj.asteroidDef.radius = Asteroids_Radius;
SQLSTRCPY (obj.asteroidDef.modelName, Asteroids_Model);
SQLSTRCPY (obj.asteroidDef.textureName, Asteroids_Texture);
SQLSTRCPY (obj.asteroidDef.iconName, Asteroids_PRIcon);
obj.clusterID = Asteroids_ClusterID;
SQLSTRCPY (obj.name, Asteroids_Name);
if (obj.name[0] == '#')
obj.name[0] = '\0';
obj.fraction = 1.0f;
if (StringStartsWith (obj.name, "template") || StringStartsWith (obj.name, "t_"))
continue;
printf (" Creating Asteroid %s...\n", obj.name);
IObject* punk = pMission->CreateObject(g.timeNow, OT_asteroid, &obj, sizeof(obj));
punk->Release();
}
for (int j = 0; j < c_cSidesMax; j++)
{
DataSideIGC obj;
obj.nFlags = 0;
obj.nArtifacts = 0;
obj.sideID = j;
obj.gasAttributes.Initialize();
obj.civilizationID = pMission->GetCivilizations()->first()->data()->GetObjectID();
obj.ttbmDevelopmentTechs.SetAll ();
obj.conquest = 0;
obj.territory = 0;
obj.nKills = obj.nDeaths = obj.nEjections = obj.nFlags = obj.nArtifacts
= obj.nBaseKills = obj.nBaseCaptures = 0;
obj.squadID = NA;
IObject* punk = pMission->CreateObject(g.timeNow, OT_side, &obj, sizeof(obj));
punk->Release();
}
printf (" --------------------------------------------------\n");
SQL_GO(StationInstance);
while(SQL_SUCCEEDED(SQL_GETROW(StationInstance)))
{
DataStationIGC obj;
obj.position = Vector (StationInstance_xLocation, StationInstance_yLocation, StationInstance_zLocation);
obj.up = (Vector (StationInstance_xUp, StationInstance_yUp, StationInstance_zUp)).Normalize ();
obj.forward = (Vector (StationInstance_xForward, StationInstance_yForward, StationInstance_zForward)).Normalize ();
obj.rotation = Rotation ((Vector (StationInstance_xRotation, StationInstance_yRotation, StationInstance_zRotation)).Normalize (), StationInstance_rRotation);
obj.clusterID = StationInstance_SectorID;
obj.sideID = StationInstance_SideID;
obj.stationID = StationInstance_StationID;
obj.stationTypeID = StationInstance_StationTypeID;
obj.bpHull = 1.0f;
obj.bpShield = 1.0f;
SQLSTRCPY (obj.name, StationInstance_Name);
if (StringStartsWith (obj.name, "template") || StringStartsWith (obj.name, "t_"))
continue;
printf (" Creating Station %s...\n", obj.name);
IObject* punk = pMission->CreateObject(g.timeNow, OT_station, &obj, sizeof(obj));
punk->Release();
}
printf (" --------------------------------------------------\n");
SQL_GO(ProbeInstance);
while(SQL_SUCCEEDED(SQL_GETROW(ProbeInstance)))
{
DataProbeExport obj;
obj.p0 = Vector (ProbeInstance_xLocation, ProbeInstance_yLocation, ProbeInstance_zLocation);
obj.time0 = 0;
obj.exportF = true;
obj.probeID = ProbeInstance_ProbeID;
obj.probetypeID = ProbeInstance_ProbeTypeID;
obj.clusterID = ProbeInstance_SectorID;
obj.sideID = ProbeInstance_SideID;
obj.shipID = NA;
obj.otTarget = NA;
obj.oidTarget = NA;
obj.createNow = true;
printf (" Creating probe %d...\n", ProbeInstance_ProbeID);
IprobeIGC* punk = static_cast<IprobeIGC*> (pMission->CreateObject (g.timeNow, OT_probe, &obj, sizeof(obj)));
punk->SetCreateNow ();
punk->Release();
}
printf (" --------------------------------------------------\n");
SQL_GO(MineInstance);
while(SQL_SUCCEEDED(SQL_GETROW(MineInstance)))
{
DataMineExport obj;
obj.p0 = Vector (MineInstance_xLocation, MineInstance_yLocation, MineInstance_zLocation);
obj.time0 = 0;
obj.exportF = true;
obj.mineID = MineInstance_MineID;
obj.minetypeID = MineInstance_MineTypeID;
obj.launcherID = NA;
obj.clusterID = MineInstance_SectorID;
obj.sideID = MineInstance_SideID;
obj.fraction = 1.0f;
obj.createNow = true;
printf (" Creating mine %d...\n", MineInstance_MineID);
ImineIGC* punk = static_cast<ImineIGC*> (pMission->CreateObject (g.timeNow, OT_mine, &obj, sizeof(obj)));
punk->SetCreateNow ();
punk->Release();
}
printf (" --------------------------------------------------\n");
SQL_GO(TreasureInstance);
while(SQL_SUCCEEDED(SQL_GETROW(TreasureInstance)))
{
DataTreasureIGC obj;
obj.lifespan = TreasureInstance_Lifespan;
obj.objectID = -(pMission->GenerateNewTreasureID() + 2); obj.treasureID = TreasureInstance_TreasureID;
obj.p0 = Vector (TreasureInstance_xLocation, TreasureInstance_yLocation, TreasureInstance_zLocation);
obj.v0 = Vector (0.0f, 0.0f, 0.0f);
obj.time0 = 0;
obj.clusterID = TreasureInstance_SectorID;
obj.amount = TreasureInstance_Amount;
obj.treasureCode = TreasureInstance_TreasureCode;
obj.createNow = true;
printf (" Creating treasure %d...\n", TreasureInstance_TreasureID);
ItreasureIGC* punk = static_cast<ItreasureIGC*> (pMission->CreateObject (g.timeNow, OT_treasure, &obj, sizeof(obj)));
punk->SetCreateNow ();
punk->Release();
}
printf (" Writing %s.igc ...", pMaps[i].szFileName);
if (DumpIGCFile (pMaps[i].szFileName, pMission, c_maskMapTypes))
printf (" OK\n\n");
else
{
printf (" FAILED\n\n");
exit (1);
}
pMission->Terminate ();
delete pMission;
}
}
#pragma warning(pop)
#endif }
void RegisterAllSrv(BOOL fReRegister, BOOL fInstallAsService, int argc, char *argv[])
{
if (fInstallAsService && IsWin9x())
{
printf("Cannot register as a service on this operating system.\n");
return;
}
DWORD dwErrorCode(_Module.RegisterServer(fReRegister, TRUE, fInstallAsService, argc, argv));
if (FAILED(dwErrorCode))
{
char szBuf[MAX_PATH];
sprintf(szBuf, "Unable to register server [0x%08x]. %s is not properly installed.\n", dwErrorCode, argv[0]);
PrintSystemErrorMessage(szBuf, dwErrorCode);
}
else
{
printf("Registry Update Successful.\n");
}
}
void UnregisterAllSrv(char *szServerName)
{
DWORD dwErrorCode(_Module.UnregisterServer());
if (FAILED(dwErrorCode))
{
char szBuf[MAX_PATH];
sprintf(szBuf, "Unable to remove server [0x%08x]. %s is not properly uninstalled.\n", dwErrorCode, szServerName);
PrintSystemErrorMessage(szBuf, dwErrorCode);
}
else
{
printf("Registry Update Successful.\n");
}
}
int __cdecl main(int argc, char *argv[])
{
LoadSettings();
if (g.fDoublePrecision)
_controlfp(_PC_53, _MCW_PC);
srand(GetTickCount() + time(NULL));
TCCoInit init(COINIT_MULTITHREADED);
ZSucceeded((HRESULT)init);
if (init.Failed())
return (HRESULT)init;
PSECURITY_DESCRIPTOR psd = NULL;
CSecurityDescriptor sd;
if (IsWinNT())
{
sd.InitializeFromThreadToken();
psd = sd;
}
HRESULT hr;
hr = CoInitializeSecurity(psd, -1, NULL, NULL,
RPC_C_AUTHN_LEVEL_PKT, RPC_C_IMP_LEVEL_IMPERSONATE, NULL, EOAC_NONE, NULL);
ZSucceeded(hr);
RETURN_FAILED(hr);
ZSucceeded(hr = _Module.InitAGC());
RETURN_FAILED(hr);
char szSvcName[64];
strcpy(szSvcName, c_szSvcName);
SERVICE_TABLE_ENTRY rgSTE[] =
{
{ szSvcName, (LPSERVICE_MAIN_FUNCTION)_ServiceMain },
{ NULL, NULL }
};
bool fShowUsage = false;
g.hInst = GetModuleHandle(NULL);
if (argc < 1)
{
_Module.TermAGC();
return 0;
}
if (argc > 1 && (*argv[1]=='-' || *argv[1]=='/') && !lstrcmpi ("reregister", argv[1]+1))
{
RegisterAllSrv(TRUE, _Module.IsInstalledAsService(), argc, argv);
_Module.TermAGC();
return 0;
}
if (_Module.IsInstalledAsService() && !_Module.IsInServiceControlManager())
{
printf("Incomplete installation detected. Removing incomplete installation...\n");
UnregisterAllSrv(argv[0]);
}
_Module.SetCOMStarted(argc == 2 && !lstrcmpi("-Embedding",argv[1]));
#if defined(ALLSRV_STANDALONE)
#ifndef _DEBUG
if (argc == 1 && !_Module.IsInstalledAsService() && !_Module.WasCOMStarted())
{
printf("\nUse AllSrvUI.exe to run the Allegiance Server.\n");
_Module.TermAGC();
return 0;
}
#endif
#endif
if (argc > 1 && (*argv[1]=='-' || *argv[1]=='/') && !_Module.WasCOMStarted())
{
BOOL fInstallAsService = !lstrcmpi("Service",argv[1]+1);
if (fInstallAsService || !lstrcmpi("RegServer",argv[1]+1))
{
RegisterAllSrv(FALSE, fInstallAsService, argc, argv);
}
else if (!lstrcmpi("UnregServer",argv[1]+1) || !lstrcmpi("Remove",argv[1]+1))
{
UnregisterAllSrv(argv[0]);
}
#if !defined(ALLSRV_STANDALONE)
else if (!lstrcmpi ("BuildIGCFiles", argv[1]+1))
{
if (argc > 2)
BuildIGCFiles (argv[2], false, true);
else
printf ("Please provide a path for IGC files to get written to...\n");
}
else if (!lstrcmpi ("EncryptIGCFiles", argv[1]+1))
{
if (argc > 2)
BuildIGCFiles (argv[2], true, true);
else
printf ("Please provide a path for IGC files to get written to...\n");
}
else if (!lstrcmpi ("BuildIGCFilesNM", argv[1]+1))
{
if (argc > 2)
BuildIGCFiles (argv[2], false, false);
else
printf ("Please provide a path for IGC files to get written to...\n");
}
else if (!lstrcmpi ("EncryptIGCFilesNM", argv[1]+1))
{
if (argc > 2)
BuildIGCFiles (argv[2], true, false);
else
printf ("Please provide a path for IGC files to get written to...\n");
}
#endif else
{
fShowUsage = true;
}
}
else
{
if (argc == 1 || _Module.WasCOMStarted())
{
if (_Module.IsInstalledAsService())
{
printf("Trying to run %s as an NT Service...\nType \"%s -RegServer\" to re-install as EXE.\n", argv[0], argv[0]);
if (!StartServiceCtrlDispatcher(rgSTE))
_AGCModule.TriggerEvent(NULL, AllsrvEventID_StartingService, "", -1, -1, -1, 0);
}
else
{
if (!_Module.IsInstalled())
{
printf("\nInstalling %s as an EXE...\n", argv[0]);
RegisterAllSrv(FALSE, FALSE, argc, argv); }
_Module.RunAsExecutable();
}
}
else fShowUsage = true;
}
if (fShowUsage)
{
ZVersionInfo vi;
printf("%s\n%s\n\n",
(LPCSTR)vi.GetFileDescription(), (LPCSTR)vi.GetLegalCopyright());
if (!_Module.IsInstalled())
{
printf("\nThe server needs to be installed before running.\n\n", argv[0]);
}
printf("usage is ONE of:\n\n");
printf("AllSrv starts the server if registered as an exe\n");
printf("AllSrv -RegServer install the server as an EXE\n");
if (IsWinNT())
printf("AllSrv -Service [user pw] install the server as an NT Service\n");
printf("AllSrv -UnregServer uninstall the server\n");
#if !defined(ALLSRV_STANDALONE)
printf("AllSrv -BuildIGCFiles <artpath> builds igc files from database\n");
printf(" (see root makefile for required env vars).\n");
printf("AllSrv -EncryptIGCFiles <artpath> builds & encrypts igc files from database\n");
printf(" (see root makefile for required env vars).\n");
printf("AllSrv -BuildIGCFilesNM <artpath> as above, but no maps\n");
printf(" (see root makefile for required env vars).\n");
printf("AllSrv -EncryptIGCFilesNM <artpath> as above, but no maps\n");
printf(" (see root makefile for required env vars).\n");
#endif if (IsWinNT())
printf("\nTo start this service (when installed as NT service): net start %s\n",c_szSvcName);
}
_Module.TermAGC();
return 0;
}
HRESULT pascal FedSrv_Pause()
{
if (!g.fPaused)
{
g.fPaused = true;
PostThreadMessage(g.idReceiveThread, wm_fs_pause, 0, 0);
}
return S_OK;
}
HRESULT pascal FedSrv_Continue()
{
if (g.fPaused)
{
g.fPaused = false;
PostThreadMessage(g.idReceiveThread, wm_fs_pause, 0, 0);
}
return S_OK;
}
HRESULT pascal FedSrv_Init()
{
int iCon = 0;
HRESULT hr = S_OK;
_AGCModule.TriggerEvent(NULL, AllsrvEventID_Initialize, "", -1, -1, -1, 0);
HMODULE hmod = GetModuleHandle(NULL);
assert(hmod);
char path_buffer[_MAX_PATH];
GetModuleFileName(hmod, path_buffer, sizeof(path_buffer));
char drive[_MAX_DRIVE];
char dir[_MAX_DIR];
_splitpath(path_buffer, drive, dir, NULL, NULL);
_makepath(path_buffer, drive, dir, NULL, NULL);
SetCurrentDirectory(path_buffer);
LoadTechBits(); bool fSWMRGInit = FSWMRGInitialize(&g.swmrg, "FedSrv");
ZAssert(fSWMRGInit);
ZVerify(g.perfshare.Initialize());
g.pServerCounters = (SERVER_COUNTERS *)g.perfshare.AllocateCounters(
"AllSrv",
"0", sizeof(SERVER_COUNTERS));
memset(g.pServerCounters, 0x00, sizeof(SERVER_COUNTERS));
#if defined(USEAUTH) g.pzas = CreateZoneAuthServer();
if (!g.pzas)
{
#if !defined(ALLSRV_STANDALONE)
_AGCModule.TriggerEvent(NULL, AllsrvEventID_ZoneAuthServer, "", -1, -1, -1, 0);
#endif return E_FAIL;
}
#endif g.hKillReceiveEvent = CreateEvent(NULL, TRUE, FALSE, NULL);
assert(g.hKillReceiveEvent);
g.idReceiveThread = 0; g.hReceiveThread = CreateThread(NULL, 0, ReceiveThread, 0, 0, &g.idReceiveThread);
assert(g.hReceiveThread);
ZVerify (TIMERR_NOERROR == timeBeginPeriod(1));
return hr;
}
class ThingSiteImpl : public ThingSite
{
public:
ThingSiteImpl(ImodelIGC* pmodel)
:
m_pmodel(pmodel) {
ModelAttributes ma = pmodel->GetAttributes();
m_bSideVisibility = (ma & c_mtSeenBySide) != 0;
m_bPredictable = (ma & c_mtPredictable) != 0;
}
virtual ~ThingSiteImpl(void)
{
}
virtual void Terminate(void)
{
}
void SetCluster(ImodelIGC* pmodel, IclusterIGC* pcluster)
{
assert (pmodel);
if (m_bSideVisibility)
{
if (!m_bPredictable)
{
IsideIGC* psideModel = pmodel->GetSide();
assert (psideModel);
for (SideLinkIGC* l = pmodel->GetMission()->GetSides()->first();
(l != NULL);
l = l->next())
{
IsideIGC* pside = l->data();
if (pside != psideModel)
{
m_rgSideVisibility[pside->GetObjectID()].fVisible(false);
HideObject(pside, pmodel);
}
}
}
if (pcluster)
UpdateSideVisibility(pmodel, pcluster);
}
}
static bool ShowObject(IsideIGC* pside, ImodelIGC* pmodel)
{
assert (pside);
assert (pmodel);
bool bSent = false;
ObjectType type = pmodel->GetObjectType();
if (pmodel->GetAttributes() & c_mtPredictable)
{
CFSMission* pfsMission = (CFSMission *)(pside->GetMission()->GetPrivateData());
assert (pfsMission);
assert (type != OT_ship);
if (pside->GetActiveF() &&
((pfsMission->GetStage() == STAGE_STARTED) ||
(pfsMission->GetStage() == STAGE_STARTING)))
{
SideID sideID = pside->GetObjectID();
g.fm.UseMainOutBox(false);
g.fm.SetDefaultRecipient(CFSSide::FromIGC(pside)->GetGroup(), FM_GUARANTEED);
bSent = true;
ExportObj(pmodel, type, NULL);
if (type == OT_warp)
{
IwarpIGC* pwarpOther = ((IwarpIGC*)pmodel)->GetDestination();
assert (pwarpOther);
ExportObj(pwarpOther, OT_warp, NULL);
assert (!pwarpOther->SeenBySide(pside));
{
ThingSiteImpl* pts = (ThingSiteImpl*)(pwarpOther->GetThingSite());
SideVisibility& sv = pts->m_rgSideVisibility[sideID];
sv.fVisible(true);
}
{
for (WarpBombLink* p = ((IwarpIGC*)pmodel)->GetBombs()->first(); (p != NULL); p = p->next())
{
BEGIN_PFM_CREATE(g.fm, pfmWB, S, WARP_BOMB)
END_PFM_CREATE
pfmWB->timeExplosion = p->data().timeExplosion;
pfmWB->warpidBombed = pmodel->GetObjectID();
pfmWB->expendableidMissile = p->data().pmt->GetObjectID();
}
}
{
for (WarpBombLink* p = pwarpOther->GetBombs()->first(); (p != NULL); p = p->next())
{
BEGIN_PFM_CREATE(g.fm, pfmWB, S, WARP_BOMB)
END_PFM_CREATE
pfmWB->timeExplosion = p->data().timeExplosion;
pfmWB->warpidBombed = pwarpOther->GetObjectID();
pfmWB->expendableidMissile = p->data().pmt->GetObjectID();
}
}
}
else if (type == OT_asteroid)
{
IbuildingEffectIGC* pbe = ((IasteroidIGC*)pmodel)->GetBuildingEffect();
if (pbe)
ExportObj(pbe, OT_buildingEffect, NULL);
}
g.fm.SendMessages(CFSSide::FromIGC(pside)->GetGroup(), FM_GUARANTEED, FM_FLUSH);
}
}
else if (type == OT_ship)
{
CFSShip* pfsShip = (CFSShip *)(((IshipIGC*)pmodel)->GetPrivateData());
assert (pfsShip);
pfsShip->ShipStatusSpotted(pside);
}
g.fm.UseMainOutBox(true);
return bSent;
}
static void HideObject(IsideIGC* pside, ImodelIGC* pmodel)
{
if (pmodel->GetObjectType() == OT_ship)
{
CFSShip* pfsShip = (CFSShip *)(((IshipIGC*)pmodel)->GetPrivateData());
assert (pfsShip);
pfsShip->ShipStatusHidden(pside);
}
}
virtual void UpdateSideVisibility(ImodelIGC* pmodel,
IclusterIGC* pcluster)
{
assert (pmodel == m_pmodel);
if (m_bSideVisibility)
{
ClusterSite* pcs = pcluster->GetClusterSite();
for (SideLinkIGC* l = pcluster->GetMission()->GetSides()->first();
(l != NULL);
l = l->next())
{
IsideIGC* pside = l->data();
SideID sid = pside->GetObjectID();
assert (sid >= 0);
assert (sid < c_cSidesMax);
SideVisibility& sv = m_rgSideVisibility[sid];
if (!(m_bPredictable && sv.fVisible()))
{
if (pside == pmodel->GetSide())
{
sv.fVisible(true);
ShowObject(pside, pmodel);
}
else if (sv.pLastSpotter() && sv.pLastSpotter()->InScannerRange(pmodel))
{
if (!sv.fVisible())
{
sv.fVisible(true);
ShowObject(pside, pmodel);
}
}
else
{
sv.fVisible(false);
for (ScannerLinkIGC* l = pcs->GetScanners(sid)->first();
(l != NULL);
l = l->next())
{
IscannerIGC* s = l->data();
assert (s->GetCluster() == pcluster);
if (s->InScannerRange(pmodel))
{
sv.fVisible(true);
bool bSent = ShowObject(pside, pmodel);
sv.pLastSpotter(s);
if (bSent)
{
ObjectType otModel = pmodel->GetObjectType();
if (otModel == OT_station || otModel == OT_warp ||
(otModel == OT_asteroid &&
(static_cast<IasteroidIGC*>(pmodel)->GetCapabilities() & ~c_aabmBuildable) != 0))
{
ObjectType otSpotter = s->GetObjectType();
BEGIN_PFM_CREATE(g.fm, pfmObjectSpotted, S, OBJECT_SPOTTED)
END_PFM_CREATE
pfmObjectSpotted->otObject = otModel;
pfmObjectSpotted->oidObject = pmodel->GetObjectID();
pfmObjectSpotted->otSpotter = otSpotter;
pfmObjectSpotted->oidSpotter = s->GetObjectID();
g.fm.SendMessages(CFSSide::FromIGC(pside)->GetGroup(), FM_GUARANTEED, FM_FLUSH);
if ((otModel == OT_warp) || (otModel == OT_asteroid))
{
if (otSpotter == OT_ship)
{
IshipIGC* pship = (IshipIGC*)s;
CFSShip* pfsship = (CFSShip*)(pship->GetPrivateData());
PlayerScoreObject* ppso = pfsship->GetPlayerScoreObject();
if (otModel == OT_warp)
ppso->SpotWarp();
else
{
assert (otModel == OT_asteroid);
ppso->SpotSpecialAsteroid();
}
}
}
}
}
break;
}
}
if (!sv.fVisible())
{
HideObject(pside, pmodel);
sv.pLastSpotter(NULL);
}
}
}
}
}
}
virtual bool GetSideVisibility(IsideIGC* pside)
{
assert (pside != NULL);
return m_bSideVisibility ? m_rgSideVisibility[pside->GetObjectID()].fVisible() : true;
}
virtual void SetSideVisibility(IsideIGC* pside,
bool fVisible)
{
assert (pside);
if (m_bSideVisibility)
{
SideID sid = pside->GetObjectID();
SideVisibility& sv = m_rgSideVisibility[sid];
if (fVisible != sv.fVisible())
{
sv.fVisible(fVisible);
if (fVisible)
ShowObject(pside, m_pmodel);
else
HideObject(pside, m_pmodel);
}
}
}
private:
SideVisibility m_rgSideVisibility[c_cSidesMax];
ImodelIGC* m_pmodel;
bool m_bPredictable;
bool m_bSideVisibility;
};
class ClusterSiteImpl : public ClusterSite
{
public:
ClusterSiteImpl(IclusterIGC * pcluster)
:
m_pcluster(pcluster)
{
CFSMission * pfsMission = (CFSMission *) pcluster->GetMission()->GetPrivateData();
}
virtual void AddScanner(SideID sid, IscannerIGC* scannerNew)
{
assert (sid >= 0);
assert (sid < c_cSidesMax);
assert (scannerNew);
AddIbaseIGC((BaseListIGC*)&(m_scanners[sid]), scannerNew);
}
virtual void DeleteScanner(SideID sid, IscannerIGC* scannerOld)
{
assert (sid >= 0);
assert (sid < c_cSidesMax);
assert (scannerOld);
DeleteIbaseIGC((BaseListIGC*)&(m_scanners[sid]), scannerOld);
}
virtual const ScannerListIGC* GetScanners(SideID sid) const
{
assert (sid >= 0);
assert (sid < c_cSidesMax);
return &(m_scanners[sid]);
}
virtual void Terminate()
{
((CFSMission *)m_pcluster->GetMission()->GetPrivateData())->DeleteCluster(m_pcluster); ClusterSite::Terminate();
}
private:
IclusterIGC* m_pcluster;
ScannerListIGC m_scanners[c_cSidesMax];
};
TRef<ThingSite> FedSrvSiteBase::CreateThingSite(ImodelIGC* pModel)
{
return new ThingSiteImpl(pModel);
}
TRef<ClusterSite> FedSrvSiteBase::CreateClusterSite(IclusterIGC* pCluster)
{
m_pfsMission->CreateCluster(pCluster); return new ClusterSiteImpl(pCluster);
}
void FedSrvSiteBase::UpgradeDrones(IsideIGC* pside)
{
{
for (StationLinkIGC* pslStation = pside->GetStations()->first();
(pslStation != NULL);
pslStation = pslStation->next())
{
IstationIGC* pstation = pslStation->data();
for (ShipLinkIGC* pslShip = pstation->GetShips()->first();
(pslShip != NULL);
pslShip = pslShip->next())
{
IshipIGC* pship = pslShip->data();
CFSShip* pfsship = (CFSShip*)(pship->GetPrivateData());
if (!pfsship->IsPlayer())
UpgradeShip(pship, pstation);
}
}
}
}
void FedSrvSiteBase::DevelopmentCompleted(IbucketIGC * pbucket, IdevelopmentIGC * pdev, Time now)
{
IsideIGC * pside = pbucket->GetSide();
SideID sideid = pside->GetObjectID();
pside->ApplyDevelopmentTechs(pdev->GetEffectTechs());
BEGIN_PFM_CREATE(g.fm, pfmDevCompleted, S, DEV_COMPLETED)
END_PFM_CREATE
pfmDevCompleted->devId = pdev->GetObjectID();
g.fm.SendMessages(CFSSide::FromIGC(pside)->GetGroup(), FM_GUARANTEED, FM_FLUSH);
if (!pdev->GetTechOnly())
pside->ApplyGlobalAttributeSet(pdev->GetGlobalAttributeSet());
if (pdev->GetObjectID() == c_didTeamMoney)
{
static char szReason[100];
sprintf(szReason, "%s has proven the economic value of their outpost.", pside->GetName());
m_pfsMission->GameOver(pside, szReason);
}
}
void FedSrvSiteBase::SideDevelopmentTechChange(IsideIGC* pside)
{
assert (pside);
if (m_pfsMission->GetStage() == STAGE_STARTED)
{
SideID sideid = pside->GetObjectID();
const TechTreeBitMask& ttbmDev = pside->GetDevelopmentTechs();
BEGIN_PFM_CREATE(g.fm, pfmSideTechChange, S, SIDE_TECH_CHANGE)
END_PFM_CREATE
pfmSideTechChange->sideID = sideid;
pfmSideTechChange->ttbmDevelopments = ttbmDev;
g.fm.SendMessages(CFSSide::FromIGC(pside)->GetGroup(), FM_GUARANTEED, FM_FLUSH);
}
for (StationLinkIGC* pslStation = pside->GetStations()->first();
(pslStation != NULL);
pslStation = pslStation->next())
{
IstationIGC* pstation = pslStation->data();
IstationTypeIGC* pstOld = pstation->GetBaseStationType();
IstationTypeIGC* pstSuccessor = pstOld->GetSuccessorStationType(pside);
if (pstOld != pstSuccessor)
{
pstation->SetName(pstSuccessor->GetName());
pstation->SetBaseStationType(pstSuccessor);
}
}
UpgradeDrones(pside);
}
void FedSrvSiteBase::SideGlobalAttributeChange(IsideIGC* pside)
{
assert (pside);
BEGIN_PFM_CREATE(g.fm, pfmSideAttrChange, S, SIDE_ATTRIBUTE_CHANGE)
END_PFM_CREATE
pfmSideAttrChange->sideID = pside->GetObjectID();
pfmSideAttrChange->gasAttributes = pside->GetGlobalAttributeSet();
g.fm.SendMessages(m_pfsMission->GetGroupMission(), FM_GUARANTEED, FM_FLUSH);
}
void FedSrvSiteBase::HullTypeCompleted(IsideIGC* pside, IhullTypeIGC* pht)
{
pside->AddToStockpile(pht);
}
void FedSrvSiteBase::PartTypeCompleted(IsideIGC* pside, IpartTypeIGC* ppt)
{
pside->AddToStockpile(ppt, IlauncherTypeIGC::IsLauncherType(ppt->GetEquipmentType())
? ppt->GetAmount(NULL)
: 1);
}
void FedSrvSiteBase::StationTypeCompleted(IbucketIGC * pbucket, IstationIGC* pstation, IstationTypeIGC * pstationtype, Time now)
{
IsideIGC * pside = pbucket->GetSide();
assert (pside);
if (pside->GetActiveF())
{
CFSDrone * pfsDrone = CreateStockDrone(pstationtype->GetConstructionDroneType(), pstation->GetSide(), pstationtype);
assert (pfsDrone);
pfsDrone->GetIGCShip()->SetStation(pstation); pfsDrone->GetIGCShip()->PickDefaultOrder(pstation->GetCluster(), pstation->GetPosition(), true);
pfsDrone->GetIGCShip()->SetStation(NULL); if (pfsDrone->GetIGCShip()->GetCommandID(c_cmdCurrent) != c_cidBuild)
{
SendChat(pfsDrone->GetIGCShip(), CHAT_TEAM, pfsDrone->GetIGCShip()->GetSide()->GetObjectID(),
pstationtype->GetConstructorNeedRockSound(), "New constructor requesting asteroid.");
}
}
}
void FedSrvSiteBase::BuildStation(IasteroidIGC* pasteroid,
IsideIGC* pside,
IstationTypeIGC* pstationtype,
Time now)
{
pstationtype = pstationtype->GetSuccessorStationType(pside);
ImissionIGC* pmission = m_pfsMission->GetIGCMission();
IclusterIGC* pcluster = pasteroid->GetCluster();
DataStationIGC ds;
strcpy(ds.name, pstationtype->GetName());
ds.clusterID = pcluster->GetObjectID();
ds.position = pasteroid->GetPosition();
ds.forward.x = ds.forward.y = 0.0f;
ds.forward.z = 1.0f;
ds.up.x = ds.up.z = 0.0f;
ds.up.y = 1.0f;
ds.rotation.axis(ds.forward);
ds.rotation.angle(0.0f);
ds.sideID = pside->GetObjectID();
ds.stationID = pmission->GenerateNewStationID();
ds.stationTypeID = pstationtype->GetObjectID();
ds.bpHull = pasteroid->GetFraction();
ds.bpShield = 0.0f;
KillAsteroidEvent(pasteroid, false);
IstationIGC * pstationNew = (IstationIGC *) (pmission->CreateObject(now, OT_station, &ds, sizeof(ds)));
assert (pstationNew->SeenBySide(pside));
LPCSTR pszContext = m_pfsMission->GetIGCMission() ? m_pfsMission->GetIGCMission()->GetContextName() : NULL; _AGCModule.TriggerContextEvent(NULL, EventID_StationCreated, pszContext,
pside->GetName(), pside->GetObjectID(), -1, -1, 4,
"MissionID", VT_I4, m_pfsMission->GetMissionID(),
"TeamID" , VT_I4 , pside->GetObjectID(),
"TeamName", VT_LPSTR, pside->GetName(),
"zStationName", VT_LPSTR, pstationNew->GetName());
#if 0
ZString pszPlayerList = ""; if(pmission->GetShips() != NULL && pside) {
ShipLinkIGC * pShiplink = pmission->GetShips()->first();
while (pShiplink)
{
CFSShip * pfsShip = (CFSShip *) pShiplink->data()->GetPrivateData();
if (pfsShip != NULL & pfsShip->IsPlayer())
{
if(pfsShip->GetSide() && pfsShip->GetSide()->GetObjectID() == pside->GetObjectID() && pfsShip->GetCluster()->GetObjectID() == pcluster->GetObjectID() && pfsShip->GetPlayer()) {
pszPlayerList = pszPlayerList + ";" + ZString(pfsShip->GetPlayer()->GetName()); if(pfsShip->GetPlayer()->GetIGCShip())
{
pszPlayerList = pszPlayerList + ":" + ZString( (pasteroid->GetPosition() - pfsShip->GetPlayer()->GetIGCShip()->GetPosition()).Length()); }
}
}
pShiplink = pShiplink->next();
}
}
_AGCModule.TriggerContextEvent(NULL, EventID_StationCreatedEscort, pszContext,
pside->GetName(), pside->GetObjectID(), -1, -1, 4,
"MissionID", VT_I4, m_pfsMission->GetMissionID(),
"Team" , VT_I4 , pside->GetObjectID(), "TeamName", VT_LPSTR, pside->GetName(), "zPlayerList", VT_LPSTR, pszPlayerList); #endif
pstationNew->Release();
UpgradeDrones(pside);
IsideIGC* psideWin = m_pfsMission->CheckForVictoryByStationBuild(pside);
if (psideWin)
{
static char szReason[100]; sprintf(szReason, "%s won by out-building their opponents", psideWin->GetName());
m_pfsMission->GameOver(psideWin, szReason);
}
}
void FedSrvSiteBase::DroneTypeCompleted(IbucketIGC * pbucket, IstationIGC* pstation, IdroneTypeIGC * pdronetype, Time now)
{
IsideIGC* pside = pstation->GetSide();
if (pside->GetActiveF())
{
assert (pdronetype->GetPilotType() != c_ptBuilder);
CFSDrone * pfsDrone = CreateStockDrone(pdronetype, pside, (pdronetype->GetPilotType() == c_ptLayer)
? pdronetype->GetLaidExpendable()
: NULL);
if (pfsDrone)
{
pfsDrone->GetIGCShip()->SetStation(pstation); pfsDrone->GetIGCShip()->PickDefaultOrder(pstation->GetCluster(), pstation->GetPosition(), true);
pfsDrone->GetIGCShip()->SetStation(NULL); if (pdronetype->GetPilotType() == c_ptLayer)
{
if (pfsDrone->GetIGCShip()->GetBaseData()->GetObjectType() == OT_mineType)
SendChat(pfsDrone->GetIGCShip(), CHAT_TEAM, pfsDrone->GetIGCShip()->GetSide()->GetObjectID(),
droneWhereToLayMinefieldSound, "New minefield requesting location.");
else
SendChat(pfsDrone->GetIGCShip(), CHAT_TEAM, pfsDrone->GetIGCShip()->GetSide()->GetObjectID(),
droneWhereToLayTowerSound, "New tower requesting location.");
}
else if ((pdronetype->GetPilotType() == c_ptMiner) && (pfsDrone->GetIGCShip()->GetCommandID(c_cmdCurrent) != c_cidMine))
{
SendChat(pfsDrone->GetIGCShip(), CHAT_TEAM, pfsDrone->GetIGCShip()->GetSide()->GetObjectID(),
droneWhereToSound, "New miner requesting He3 asteriod.");
}
}
}
}
void FedSrvSiteBase::UpgradeShip(IshipIGC* pship, const IstationIGC* pstation)
{
assert (pship->GetParentShip() == NULL);
assert (pship->GetStation() == pstation);
IhullTypeIGC* pht = pship->GetBaseHullType();
assert (pht);
IhullTypeIGC* phtSuccessor = (IhullTypeIGC*)(pstation->GetSuccessor(pht));
if (pht != phtSuccessor)
{
{
const PartListIGC* pparts = pship->GetParts();
PartLinkIGC* ppl;
while (ppl = pparts->first())
ppl->data()->Terminate();
}
pship->SetBaseHullType(phtSuccessor);
{
for (PartTypeLinkIGC* ptl = phtSuccessor->GetPreferredPartTypes()->first();
(ptl != NULL);
ptl = ptl->next())
{
IpartTypeIGC* ppt = ptl->data();
if (pstation->CanBuy(ppt))
{
ppt = (IpartTypeIGC*)(pstation->GetSuccessor(ppt));
EquipmentType et = ppt->GetEquipmentType();
Mount mountMax = (et == ET_Weapon)
? phtSuccessor->GetMaxWeapons()
: 1;
for (Mount i = 0; (i < mountMax); i++)
{
if ((pship->GetMountedPart(et, i) == NULL) && phtSuccessor->CanMount(ppt, i))
pship->CreateAndAddPart(ppt, i, 0x7fff);
}
}
}
}
}
else
{
PartLinkIGC* pplPart = pship->GetParts()->last();
while (pplPart)
{
IpartIGC* ppart = pplPart->data();
pplPart = pplPart->txen();
if (ppart->GetMountID() < 0)
ppart->Terminate(); else
{
IpartTypeIGC* ppt = ppart->GetPartType();
IpartTypeIGC* pptSuccessor = (IpartTypeIGC*)(pstation->GetSuccessor(ppt));
if (pptSuccessor != ppt)
{
Mount mount = ppart->GetMountID();
ppart->Terminate();
pship->CreateAndAddPart(pptSuccessor, mount, 0x7fff);
}
}
}
}
}
void FedSrvSiteBase::TerminateModelEvent(ImodelIGC* pmodel)
{
}
void FedSrvSiteBase::KillShipEvent(Time timeCollision, IshipIGC* pship, ImodelIGC* pcredit, float amount, const Vector& p1, const Vector& p2)
{
ImissionIGC* pmission = m_pfsMission->GetIGCMission();
const MissionParams* pmp = pmission->GetMissionParams();
IsideIGC* pside = pship->GetSide();
IclusterIGC* pcluster = pship->GetCluster();
IshipIGC* pshipParent = pship->GetParentShip();
DamageBucketLink* pdmglink = NULL;
if (pshipParent == NULL)
{
DamageTrack* pdt = pship->GetDamageTrack();
if (pdt)
{
pdmglink = pdt->GetDamageBuckets()->first();
if (pdmglink)
{
if (pdmglink->data()->model()->GetMission() == pmission)
pcredit = pdmglink->data()->model();
DamageBucketLink* pblAssist = pdmglink->next();
while (pblAssist)
{
ImodelIGC* pAssist = pblAssist->data()->model();
if ((pAssist->GetObjectType() == OT_ship) &&
(pAssist->GetSide() != pside) &&
(pAssist->GetMission() == pmission))
{
CFSShip* pfsAssist = (CFSShip*)( ((IshipIGC*)pAssist)->GetPrivateData() );
if (pfsAssist->IsPlayer())
{
pfsAssist->GetPlayerScoreObject()->AddAssist();
break;
}
}
pblAssist = pblAssist->next();
}
}
}
const ShipListIGC* pshipsChildren = pship->GetChildShips();
ShipLinkIGC* psl;
while (psl = pshipsChildren->first()) {
KillShipEvent(timeCollision, psl->data(), pcredit, amount, p1, p2);
}
const PartListIGC* plist = pship->GetParts();
PartLinkIGC* plink;
while (plink = plist->first()) {
IpartIGC* p = plink->data();
if (randomInt(0, 4) == 0)
CreateTreasure(timeCollision, pship, p, p->GetPartType(), p1, 100.0f, 60.0f);
p->Terminate();
}
{
short ammo = pship->GetAmmo();
if (ammo > 0)
{
IpartTypeIGC* pptAmmo = pmission->GetAmmoPack();
assert (pptAmmo);
if (randomInt(0, 4) == 0)
{
CreateTreasure(timeCollision, pship, ammo, pptAmmo, p1, 100.0f, 30.0f);
}
pship->SetAmmo(0);
}
}
{
short fuel = short(pship->GetFuel());
if (fuel > 0)
{
IpartTypeIGC* pptFuel = pmission->GetFuelPack();
assert (pptFuel);
if (randomInt(0, 4) == 0)
{
CreateTreasure(timeCollision, pship, fuel, pptFuel, p1, 100.0f, 30.0f);
}
}
pship->SetFuel(0.0f);
}
{
SideID sidFlag = pship->GetFlag();
if (sidFlag != NA)
{
pship->SetFlag(NA);
const Vector& p = pship->GetPosition();
float lm = pmission->GetFloatConstant(c_fcidLensMultiplier);
float r = 1.5f * pmission->GetFloatConstant(c_fcidRadiusUniverse);
if (p.x*p.x + p.y*p.y + p.z*p.z/(lm*lm) > r*r)
{
RespawnFlag(sidFlag,NULL); }
else
{
DataTreasureIGC dt;
dt.treasureCode = c_tcFlag;
dt.treasureID = sidFlag;
dt.amount = 0;
dt.lifespan = 3600.0f * 24.0f * 10.0f; dt.createNow = false;
CreateTreasure(timeCollision, pship, &dt, p1, 100.0f);
}
BEGIN_PFM_CREATE(g.fm, pfmGain, S, GAIN_FLAG)
END_PFM_CREATE
pfmGain->sideidFlag = NA;
pfmGain->shipidRecipient = pship->GetObjectID();
pfmGain->bIsTreasureDocked = false; g.fm.SendMessages(m_pfsMission->GetGroupRealSides(), FM_GUARANTEED, FM_FLUSH);
}
}
}
CFSShip * pfsShip = (CFSShip *) pship->GetPrivateData();
ShipID shipID = pship->GetObjectID();
bool bKilled;
bool bLifepod;
if (pfsShip->IsPlayer())
{
pfsShip->GetPlayer()->SetTreasureObjectID(NA);
bLifepod = (pshipParent == NULL) &&
pship->GetBaseHullType()->HasCapability(c_habmLifepod);
bKilled = (!pmp->bEjectPods) || bLifepod || (amount < 0.0f);
}
else
{
bKilled = true;
bLifepod = false;
}
if (bKilled)
pship->SetExperience(0.0f);
IshipIGC* pshipCredit = NULL;
if (amount != 0.0f)
{
BEGIN_PFM_CREATE(g.fm, pfmKillShip, S, KILL_SHIP)
END_PFM_CREATE
pfmKillShip->shipID = shipID;
pfmKillShip->bKillCredit = false;
pfmKillShip->bDeathCredit = bKilled;
pfmKillShip->sideidKiller = NA;
if (pcredit)
{
ObjectType type = pcredit->GetObjectType();
IsideIGC* psideCredit = pcredit->GetSide();
if (psideCredit)
{
pfmKillShip->sideidKiller = psideCredit->GetObjectID();
if ((!bLifepod) && (psideCredit != pside))
{
pfmKillShip->bKillCredit = true;
if (type == OT_ship)
{
CFSShip* pfsshipCredit = (CFSShip*)(((IshipIGC*)pcredit)->GetPrivateData());
pfsshipCredit->AddKill();
PlayerScoreObject::AdjustCombatRating(pmission, pfsshipCredit->GetPlayerScoreObject(), pfsShip->GetPlayerScoreObject());
if (pside != psideCredit)
((IshipIGC*)pcredit)->AddExperience();
if (pdmglink)
{
float totalDamage = 0.0f;
{
for (DamageBucketLink* l = pdmglink; (l != NULL); l = l->next())
{
if (l->data()->model()->GetSide() != pside)
totalDamage += l->data()->totalDamage();
}
}
if (totalDamage != 0.0f)
{
for (DamageBucketLink* l = pdmglink; (l != NULL); l = l->next())
{
ImodelIGC* pmodel = l->data()->model();
if ((pmodel->GetObjectType() == OT_ship) &&
(pmodel->GetSide() != pside) &&
(pmodel->GetMission() == pmission))
{
IshipIGC* pshipCredit = (IshipIGC*)pmodel;
CFSShip* pfsShip = (CFSShip*)(pshipCredit->GetPrivateData());
pfsShip->GetPlayerScoreObject()->KillShip(pship, l->data()->totalDamage() / totalDamage);
IshipIGC* pshipParent = pshipCredit->GetParentShip();
if (pshipParent)
{
IhullTypeIGC* phtParent = pshipParent->GetBaseHullType();
assert (phtParent);
float divisor = 2.0f + float(phtParent->GetMaxWeapons() - phtParent->GetMaxFixedWeapons());
CFSShip* pfsParent = (CFSShip*)(pshipParent->GetPrivateData());
pfsParent->GetPlayerScoreObject()->KillShip(pship,
l->data()->totalDamage() /
(totalDamage * divisor));
}
}
}
}
}
}
else
{
psideCredit->AddKill();
}
IsideIGC* psideWin = m_pfsMission->CheckForVictoryByKills(psideCredit);
if (psideWin)
{
static char szReason[100]; if (pshipCredit)
sprintf(szReason, "%s pushes %s over the top with a kill", pshipCredit->GetName(), psideWin->GetName());
else
sprintf(szReason, "%s won by killing enough of their opponents", psideWin->GetName());
m_pfsMission->GameOver(psideWin, szReason);
}
}
}
pfmKillShip->typeCredit = type;
pfmKillShip->idCredit = pcredit->GetObjectID();
}
else
pfmKillShip->typeCredit = pfmKillShip->idCredit = NA;
g.fm.SendMessages(m_pfsMission->GetGroupMission(), FM_GUARANTEED, FM_FLUSH);
}
IhullTypeIGC* pht = pside->GetCivilization()->GetLifepod();
if (!bKilled)
{
CFSPlayer* pfsPlayer = pfsShip->GetPlayer();
pfsPlayer->AddEjection();
assert (pcluster);
for (MissileLinkIGC* pml = pcluster->GetMissiles()->first();
(pml != NULL);
pml = pml->next())
{
ImissileIGC* pmissile = pml->data();
if (pmissile->GetTarget() == pship)
pmissile->SetTarget(NULL);
}
Vector v = pship->GetSourceShip()->GetVelocity();
pfsShip->ShipStatusHullChange(pht);
if (pshipParent)
pship->SetParentShip(NULL);
pship->SetBaseHullType(pht);
Vector f = Vector::RandomDirection();
Vector position;
Orientation o;
if (pshipParent)
{
o.Set(f);
position = p1 - f * (40.0f + 0.5f * pht->GetLength() + pshipParent->GetRadius());
}
else
{
bool bLook;
Vector vectorLook;
if (pcredit)
{
ImodelIGC* plauncher = (pcredit->GetObjectType() == OT_ship)
? ((IshipIGC*)pcredit)->GetSourceShip()
: pcredit;
if (plauncher->GetCluster() == pcluster)
{
bLook = true;
vectorLook = plauncher->GetPosition();
}
else
{
bLook = false;
}
}
else
{
bLook = true;
vectorLook = p2;
}
if (bLook)
{
Vector dp = (vectorLook - p1);
float length2 = dp.LengthSquared();
if (length2 >= 1.0f)
{
o.Set(dp);
Vector fNew = (f + dp * (8.0f / float(sqrt(length2))));
length2 = fNew.LengthSquared();
if (length2 > 0.01f)
f = fNew / float(sqrt(length2));
}
else
o.Set(f);
}
else
o.Set(f);
position = p1;
}
v -= f * 100.0f;
pship->SetPosition(position);
pship->SetVelocity(v);
pship->SetOrientation(o);
pship->SetCurrentTurnRate(c_axisRoll, pi * 2.0f);
pship->SetBB(timeCollision, timeCollision, 0.0f);
{
BEGIN_PFM_CREATE(g.fm, pfmEject, S, EJECT)
END_PFM_CREATE
pfmEject->shipID = shipID;
pfmEject->position = position;
pfmEject->velocity = v;
pfmEject->forward = f;
pfmEject->cookie = pfsPlayer->NewCookie();
g.fm.SendMessages(GetGroupSectorFlying(pcluster), FM_GUARANTEED, FM_FLUSH);
}
}
else
{
pfsShip->AnnounceExit(NULL, (amount != 0.0f) ? SDR_KILLED : SDR_TERMINATE);
if (pfsShip->IsPlayer())
{
assert (amount != 0.0f);
assert (pcluster);
CFSPlayer * pfsPlayer = pfsShip->GetPlayer();
pfsPlayer->AddDeath();
IstationIGC* pstationDest = (IstationIGC*)(FindTarget(pship, c_ttFriendly | c_ttStation | c_ttNearest | c_ttAnyCluster,
NULL, NULL, NULL, NULL,
c_sabmRestart));
if (!pstationDest)
pstationDest = m_pfsMission->GetBase(pside);
pship->SetCluster(NULL);
if (pshipParent)
pship->SetParentShip(NULL);
assert (pfsShip->GetIGCShip()->GetChildShips()->n() == 0);
pship->SetBaseHullType(pht);
if (pstationDest)
{
pfsPlayer->ShipStatusRestart(pstationDest);
BEGIN_PFM_CREATE(g.fm, pfmEnterLifepod, S, ENTER_LIFEPOD)
END_PFM_CREATE
g.fm.SendMessages(pfsPlayer->GetConnection(), FM_GUARANTEED, FM_FLUSH);
pfsPlayer->GetIGCShip()->SetStation(pstationDest);
pfsPlayer->ShipStatusDocked(pstationDest);
pfsPlayer->SetCluster(pcluster, true); if (pship->IsGhost() && !m_pfsMission->HasPlayers(pside, false))
{
m_pfsMission->DeactivateSide(pside);
}
}
else
{
assert (!pside->GetActiveF() || m_pfsMission->GetSideWon());
}
}
else {
assert (pship->GetParentShip() == NULL);
delete pfsShip->GetDrone();
}
}
}
void FedSrvSiteBase::DamageShipEvent(Time now, IshipIGC* ship, ImodelIGC* launcher, DamageTypeID type, float amount, float leakage, const Vector& p1, const Vector& p2)
{
if ((amount >= 1.0f) && launcher && ((type & c_dmgidNoWarn) == 0))
{
IsideIGC* psideLauncher = launcher->GetSide();
if (psideLauncher)
{
CFSShip* pcfs = (CFSShip *)(ship->GetPrivateData());
if (!pcfs->IsPlayer())
{
CFSDrone* pd = (CFSDrone*)pcfs;
if ((now - pd->GetLastDamageReport()) > 10.0f)
{
IsideIGC* pside = ship->GetSide();
assert (pside);
if (pside != psideLauncher)
{
SoundID underAttackSound;
switch (ship->GetPilotType())
{
case c_ptCarrier:
underAttackSound = carrierUnderAttackSound;
break;
case c_ptMiner:
if (ship->GetFraction() < 0.5f)
underAttackSound = minerCriticalSound;
else
underAttackSound = minerUnderAttackSound;
break;
case c_ptBuilder:
underAttackSound =
((IstationTypeIGC*)(IbaseIGC*)(ship->GetBaseData()))
->GetConstructorUnderAttackSound();
break;
default:
case c_ptLayer:
underAttackSound = droneUnderAttackSound;
break;
}
SendChatf(ship, CHAT_TEAM, ship->GetSide()->GetObjectID(),
underAttackSound, "Under attack by %s in %s",
GetModelName(launcher), ship->GetCluster()->GetName());
}
else if (launcher->GetObjectType() == OT_ship)
{
CFSShip* pfsLauncher = (CFSShip*)(((IshipIGC*)(launcher))->GetPrivateData());
if (pfsLauncher->IsPlayer())
{
SendChat(ship, CHAT_INDIVIDUAL, launcher->GetObjectID(),
droneWatchFireSound, "Watch your fire");
}
}
pd->SetLastDamageReport(now);
}
}
}
}
}
void FedSrvSiteBase::DamageStationEvent(IstationIGC* station, ImodelIGC* launcher, DamageTypeID type, float amount)
{
if ((amount >= 1.0f) && launcher && ((type & c_dmgidNoWarn) == 0))
{
IsideIGC* psideLauncher = launcher->GetSide();
if (psideLauncher)
{
if ((g.timeNow - station->GetLastDamageReport()) > 10.0f)
{
IsideIGC* pside = station->GetSide();
if (pside != psideLauncher)
{
if (station->GetFraction() < 0.30)
{
SendChatf(NULL, CHAT_TEAM, station->GetSide()->GetObjectID(),
station->GetStationType()->GetCriticalSound(),
"%s in %s critically damaged and under attack by %s", station->GetName(),
station->GetCluster()->GetName(), GetModelName(launcher));
}
else
{
SendChatf(NULL, CHAT_TEAM, station->GetSide()->GetObjectID(),
station->GetStationType()->GetUnderAttackSound(),
"%s in %s under attack by %s", station->GetName(),
station->GetCluster()->GetName(), GetModelName(launcher));
}
}
else if (launcher->GetObjectType() == OT_ship)
{
CFSShip* pfsLauncher = (CFSShip*)(((IshipIGC*)(launcher))->GetPrivateData());
if (pfsLauncher->IsPlayer())
{
SendChat(NULL, CHAT_INDIVIDUAL, launcher->GetObjectID(),
droneWatchFireSound, "Watch your fire");
}
}
station->SetLastDamageReport(g.timeNow);
}
}
}
}
void FedSrvSiteBase::KillStationEvent(IstationIGC* pstation, ImodelIGC* plauncher, float amount)
{
StationID stationID = pstation->GetObjectID();
m_pfsMission->VacateStation(pstation);
ObjectType otLauncher = NA;
IsideIGC* psideLauncher = NULL;
if (plauncher)
{
otLauncher = plauncher->GetObjectType();
if (otLauncher == OT_ship)
{
IshipIGC* pship = (IshipIGC*)plauncher;
CFSShip* pfsship = (CFSShip*)(pship->GetPrivateData());
pfsship->GetPlayerScoreObject()->KillBase(true);
for (ShipLinkIGC* psl = pship->GetChildShips()->first();
(psl != NULL);
psl = psl->next())
{
CFSShip* ps = (CFSShip*)(psl->data()->GetPrivateData());
ps->GetPlayerScoreObject()->KillBase(false);
}
}
psideLauncher = plauncher->GetSide();
if (psideLauncher)
{
psideLauncher->AddBaseKill();
}
}
BEGIN_PFM_CREATE(g.fm, pfmStationDestroyed, S, STATION_DESTROYED)
END_PFM_CREATE
pfmStationDestroyed->stationID = stationID;
pfmStationDestroyed->launcher = (otLauncher == OT_ship) ? plauncher->GetObjectID() : NA;
g.fm.SendMessages(m_pfsMission->GetGroupRealSides(), FM_GUARANTEED, FM_FLUSH);
const char* szLauncherName = "(unknown)";
int iLauncherUniqueID = -1;
int iLauncherSideUniqueID = -1;
if (plauncher != NULL)
{
ObjectType LauncherType = plauncher->GetObjectType();
if (LauncherType && LauncherType != OT_probe && LauncherType != OT_missile)
{
szLauncherName = plauncher->GetName();
iLauncherUniqueID = plauncher->GetUniqueID();
iLauncherSideUniqueID = plauncher->GetSide()->GetUniqueID();
}
}
LPCSTR pszContext = m_pfsMission->GetIGCMission() ? m_pfsMission->GetIGCMission()->GetContextName() : NULL;
_AGCModule.TriggerContextEvent(NULL, EventID_StationDeleted, pszContext,
szLauncherName, iLauncherUniqueID, iLauncherSideUniqueID, -1, 4,
"MissionID", VT_I4, m_pfsMission->GetMissionID(),
"TeamID", VT_I4, pstation->GetSide()->GetUniqueID(),
"TeamName", VT_LPSTR, pstation->GetSide()->GetName(),
"zStationName", VT_LPSTR, pstation->GetName());
#if 0
ZString pszPlayerList = ""; 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())
{
if(pfsShip->GetSide() && pfsShip->GetSide()->GetObjectID() == iLauncherSideUniqueID && pfsShip->GetCluster() && pstation->GetCluster() && pfsShip->GetCluster()->GetObjectID() == pstation->GetCluster()->GetObjectID()) {
pszPlayerList = pszPlayerList + ";" + ZString(pfsShip->GetPlayer()->GetName()); if(pfsShip->GetPlayer()->GetIGCShip() )
{
pszPlayerList = pszPlayerList + ":" + ZString( (pstation->GetPosition() - pfsShip->GetPlayer()->GetIGCShip()->GetPosition()).Length()); }
}
}
pShiplink = pShiplink->next();
}
}
_AGCModule.TriggerContextEvent(NULL, EventID_StationDeletedEscort, pszContext,
szLauncherName, iLauncherUniqueID, iLauncherSideUniqueID, -1, 4,
"MissionID", VT_I4, m_pfsMission->GetMissionID(),
"TeamID" , VT_I4 , pstation->GetSide()->GetUniqueID(), "TeamName", VT_LPSTR, pstation->GetSide()->GetName(), "zPlayerList", VT_LPSTR, pszPlayerList); #endif
IsideIGC* pside = pstation->GetSide();
IsideIGC* psideWin = m_pfsMission->CheckForVictoryByStationKill(pstation, pside);
if (psideWin)
{
static char szReason[100]; if ((otLauncher == OT_ship) && (psideLauncher == psideWin))
{
sprintf(szReason, "%s has destroyed %s's %s in %s.", psideLauncher->GetName(), pside->GetName(), pstation->GetName(), pstation->GetCluster()->GetName());
}
else
sprintf(szReason, "%s won by dominating their opponents", psideWin->GetName());
m_pfsMission->GameOver(psideWin, szReason);
}
else if ((otLauncher == OT_ship) && psideLauncher)
SendChatf(NULL, CHAT_EVERYONE, NA,
NA, "%s has destroyed %s's %s.",
psideLauncher->GetName(), pside->GetName(), pstation->GetName());
pstation->Terminate();
}
void FedSrvSiteBase::KillAsteroidEvent(IasteroidIGC* pasteroid, bool explodeF)
{
BEGIN_PFM_CREATE(g.fm, pfmAsteroidDestroyed, S, ASTEROID_DESTROYED)
END_PFM_CREATE
pfmAsteroidDestroyed->clusterID = pasteroid->GetCluster()->GetObjectID();
pfmAsteroidDestroyed->asteroidID = pasteroid->GetObjectID();
pfmAsteroidDestroyed->explodeF = explodeF;
g.fm.SendMessages(m_pfsMission->GetGroupRealSides(), FM_GUARANTEED, FM_FLUSH);
pasteroid->Terminate();
}
void FedSrvSiteBase::DrainAsteroidEvent(IasteroidIGC* pasteroid)
{
BEGIN_PFM_CREATE(g.fm, pfmAsteroidDrained, S, ASTEROID_DRAINED)
END_PFM_CREATE
pfmAsteroidDrained->clusterID = pasteroid->GetCluster()->GetObjectID();
pfmAsteroidDrained->asteroidID = pasteroid->GetObjectID();
g.fm.SendMessages(m_pfsMission->GetGroupRealSides(), FM_GUARANTEED, FM_FLUSH);
pasteroid->SetOre(0.0f);
}
void FedSrvSiteBase::KillProbeEvent(IprobeIGC* pprobe)
{
BEGIN_PFM_CREATE(g.fm, pfmProbeDestroyed, S, PROBE_DESTROYED)
END_PFM_CREATE
pfmProbeDestroyed->clusterID = pprobe->GetCluster()->GetObjectID();
pfmProbeDestroyed->probeID = pprobe->GetObjectID();
g.fm.SendMessages(m_pfsMission->GetGroupRealSides(), FM_GUARANTEED, FM_FLUSH);
pprobe->Terminate();
}
void FedSrvSiteBase::KillBuildingEffectEvent(IbuildingEffectIGC* pbe)
{
BEGIN_PFM_CREATE(g.fm, pfmBuildingEffectDestroyed, S, BUILDINGEFFECT_DESTROYED)
END_PFM_CREATE
pfmBuildingEffectDestroyed->asteroidID = pbe->GetAsteroid()->GetObjectID();
g.fm.SendMessages(m_pfsMission->GetGroupRealSides(), FM_GUARANTEED, FM_FLUSH);
pbe->Terminate();
}
void FedSrvSiteBase::KillTreasureEvent(ItreasureIGC* ptreasure)
{
if (m_pfsMission && m_pfsMission->GetIGCMission()->GetMissionStage() == STAGE_STARTED)
{
BEGIN_PFM_CREATE(g.fm, pfmDT, S, DESTROY_TREASURE)
END_PFM_CREATE
pfmDT->treasureID = ptreasure->GetObjectID();
pfmDT->sectorID = ptreasure->GetCluster()->GetObjectID();
g.fm.SendMessages(m_pfsMission->GetGroupRealSides(), FM_NOT_GUARANTEED, FM_FLUSH);
if (ptreasure->GetTreasureCode() == c_tcFlag)
RespawnFlag(ptreasure->GetTreasureID(),NULL); }
ptreasure->Terminate();
}
void FedSrvSiteBase::KillMissileEvent(ImissileIGC* pmissile, const Vector& position)
{
BEGIN_PFM_CREATE(g.fm, pfmMissileDestroyed, S, MISSILE_DESTROYED)
END_PFM_CREATE
pfmMissileDestroyed->clusterID = pmissile->GetCluster()->GetObjectID();
pfmMissileDestroyed->missileID = pmissile->GetObjectID();
pfmMissileDestroyed->position = position;
g.fm.SendMessages(m_pfsMission->GetGroupRealSides(), FM_GUARANTEED, FM_FLUSH);
if (position != Vector::GetZero()) pmissile->Explode(position);
pmissile->Terminate();
}
void FedSrvSiteBase::KillMineEvent(ImineIGC* pmine)
{
BEGIN_PFM_CREATE(g.fm, pfmMineDestroyed, S, MINE_DESTROYED)
END_PFM_CREATE
pfmMineDestroyed->clusterID = pmine->GetCluster()->GetObjectID();
pfmMineDestroyed->mineID = pmine->GetObjectID();
g.fm.SendMessages(m_pfsMission->GetGroupRealSides(), FM_GUARANTEED, FM_FLUSH);
pmine->Terminate();
}
void FedSrvSiteBase::WarpBombEvent(IwarpIGC* pwarp, ImissileIGC* pmissile)
{
assert (pwarp);
assert (pmissile);
ImissileTypeIGC* pmt = pmissile->GetMissileType();
assert (pmt);
assert (pmt->GetObjectType() == OT_missileType);
Time timeExplosion = pwarp->GetLastUpdate() + m_pfsMission->GetIGCMission()->GetFloatConstant(c_fcidWarpBombDelay);
{
BEGIN_PFM_CREATE(g.fm, pfmWB, S, WARP_BOMB)
END_PFM_CREATE
pfmWB->timeExplosion = timeExplosion;
pfmWB->warpidBombed = pwarp->GetObjectID();
pfmWB->expendableidMissile = pmt->GetObjectID();
g.fm.SendMessages(m_pfsMission->GetGroupRealSides(), FM_GUARANTEED, FM_FLUSH);
}
pwarp->AddBomb(timeExplosion, pmt);
}
static void RefillPart(IshipIGC* pship, IpartIGC* ppart, const TechTreeBitMask& ttbm)
{
IpartTypeIGC* pptBase = ppart->GetPartType();
if (pptBase->GetRequiredTechs() <= ttbm)
{
IpartTypeIGC* ppt = pptBase;
while (true)
{
IpartTypeIGC* pptNext = ppt->GetSuccessorPartType();
if (pptNext && (pptNext->GetRequiredTechs() <= ttbm))
ppt = pptNext;
else
break;
}
short newAmount = (ppart->GetPrice() == 0)
? SHRT_MAX
: ppart->GetAmount();
if (ppt == pptBase)
{
ppart->SetAmount(newAmount);
}
else
{
Mount oldMount = ppart->GetMountID();
ppart->Terminate();
pship->CreateAndAddPart(ppt, oldMount, newAmount);
}
}
}
static bool MatchPT(IpartTypeIGC* ppt1, IpartTypeIGC* ppt2)
{
do
{
if (ppt1 == ppt2)
return true;
ppt1 = ppt1->GetSuccessorPartType();
}
while (ppt1);
return false;
}
static void ErasePart(IshipIGC* pship, EquipmentType et, Mount mount, IpartTypeIGC* ptDesired[c_maxCargo + 3])
{
IpartIGC* ppart = pship->GetMountedPart(et, mount);
if (ppart)
{
IpartTypeIGC* ppt = ppart->GetPartType();
for (int i = 0; (i < c_maxCargo + 3); i++)
{
if (ptDesired[i] && MatchPT(ptDesired[i], ppt))
{
ptDesired[i] = NULL;
break;
}
}
}
}
bool FedSrvSiteBase::LandOnCarrierEvent(IshipIGC* pshipCarrier, IshipIGC* pship, float tCollision)
{
CFSPlayer* pfsPlayer = ((CFSShip*)(pship->GetPrivateData()))->GetPlayer();
ImissionIGC* pMission = pship->GetMission();
TechTreeBitMask ttbm = pship->GetSide()->GetDevelopmentTechs() | pship->GetSide()->GetBuildingTechs();
{
PartLinkIGC* ppl = pship->GetParts()->last();
while (ppl)
{
IpartIGC* ppart = ppl->data();
ppl = ppl->txen();
if (ppart)
RefillPart(pship, ppart, ttbm);
}
}
IpartTypeIGC* ptDesired[c_maxCargo + 3]; memcpy(ptDesired, pfsPlayer->GetDesiredLoadout(), sizeof(ptDesired));
{
ErasePart(pship, ET_Magazine, 0, ptDesired);
ErasePart(pship, ET_Dispenser, 0, ptDesired);
ErasePart(pship, ET_ChaffLauncher, 0, ptDesired);
for (Mount i = 0; (i < c_maxCargo); i++)
ErasePart(pship, NA, -1 - i, ptDesired);
}
{
IpartTypeIGC* ptFuel = (pship->GetMountedPart(ET_Afterburner, 0) != NULL)
? pMission->GetFuelPack()
: NULL;
IpartTypeIGC* ptAmmo = NULL;
{
for (Mount i = pship->GetHullType()->GetMaxWeapons() - 1; (i >= 0); i--)
{
IweaponIGC* pw = (IweaponIGC*)(pship->GetMountedPart(ET_Weapon, i));
if (pw && (pw->GetAmmoPerShot() != 0))
{
ptAmmo = pMission->GetAmmoPack();
break;
}
}
}
bool bBuyFuel = true;
int iDesired = 0;
for (Mount i = 0; (i < c_maxCargo); i++)
{
IpartIGC* ppart = pship->GetMountedPart(NA, -1 - i);
if (ppart == NULL)
{
while (iDesired < c_maxCargo + 3)
{
IpartTypeIGC* pt = ptDesired[iDesired++];
if (pt && (pt->GetRequiredTechs() <= ttbm))
{
while (true)
{
IpartTypeIGC* ptNext = pt->GetSuccessorPartType();
if (ptNext && (ptNext->GetRequiredTechs() <= ttbm))
pt = ptNext;
else
break;
}
ppart = pship->CreateAndAddPart(pt, -1 - i, SHRT_MAX);
assert (ppart->GetPrice() == 0);
break;
}
}
if (ppart == NULL)
{
if (bBuyFuel && ptFuel)
{
pship->CreateAndAddPart(ptFuel, -1 - i, SHRT_MAX);
bBuyFuel = (ptAmmo == NULL);
}
else if (ptAmmo)
{
pship->CreateAndAddPart(ptAmmo, -1 - i, SHRT_MAX);
bBuyFuel = true;
}
}
}
}
}
pship->SetAmmo(SHRT_MAX);
pship->SetFuel(FLT_MAX);
pship->SetEnergy(pship->GetHullType()->GetMaxEnergy());
pship->SetFraction(1.0f);
{
IshieldIGC* pshield = (IshieldIGC*)(pship->GetMountedPart(ET_Shield, 0));
if (pshield)
pshield->SetFraction(1.0f);
}
const Orientation& orientation = pshipCarrier->GetOrientation();
float vLaunch = pMission->GetFloatConstant(c_fcidExitStationSpeed);
Vector position = pshipCarrier->GetPosition();
Vector velocity = pshipCarrier->GetVelocity();
position.x += random(-0.5f, 0.5f);
position.y += random(-0.5f, 0.5f);
position.z += random(-0.5f, 0.5f);
IhullTypeIGC* phtCarrier = pshipCarrier->GetBaseHullType();
Orientation orientationBfr;
const Orientation* porientation;
if (phtCarrier->GetLaunchSlots() == 0)
{
position -= orientation.GetBackward() * (pshipCarrier->GetRadius() + pship->GetRadius() + vLaunch * 0.5f);
velocity -= orientation.GetBackward() * vLaunch;
porientation = &orientation;
}
else
{
short slot = pshipCarrier->GetLaunchSlot();
position += phtCarrier->GetLaunchPosition(slot) * orientation;
Vector forward = phtCarrier->GetLaunchDirection(slot) * orientation;
position += forward * (pship->GetRadius() + vLaunch * 0.5f);
velocity += forward * vLaunch;
orientationBfr = orientation;
orientationBfr.TurnTo(forward);
porientation = &orientationBfr;
}
pship->SetPosition(position);
pship->SetVelocity(velocity);
pship->SetOrientation(*porientation);
IclusterIGC* pcluster = pship->GetCluster();
pcluster->RecalculateCollisions(tCollision, pship, NULL);
{
BEGIN_PFM_CREATE(g.fm, pfmLaunch, S, RELAUNCH_SHIP)
FM_VAR_PARM(NULL, pship->ExportShipLoadout(NULL))
END_PFM_CREATE
pship->ExportShipLoadout((ShipLoadout*)FM_VAR_REF(pfmLaunch, loadout));
pfmLaunch->shipID = pship->GetObjectID();
pfmLaunch->carrierID = pshipCarrier->GetObjectID();
pfmLaunch->position = position;
pfmLaunch->velocity = velocity;
pfmLaunch->orientation.Set(*porientation);
pfmLaunch->cookie = pfsPlayer->NewCookie();
g.fm.SendMessages(GetGroupSectorFlying(pship->GetCluster()), FM_GUARANTEED, FM_FLUSH);
}
return true;
}
bool FedSrvSiteBase::RescueShipEvent(IshipIGC* pshipRescued, IshipIGC* pshipRescuer)
{
assert (pshipRescued);
if (pshipRescuer)
{
CFSShip* pfsShip = (CFSShip*)(pshipRescuer->GetPrivateData());
pfsShip->GetPlayerScoreObject()->AddRescue();
BEGIN_PFM_CREATE(g.fm, pfmPlayerRescued, S, PLAYER_RESCUED)
END_PFM_CREATE
pfmPlayerRescued->shipIDRescuer = pshipRescuer->GetObjectID();
pfmPlayerRescued->shipIDRescuee = pshipRescued->GetObjectID();
if (pfsShip->IsPlayer())
g.fm.SendMessages(pfsShip->GetPlayer()->GetConnection(), FM_GUARANTEED, FM_DONT_FLUSH);
g.fm.SendMessages(((CFSShip*)(pshipRescued->GetPrivateData()))->GetPlayer()->GetConnection(), FM_GUARANTEED, FM_FLUSH);
}
((CFSShip*)(pshipRescued->GetPrivateData()))->ResetWarpState();
IstationIGC* pstation = (IstationIGC*)FindTarget(pshipRescued,
(c_ttStation | c_ttFriendly | c_ttAnyCluster | c_ttNearest),
NULL, NULL, NULL, NULL, c_sabmRestart);
return pstation ? DockWithStationEvent(pshipRescued, pstation) : false;
}
void FedSrvSiteBase::CaptureStationEvent(IshipIGC* pship, IstationIGC* pstation)
{
CFSShip* pfsShip = (CFSShip *) pship->GetPrivateData();
pfsShip->CaptureStation(pstation);
}
bool FedSrvSiteBase::DockWithStationEvent(IshipIGC* pship, IstationIGC* pstation)
{
assert (pship->GetParentShip() == NULL);
CFSShip* pfsShip = (CFSShip *) pship->GetPrivateData();
if (!pfsShip->OkToWarp())
return false;
IsideIGC* pside = pship->GetSide();
IsideIGC* psideOld = pstation->GetSide();
if (pside != psideOld)
{
pfsShip->CaptureStation(pstation);
}
pfsShip->AnnounceExit(pship->GetCluster(), SDR_DOCKED);
pfsShip->ShipStatusDocked(pstation);
{
SideID sidFlag = pship->GetFlag();
if (sidFlag != NA)
{
if (sidFlag == SIDE_TEAMLOBBY)
{
pfsShip->GetPlayerScoreObject()->AddArtifact();
pside->SetArtifacts(pside->GetArtifacts() + 1);
SendChatf(NULL, CHAT_TEAM, pside->GetObjectID(),
artifactSecuredSound, "%s has secured an artifact.",
pship->GetName());
}
else
{
pfsShip->GetPlayerScoreObject()->AddFlag();
pside->SetFlags(pside->GetFlags() + 1);
SendChatf(NULL, CHAT_TEAM, pside->GetObjectID(),
enemyFlagSecuredSound, "%s has secured %s's flag.",
pship->GetName(), pfsShip->GetIGCShip()->GetMission()->GetSide(sidFlag)->GetName());
SendChatf(NULL, CHAT_TEAM, sidFlag,
flagSecuredSound, "%s of %s has secured your flag.",
pship->GetName(), pside->GetName ());
}
pship->SetFlag(NA);
BEGIN_PFM_CREATE(g.fm, pfmGain, S, GAIN_FLAG)
END_PFM_CREATE
pfmGain->sideidFlag = NA;
pfmGain->shipidRecipient = pship->GetObjectID();
pfmGain->bIsTreasureDocked = false; g.fm.SendMessages(m_pfsMission->GetGroupRealSides(), FM_GUARANTEED, FM_FLUSH);
IsideIGC* psideWin = m_pfsMission->CheckForVictoryByFlags(pside, sidFlag);
if (psideWin)
{
static char szReason[100]; sprintf(szReason,
(sidFlag != NA)
? "%s wins with the flag recovered by %s"
: "%s wins with the artifact recovered by %s",
psideWin->GetName(), pship->GetName());
m_pfsMission->GameOver(psideWin, szReason);
}
RespawnFlag(sidFlag,pside); }
}
pship->SetStation(pstation);
{
for (ShipLinkIGC* psl = pship->GetChildShips()->first();
(psl != NULL);
psl = psl->next())
{
psl->data()->SetStation(pstation);
}
}
return true;
}
void FedSrvSiteBase::ChangeStation(IshipIGC* pship, IstationIGC* pstationOld, IstationIGC* pstationNew)
{
assert (pship);
CFSShip * pfsShip = (CFSShip *) pship->GetPrivateData();
if (pstationNew == NULL)
{
if ((m_pfsMission->GetStage() == STAGE_STARTED) && (pship->GetParentShip() == NULL))
{
pstationOld->RepairAndRefuel(pship);
pfsShip->Launch(pstationOld);
}
}
else
{
if (pstationOld == NULL)
{
TechTreeBitMask ttbm;
ttbm.ClearAll();
for (PartLinkIGC* ppl = pship->GetParts()->first(); (ppl != NULL); ppl = ppl->next())
{
IpartIGC* ppart = ppl->data();
ttbm |= ppart->GetPartType()->GetEffectTechs();
if (pship->GetSide()->IsNewDevelopmentTechs(ppart->GetPartType()->GetEffectTechs()))
{
BEGIN_PFM_CREATE(g.fm, pfmGain, S, GAIN_FLAG)
END_PFM_CREATE
pfmGain->sideidFlag = NA;
pfmGain->shipidRecipient = pship->GetObjectID();
pfmGain->bIsTreasureDocked = true;
pfmGain->parttypeidDocked = ppart->GetPartType()->GetObjectID();
g.fm.SendMessages(CFSSide::FromIGC(pship->GetSide())->GetGroup(), FM_GUARANTEED, FM_FLUSH);
}
}
IsideIGC* pside = pship->GetSide();
assert (pside);
if (pside->ApplyDevelopmentTechs(ttbm))
pfsShip->GetPlayerScoreObject()->AddTechsRecovered();
}
pfsShip->Dock(pstationNew);
if (!pfsShip->IsPlayer())
UpgradeShip(pship, pstationNew);
}
}
void * FedSrvSiteBase::GetDroneFromShip(IshipIGC * pship) {
CFSShip * pfsShip = (CFSShip *) pship->GetPrivateData();
return pfsShip->IsPlayer() ? NULL : (void *) pfsShip->GetDrone()->GetDrone();
}
void FedSrvSiteBase::RequestRipcord(IshipIGC* pship, IclusterIGC* pcluster)
{
IclusterIGC* pclusterShip = pship->GetCluster();
CFSShip* pfsShip = (CFSShip *)pship->GetPrivateData();
CFSMission* pfsMission = pfsShip->GetMission();
ImodelIGC* pmodelRipcord = pship->GetRipcordModel();
if (pcluster == NULL)
{
if (pmodelRipcord != NULL)
{
assert (pclusterShip);
pship->SetRipcordModel(NULL);
BEGIN_PFM_CREATE(g.fm, pfmRipcordAborted, S, RIPCORD_ABORTED)
END_PFM_CREATE
pfmRipcordAborted->shipidRipcord = pship->GetObjectID();
g.fm.SendMessages(GetGroupSectorFlying(pclusterShip), FM_GUARANTEED, FM_FLUSH);
}
}
else if ((pmodelRipcord == NULL) ||
(pmodelRipcord->GetCluster() != pcluster))
{
assert (pclusterShip);
ImodelIGC* pmodelNew = pship->FindRipcordModel(pcluster);
if (pmodelNew)
{
ImodelIGC* pmodelOld = pship->GetRipcordModel();
if (pmodelNew != pmodelOld)
{
pship->SetRipcordModel(pmodelNew);
pship->ResetRipcordTimeLeft();
}
if ((pmodelNew != pmodelOld) && pfsShip->IsPlayer())
{
BEGIN_PFM_CREATE(g.fm, pfmRA, S, RIPCORD_ACTIVATE)
END_PFM_CREATE
pfmRA->shipidRipcord = pship->GetObjectID();
pfmRA->otRipcord = pmodelNew->GetObjectType();
pfmRA->oidRipcord = pmodelNew->GetObjectID();
pfmRA->sidRipcord = pcluster->GetObjectID();
g.fm.SendMessages((pmodelOld == NULL)
? (CFMRecipient*)(GetGroupSectorFlying(pclusterShip))
: (CFMRecipient*)(pfsShip->GetPlayer()->GetConnection()), FM_GUARANTEED, FM_FLUSH);
}
}
else if (pfsShip->IsPlayer())
{
BEGIN_PFM_CREATE(g.fm, pfmRipcordDenied, S, RIPCORD_DENIED)
END_PFM_CREATE
g.fm.SendMessages(pfsShip->GetPlayer()->GetConnection(), FM_GUARANTEED, FM_FLUSH);
}
}
}
bool FedSrvSiteBase::ContinueRipcord(IshipIGC* pship, ImodelIGC* pmodel)
{
bool rc;
if ((pship->GetFlag() != NA) ||
(pship->GetSide() != pmodel->GetSide()) ||
(pmodel->GetCluster() == NULL))
{
rc = false;
}
else if (pmodel->GetObjectType() == OT_ship)
{
IshipIGC* ps = (IshipIGC*)pmodel;
IhullTypeIGC* pht = ps->GetBaseHullType();
rc = pht &&
pht->HasCapability(pship->GetBaseHullType()->HasCapability(c_habmCanLtRipcord)
? (c_habmIsRipcordTarget | c_habmIsLtRipcordTarget)
: c_habmIsRipcordTarget);
}
else
rc = true;
if (!rc)
{
BEGIN_PFM_CREATE(g.fm, pfmRipcordAborted, S, RIPCORD_ABORTED)
END_PFM_CREATE
pfmRipcordAborted->shipidRipcord = pship->GetObjectID();
g.fm.SendMessages(GetGroupSectorFlying(pship->GetCluster()), FM_GUARANTEED, FM_FLUSH);
}
return rc;
}
bool FedSrvSiteBase::UseRipcord(IshipIGC* pship, ImodelIGC* pmodel)
{
assert (pmodel);
ObjectType type = pmodel->GetObjectType();
if (type == OT_station)
((IstationIGC*)pmodel)->Launch(pship);
else
{
if (type == OT_ship)
{
float newEnergy = ((IshipIGC*)pmodel)->GetEnergy() - pship->GetBaseHullType()->GetRipcordCost();
if (newEnergy < 0.0f)
{
BEGIN_PFM_CREATE(g.fm, pfmRipcordAborted, S, RIPCORD_ABORTED)
END_PFM_CREATE
pfmRipcordAborted->shipidRipcord = pship->GetObjectID();
g.fm.SendMessages(GetGroupSectorFlying(pship->GetCluster()), FM_GUARANTEED, FM_FLUSH);
return true;
}
else
((IshipIGC*)pmodel)->SetEnergy(newEnergy);
}
float r = pmodel->GetRadius() + pship->GetRadius() + 25.0f;
Vector v = Vector::RandomDirection();
Orientation o(v);
IclusterIGC* pcluster = pmodel->GetCluster();
Time lastUpdate = pcluster->GetLastUpdate();
pship->SetPosition(pmodel->GetPosition() + v * r);
pship->SetVelocity(v * m_pfsMission->GetIGCMission()->GetFloatConstant(c_fcidExitStationSpeed));
pship->SetOrientation(o);
pship->SetCurrentTurnRate(c_axisYaw, 0.0f);
pship->SetCurrentTurnRate(c_axisPitch, 0.0f);
pship->SetCurrentTurnRate(c_axisRoll, 0.0f);
pship->SetCluster(pcluster);
}
return true;
}
void FedSrvSiteBase::HitWarpEvent(IshipIGC* pship, IwarpIGC* pwarp)
{
CFSShip * pfsShip = (CFSShip *) pship->GetPrivateData();
pfsShip->HitWarp(pwarp);
}
void FedSrvSiteBase::ChangeCluster(IshipIGC* pship,
IclusterIGC* pclusterOld,
IclusterIGC* pclusterNew)
{
CFSShip* pfsShip = (CFSShip *) pship->GetPrivateData();
if ((pclusterOld && pclusterNew) && (pclusterOld != pclusterNew))
pfsShip->AnnounceExit(pclusterOld, SDR_LEFTSECTOR);
pfsShip->SetCluster(pclusterNew);
}
void FedSrvSiteBase::LoadoutChangeEvent(IshipIGC* pship, IpartIGC* ppart, LoadoutChange lc)
{
if (lc == c_lcAdded && ppart->GetEquipmentType() == ET_Weapon
&& ((IweaponIGC*)ppart)->GetProjectileType()->GetBlastRadius() > 0.0f)
{
CommandChangedEvent(c_cmdCurrent, pship,
pship->GetCommandTarget(c_cmdCurrent),
pship->GetCommandID(c_cmdCurrent));
}
}
bool FedSrvSiteBase::HitTreasureEvent(Time now, IshipIGC* ship, ItreasureIGC* treasure)
{
TreasureCode tc = treasure->GetTreasureCode();
ObjectID oid = treasure->GetTreasureID();
if (tc == c_tcFlag)
{
if ((ship->GetFlag() != NA) || (oid == ship->GetSide()->GetObjectID()))
{
return false;
}
BEGIN_PFM_CREATE(g.fm, pfmGain, S, GAIN_FLAG)
END_PFM_CREATE
pfmGain->sideidFlag = oid;
pfmGain->shipidRecipient = ship->GetObjectID();
pfmGain->bIsTreasureDocked = false; g.fm.SendMessages(m_pfsMission->GetGroupRealSides(), FM_GUARANTEED, FM_FLUSH);
treasure->SetTreasureID(NA);
}
short amount = treasure->GetAmount();
if (tc == c_tcPart)
{
}
else if (tc == c_tcCash)
{
CFSShip* pfsShip = (CFSShip*)(ship->GetPrivateData());
if (pfsShip->IsPlayer())
{
IshipIGC* pshipDonate = ship->GetAutoDonate();
if (pshipDonate == NULL)
pshipDonate = ship;
CFSShip* pfsDonate = (CFSShip*)(pshipDonate->GetPrivateData());
assert (pfsDonate->IsPlayer());
assert (amount >= 0);
BEGIN_PFM_CREATE(g.fm, pfmMoney, S, MONEY_CHANGE)
END_PFM_CREATE
pfmMoney->sidTo = pshipDonate->GetObjectID();
pfmMoney->sidFrom = NA;
pfmMoney->dMoney = amount;
pfsDonate->SetMoney(pfsDonate->GetMoney() + amount);
g.fm.SendMessages(CFSSide::FromIGC(pfsShip->GetSide())->GetGroup(), FM_GUARANTEED, FM_FLUSH);
}
else
{
m_pfsMission->GiveSideMoney(ship->GetSide(), Money(amount));
}
}
else
ship->HitTreasure(tc, oid, amount);
CFSShip* pfsShip = (CFSShip*)(ship->GetPrivateData());
if (pfsShip->IsPlayer())
{
CFSPlayer* pfsPlayer = pfsShip->GetPlayer();
if ((tc != c_tcPart) || (pfsPlayer->GetTreasureObjectID() == NA))
{
if (tc == c_tcPart)
pfsPlayer->SetTreasureData(oid, amount);
BEGIN_PFM_CREATE(g.fm, pfmAT, S, ACQUIRE_TREASURE)
END_PFM_CREATE
pfmAT->treasureCode = tc;
pfmAT->treasureID = oid;
pfmAT->amount = amount;
g.fm.SendMessages(pfsPlayer->GetConnection(), FM_GUARANTEED, FM_FLUSH);
}
}
return true;
}
void FedSrvSiteBase::PaydayEvent(IsideIGC* pside, float money)
{
m_pfsMission->GiveSideMoney(pside, Money(money));
}
void FedSrvSiteBase::SendChat(IshipIGC* pshipSender,
ChatTarget chatTarget,
ObjectID oidRecipient,
SoundID soVoiceOver,
const char* pszText,
CommandID cid,
ObjectType otTarget,
ObjectID oidTarget,
ImodelIGC* pmodelTarget,
bool bObjectModel)
{
BEGIN_PFM_CREATE_ALLOC(g.fm, pfmChatAlloc, CS, CHATMESSAGE)
FM_VAR_PARM(pszText, CB_ZTS)
END_PFM_CREATE
pfmChatAlloc->cd.sidSender = pshipSender ? pshipSender->GetObjectID()
: NA;
pfmChatAlloc->cd.chatTarget = chatTarget;
pfmChatAlloc->cd.oidRecipient = oidRecipient;
pfmChatAlloc->cd.commandID = cid;
pfmChatAlloc->cd.voiceOver = soVoiceOver;
pfmChatAlloc->cd.bObjectModel = bObjectModel;
pfmChatAlloc->otTarget = otTarget;
pfmChatAlloc->oidTarget = oidTarget;
ForwardChatMessage(m_pfsMission,
pshipSender
? (CFSShip*)(pshipSender->GetPrivateData())
: NULL,
pfmChatAlloc,
&(pfmChatAlloc->cd),
pszText,
otTarget,
oidTarget,
NULL);
PFM_DEALLOC(pfmChatAlloc);
}
void FedSrvSiteBase::ClusterUpdateEvent(IclusterIGC* c)
{
}
void FedSrvSiteBase::CommandChangedEvent(Command i, IshipIGC * pship, ImodelIGC* ptarget, CommandID cid)
{
IclusterIGC* pcluster;
if ((i == c_cmdAccepted) ||
((i == c_cmdCurrent) &&
(pship->GetPilotType() >= c_ptPlayer) &&
(pcluster = pship->GetCluster()) && (pship->IsUsingAreaOfEffectWeapon())))
{
BEGIN_PFM_CREATE(g.fm, pfmOC, CS, ORDER_CHANGE)
END_PFM_CREATE
pfmOC->command = i;
pfmOC->shipID = pship->GetObjectID();
pfmOC->commandID = cid;
if (ptarget)
{
pfmOC->objectType = ptarget->GetObjectType();
pfmOC->objectID = ptarget->GetObjectID();
}
else
{
pfmOC->objectType = OT_invalid;
pfmOC->objectID = NA;
}
bool fCurrentTarget = (i == c_cmdCurrent);
g.fm.SendMessages(fCurrentTarget
? GetGroupSectorFlying(pcluster)
: CFSSide::FromIGC(pship->GetSide())->GetGroup(),
fCurrentTarget ? FM_NOT_GUARANTEED : FM_GUARANTEED, FM_FLUSH);
}
}
void FedSrvSiteBase::CreateBuildingEffect(Time now,
IasteroidIGC* pasteroid,
IshipIGC* pshipBuilder)
{
assert (pasteroid);
assert (pshipBuilder);
assert (pshipBuilder->GetPilotType() == c_ptBuilder);
assert (pshipBuilder->GetBaseData());
assert (pshipBuilder->GetCluster());
IbuildingEffectIGC* pbe = pshipBuilder->GetCluster()->CreateBuildingEffect(now,
pasteroid,
NULL,
pshipBuilder,
pasteroid->GetRadius(),
((IstationTypeIGC*)(pshipBuilder->GetBaseData()))->GetRadius(),
pshipBuilder->GetPosition() - pshipBuilder->GetOrientation().GetBackward() * pshipBuilder->GetRadius(),
pasteroid->GetPosition());
for (SideLinkIGC* psl = m_pfsMission->GetIGCMission()->GetSides()->first();
(psl != NULL);
psl = psl->next())
{
if (pasteroid->SeenBySide(psl->data()))
{
ExportObj(pbe, OT_buildingEffect, NULL);
g.fm.SendMessages(CFSSide::FromIGC(psl->data())->GetGroup(), FM_GUARANTEED, FM_FLUSH);
}
}
}
void FedSrvSiteBase::LayExpendable(Time now,
IexpendableTypeIGC* pet,
IshipIGC* pshipLayer)
{
assert (pet);
assert (pshipLayer);
ObjectType type = pet->GetObjectType();
ImissionIGC* pMission = m_pfsMission->GetIGCMission();
const Vector& position = pshipLayer->GetPosition();
IclusterIGC* pcluster = pshipLayer->GetCluster();
IsideIGC* pside = pshipLayer->GetSide();
if (type == OT_mineType)
{
DataMineIGC dm;
dm.pshipLauncher = NULL;
dm.psideLauncher = pside;
dm.mineID = pMission->GenerateNewMineID();
dm.time0 = now;
dm.p0 = position;
dm.pminetype = (ImineTypeIGC*)pet;
assert (dm.pminetype);
dm.pcluster = pcluster;
dm.exportF = false;
ImineIGC * m = (ImineIGC*)(pMission->CreateObject(now, OT_mine, &dm, sizeof(dm)));
assert (m);
m->Release();
}
else
{
assert (type == OT_probeType);
DataProbeIGC dp;
dp.pside = pside;
dp.pship = NULL;
dp.pmodelTarget = NULL;
dp.probeID = pMission->GenerateNewProbeID();
dp.time0 = now;
dp.p0 = position;
dp.pprobetype = (IprobeTypeIGC*)pet;
assert (dp.pprobetype);
dp.pcluster = pcluster;
dp.exportF = false;
IprobeIGC * p = (IprobeIGC*)(pMission->CreateObject(now, OT_probe, &dp, sizeof(dp)));
assert (p);
p->Release();
}
{
const PartListIGC* parts = pshipLayer->GetParts();
PartLinkIGC* plink;
while (plink = parts->first()) plink->data()->Terminate();
}
pshipLayer->SetAmmo(0);
pshipLayer->SetFuel(0.0f);
KillShipEvent(now, pshipLayer, NULL, 0.0f, position, Vector::GetZero());
}
void FedSrvSiteBase::RespawnFlag(SideID sidFlag, IsideIGC* pcapturersside) {
if (sidFlag != NA)
{
if (sidFlag == SIDE_TEAMLOBBY)
{
const int c_maxClusters = 100;
IclusterIGC* pclusters[c_maxClusters];
int nClusters = 0;
for (ClusterLinkIGC* pcl = m_pfsMission->GetIGCMission()->GetClusters()->first();
(pcl != NULL);
pcl = pcl->next())
{
IclusterIGC* pcluster = pcl->data();
if (!pcluster->GetHomeSector())
{
assert (nClusters < c_maxClusters);
pclusters[nClusters++] = pcluster;
}
}
assert (nClusters != 0);
m_pfsMission->GetIGCMission()->GenerateTreasure(g.timeNow, pclusters[randomInt(0, nClusters - 1)], -2);
}
else
{
IsideIGC* pside = m_pfsMission->GetIGCMission()->GetSide(sidFlag);
assert(pside);
const int c_maxStations = 10;
IstationIGC* pstations[c_maxStations];
int nStations = 0;
for (StationLinkIGC* psl = pside->GetStations()->first(); (psl != NULL); psl = psl->next())
{
IstationIGC* pstation = psl->data();
if (pstation->GetStationType()->HasCapability(c_sabmPedestal))
{
const float c_spittingDistance = 300.0f;
TreasureLinkIGC* ptl;
for (ptl = pstation->GetCluster()->GetTreasures()->first(); (ptl != NULL); ptl = ptl->next())
{
ItreasureIGC* pt = ptl->data();
if ((pt->GetTreasureCode() == c_tcFlag) && (pt->GetTreasureID() == sidFlag))
{
float d = (pt->GetPosition() - pstation->GetPosition()).LengthSquared();
if (d < c_spittingDistance * c_spittingDistance)
break;
}
}
if (ptl == NULL)
{
assert (nStations < c_maxStations);
pstations[nStations++] = pstation;
}
}
}
if (nStations == 0) {
if (pcapturersside != NULL) {
static char szReason[100]; sprintf(szReason,"%s wins. Team owning captured flag has no stations left.",
pcapturersside->GetName());
m_pfsMission->GameOver(pcapturersside, szReason);
}
} else {
IstationIGC* pstation = pstations[randomInt(0, nStations - 1)];
DataTreasureIGC dt;
dt.treasureCode = c_tcFlag;
dt.treasureID = sidFlag;
dt.amount = 0;
dt.clusterID = pstation->GetCluster()->GetObjectID();
dt.lifespan = 10.0f * 24.0f * 3600.0f;
dt.createNow = false;
dt.objectID = m_pfsMission->GetIGCMission()->GenerateNewTreasureID();
dt.p0 = pstation->GetPosition();
dt.p0.z += pstation->GetRadius() + c_fFlagOffset;
dt.v0 = Vector::GetZero();
dt.time0 = g.timeNow;
ItreasureIGC* t = (ItreasureIGC *)m_pfsMission->GetIGCMission()->CreateObject(g.timeNow, OT_treasure,
&dt, sizeof(dt));
assert (t);
t->Release();
}
}
}
}
void FedSrvSiteBase::CreateSideEvent(IsideIGC * pIsideIGC)
{
m_pfsMission->CreateSide(pIsideIGC);
}
void FedSrvSiteBase::DestroySideEvent(IsideIGC * pIsideIGC)
{
m_pfsMission->DeleteSide(pIsideIGC);
}
void FedSrvSiteBase::Destroy(CFSMission * pfsMission)
{
delete this;
}
IshipIGC* PickNewLeader(const ShipListIGC* pships,
IshipIGC* pshipIgnore,
int maxVotes)
{
struct Contender
{
IshipIGC* pship;
int nVotes;
};
Contender* pcontenders = new Contender[pships->n()];
int nContenders = 0;
IshipIGC* pshipMax = NULL;
for (ShipLinkIGC* psl = pships->first(); (psl != NULL); psl = psl->next())
{
IshipIGC* pshipAD = psl->data()->GetAutoDonate();
if (pshipAD && (pshipAD != pshipIgnore))
{
int i;
for (i = 0; (i < nContenders); i++)
{
if (pcontenders[i].pship == pshipAD)
{
pcontenders[i].nVotes++;
break;
}
}
if (i == nContenders)
{
pcontenders[nContenders].pship = pshipAD;
pcontenders[nContenders++].nVotes = 1;
}
if (pcontenders[i].nVotes > maxVotes)
{
maxVotes = pcontenders[i].nVotes;
pshipMax = pcontenders[i].pship;
}
}
}
delete pcontenders;
return pshipMax;
}
#ifdef _DEBUG
#define SRVLOG
#endif
#ifdef SRVLOG void FlushDebugLog(void)
{
g_app.CloseLogFile();
}
VOID CALLBACK FileIOCompletionRoutine(
DWORD dwErrorCode, DWORD dwNumberOfBytesTransfered, LPOVERLAPPED lpOverlapped )
{
delete [] (char*)lpOverlapped;
}
void FedSrvApp::AsyncFileOut(const char *psz)
{
SYSTEMTIME systime;
DWORD l = strlen(psz);
const DWORD c_cbPrefix = 19; DWORD cbLine = l + c_cbPrefix;
OVERLAPPED* pov = (OVERLAPPED*)(new char [ sizeof(OVERLAPPED) + cbLine ]);
*pov = m_overlapped;
GetLocalTime(&systime);
wsprintf((char*)(pov + 1), "%02d/%02d %02d:%02d:%02d.%03d ", systime.wMonth, systime.wDay,
systime.wHour, systime.wMinute, systime.wSecond, systime.wMilliseconds);
memcpy(((char*)(pov + 1)) + c_cbPrefix, psz, l);
pov->Offset = ::InterlockedExchangeAdd(&m_nOffset, cbLine);
WriteFileEx(m_hFile, pov + 1, cbLine, pov, FileIOCompletionRoutine);
}
void FedSrvApp::DebugOutput(const char *psz)
{
static TCAutoCriticalSection critsec;
Time tStart = Time::Now();
critsec.Lock();
if (m_dwDebug & FED_DEBUG_FILE)
AsyncFileOut(psz);
if (m_dwDebug & FED_DEBUG_DEBUGOUT)
::OutputDebugStringA(psz);
Time tStop = Time::Now();
DWORD dt = (tStop.clock() - tStart.clock());
if (dt > 20)
{
static char bfr[200];
sprintf(bfr, "DebugOutput delay of %f: %d %d\n", float(dt) / 1000.0f, tStart.clock(), tStop.clock());
if (m_dwDebug & FED_DEBUG_FILE)
AsyncFileOut(bfr);
if (m_dwDebug & FED_DEBUG_DEBUGOUT)
::OutputDebugStringA(bfr);
}
critsec.Unlock();
}
bool FedSrvApp::OnAssert(const char* psz, const char* pszFile, int line, const char* pszModule)
{
_AGCModule.TriggerEvent(NULL, EventID_AGCAssert, "", -1, -1, -1, 3,
"File", VT_LPSTR, pszFile,
"Line", VT_I4, line,
"Text", VT_LPSTR, psz);
return g.fWantInt3;
}
void FedSrvApp::OnAssertBreak()
{
if (m_hFile)
{
CloseHandle(m_hFile);
m_hFile = NULL;
}
*(DWORD*)0 = 0;
}
FedSrvApp g_app;
#endif