#include "pch.h"
#include <objbase.h>
#include <malloc.h>
//////////////////////////////////////////////////////////////////////////////
//
// Include the main function
//
//////////////////////////////////////////////////////////////////////////////
#include "main.h"
#include "regkey.h"
extern bool g_bEnableSound = true;
extern bool g_bCheckFiles;
extern bool g_fZoneAuth;
bool g_bSkipAutoUpdate = false;
bool g_bDownloadZoneMessage = true;
bool g_bDisableZoneClub = false;
bool g_bDisableNewCivs = true;
bool g_bQuickstart = false;
bool g_bReloaded = false;
int g_civStart = -1;
bool g_bDownloadNewConfig = true;
bool g_bAskForCDKey =
//#ifdef USEAUTH // We don't bother with CD keys anymore.
// true;
//#else
false;
//#endif
// wlp 2006 - added askforcallsign - don't ask if passed in on commandline
bool g_bAskForCallSign = true ; // wlp 2006
//////////////////////////////////////////////////////////////////////////////
//
// Trek Application Implementation
//
//////////////////////////////////////////////////////////////////////////////
#define GAME_REG_KEY "Software\\Microsoft\\Microsoft Games\\Allegiance\\1.0"
typedef DWORD (*EBUPROC) (LPCTSTR lpRegKeyLocation, LPCTSTR lpEULAFileName, LPCSTR lpWarrantyFileName, BOOL fCheckForFirstRun);
//
// EULA related files should be in the artwork folder so that they may be autoupdated
//
// yp your_persona march 25 2006 : Remove EULA.dll dependency patch
//
//HRESULT FirstRunEula(PathString strArtPath)
//{
// TCHAR szEULA[MAX_PATH];
// if (UTL::getFile("eula", ".rtf", szEULA, false, false) != S_OK)
// return false;
//
// // don't use += operator cause it's buggy with PathString
// strArtPath = strArtPath + "EBUEula.dll";
//
// HINSTANCE hMod = LoadLibrary(PCC(strArtPath));
// if (NULL == hMod) // can't attach to DLL
// {
// // this time, search path
// hMod = LoadLibrary("EBUEula.dll");
// if (NULL == hMod) // can't attach to DLL
// return E_FAIL;
// }
//
// EBUPROC pfnEBUEula = (EBUPROC) GetProcAddress(hMod, "EBUEula");
// if (NULL == pfnEBUEula) // can't find entry point
// {
// FreeLibrary(hMod);
// return E_FAIL;
// }
//
// /*
// TCHAR szWarranty[MAX_PATH];
// LoadString(GetModuleHandle(), STR_EULAFILENAME, szEULA, sizeof(szEULA));
// LoadString(GetModuleHandle(), STR_WARRANTYNAME, szWarranty, sizeof(szWarranty));
//
// //
// //This call enables both EULA and warranty accepting/viewing/printing. If your
// //game doesn't ship with a WARRANTY file, specifiy NULL instead of szWarranty…
// //The code below, for instance, works with both OEM and retail builds…
// //
// TCHAR *pszWarrantyParam = 0xFFFFFFFF != GetFileAttributes(szWarranty) ? szWarranty : NULL;
// */
// bool fAllowGameToRun = pfnEBUEula(GAME_REG_KEY, szEULA, NULL, TRUE) != 0;
//
// FreeLibrary(hMod);
//
// return (fAllowGameToRun ? S_OK : S_FALSE);
//}
//
// Check to make sure that they are running DX 7 Dsound or better
//
bool CheckDSoundVersion()
{
// Get version information from the application
HMODULE hmodDSound = GetModuleHandle("dsound");
if (NULL == hmodDSound) // why isn't the dll loaded???
return false;
char szDSoundPath[MAX_PATH];
GetModuleFileName(hmodDSound, szDSoundPath, sizeof(szDSoundPath));
DWORD dwTemp;
DWORD dwVerInfoSize = GetFileVersionInfoSize(szDSoundPath, &dwTemp);
if (0 == dwVerInfoSize)
return false;
void *pvVerInfo = _alloca(dwVerInfoSize);
GetFileVersionInfo(szDSoundPath, NULL, dwVerInfoSize, pvVerInfo);
VS_FIXEDFILEINFO *lpvsFixedFileInfo = NULL;
unsigned uTemp;
if (!VerQueryValue(pvVerInfo, "\\", (LPVOID*) &lpvsFixedFileInfo, &uTemp))
return false;
// check the version info
WORD ver1 = HIWORD(lpvsFixedFileInfo->dwFileVersionMS);
WORD ver2 = LOWORD(lpvsFixedFileInfo->dwFileVersionMS);
WORD ver3 = HIWORD(lpvsFixedFileInfo->dwFileVersionLS);
WORD ver4 = LOWORD(lpvsFixedFileInfo->dwFileVersionLS);
if (ver1 > 5) // assume all major new versions work
return true;
if (ver1 == 5) // NT -- WARNING -- if future versions of DX go outside 4.??? and spill into NT versions, we're in trouble
return ver2 > 0 || ver3 >= 2113; // ver3 == NT build #
else if (ver1 == 4) // Stand-alone DX runtimes
{
if (ver2 > 7) // new major dx versions (DX8+)
return true;
else if (ver2 == 7) // DX7
return ver3 > 0 || ver4 >= 700;
}
return false;
}
//
// Check to make sure that they are running DX 7 Dsound or better
//
bool CheckFreeMemory()
{
const int nAppSize = 40 * 1024 * 1024;
// first, try a non-invasive check to see if we would fit in the current
// swap file.
MEMORYSTATUS ms;
GlobalMemoryStatus(&ms);
if (ms.dwAvailVirtual == -1 || ms.dwAvailPhys == -1
|| ms.dwAvailVirtual + ms.dwAvailPhys >= nAppSize)
{
return true;
}
// if that fails, try allocating a big chunk of memory to try to force the
// swap file to grow.
void *pv = VirtualAlloc(NULL, nAppSize, MEM_COMMIT, PAGE_NOACCESS);
if (pv)
{
VirtualFree(pv, 0, MEM_RELEASE);
return true;
}
else
return false;
}
bool CheckForAllGuard()
{
// KGJV: allways bypass
return true;
// Bypass any other tests if -nod is specified on the command line
ZString strCmdLine(::GetCommandLine());
while (!strCmdLine.IsEmpty())
if (strCmdLine.GetToken() == "-nod")
return true;
// Load KERNEL32
HINSTANCE hinstKernel32 = ::GetModuleHandle("kernel32.dll");
assert(hinstKernel32);
// Get the address of IsDebuggerPresent, if available
typedef BOOL (WINAPI* PFNIsDebuggerPresent)(VOID);
PFNIsDebuggerPresent pfnIsDebuggerPresent = (PFNIsDebuggerPresent)
::GetProcAddress(hinstKernel32, "IsDebuggerPresent");
if (pfnIsDebuggerPresent)
{
// Indicate that we are being debugged, if we are
if ((*pfnIsDebuggerPresent)())
return true;
}
else
{
// Win95 doesn't support IsDebuggerPresent, so we must check some other ways
// Format an event name using the current process ID
char szEvent[24];
sprintf(szEvent, "MSRGuard_%08X", GetCurrentProcessId());
// Determine if the named event already exists
HANDLE hEvent = ::OpenEvent(EVENT_ALL_ACCESS, false, szEvent);
if (hEvent)
{
// Close the event handle and indicate that we are being debugged
::CloseHandle(hEvent);
return true;
}
}
// Get the command-line options (again)
strCmdLine = ::GetCommandLine();
strCmdLine.GetToken();
// Get the fully-qualified path to the current process
char szModulePath[_MAX_PATH];
GetModuleFileName(NULL, szModulePath, sizeof(szModulePath));
char szDrive[_MAX_DRIVE], szDir[_MAX_DIR];
_splitpath(szModulePath, szDrive, szDir, NULL, NULL);
_makepath(szModulePath, szDrive, szDir, NULL, NULL);
// Get the ArtPath, since that's where AllGuard.exe should be
HKEY hKey = NULL;
if (ERROR_SUCCESS != ::RegOpenKeyEx(HKEY_LOCAL_MACHINE, ALLEGIANCE_REGISTRY_KEY_ROOT, 0, KEY_READ, &hKey))
return true; // If it can't be read, just keep running
char szArtPath[_MAX_PATH];
DWORD cbArtPath = sizeof(szArtPath);
if (ERROR_SUCCESS != ::RegQueryValueEx(hKey, "ArtPath", NULL, NULL, (BYTE*)&szArtPath, &cbArtPath))
{
lstrcpy(szArtPath, szModulePath);
lstrcat(szArtPath, "artwork\\");
cbArtPath = lstrlen(szArtPath);
}
else if ('\\' != szArtPath[cbArtPath - 1])
{
lstrcat(szArtPath, "\\");
++cbArtPath;
}
::RegCloseKey(hKey);
// Append the AllGuard.exe filename and parameters
char szAllGuard[_MAX_PATH * 4];
sprintf(szAllGuard, "\"%sAllGuard.exe\" %s", szArtPath, (LPCSTR)strCmdLine);
// Create the AllGuard.exe process
STARTUPINFO si = {sizeof(si)};
PROCESS_INFORMATION pi;
if (!::CreateProcess(NULL, szAllGuard, NULL, NULL, false, 0, NULL, szModulePath, &si, &pi))
return true; // If it can't be created, just keep running
// Indicate false to exit this instance of the process
return false;
}
class TrekAppImpl : public EffectApp {
public:
TrekAppImpl()
{
AddRef();
}
HRESULT Initialize(const ZString& strCommandLine)
{
_controlfp(_PC_53, _MCW_PC);
//
// Make sure reloader finished correctly--this must be first before any other files are opened
//
//
{
// Make sure the current path is where Allegiance.exe is for the AutoUpdate:
// For Download -AND- for Reloader.exe -AND- Loading FileList which happens
// when client logs onto lobby
//
char path[MAX_PATH + 16];
::GetModuleFileName(NULL, path, MAX_PATH);
char* p = strrchr(path, '\\');
if (!p)
p = path;
else
p++;
*p = 0; // erase filename
::SetCurrentDirectory(path);
HKEY hKey;
DWORD dwType;
char szValue[MAX_PATH];
DWORD cbValue = MAX_PATH;
// NOTE: please keep reloader.cpp's GetArtPath() in sync with this!!!
if (ERROR_SUCCESS == ::RegOpenKeyEx(HKEY_LOCAL_MACHINE, ALLEGIANCE_REGISTRY_KEY_ROOT, 0, KEY_READ, &hKey))
{
// Get MoveInProgress from registry
if (ERROR_SUCCESS == ::RegQueryValueEx(hKey, "MoveInProgress", NULL, &dwType, (unsigned char*)&szValue, &cbValue) &&
*((DWORD*)szValue) == 1)
{
if (::MessageBox(NULL, "The AutoUpdate process failed to finish. Try again to finish? (YES is recommended)", "Error", MB_ICONERROR | MB_YESNO) == IDYES)
{
if (!LaunchReloaderAndExit(false))
{
::MessageBox(NULL, "Couldn't launch Reloader.exe", "Fatal Error", MB_ICONERROR);
::ExitProcess(0);
return S_FALSE;
}
}
else
{
::ExitProcess(0);
return S_FALSE;
}
}
::RegCloseKey(hKey);
}
}
//
// Check to see if we are being debugged
//
if (!CheckForAllGuard())
return S_FALSE;
//
// Check for sufficient free memory
//
if (!CheckFreeMemory())
{
if (MessageBox(NULL,
"You are low on free memory and/or hard drive space. "
"You may experience proplems running Allegiance. Run anyway?",
"Allegiance",
MB_ICONERROR | MB_YESNO
) != IDYES)
{
::ExitProcess(0);
return S_FALSE;
}
}
//
// Check the DSound version
//
if (!CheckDSoundVersion())
{
MessageBox(NULL,
"Allegiance requires DirectX 7 or higher, which was not detected. "
"Please re-run setup and choose to install DirectX 7.",
"Allegiance",
MB_ICONERROR | MB_OK
);
return E_FAIL;
}
HRESULT hr = CoInitialize(NULL);
if (FAILED(hr))
return hr;
// Fix success HRESULT
hr = S_OK;
EffectApp::Initialize(strCommandLine);
//
// get the artpath
//
PathString pathStr; // = ZString::GetProfileString("Federation", "ArtPath");
HKEY hKey;
DWORD dwType;
char szValue[MAX_PATH];
DWORD dwValue;
DWORD cbValue = MAX_PATH;
// NOTE: please keep reloader.cpp's GetArtPath() in sync with this!!!
if (ERROR_SUCCESS == ::RegOpenKeyEx(HKEY_LOCAL_MACHINE, ALLEGIANCE_REGISTRY_KEY_ROOT, 0, KEY_READ, &hKey))
{
// Get the art path from the registry
if (ERROR_SUCCESS != ::RegQueryValueEx(hKey, "ArtPath", NULL, &dwType, (unsigned char*)&szValue, &cbValue))
{
// Set ArtPath to be relative to the application path
GetModuleFileNameA(NULL, szValue, MAX_PATH);
char* p = strrchr(szValue, '\\');
if (!p)
p = szValue;
else
p++;
strcpy(p, "artwork");
//Create a subdirectory for the artwork (nothing will happen if it already there)
CreateDirectoryA(szValue, NULL);
}
pathStr = szValue;
cbValue = MAX_PATH; // reset this
// Start the frame rate data log, if necessary
if (ERROR_SUCCESS == ::RegQueryValueEx(hKey, "LogFrameData", NULL, &dwType, (unsigned char*)&dwValue, &cbValue))
{
cbValue = MAX_PATH;
if (dwValue==1)
{
if (ERROR_SUCCESS == ::RegQueryValueEx(hKey, "LogFrameDataPath", NULL, &dwType, (unsigned char*)&szValue, &cbValue))
{
if (strlen(szValue)>0)
{
ZString strFile = szValue;
g_pzfFrameDump = new ZWriteFile(strFile);
// check for a valid file handle
if (g_pzfFrameDump->IsValid())
{
// dump out the header row of data
g_pzfFrameDump->Write(
"Mspf,"
"Fps,"
"Warps,"
"Ships,"
"Projectiles,"
"Asteroids,"
"Stations,"
"Treasures,"
"Missiles,"
"SectorWarps,"
"SectorShips,"
"SectorProjectiles,"
"SectorAsteroids,"
"SectorStations,"
"SectorTreasures,"
"SectorMissiles,"
"Triangles,"
"DrawStringCalls,"
"Chars"
"\n"
);
}
else
{
// pop up error message box
MessageBox(NULL, "Framerate log file location is invalid.\n"
"Use CliConfig to set the framerate log file location to "
"a valid location.",
"Framerate Logging Error", MB_ICONEXCLAMATION | MB_OK);
}
}
}
}
}
::RegCloseKey(hKey);
}
if (pathStr.IsEmpty()) {
// marksn: to make everyone consistent, this should go back to getmodulefilename path
// like for convex hull and sounds
// pathStr = PathString::GetCurrentDirectory() + "artwork";
char logFileName[MAX_PATH + 16];
GetModuleFileName(NULL, logFileName, MAX_PATH);
char* p = strrchr(logFileName, '\\');
if (!p)
p = logFileName;
else
p++;
strcpy(p, "artwork");
pathStr = logFileName;
}
GetModeler()->SetArtPath(pathStr);
UTL::SetArtPath(pathStr);
// yp your_persona march 25 2006 : Remove EULA.dll dependency patch
//
/*{
HRESULT hr = FirstRunEula(pathStr);
if (hr == E_FAIL)
{
::MessageBox(NULL, "Error while trying to load ebueula.dll. Please reboot and retry. If it still fails, reinstall Allegiance", "Initialization Error", MB_OK);
return S_FALSE;
}
else
if (hr == S_FALSE)
{
::MessageBox(NULL, "You must accept the End User License Agreement before playing the Allegiance", "Allegiance", MB_OK);
return S_FALSE;
}
else
{
assert(hr == S_OK);
}
}*/
//
// load the fonts
//
TrekResources::Initialize(GetModeler());
//
// Initialize the runtime
//
srand((unsigned)timeGetTime());
//
// Parse the command line
//
bool bLogonDialog = true;
bool bStartOffline = false;
bool bStartTraining = false;
bool bMovies = true;
bool bSingleInstance = true;
bool bSoftware = false;
bool bHardware = false;
bool bPrimary = false;
bool bSecondary = false;
ZString strMap;
PCC pcc = strCommandLine;
CommandLineToken token(pcc, strCommandLine.GetLength());
while (token.MoreTokens()) {
ZString str;
if (token.IsMinus(str))
{
if (str == "training") {
bStartTraining = true;
bLogonDialog = false;
bMovies = false;
} else if (str == "software") {
bSoftware = true;
} else if (str == "hardware") {
bHardware = true;
} else if (str == "primary") {
bPrimary = true;
} else if (str == "secondary") {
bSecondary = true;
} else if (str == "nooutput") {
g_bOutput = false;
} else if (str == "quickstart") {
g_bQuickstart = true;
float civStart;
if (token.IsNumber(civStart))
g_civStart = (int)civStart;
} else if (str == "nocfgdl") {
g_bDownloadNewConfig = false;
} else if (str == "checkfiles") {
g_bCheckFiles = true;
} else if (str == "noautoupdate") {
g_bSkipAutoUpdate = true;
} else if (str == "nosound") {
g_bEnableSound = false;
} else if (str == "nomessage") {
g_bDownloadZoneMessage = false;
} else if (str == "nomovies") {
bMovies = false;
} else if (str == "zone") {
g_bDisableZoneClub = false;
} else if (str == "newcivs") {
g_bDisableNewCivs = false;
} else if (str == "map") {
if (token.IsString(strMap))
{
bStartOffline = true;
bLogonDialog = false;
}
} else if(str == "reloaded") {
//
// reloaded after an auto-update
//
//g_bReloaded = true;
// TODO: make two types of reloaded: one for internet, one for zone
// that way we know how to log on. Right now there it just relogs on
// using internet connect
} else if (str == "multi") {
bSingleInstance = false;
} else if (str == "noauth") {
g_fZoneAuth = false;
} else if (str == "cdkey") {
g_bAskForCDKey = true;
// wlp 2006 - added debug option to turn on debug output
} else if (str == "debug") {
g_outputdebugstring = true; //wlp allow debug outputs
} else if (str.Left(10) == "authtoken=") { // wlp - 2006, added new ASGS tickettoken
trekClient.SetCDKey(str.RightOf(10)) ; // Use CdKey for ASGS storage
} else if (str.Left(9) == "callsign=") { // wlp - 2006, added new ASGS token
trekClient.SaveCharacterName(str.RightOf(9)) ; // Use CdKey for ASGS callsign storage
g_bAskForCallSign = false ; // wlp callsign was entered on commandline
}
}
else // wlp 2006 - adapted this string featture to add ASGS Ticket to cdKey field
if (token.IsString(str)){} ;
}
//
// Check for other running copies of the app
//
if (bSingleInstance)
{
HWND hOldInstance = FindWindow(TrekWindow::GetTopLevelWindowClassname(),
TrekWindow::GetWindowTitle());
// if we found another copy of the app
if (hOldInstance)
{
// find out if it has any popups
HWND hPopup = GetLastActivePopup(hOldInstance);
// Bring the main window to the top.
if (SetForegroundWindow(hOldInstance))
{
// If the old instance was minimized, restore it.
if (IsIconic(hOldInstance))
{
ShowWindow(hOldInstance, SW_RESTORE);
}
// If the old instance had a pop-up, bring that to the foreground
if (hPopup != hOldInstance)
{
SetForegroundWindow(hPopup);
}
}
return S_FALSE;
}
}
//
// Create the window
//
TRef<TrekWindow> pwindow =
TrekWindow::Create(
this,
strCommandLine,
bMovies,
bSoftware,
bHardware,
bPrimary,
bSecondary
);
if (!pwindow->IsValid()) {
return E_FAIL;
}
//
// Handling command line options
//
if (bStartTraining)
GetWindow ()->screen (ScreenIDTrainScreen);
return hr;
}
void Terminate()
{
EffectApp::Terminate();
CoUninitialize();
}
} g_trekImpl;