#include "pch.h"
#include <string.h> const DWORD CFLServer::c_dwID = 19680815;
const CFLMission * CFLServer::c_AllMissions = (CFLMission*) -1;
bool IsServerAllowed(const char *ip)
{
char config_dir[MAX_PATH];
char config_file_name[MAX_PATH];
GetCurrentDirectory(MAX_PATH,config_dir);
sprintf(config_file_name,"%s\\Allegiance.cfg",config_dir);
const char * c_szCfgApp = "Lobby";
char numservStr[128], ftStr[128], szStr[128];
GetPrivateProfileString(c_szCfgApp, "NumberOfServers", "",
numservStr, sizeof(numservStr), config_file_name);
GetPrivateProfileString(c_szCfgApp, "FilterType", "",
ftStr, sizeof(ftStr), config_file_name);
int numServers=0, ipLen=0, ftLen=0, i=0;
bool bFilterTypeAllow=true;
char key[128];
ipLen = strlen(ip);
ftLen = strlen(ftStr);
if (ftLen>0) {
if (!strncmp("Block",ftStr,ftLen)) bFilterTypeAllow=false;
else bFilterTypeAllow=true;
}
if (strlen(numservStr)>0) {
numServers = atoi(numservStr);
for (i=1; i<=numServers; i++) {
sprintf(key,"Server%d",i);
GetPrivateProfileString(c_szCfgApp, key, "",
szStr, sizeof(szStr), config_file_name);
if (!strncmp(ip,szStr,ipLen)) {
if (bFilterTypeAllow) return true;
else return false;
}
}
if (bFilterTypeAllow) return false;
else return true;
} else {
return true;
}
}
HRESULT LobbyServerSite::OnAppMessage(FedMessaging * pthis, CFMConnection & cnxnFrom, FEDMESSAGE * pfm)
{
CFLServer * pServer = CFLServer::FromConnection(cnxnFrom);
assert(pServer);
cnxnFrom.ResetAbsentCount();
switch (pfm->fmid)
{
case FM_S_LOGON_LOBBY:
{
CASTPFM(pfmLogon, S, LOGON_LOBBY, pfm);
if (pfmLogon->verLobby == LOBBYVER_LS)
{
if(pfmLogon->dwPort != 0) pServer->SetServerPort(pfmLogon->dwPort);
else
pServer->SetServerPort(6073); StaticCoreInfo* pcoreinfo = (StaticCoreInfo*)FM_VAR_REF(pfmLogon, vStaticCoreInfo);
pServer->SetStaticCoreInfo(pfmLogon->cStaticCoreInfo, pcoreinfo);
char * szLoc = FM_VAR_REF(pfmLogon, szLocation);
pServer->SetLocation(szLoc);
pServer->SetMaxGamesAllowed(pfmLogon->MaxGames);
g_pLobbyApp->BuildStaticCoreInfo();
char szRemote[16];
pthis->GetIPAddress(cnxnFrom, szRemote);
if (!strncmp("127.0.0.1",szRemote,9)) break; if (IsServerAllowed(szRemote)) break;
}
char * szReason;
szReason = "Your server IP address is not approved for connection to this Lobby. Please contact the Lobby Amin.";
if (pfmLogon->verLobby > LOBBYVER_LS)
szReason = "The Public Lobby server that you connected to is older than your version. The Zone needs to update their lobby server. Please try again later.";
if (pfmLogon->verLobby < LOBBYVER_LS) szReason = "Your server's version did not get auto-updated properly. Please try again later.";
BEGIN_PFM_CREATE(*pthis, pfmNewMissionAck, L, LOGON_SERVER_NACK)
FM_VAR_PARM((char *)szReason, CB_ZTS)
END_PFM_CREATE
pthis->SendMessages(&cnxnFrom, FM_GUARANTEED, FM_FLUSH);
pthis->DeleteConnection(cnxnFrom);
break;
}
case FM_S_NEW_MISSION:
{
CASTPFM(pfmNewMission, S, NEW_MISSION, pfm);
CFLMission * pMission = pServer->CreateMission(NULL); BEGIN_PFM_CREATE(*pthis, pfmNewMissionAck, L, NEW_MISSION_ACK)
END_PFM_CREATE
pfmNewMissionAck->dwIGCMissionID = pfmNewMission->dwIGCMissionID;
pfmNewMissionAck->dwCookie = (DWORD) pMission;
pthis->SendMessages(&cnxnFrom, FM_GUARANTEED, FM_FLUSH);
}
break;
case FM_LS_LOBBYMISSIONINFO:
{
CASTPFM(pfmLobbyMissionInfo, LS, LOBBYMISSIONINFO, pfm);
char szAddr[16];
pthis->GetIPAddress(cnxnFrom, szAddr); char *pfmdata = FM_VAR_REF(pfmLobbyMissionInfo, szServerAddr); strcpy(pfmdata,szAddr); CFLMission * pMission = CFLMission::FromCookie(pfmLobbyMissionInfo->dwCookie);
if (pMission) {
pMission->SetLobbyInfo(pfmLobbyMissionInfo);
pMission->NotifyCreator();
}
}
break;
case FM_LS_MISSION_GONE:
{
CASTPFM(pfmMissionGone, LS, MISSION_GONE, pfm);
CFLMission * pMission = CFLMission::FromCookie(pfmMissionGone->dwCookie);
pServer->DeleteMission(pMission);
}
break;
case FM_S_HEARTBEAT:
pServer->SetHere();
break;
case FM_S_PLAYER_JOINED:
{
CASTPFM(pfmPlayerJoined, S, PLAYER_JOINED, pfm);
CFLMission * pMission = CFLMission::FromCookie(pfmPlayerJoined->dwMissionCookie);
const char* szCharacterName = FM_VAR_REF(pfmPlayerJoined, szCharacterName);
const char* szCDKey = FM_VAR_REF(pfmPlayerJoined, szCDKey);
if (NULL == szCharacterName || '\0' != szCharacterName[pfmPlayerJoined->cbszCharacterName-1]
|| NULL == szCDKey || '\0' != szCDKey[pfmPlayerJoined->cbszCDKey-1])
{
g_pLobbyApp->GetSite()->LogEvent(EVENTLOG_ERROR_TYPE, LE_CorruptPlayerJoinMsg,
cnxnFrom.GetName());
}
else if (NULL == pMission)
{
g_pLobbyApp->GetSite()->LogEvent(EVENTLOG_WARNING_TYPE, LE_PlayerJoinInvalidMission,
szCharacterName, cnxnFrom.GetName(), pfmPlayerJoined->dwMissionCookie);
}
else
{
if (g_pLobbyApp->EnforceCDKey())
{
char * szUnencryptedCDKey = (char*)_alloca(strlen(szCDKey) + 1);
ZUnscramble(szUnencryptedCDKey, szCDKey, szCharacterName);
szCDKey = szUnencryptedCDKey;
}
g_pLobbyApp->SetPlayerMission(szCharacterName, szCDKey, pMission);
}
}
break;
case FM_S_PLAYER_QUIT:
{
CASTPFM(pfmPlayerQuit, S, PLAYER_QUIT, pfm);
CFLMission * pMission = CFLMission::FromCookie(pfmPlayerQuit->dwMissionCookie);
const char* szCharacterName = FM_VAR_REF(pfmPlayerQuit, szCharacterName);
if (NULL == szCharacterName || '\0' != szCharacterName[pfmPlayerQuit->cbszCharacterName-1])
{
g_pLobbyApp->GetSite()->LogEvent(EVENTLOG_ERROR_TYPE, LE_CorruptPlayerQuitMsg,
cnxnFrom.GetName());
}
else
g_pLobbyApp->RemovePlayerFromMission(szCharacterName, pMission);
}
break;
case FM_S_PAUSE:
{
CASTPFM(pfmPause, S, PAUSE, pfm);
pServer->Pause(pfmPause->fPause);
g_pLobbyApp->BuildStaticCoreInfo();
break;
}
default:
ZError("unknown message\n");
}
return S_OK;
}
HRESULT LobbyServerSite::OnSysMessage(FedMessaging * pthis)
{
return S_OK;
}
void LobbyServerSite::OnMessageNAK(FedMessaging * pthis, DWORD dwTime, CFMRecipient * prcp)
{}
HRESULT LobbyServerSite::OnNewConnection(FedMessaging * pthis, CFMConnection & cnxn)
{
char szRemote[16];
pthis->GetIPAddress(cnxn, szRemote);
CFLServer * pServer = new CFLServer(&cnxn);
g_pLobbyApp->GetSite()->LogEvent(EVENTLOG_INFORMATION_TYPE, LE_ServerConnected, cnxn.GetName(), szRemote);
BEGIN_PFM_CREATE(*pthis, pfmToken, L, TOKEN)
FM_VAR_PARM(g_pLobbyApp->GetToken(), CB_ZTS)
END_PFM_CREATE
pthis->SendMessages(&cnxn, FM_GUARANTEED, FM_FLUSH);
return S_OK;
}
HRESULT LobbyServerSite::OnDestroyConnection(FedMessaging * pthis, CFMConnection & cnxn)
{
g_pLobbyApp->GetSite()->LogEvent(EVENTLOG_INFORMATION_TYPE, LE_ServerDisconnected, cnxn.GetName());
delete CFLServer::FromConnection(cnxn);
g_pLobbyApp->BuildStaticCoreInfo();
return S_OK;
}
HRESULT LobbyServerSite::OnSessionLost(FedMessaging * pthis)
{
g_pLobbyApp->GetSite()->LogEvent(EVENTLOG_ERROR_TYPE, LE_ServersSessionLost);
return S_OK;
}
int LobbyServerSite::OnMessageBox(FedMessaging * pthis, const char * strText, const char * strCaption, UINT nType)
{
debugf("LobbyServerSite::OnMessageBox: ");
return g_pLobbyApp->OnMessageBox(strText, strCaption, nType);
}
#ifndef NO_MSG_CRC
void LobbyServerSite::OnBadCRC(FedMessaging * pthis, CFMConnection & cnxn, BYTE * pMsg, DWORD cbMsg)
{
assert(0); }
#endif
CFLServer::CFLServer(CFMConnection * pcnxn) :
m_dwID(c_dwID),
m_pcnxn(pcnxn),
m_sPort(6703), m_cPlayers(0),
m_maxLoad(300), m_bHere(false),
m_fPaused(false),
m_cStaticCoreInfo(0), m_vStaticCoreInfo(NULL), m_dwStaticCoreMask(0), m_iMaxGames(20) {
assert(m_pcnxn);
m_pcnxn->SetPrivateData((DWORD) this); m_pCounters = g_pLobbyApp->AllocatePerServerCounters(pcnxn->GetName());
strcpy(m_szLocation,"unknown"); }
CFLServer::~CFLServer()
{
DeleteMission(c_AllMissions);
m_pcnxn->SetPrivateData(0); g_pLobbyApp->FreePerServerCounters(m_pCounters);
MissionList::Iterator iter(m_missions);
while (!iter.End())
{
delete iter.Value();
iter.Remove();
}
FreeStaticCoreInfo();
}
void CFLServer::DeleteMission(const CFLMission * pMission)
{
if (!pMission)
return;
if (c_AllMissions == pMission)
g_pLobbyApp->RemoveAllPlayersFromServer(this);
MissionList::Iterator iter(m_missions);
while (!iter.End())
{
if (c_AllMissions == pMission || iter.Value() == pMission)
{
if (c_AllMissions != pMission)
g_pLobbyApp->RemoveAllPlayersFromMission(iter.Value());
delete iter.Value();
iter.Remove();
}
else
iter.Next();
}
}
void CFLServer::Pause(bool fPause)
{
if (m_fPaused == fPause)
return;
m_fPaused = fPause;
MissionList::Iterator iter(m_missions);
if (m_fPaused) {
g_pLobbyApp->GetSite()->LogEvent(EVENTLOG_INFORMATION_TYPE, LE_ServerPause,
GetConnection()->GetName());
while (!iter.End())
{
BEGIN_PFM_CREATE(g_pLobbyApp->GetFMClients(), pfmMissionGone, LS, MISSION_GONE)
END_PFM_CREATE
pfmMissionGone->dwCookie = iter.Value()->GetCookie();
iter.Next();
}
g_pLobbyApp->GetFMClients().SendMessages(g_pLobbyApp->GetFMClients().Everyone(), FM_GUARANTEED, FM_FLUSH);
}
else {
g_pLobbyApp->GetSite()->LogEvent(EVENTLOG_INFORMATION_TYPE, LE_ServerContinue,
GetConnection()->GetName());
while (!iter.End())
{
FMD_LS_LOBBYMISSIONINFO * plmi = iter.Value()->GetMissionInfo();
if (plmi)
g_pLobbyApp->GetFMClients().QueueExistingMsg(plmi);
iter.Next();
}
g_pLobbyApp->GetFMClients().SendMessages(g_pLobbyApp->GetFMClients().Everyone(), FM_GUARANTEED, FM_FLUSH);
}
}