285 lines
8.1 KiB
C++
285 lines
8.1 KiB
C++
//
|
|
// Copyright 2020 Electronic Arts Inc.
|
|
//
|
|
// TiberianDawn.DLL and RedAlert.dll and corresponding source code is free
|
|
// software: you can redistribute it and/or modify it under the terms of
|
|
// the GNU General Public License as published by the Free Software Foundation,
|
|
// either version 3 of the License, or (at your option) any later version.
|
|
|
|
// TiberianDawn.DLL and RedAlert.dll and corresponding source code is distributed
|
|
// in the hope that it will be useful, but with permitted additional restrictions
|
|
// under Section 7 of the GPL. See the GNU General Public License in LICENSE.TXT
|
|
// distributed with this program. You should have received a copy of the
|
|
// GNU General Public License along with permitted additional restrictions
|
|
// with this program. If not, see https://github.com/electronicarts/CnC_Remastered_Collection
|
|
|
|
#ifdef WOLAPI_INTEGRATION
|
|
|
|
// Wol_Main.cpp - Bottom level wolapi-stuff function.
|
|
// ajw 07/16/98
|
|
|
|
#include "function.h"
|
|
#include "WolapiOb.h"
|
|
#include "wol_gsup.h"
|
|
#include "WolStrng.h"
|
|
|
|
int WOL_Login_Dialog( WolapiObject* pWolapi );
|
|
int WOL_Chat_Dialog( WolapiObject* pWolapi );
|
|
const char* Game_Registry_Key();
|
|
|
|
bool ReregisterWolapiDLL();
|
|
void HandleDLLFail();
|
|
|
|
WolapiObject* pWolapi = NULL;
|
|
|
|
#include "WolDebug.h"
|
|
|
|
//***********************************************************************************************
|
|
// The first time through, pWolapi is NULL thus wolapi gets set up. WOL_Login_Dialog presents the user
|
|
// with the login dialog and attempts to log us on to the server. If the user continues on all the
|
|
// way to a game start, we will drop out of here with pWolapi still pointing to a valid WolapiObject,
|
|
// and with pWolapi's iLobbyReturnAfterGame set to the number of the lobby to return to automatically
|
|
// after the game ends.
|
|
// Init() automatically brings us here if pWolapi is non-null.
|
|
//***********************************************************************************************
|
|
int WOL_Main()
|
|
{
|
|
// Return values:
|
|
// 0 = cancel
|
|
// 1 = start game
|
|
// -1 = patch downloaded, shut down app
|
|
int iReturn = 0;
|
|
|
|
if( pWolapi )
|
|
{
|
|
// We have returned from a game started through ww online.
|
|
|
|
// Start theme up again.
|
|
Theme.Play_Song( THEME_INTRO );
|
|
|
|
// Verify that we are still connected. If we aren't, kill WolapiObject and start over.
|
|
// (This will likely occur during the game, if connection is lost. Ensure that it is done here.)
|
|
pWolapi->pChat->PumpMessages(); // Causes OnNetStatus() call if no longer connected.
|
|
if( pWolapi->bConnectionDown )
|
|
{
|
|
//debugprint( "Re-entering WOL_Main(), pWolapi->bConnectionDown is true. Deleting old WolapiObject...\n" );
|
|
WWMessageBox().Process( TXT_WOL_WOLAPIREINIT );
|
|
// Kill wolapi.
|
|
pWolapi->UnsetupCOMStuff();
|
|
delete pWolapi;
|
|
pWolapi = NULL;
|
|
}
|
|
}
|
|
|
|
if( !pWolapi )
|
|
{
|
|
// Start up wolapi.
|
|
pWolapi = new WolapiObject;
|
|
if( !pWolapi->bSetupCOMStuff() )
|
|
{
|
|
// Things are really bad if this happens. A COM call failed.
|
|
|
|
// We first assume that their wolapi.dll failed to register during wolsetup.exe, part of the patch process.
|
|
// This happens if they have an outdated oleaut32.dll, such as the one that comes with original
|
|
// version of Windows 95.
|
|
|
|
// debugprint( "bSetupCOMStuff failed. Attemping to reregister wolapi.dll...\n" );
|
|
// Attempt to re-register wolapi.dll...
|
|
if( ReregisterWolapiDLL() )
|
|
{
|
|
if( !pWolapi->bSetupCOMStuff() )
|
|
{
|
|
// Still failed after reregistering seemed to work.
|
|
HandleDLLFail();
|
|
return 0;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
HandleDLLFail();
|
|
return 0;
|
|
}
|
|
}
|
|
pWolapi->PrepareButtonsAndIcons();
|
|
// Undocumented hack needed for patch downloading, per Neal.
|
|
pWolapi->pChat->SetAttributeValue( "RegPath", Game_Registry_Key() );
|
|
// (Not that anything's really "documented".)
|
|
}
|
|
|
|
pWolapi->bInGame = false;
|
|
|
|
int iLoginResult = WOL_Login_Dialog( pWolapi );
|
|
if( iLoginResult == 1 )
|
|
{
|
|
pWolapi->SetOptionDefaults();
|
|
bool bKeepGoing = true;
|
|
while( bKeepGoing )
|
|
{
|
|
bool bCreator;
|
|
switch( WOL_Chat_Dialog( pWolapi ) )
|
|
{
|
|
case -1:
|
|
bKeepGoing = false;
|
|
break;
|
|
case 1:
|
|
// User created game channel.
|
|
bCreator = true;
|
|
break;
|
|
case 2:
|
|
// User joined game channel.
|
|
bCreator = false;
|
|
break;
|
|
}
|
|
if( bKeepGoing )
|
|
{
|
|
WOL_GameSetupDialog GSupDlg( pWolapi, bCreator );
|
|
switch( GSupDlg.Run() )
|
|
{
|
|
case RESULT_WOLGSUP_LOGOUT:
|
|
// User logged out.
|
|
bKeepGoing = false;
|
|
break;
|
|
case RESULT_WOLGSUP_BACKTOCHAT:
|
|
case RESULT_WOLGSUP_HOSTLEFT:
|
|
case RESULT_WOLGSUP_RULESMISMATCH:
|
|
// Return to chat.
|
|
break;
|
|
case RESULT_WOLGSUP_STARTGAMEHOST:
|
|
// Proceed with game.
|
|
bKeepGoing = false;
|
|
iReturn = 1;
|
|
pWolapi->bGameServer = true;
|
|
break;
|
|
case RESULT_WOLGSUP_STARTGAME:
|
|
// Proceed with game.
|
|
bKeepGoing = false;
|
|
iReturn = 1;
|
|
pWolapi->bGameServer = false;
|
|
break;
|
|
case RESULT_WOLGSUP_FATALERROR:
|
|
// debugprint( "RESULT_WOLGSUP_FATALERROR from game setup dialog.\n" );
|
|
// Fatal( "RESULT_WOLGSUP_FATALERROR from game setup dialog.\n" );
|
|
if( pWolapi->pChatSink->bConnected )
|
|
pWolapi->Logout();
|
|
bKeepGoing = false;
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
if( iReturn != 1 )
|
|
{
|
|
// Kill wolapi.
|
|
pWolapi->UnsetupCOMStuff();
|
|
delete pWolapi;
|
|
pWolapi = NULL;
|
|
}
|
|
else
|
|
{
|
|
pWolapi->bInGame = true;
|
|
pWolapi->bConnectionDown = false;
|
|
}
|
|
|
|
if( iLoginResult == -1 )
|
|
{
|
|
WWMessageBox().Process( TXT_WOL_DOWNLOADEXITWARNING );
|
|
iReturn = -1;
|
|
}
|
|
|
|
return iReturn;
|
|
}
|
|
|
|
//***********************************************************************************************
|
|
bool ReregisterWolapiDLL()
|
|
{
|
|
// Attempt to reregister wolapi.dll.
|
|
// Returns true if we think we succeeded.
|
|
HKEY hKey;
|
|
char szInstallPath[ _MAX_PATH ];
|
|
if( ::RegOpenKeyEx( HKEY_LOCAL_MACHINE, "Software\\Westwood\\WOLAPI", 0, KEY_READ, &hKey ) == ERROR_SUCCESS )
|
|
{
|
|
DWORD dwBufSize = _MAX_PATH;
|
|
if( ::RegQueryValueEx( hKey, "InstallPath", 0, NULL, (LPBYTE)szInstallPath, &dwBufSize ) == ERROR_SUCCESS )
|
|
{
|
|
WIN32_FIND_DATA wfd;
|
|
HANDLE handle = FindFirstFile( szInstallPath, &wfd );
|
|
if( handle == INVALID_HANDLE_VALUE )
|
|
{
|
|
// File is not there.
|
|
FindClose( handle );
|
|
::RegCloseKey( hKey );
|
|
return false;
|
|
}
|
|
// debugprint( "Found dll -> %s\n", szInstallPath );
|
|
// Get the DLL to register itself.
|
|
HINSTANCE hLib = LoadLibrary( szInstallPath );
|
|
if( !hLib )
|
|
{
|
|
// debugprint( "LoadLibrary failed, GetLastError is %i\n", GetLastError() );
|
|
::RegCloseKey( hKey );
|
|
return false;
|
|
}
|
|
FARPROC lpDllRegisterFunction = GetProcAddress( hLib, "DllRegisterServer" );
|
|
if( !lpDllRegisterFunction )
|
|
{
|
|
::RegCloseKey( hKey );
|
|
return false;
|
|
}
|
|
if( lpDllRegisterFunction() != S_OK )
|
|
{
|
|
::RegCloseKey( hKey );
|
|
return false;
|
|
}
|
|
// There is a bug in wolapi.dll that makes the following delay necessary.
|
|
// Something about Neal's extra threads only getting half-way set up before they get deleted.
|
|
// (The extra threads shouldn't really be created in this case, anyway...)
|
|
::Sleep( 1000 );
|
|
FreeLibrary( hLib );
|
|
FindClose( handle );
|
|
}
|
|
else
|
|
{
|
|
::RegCloseKey( hKey );
|
|
return false;
|
|
}
|
|
::RegCloseKey( hKey );
|
|
}
|
|
else
|
|
{
|
|
return false;
|
|
}
|
|
return true;
|
|
}
|
|
|
|
//***********************************************************************************************
|
|
void HandleDLLFail()
|
|
{
|
|
// The DLL failed to load. Either we failed to reregister it, or we think we succeeded at this but it
|
|
// still is not working. Show an error message and delete pWolapi.
|
|
// We show either "call tech support" or "download IE3", depending on whether oleaut32.dll looks out of date.
|
|
|
|
char szPath[ _MAX_PATH + 1 ];
|
|
::GetSystemDirectory( szPath, _MAX_PATH );
|
|
if( *szPath && szPath[ strlen( szPath ) - 1 ] != '\\' )
|
|
strcat( szPath, "\\" );
|
|
|
|
strcat( szPath, "oleaut32.dll" );
|
|
|
|
WIN32_FIND_DATA wfd;
|
|
HANDLE handle = FindFirstFile( szPath, &wfd );
|
|
|
|
// debugprint( "HandleDLLFail(): filesize of oleaut32 is %i\n", wfd.nFileSizeLow );
|
|
if( handle != INVALID_HANDLE_VALUE && wfd.nFileSizeLow <= 232720 )
|
|
WWMessageBox().Process( TXT_WOL_DLLERROR_GETIE3 );
|
|
else
|
|
WWMessageBox().Process( TXT_WOL_DLLERROR_CALLUS );
|
|
|
|
FindClose( handle );
|
|
|
|
delete pWolapi;
|
|
pWolapi = NULL;
|
|
}
|
|
|
|
#endif
|