#include "pch.h"
#include <zreg.h>
bool g_fZoneAuth =
#ifdef USEAUTH
true;
#else
false;
#endif
extern bool g_bDownloadZoneMessage;
extern bool g_bDownloadNewConfig;
extern bool g_bDisableZoneClub;
extern bool g_bSkipAutoUpdate;
const char * szValidCfg = "THIS IS A VALID CONFIG FILE";
const char * szValidMotd = "THIS IS A VALID MESSAGE OF THE DAY FILE";
class ZoneClubScreen :
public Screen,
public LogonSite,
public TrekClientEventSink,
public IIntegerEventSink,
public IAutoUpdateSink,
public EventTargetContainer<ZoneClubScreen>
{
private:
TRef<Modeler> m_pmodeler;
TRef<Pane> m_ppane;
TRef<ButtonPane> m_pbuttonGames;
TRef<ButtonPane> m_pbuttonGamesBig;
TRef<ButtonPane> m_pbuttonZoneEvents;
TRef<ButtonPane> m_pbuttonSquads;
TRef<ButtonPane> m_pbuttonMainMenu;
TRef<ButtonPane> m_pbuttonPlayerProfile;
TRef<ButtonPane> m_pbuttonLeaderboard;
TRef<ButtonPane> m_pbuttonWeb;
TRef<MDLFileImage> m_pMDLFileImage;
char m_szName[c_cbPassportName];
char m_szPW[c_cbName];
char m_szPWOrig[c_cbName];
char m_szConfig[MAX_PATH];
BOOL m_fRememberPW;
bool m_bErrorOccured;
bool m_bMessageStage; bool m_bTriedCurrentLogin;
IHTTPSession * m_pSession;
bool m_bConnectLobby; TRef<IMessageBox> m_pmsgBox;
ScreenID m_screenPostConnect;
static bool s_bWasAuthenticated;
public:
ZoneClubScreen(Modeler* pmodeler, Number* ptime) :
m_pSession(NULL),
m_bErrorOccured(false),
m_bMessageStage(false),
m_pmsgBox(NULL),
m_pmodeler(pmodeler),
m_bTriedCurrentLogin(false)
{
TRef<INameSpace> pnsZoneClubData = GetModeler()->CreateNameSpace("zoneclubdata");
pnsZoneClubData->AddMember("timeStart", ptime->MakeConstant());
TRef<INameSpace> pns = pmodeler->GetNameSpace(
trekClient.GetIsZoneClub() ? "zoneclubscreen" : "zonepublicscreen");
CastTo(m_ppane, pns->FindMember("screen"));
CastTo(m_pMDLFileImage, (Value*)pns->FindMember("messageImage"));
CastTo(m_pbuttonGames, pns->FindMember("gamesButtonPane"));
CastTo(m_pbuttonGamesBig, pns->FindMember("gamesBigButtonPane"));
CastTo(m_pbuttonZoneEvents, pns->FindMember("zoneEventsButtonPane"));
CastTo(m_pbuttonSquads, pns->FindMember("squadsButtonPane"));
CastTo(m_pbuttonMainMenu, pns->FindMember("mainmenuButtonPane"));
CastTo(m_pbuttonPlayerProfile, pns->FindMember("playerProfileButtonPane"));
CastTo(m_pbuttonLeaderboard, pns->FindMember("leaderboardButtonPane"));
CastTo(m_pbuttonWeb, pns->FindMember("webButtonPane"));
AddEventTarget(&ZoneClubScreen::OnButtonGames, m_pbuttonGames->GetEventSource());
AddEventTarget(&ZoneClubScreen::OnButtonGames, m_pbuttonGamesBig->GetEventSource());
AddEventTarget(&ZoneClubScreen::OnButtonMainMenu, m_pbuttonMainMenu->GetEventSource());
if (trekClient.GetIsZoneClub())
{
AddEventTarget(&ZoneClubScreen::OnButtonZoneEvents, m_pbuttonZoneEvents->GetEventSource());
AddEventTarget(&ZoneClubScreen::OnButtonSquads, m_pbuttonSquads->GetEventSource());
AddEventTarget(&ZoneClubScreen::OnButtonPlayerProfile, m_pbuttonPlayerProfile->GetEventSource());
AddEventTarget(&ZoneClubScreen::OnButtonZoneWeb, m_pbuttonWeb->GetEventSource());
AddEventTarget(&ZoneClubScreen::OnButtonLeaderBoard, m_pbuttonLeaderboard->GetEventSource());
}
m_pbuttonMainMenu->SetEnabled(false); m_pbuttonGames->SetEnabled(false);
m_pbuttonGamesBig->SetEnabled(false);
if (trekClient.GetIsZoneClub())
{
m_pbuttonSquads->SetEnabled(false);
m_pbuttonZoneEvents->SetEnabled(false);
m_pbuttonPlayerProfile->SetEnabled(false);
m_pbuttonLeaderboard->SetEnabled(false);
}
pmodeler->UnloadNameSpace(pns);
BeginConfigDownload();
if (g_bQuickstart)
AddEventTarget(&ZoneClubScreen::OnButtonGames, GetWindow(), 0.01f);
trekClient.FlushSessionLostMessage();
}
~ZoneClubScreen()
{
if (m_pSession)
{
delete m_pSession;
m_pSession = NULL;
}
}
void ConnectToZone(bool bConnectLobby, ScreenID screenid)
{
ZString strPrompt;
#ifdef USEAUTH
if (trekClient.GetCfgInfo().bUsePassport)
strPrompt = "Sign in to Microsoft Passport";
else
strPrompt = "Sign in to the Microsoft Gaming Zone";
#else
strPrompt = "Enter a call sign (player name) to use for this game.";
#endif
ConnectToZone(bConnectLobby, screenid, strPrompt);
}
void ConnectToZone(bool bConnectLobby, ScreenID screenid, const ZString& strPrompt)
{
if (bConnectLobby)
{
if (trekClient.GetIsZoneClub())
{
if (trekClient.GetCfgInfo().strClubLobby.IsEmpty())
{
TRef<IMessageBox> pmsgBox = CreateMessageBox(
"The Allegiance Zone lobby is not available at the moment. "
+ ZString(trekClient.GetCfgInfo().strPublicLobby.IsEmpty()
? "Please try again later."
: "Please try the free lobby instead.")
);
GetWindow()->GetPopupContainer()->OpenPopup(pmsgBox, false);
return;
}
}
else
{
if (trekClient.GetCfgInfo().strPublicLobby.IsEmpty())
{
TRef<IMessageBox> pmsgBox = CreateMessageBox(
"The free lobby is not available at the moment. "
+ ZString(trekClient.GetCfgInfo().strClubLobby.IsEmpty()
? "Please try again later."
: "Please try the Allegiance Zone instead.")
);
GetWindow()->GetPopupContainer()->OpenPopup(pmsgBox, false);
return;
}
}
}
else
{
if (trekClient.GetCfgInfo().strClub.IsEmpty())
{
TRef<IMessageBox> pmsgBox = CreateMessageBox(
"The Club server is not available at the moment. "
"Please try again later."
);
GetWindow()->GetPopupContainer()->OpenPopup(pmsgBox, false);
return;
}
}
m_bConnectLobby = bConnectLobby;
m_screenPostConnect = screenid;
assert (!trekClient.LoggedOn() && !trekClient.m_fm.IsConnected());
HRESULT hr = E_FAIL;
#ifdef USEAUTH
TRef<IZoneAuthClient> pzac;
if (g_fZoneAuth)
{
pzac = trekClient.GetZoneAuthClient();
if (!pzac)
pzac = trekClient.CreateZoneAuthClient();
if (trekClient.GetCfgInfo().bUsePassport
&& !pzac->HasInterface(trekClient.GetCfgInfo().guidZoneAuth))
{
GetWindow()->ShowWebPage(trekClient.GetCfgInfo().strPassportUpdateURL);
GetWindow()->PostMessage(WM_CLOSE);
return;
}
if (s_bWasAuthenticated)
{
hr = S_OK;
}
else
{
pzac->SetAuthServer(trekClient.GetCfgInfo().strZAuth);
if (!m_bTriedCurrentLogin)
hr = pzac->IsAuthenticated(5000);
}
}
if (SUCCEEDED(hr)) {
BaseClient::ConnectInfo ci;
DWORD cbZoneTicket;
DWORD cbName = sizeof(ci.szName);
ZSucceeded(pzac->GetTicket(&ci.pZoneTicket, &cbZoneTicket, ci.szName, &cbName));
assert(cbName <= sizeof(ci.szName));
ci.cbZoneTicket = cbZoneTicket;
if(m_bConnectLobby)
trekClient.ConnectToLobby(&ci);
else
trekClient.ConnectToClub(&ci);
m_bTriedCurrentLogin = true;
}
else
#endif
{
m_szName[0] = '\0';
m_szPWOrig[0] = '\0';
#ifdef USEAUTH
if (g_fZoneAuth)
pzac->GetDefaultLogonInfo(m_szName, m_szPWOrig, &m_fRememberPW);
#else
lstrcpy(m_szName, trekClient.GetSavedCharacterName());
#endif
if (!g_bAskForCallSign)
{
this->OnLogon(trekClient.GetSavedCharacterName(), "", false);
} else
{
TRef<IPopup> plogonPopup = CreateLogonPopup(m_pmodeler, this,
(trekClient.GetIsZoneClub() ?
LogonAllegianceZone :
#ifdef USEAUTH
LogonFreeZone
#else
LogonLAN
#endif
), strPrompt, m_szName, m_szPWOrig, m_fRememberPW);
Point point(c_PopupX, c_PopupY);
Rect rect(point, point);
GetWindow()->GetPopupContainer()->OpenPopup(plogonPopup, rect, false);
} }
}
bool OnButtonMainMenu()
{
GetWindow()->screen(ScreenIDIntroScreen);
return true;
}
bool OnButtonSquads()
{
if (trekClient.LoggedOnToClub())
{
GetWindow()->screen(ScreenIDSquadsScreen);
}
else
{
ConnectToZone(false, ScreenIDSquadsScreen);
}
return true;
}
bool OnButtonGames()
{
ConnectToZone(true, ScreenIDGameScreen);
return true;
}
bool OnButtonZoneEvents()
{
GetWindow()->screen(ScreenIDZoneEvents);
return true;
}
bool OnButtonPlayerProfile()
{
#ifdef NO_CLUB_SERVER_CONNECTION
GetWindow()->screen(ScreenIDCharInfo);
#else
if (trekClient.LoggedOnToClub())
{
GetWindow()->screen(ScreenIDCharInfo);
}
else
{
ConnectToZone(false, ScreenIDCharInfo);
}
#endif
return true;
}
bool OnButtonZoneWeb()
{
GetWindow()->ShowWebPage();
return true;
}
bool OnButtonLeaderBoard()
{
if (trekClient.LoggedOnToClub())
{
GetWindow()->screen(ScreenIDLeaderBoard);
}
else
{
ConnectToZone(false, ScreenIDLeaderBoard);
}
return true;
}
void BeginConfigDownload()
{
if (!g_bDownloadNewConfig)
{
debugf("Skipping download of config file due to command-line switch.\n");
OnConfigDownloadDone(true, false);
return;
}
lstrcpy(m_szConfig, "http://Allegiance.zone.com/Allegiance.cfg");
HKEY hKey;
if (ERROR_SUCCESS == ::RegOpenKeyEx(HKEY_LOCAL_MACHINE, ALLEGIANCE_REGISTRY_KEY_ROOT, 0, KEY_READ, &hKey))
{
DWORD cbValue = MAX_PATH;
char szConfig[MAX_PATH];
szConfig[0] = '\0';
::RegQueryValueEx(hKey, "CfgFile", NULL, NULL, (LPBYTE)&szConfig, &cbValue);
if (lstrlen(szConfig) > 0)
lstrcpy(m_szConfig, szConfig);
}
if (ZString(m_szConfig).Find("http://") == -1)
{
debugf("Using local config file due to registry setting for ConfigFile because \"http://\" was missing from it. %s\n", m_szConfig);
if (!IsFileValid(m_szConfig))
{
#ifndef DEBUG m_pmsgBox = CreateMessageBox("Warning, Local CFG missing validation string");
GetWindow()->GetPopupContainer()->OpenPopup(m_pmsgBox, false);
#endif
}
OnConfigDownloadDone(false, false);
return;
}
if (m_pSession)
return;
debugf("Beginning Config Download: %s.\n", m_szConfig);
m_pSession = CreateHTTPSession(this);
const char * szFileList[] = { m_szConfig, "temp.cfg", NULL };
m_pSession->InitiateDownload(szFileList, "."); return;
}
void BeginMessageOfDayDownload()
{
if (!g_bDownloadZoneMessage)
{
debugf("Skipping download of Message Of the Day due to command-line switch.\n");
OnMessageOfDayDone(false);
return;
}
PCC szMessageOfTheDayFileName = trekClient.GetIsZoneClub()
? "clubmessageoftheday.mdl" : "publicmessageoftheday.mdl";
PathString path(trekClient.GetArtPath());
path = path + szMessageOfTheDayFileName;
int crc = FileCRC(PCC(path), NULL);
if (crc != 0 && crc == (trekClient.GetIsZoneClub()
? trekClient.GetCfgInfo().crcClubMessageFile
: trekClient.GetCfgInfo().crcPublicMessageFile))
{
debugf("Existing messageoftheday file has the correct CRC, skipping download.\n");
OnMessageOfDayDone(true);
return;
}
else
{
debugf("Existing messageoftheday file has the wrong CRC (%X).\n", crc);
}
if (m_pSession)
return;
PCC szMessageOfTheDayURL = trekClient.GetIsZoneClub()
? PCC(trekClient.GetCfgInfo().strClubMessageURL)
: PCC(trekClient.GetCfgInfo().strPublicMessageURL);
debugf("Beginning messageoftheday download: %s.\n", szMessageOfTheDayURL);
m_pSession = CreateHTTPSession(this);
const char * szFileList[3] = { szMessageOfTheDayURL, szMessageOfTheDayFileName, NULL };
m_pSession->InitiateDownload(szFileList, trekClient.GetArtPath());
return;
}
void OnError(char * szErrorMessage) {
debugf("Error while downloading file.\n");
debugf("%s\n", szErrorMessage);
m_bErrorOccured = true;
}
bool IsFileValid(char * szFileName)
{
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;
if (m_bMessageStage)
{
if (strstr(pData, szValidMotd) == NULL)
{
debugf("File %s is not a valid messageoftheday file.\n", szFileName);
#ifdef DEBUG
m_pmsgBox = CreateMessageBox("Warning, downloaded Motd file missing validation string");
GetWindow()->GetPopupContainer()->OpenPopup(m_pmsgBox, false);
#endif
delete[] pData;
return false;
}
}
else
{
if (strstr(pData, szValidCfg) == NULL)
{
debugf("File %s is not a valid config file.\n", szFileName);
#ifdef DEBUG
m_pmsgBox = CreateMessageBox("Warning, CFG file missing validation string");
GetWindow()->GetPopupContainer()->OpenPopup(m_pmsgBox, false);
#endif
delete[] pData;
return false;
}
}
delete[] pData;
}
else
{
debugf("File %s error while trying to load downloaded config file.\n", szFileName);
return false;
}
return true;
}
bool OnFileCompleted(char * szFileName)
{
debugf("Downloaded file: %s\n", szFileName);
char szPath[MAX_PATH+20];
strcpy(szPath, m_pSession->GetDownloadPath());
strcat(szPath, szFileName);
if (!IsFileValid(szPath))
{
m_bErrorOccured = true;
debugf("Aborting either cfg or motd because file is invalid.");
m_pmsgBox = CreateMessageBox("Unable to connect to Zone. Please try again later.");
GetWindow()->GetPopupContainer()->OpenPopup(m_pmsgBox, false);
}
return true; }
void OnFrame()
{
if (m_pSession)
{
if(m_bErrorOccured || !m_pSession->ContinueDownload())
{
if (m_bMessageStage)
OnMessageOfDayDone(!m_bErrorOccured);
else
OnConfigDownloadDone(true, !m_bErrorOccured);
}
}
}
void OnConfigDownloadDone(bool bUseEXEFolder, bool bDownloadSuccesful)
{
m_bMessageStage = true;
if (m_pSession)
{
delete m_pSession;
m_pSession = NULL;
}
if (bUseEXEFolder)
{
PathString pathEXE(PathString::GetCurrentDirectory());
PathString pathConfig(pathEXE + PathString(PathString(m_szConfig).GetFilename()));
if (bDownloadSuccesful)
{
PathString pathTemp(pathEXE + "temp.cfg");
trekClient.GetCfgInfo().Load(PCC(pathTemp));
debugf("Loaded downloaded config file: %s\n", PCC(pathTemp));
debugf("Renaming %s to %s\n", PCC(pathTemp), PCC(pathConfig));
DeleteFile(PCC(pathConfig));
MoveFile(PCC(pathTemp), PCC(pathConfig));
trekClient.GetCfgInfo().SetCfgFile(pathConfig);
}
else
{
debugf("Error detected, loading existing config file: %s\n", PCC(pathConfig));
trekClient.GetCfgInfo().Load(PCC(pathConfig));
}
}
else
{
debugf("Using local config file %s\n", m_szConfig);
trekClient.GetCfgInfo().Load(m_szConfig);
}
if (!m_bErrorOccured)
{
if(!g_bSkipAutoUpdate)
{
if (trekClient.GetCfgInfo().crcFileList != 0 &&
trekClient.GetCfgInfo().nFilelistSize != 0 &&
trekClient.GetCfgInfo().strFilelistSite != "" &&
trekClient.GetCfgInfo().strFilelistDirectory != "")
{
bool bForceFileCheck = trekClient.ShouldCheckFiles();
if (bForceFileCheck || trekClient.GetCfgInfo().crcFileList != FileCRC("Filelist.txt", NULL))
{
if (trekClient.m_pAutoDownload == NULL)
trekClient.m_pAutoDownload = CreateAutoDownload();
IAutoUpdateSink * pAutoUpdateSink = trekClient.OnBeginAutoUpdate(this, false);
assert(pAutoUpdateSink);
trekClient.m_pAutoDownload->SetFTPSite(PCC(trekClient.GetCfgInfo().strFilelistSite),
PCC(trekClient.GetCfgInfo().strFilelistDirectory),
"blah", "blah"); trekClient.m_pAutoDownload->SetOfficialFileListAttributes(trekClient.GetCfgInfo().crcFileList,
trekClient.GetCfgInfo().nFilelistSize);
trekClient.m_pAutoDownload->SetArtPath(trekClient.GetArtPath());
trekClient.m_pAutoDownload->BeginUpdate(pAutoUpdateSink, bForceFileCheck, false);
}
else
{
OnAutoUpdateSystemTermination(false, false);
}
}
else
{
debugf("Your cfg file is missing one or more of the following:\nFilelistCRC, FilelistSize, FilelistSite, FilelistDirectory\nSkipping AutoUpdate.\n");
OnAutoUpdateSystemTermination(false, false);
}
}
else
{
OnAutoUpdateSystemTermination(false, false);
}
BeginMessageOfDayDownload();
}
else
m_pbuttonMainMenu->SetEnabled(true); }
void OnMessageOfDayDone(bool bSuccessful)
{
if (m_pSession)
{
delete m_pSession;
m_pSession = NULL;
}
m_pbuttonMainMenu->SetEnabled(true); if (bSuccessful)
{
debugf("Loading messageoftheday file.\n");
m_pMDLFileImage->Load(trekClient.GetIsZoneClub()
? "clubmessageoftheday" : "publicmessageoftheday");
}
else
{
debugf("Errors detected while downloading message of the day. Skipping load.\n");
}
}
virtual void OnAutoUpdateSystemTermination(bool bErrorOccurred, bool bRestarting)
{
m_pbuttonMainMenu->SetEnabled(true); if (!bErrorOccurred && !bRestarting)
{
m_pbuttonGames->SetEnabled(true);
m_pbuttonGamesBig->SetEnabled(true);
if (trekClient.GetIsZoneClub())
{
m_pbuttonPlayerProfile->SetEnabled(true);
m_pbuttonLeaderboard->SetEnabled(true);
m_pbuttonSquads->SetEnabled(!g_bDisableZoneClub);
m_pbuttonZoneEvents->SetEnabled(!trekClient.GetCfgInfo().strZoneEventsURL.IsEmpty());
}
}
}
bool OnEvent(IIntegerEventSource* pevent, int value)
{
assert(m_pmsgBox);
GetWindow()->GetPopupContainer()->ClosePopup(m_pmsgBox);
GetWindow()->RestoreCursor();
return false;
}
void OnLogon(const ZString& strName, const ZString& strPassword, BOOL fRememberPW)
{
lstrcpy(m_szName, strName);
lstrcpy(m_szPW, strPassword);
m_fRememberPW = fRememberPW;
GetWindow()->SetWaitCursor();
TRef<IMessageBox> pmsgBox = CreateMessageBox("Connecting...", NULL, false);
Point point(c_PopupX, c_PopupY);
Rect rect(point, point);
GetWindow()->GetPopupContainer()->OpenPopup(pmsgBox, rect, false);
AddEventTarget(&ZoneClubScreen::OnUsernameAndPassword, GetWindow(), 0.1f);
}
bool OnUsernameAndPassword()
{
HRESULT hr = E_FAIL;
#ifdef USEAUTH
TRef<IZoneAuthClient> pzac;
if (g_fZoneAuth)
{
pzac = trekClient.GetZoneAuthClient();
hr = pzac->Authenticate(m_szName, m_szPW,
!!lstrcmp(m_szPW, m_szPWOrig), m_fRememberPW, 5000);
}
if (g_fZoneAuth && FAILED(hr))
{
bool bRetry;
ZString strReason;
if (ZT_E_AUTH_DENIED == hr)
{
if (trekClient.GetCfgInfo().bUsePassport)
strReason = "Either the username or the password you supplied was incorrect. Be sure to sign in with your Microsoft Passport name (not your Zone ID).";
else
strReason = "Either the username or the password you supplied was incorrect. Please try again.";
bRetry = true;
}
else
{
strReason = "Unable to contact the authentication server. Please check your network connection.";
bRetry = false;
}
GetWindow()->GetPopupContainer()->ClosePopup(m_pmsgBox);
GetWindow()->RestoreCursor();
if (m_bConnectLobby)
OnLogonLobbyFailed(bRetry, strReason);
else
OnLogonClubFailed(bRetry, strReason);
}
else
#endif
{
s_bWasAuthenticated = true;
BaseClient::ConnectInfo ci;
DWORD cbZoneTicket = 0;
ci.pZoneTicket = NULL;
DWORD cbName = sizeof(ci.szName);
#ifdef USEAUTH
if (g_fZoneAuth)
{
ZSucceeded(pzac->GetTicket(&ci.pZoneTicket, &cbZoneTicket, ci.szName, &cbName));
assert(cbName <= sizeof(ci.szName));
ci.cbZoneTicket = cbZoneTicket;
}
else
#endif
lstrcpy(ci.szName, m_szName);
ZeroMemory(&ci.ftLastArtUpdate, sizeof(ci.ftLastArtUpdate));
if (m_bConnectLobby)
trekClient.ConnectToLobby(&ci);
else
trekClient.ConnectToClub(&ci);
}
return false;
}
void OnAbort()
{
}
void OnLogonLobby()
{
GetWindow()->screen(m_screenPostConnect);
}
void OnLogonLobbyFailed(bool bRetry, const char* szReason)
{
if (bRetry)
{
s_bWasAuthenticated = false;
ConnectToZone(true, m_screenPostConnect, szReason);
}
else
{
TRef<IMessageBox> pmsgBox = CreateMessageBox(szReason);
GetWindow()->GetPopupContainer()->OpenPopup(pmsgBox, false);
}
}
void OnLogonClub()
{
GetWindow()->screen(m_screenPostConnect);
}
void OnLogonClubFailed(bool bRetry, const char* szReason)
{
if (bRetry)
{
s_bWasAuthenticated = false;
ConnectToZone(false, m_screenPostConnect, szReason);
}
else
{
TRef<IMessageBox> pmsgBox = CreateMessageBox(szReason);
GetWindow()->GetPopupContainer()->OpenPopup(pmsgBox, false);
}
}
Pane* GetPane()
{
return m_ppane;
}
};
bool ZoneClubScreen::s_bWasAuthenticated = false;
TRef<Screen> CreateZoneClubScreen(Modeler* pmodeler, Number * ptime)
{
return new ZoneClubScreen(pmodeler, ptime);
}