Initial commit of Command & Conquer Generals and Command & Conquer Generals Zero Hour source code.
This commit is contained in:
parent
2e338c00cb
commit
3d0ee53a05
6072 changed files with 2283311 additions and 0 deletions
428
Generals/Code/Libraries/Source/WWVegas/WWDownload/Download.cpp
Normal file
428
Generals/Code/Libraries/Source/WWVegas/WWDownload/Download.cpp
Normal file
|
@ -0,0 +1,428 @@
|
|||
/*
|
||||
** Command & Conquer Generals(tm)
|
||||
** Copyright 2025 Electronic Arts Inc.
|
||||
**
|
||||
** This program 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.
|
||||
**
|
||||
** This program is distributed in the hope that it will be useful,
|
||||
** but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
** GNU General Public License for more details.
|
||||
**
|
||||
** You should have received a copy of the GNU General Public License
|
||||
** along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
// Download.cpp : Implementation of CDownload
|
||||
#include "DownloadDebug.h"
|
||||
#include "download.h"
|
||||
#include <mmsystem.h>
|
||||
#include <assert.h>
|
||||
#include <direct.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <sys/stat.h>
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
// CDownload
|
||||
|
||||
|
||||
//
|
||||
// Kick off a download - copys the parameters for the download to the appropriate
|
||||
// data members, then sets the status flag to start the download when PumpMessages()
|
||||
// is called.
|
||||
//
|
||||
|
||||
HRESULT CDownload::DownloadFile(LPCSTR server, LPCSTR username, LPCSTR password, LPCSTR file, LPCSTR localfile, LPCSTR regkey, bool tryresume)
|
||||
{
|
||||
// Check we're not in the middle of another download.
|
||||
if((m_Status != DOWNLOADSTATUS_DONE ) && (m_Status != DOWNLOADSTATUS_FINDINGFILE))
|
||||
{
|
||||
return( DOWNLOAD_STATUSERROR );
|
||||
}
|
||||
|
||||
// If we're still connected, make sure we're on the right server
|
||||
if (m_Status == DOWNLOADSTATUS_FINDINGFILE)
|
||||
{
|
||||
if ((strcmp(m_Server, server)) || (strcmp(m_Login, username)))
|
||||
{
|
||||
// Damn, a server switch. Close conn & fix state
|
||||
m_Ftp->DisconnectFromServer();
|
||||
m_Status=DOWNLOADSTATUS_DONE;
|
||||
}
|
||||
}
|
||||
|
||||
// Check all parameters are non-null.
|
||||
|
||||
if( ( server == NULL ) || ( username == NULL ) ||
|
||||
( password == NULL ) || ( file == NULL ) ||
|
||||
( localfile == NULL ) || ( regkey == NULL ) )
|
||||
{
|
||||
//////////DBGMSG("Download Paramerror");
|
||||
return( DOWNLOAD_PARAMERROR );
|
||||
}
|
||||
|
||||
// Make sure we have a download directory
|
||||
_mkdir("download");
|
||||
|
||||
// Copy parameters to member variables.
|
||||
strncpy( m_Server, server, sizeof( m_Server ) );
|
||||
strncpy( m_Login, username, sizeof( m_Login ) );
|
||||
strncpy( m_Password, password, sizeof( m_Password ) );
|
||||
strncpy( m_File, file, sizeof( m_File ) );
|
||||
strncpy( m_LocalFile, localfile, sizeof( m_LocalFile ) );
|
||||
|
||||
strncpy( m_LastLocalFile, localfile, sizeof( m_LastLocalFile ) );
|
||||
|
||||
strncpy( m_RegKey, regkey, sizeof( m_RegKey ) );
|
||||
m_TryResume = tryresume;
|
||||
m_StartPosition=0;
|
||||
|
||||
/*********
|
||||
// figure out file offset
|
||||
if (m_TryResume == false)
|
||||
{
|
||||
m_StartPosition=0;
|
||||
}
|
||||
else if(( m_StartPosition = m_Ftp->FileRecoveryPosition( m_LocalFile, m_RegKey ) ) != 0 )
|
||||
{
|
||||
if( Listener->OnQueryResume() == DOWNLOADEVENT_DONOTRESUME )
|
||||
{
|
||||
m_Ftp->RestartFrom( 0 );
|
||||
m_StartPosition = 0;
|
||||
}
|
||||
}
|
||||
************/
|
||||
|
||||
// Set status so we start to connect at the next PumpMessages()
|
||||
if (m_Status != DOWNLOADSTATUS_FINDINGFILE)
|
||||
m_Status = DOWNLOADSTATUS_GO;
|
||||
|
||||
//////////DBGMSG("Ready to download");
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
|
||||
//
|
||||
// Get the local filename of the last file we requested to download....
|
||||
//
|
||||
HRESULT CDownload::GetLastLocalFile(char *local_file, int maxlen) {
|
||||
if (local_file==0)
|
||||
return(E_FAIL);
|
||||
|
||||
strncpy(local_file, m_LastLocalFile, maxlen);
|
||||
local_file[maxlen-1]=0;
|
||||
|
||||
return(S_OK);
|
||||
}
|
||||
|
||||
|
||||
//
|
||||
// Abort the current download - disconnects from the server and sets the
|
||||
// status flag to stop PumpMessages() from doing anything.
|
||||
//
|
||||
|
||||
HRESULT CDownload::Abort()
|
||||
{
|
||||
|
||||
if( m_Status != DOWNLOADSTATUS_NONE )
|
||||
{
|
||||
m_Ftp->DisconnectFromServer();
|
||||
m_Status = DOWNLOADSTATUS_NONE;
|
||||
}
|
||||
|
||||
m_TimeStarted = 0;
|
||||
m_StartPosition = 0;
|
||||
m_FileSize = 0;
|
||||
m_BytesRead = 0;
|
||||
m_Server[ 0 ] = '\0';
|
||||
m_Login[ 0 ] = '\0';
|
||||
m_Password[ 0 ] = '\0';
|
||||
m_File[ 0 ] = '\0';
|
||||
m_LocalFile[ 0 ] = '\0';
|
||||
m_RegKey[ 0 ] = '\0';
|
||||
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
|
||||
//
|
||||
// PumpMessages() does all the work - checks for possible resumption of a previous
|
||||
// download, connects to the server, finds the file and downloads it.
|
||||
//
|
||||
|
||||
HRESULT CDownload::PumpMessages()
|
||||
{
|
||||
int iResult = 0;
|
||||
int timetaken = 0;
|
||||
int averagetimepredicted = -1;
|
||||
static int reenter = 0;
|
||||
|
||||
/* Avoid reentrancy. */
|
||||
|
||||
////DBGMSG("Download Pump");
|
||||
|
||||
if( reenter != 0 )
|
||||
{
|
||||
return( DOWNLOAD_REENTERERROR );
|
||||
}
|
||||
|
||||
reenter = 1;
|
||||
|
||||
|
||||
if( m_Status == DOWNLOADSTATUS_GO )
|
||||
{
|
||||
// Check to see whether the file already exists locally
|
||||
|
||||
/***********
|
||||
if (m_TryResume == false)
|
||||
{
|
||||
m_StartPosition = 0;
|
||||
}
|
||||
else if( ( m_StartPosition = m_Ftp->FileRecoveryPosition( m_LocalFile, m_RegKey ) ) != 0 )
|
||||
{
|
||||
if( Listener->OnQueryResume() == DOWNLOADEVENT_DONOTRESUME )
|
||||
{
|
||||
m_Ftp->RestartFrom( 0 );
|
||||
m_StartPosition = 0;
|
||||
}
|
||||
}
|
||||
************/
|
||||
|
||||
// Tell the client that we're starting to connect.
|
||||
|
||||
Listener->OnStatusUpdate( DOWNLOADSTATUS_CONNECTING );
|
||||
|
||||
m_Status = DOWNLOADSTATUS_CONNECTING;
|
||||
}
|
||||
|
||||
|
||||
if( m_Status == DOWNLOADSTATUS_CONNECTING )
|
||||
{
|
||||
// Connect to the server
|
||||
//////////DBGMSG("Connect to Server");
|
||||
|
||||
iResult = m_Ftp->ConnectToServer( m_Server );
|
||||
////////////DBGMSG("out of FTP connect");
|
||||
|
||||
if( iResult == FTP_SUCCEEDED )
|
||||
{
|
||||
m_Status = DOWNLOADSTATUS_LOGGINGIN;
|
||||
}
|
||||
else
|
||||
{
|
||||
if( iResult == FTP_FAILED )
|
||||
{
|
||||
// Tell the client we couldn't connect
|
||||
///////////DBGMSG("Couldn't connect");
|
||||
Listener->OnError( DOWNLOADEVENT_COULDNOTCONNECT );
|
||||
reenter = 0;
|
||||
return DOWNLOAD_NETWORKERROR;
|
||||
}
|
||||
}
|
||||
reenter = 0;
|
||||
return DOWNLOAD_SUCCEEDED;
|
||||
}
|
||||
|
||||
if( m_Status == DOWNLOADSTATUS_LOGGINGIN )
|
||||
{
|
||||
// Login to the server
|
||||
////////////DBGMSG("Login to server");
|
||||
|
||||
iResult = m_Ftp->LoginToServer( m_Login, m_Password );
|
||||
|
||||
if( iResult == FTP_SUCCEEDED )
|
||||
{
|
||||
Listener->OnStatusUpdate( DOWNLOADSTATUS_FINDINGFILE );
|
||||
m_Status = DOWNLOADSTATUS_FINDINGFILE;
|
||||
}
|
||||
|
||||
if( iResult == FTP_FAILED )
|
||||
{
|
||||
// Tell the client we couldn't log in
|
||||
|
||||
Listener->OnError( DOWNLOADEVENT_LOGINFAILED );
|
||||
reenter = 0;
|
||||
return( DOWNLOAD_NETWORKERROR );
|
||||
}
|
||||
|
||||
reenter = 0;
|
||||
return DOWNLOAD_SUCCEEDED;
|
||||
}
|
||||
|
||||
if(( m_Status == DOWNLOADSTATUS_FINDINGFILE ) && (strlen(m_File)))
|
||||
{
|
||||
|
||||
// Find the file on the server
|
||||
///////////DBGMSG("Find File");
|
||||
|
||||
if( m_Ftp->FindFile( m_File, &m_FileSize ) == FTP_FAILED )
|
||||
{
|
||||
// Tell the client we couldn't find the file
|
||||
|
||||
Listener->OnError( DOWNLOADEVENT_NOSUCHFILE );
|
||||
reenter = 0;
|
||||
return( DOWNLOAD_FILEERROR );
|
||||
}
|
||||
|
||||
if( m_FileSize > 0 )
|
||||
{
|
||||
// First check to see if we already have the complete file in the proper dest location...
|
||||
//
|
||||
// Note, we will only skip the download if the file is a patch. Patch files should
|
||||
// never ever change so this is not a concern.
|
||||
//
|
||||
// We identify patches because they are written into the patches folder.
|
||||
struct _stat statdata;
|
||||
if ( (_stat(m_LocalFile, &statdata) == 0) &&
|
||||
(statdata.st_size == m_FileSize) &&
|
||||
(_strnicmp(m_LocalFile, "patches\\", strlen("patches\\"))==0)) {
|
||||
// OK, no need to download this again....
|
||||
|
||||
m_Status = DOWNLOADSTATUS_FINDINGFILE; // ready to find another file
|
||||
m_TimeStarted = 0;
|
||||
m_StartPosition = 0;
|
||||
m_FileSize = 0;
|
||||
m_BytesRead = 0;
|
||||
m_File[ 0 ] = '\0';
|
||||
m_LocalFile[ 0 ] = '\0';
|
||||
|
||||
Listener->OnEnd();
|
||||
|
||||
reenter = 0;
|
||||
return DOWNLOAD_SUCCEEDED;
|
||||
}
|
||||
|
||||
|
||||
//
|
||||
// Check if we can do a file resume
|
||||
//
|
||||
if (m_TryResume == false)
|
||||
{
|
||||
m_StartPosition = 0;
|
||||
}
|
||||
else if( ( m_StartPosition = m_Ftp->FileRecoveryPosition( m_LocalFile, m_RegKey ) ) != 0 )
|
||||
{
|
||||
if( Listener->OnQueryResume() == DOWNLOADEVENT_DONOTRESUME )
|
||||
{
|
||||
m_Ftp->RestartFrom( 0 );
|
||||
m_StartPosition = 0;
|
||||
}
|
||||
}
|
||||
// end resume check
|
||||
|
||||
|
||||
m_Status = DOWNLOADSTATUS_DOWNLOADING;
|
||||
|
||||
// Tell the client we're starting to download
|
||||
|
||||
Listener->OnStatusUpdate( DOWNLOADSTATUS_DOWNLOADING );
|
||||
}
|
||||
|
||||
reenter = 0;
|
||||
return DOWNLOAD_SUCCEEDED;
|
||||
}
|
||||
|
||||
if( m_Status == DOWNLOADSTATUS_DOWNLOADING )
|
||||
{
|
||||
|
||||
// Get the next chunk of the file
|
||||
///DBGMSG("Get Next File Block");
|
||||
|
||||
iResult = m_Ftp->GetNextFileBlock( m_LocalFile, &m_BytesRead );
|
||||
|
||||
if( m_TimeStarted == 0 )
|
||||
{
|
||||
// This is the first time through here - record the starting time.
|
||||
m_TimeStarted = timeGetTime();
|
||||
}
|
||||
|
||||
if( iResult == FTP_SUCCEEDED )
|
||||
{
|
||||
m_Status = DOWNLOADSTATUS_FINISHING;
|
||||
}
|
||||
else
|
||||
{
|
||||
if( iResult == FTP_FAILED )
|
||||
{
|
||||
Listener->OnError( DOWNLOADEVENT_TCPERROR );
|
||||
reenter = 0;
|
||||
return( DOWNLOAD_NETWORKERROR );
|
||||
}
|
||||
}
|
||||
|
||||
// Calculate time taken so far, and predict how long there is left.
|
||||
// The prediction returned is the average of the last 8 predictions.
|
||||
|
||||
timetaken = ( timeGetTime() - m_TimeStarted ) / 1000;
|
||||
|
||||
//////////if( m_BytesRead > 0 ) // NAK - RP said this is wrong
|
||||
if( ( m_BytesRead - m_StartPosition ) > 0 )
|
||||
{
|
||||
// Not the first read.
|
||||
int predictionIndex = ( m_predictions++ ) & 0x7;
|
||||
m_predictionTimes[ predictionIndex ] = MulDiv( timetaken, (m_FileSize - m_BytesRead), (m_BytesRead - m_StartPosition) );
|
||||
//__int64 numerator = ( m_FileSize - m_BytesRead ) * timetaken;
|
||||
//__int64 denominator = ( m_BytesRead - m_StartPosition );
|
||||
//m_predictionTimes[ predictionIndex ] = numerator/denominator;
|
||||
//m_predictionTimes[ predictionIndex ] = ( ( m_FileSize - m_BytesRead ) * timetaken ) / ( m_BytesRead - m_StartPosition );
|
||||
//m_predictionTimes[ predictionIndex ] = ( ( m_FileSize - m_BytesRead ) / ( m_BytesRead - m_StartPosition ) * timetaken );
|
||||
|
||||
DEBUG_LOG(("About to OnProgressUpdate() - m_FileSize=%d, m_BytesRead=%d, timetaken=%d, numerator=%d",
|
||||
m_FileSize, m_BytesRead, timetaken, ( ( m_FileSize - m_BytesRead ) * timetaken )));
|
||||
DEBUG_LOG((", m_startPosition=%d, denominator=%d, predictionTime=%d\n",
|
||||
m_StartPosition, ( m_BytesRead - m_StartPosition ), predictionIndex));
|
||||
DEBUG_LOG(("vals are %d %d %d %d %d %d %d %d\n",
|
||||
m_predictionTimes[ 0 ], m_predictionTimes[ 1 ], m_predictionTimes[ 2 ], m_predictionTimes[ 3 ],
|
||||
m_predictionTimes[ 4 ], m_predictionTimes[ 5 ], m_predictionTimes[ 6 ], m_predictionTimes[ 7 ]));
|
||||
|
||||
if( m_predictions > 8 )
|
||||
{
|
||||
// We've had enough time to build up a few predictions, so calculate
|
||||
// an average.
|
||||
averagetimepredicted = ( m_predictionTimes[ 0 ] + m_predictionTimes[ 1 ] +
|
||||
m_predictionTimes[ 2 ] + m_predictionTimes[ 3 ] +
|
||||
m_predictionTimes[ 4 ] + m_predictionTimes[ 5 ] +
|
||||
m_predictionTimes[ 6 ] + m_predictionTimes[ 7 ] ) / 8;
|
||||
}
|
||||
else
|
||||
{
|
||||
// Wait a while longer before passing a "real" prediction
|
||||
averagetimepredicted = -1;
|
||||
}
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
averagetimepredicted = -1;
|
||||
}
|
||||
|
||||
// Update the client's progress bar (or whatever)
|
||||
|
||||
Listener->OnProgressUpdate( m_BytesRead, m_FileSize, timetaken, averagetimepredicted + 1);
|
||||
}
|
||||
|
||||
|
||||
if( m_Status == DOWNLOADSTATUS_FINISHING )
|
||||
{
|
||||
if (m_Ftp->m_iCommandSocket)
|
||||
m_Status = DOWNLOADSTATUS_FINDINGFILE; // ready to find another file
|
||||
else
|
||||
m_Status = DOWNLOADSTATUS_DONE; // command channel closed, connect again...
|
||||
|
||||
m_TimeStarted = 0;
|
||||
m_StartPosition = 0;
|
||||
m_FileSize = 0;
|
||||
m_BytesRead = 0;
|
||||
m_File[ 0 ] = '\0';
|
||||
m_LocalFile[ 0 ] = '\0';
|
||||
|
||||
Listener->OnEnd();
|
||||
}
|
||||
|
||||
reenter = 0;
|
||||
return DOWNLOAD_SUCCEEDED;
|
||||
}
|
99
Generals/Code/Libraries/Source/WWVegas/WWDownload/Download.h
Normal file
99
Generals/Code/Libraries/Source/WWVegas/WWDownload/Download.h
Normal file
|
@ -0,0 +1,99 @@
|
|||
/*
|
||||
** Command & Conquer Generals(tm)
|
||||
** Copyright 2025 Electronic Arts Inc.
|
||||
**
|
||||
** This program 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.
|
||||
**
|
||||
** This program is distributed in the hope that it will be useful,
|
||||
** but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
** GNU General Public License for more details.
|
||||
**
|
||||
** You should have received a copy of the GNU General Public License
|
||||
** along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
// Download.h : Declaration of the CDownload
|
||||
|
||||
#ifndef __DOWNLOAD_H_
|
||||
#define __DOWNLOAD_H_
|
||||
|
||||
//#include "../resource.h" // main symbols
|
||||
#include "WWDownload/ftp.h"
|
||||
#include "WWDownload/downloaddefs.h"
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
// CDownload
|
||||
|
||||
class IDownload
|
||||
{
|
||||
public:
|
||||
virtual HRESULT OnError( int error )=0;
|
||||
virtual HRESULT OnEnd()=0;
|
||||
virtual HRESULT OnQueryResume()=0;
|
||||
virtual HRESULT OnProgressUpdate(int bytesread, int totalsize, int timetaken, int timeleft)=0;
|
||||
virtual HRESULT OnStatusUpdate(int status)=0;
|
||||
};
|
||||
|
||||
class CDownload
|
||||
{
|
||||
public:
|
||||
CDownload(IDownload *listener) :
|
||||
Listener(listener)
|
||||
{
|
||||
m_Status = DOWNLOADSTATUS_NONE;
|
||||
m_TimeStarted = 0;
|
||||
m_StartPosition = 0;
|
||||
m_FileSize = 0;
|
||||
m_BytesRead = 0;
|
||||
m_Server[ 0 ] = '\0';
|
||||
m_Login[ 0 ] = '\0';
|
||||
m_Password[ 0 ] = '\0';
|
||||
m_File[ 0 ] = '\0';
|
||||
m_LocalFile[ 0 ] = '\0';
|
||||
m_RegKey[ 0 ] = '\0';
|
||||
m_Ftp = new( Cftp );
|
||||
m_TryResume = false;
|
||||
|
||||
m_predictions = 0;
|
||||
for (int i=0; i<8; ++i)
|
||||
{
|
||||
m_predictionTimes[i] = 0;
|
||||
}
|
||||
}
|
||||
~CDownload() { delete m_Ftp; }
|
||||
|
||||
public:
|
||||
virtual HRESULT PumpMessages();
|
||||
virtual HRESULT Abort();
|
||||
virtual HRESULT DownloadFile(LPCSTR server, LPCSTR username, LPCSTR password, LPCSTR file, LPCSTR localfile, LPCSTR regkey, bool tryresume=true);
|
||||
virtual HRESULT GetLastLocalFile(char *local_file, int maxlen);
|
||||
|
||||
private:
|
||||
char m_Server[ 256 ];
|
||||
char m_Login[ 64 ];
|
||||
char m_Password[ 64 ];
|
||||
char m_File[ 256 ];
|
||||
char m_LocalFile[ 256 ];
|
||||
|
||||
char m_LastLocalFile[ 256 ];
|
||||
|
||||
char m_RegKey[ 256 ];
|
||||
int m_Status;
|
||||
int m_TimeStarted;
|
||||
int m_StartPosition;
|
||||
int m_FileSize;
|
||||
int m_BytesRead;
|
||||
bool m_TryResume;
|
||||
|
||||
int m_predictions;
|
||||
int m_predictionTimes[8];
|
||||
|
||||
Cftp *m_Ftp;
|
||||
IDownload *Listener;
|
||||
};
|
||||
|
||||
#endif //__DOWNLOAD_H_
|
|
@ -0,0 +1,68 @@
|
|||
/*
|
||||
** Command & Conquer Generals(tm)
|
||||
** Copyright 2025 Electronic Arts Inc.
|
||||
**
|
||||
** This program 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.
|
||||
**
|
||||
** This program is distributed in the hope that it will be useful,
|
||||
** but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
** GNU General Public License for more details.
|
||||
**
|
||||
** You should have received a copy of the GNU General Public License
|
||||
** along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
// DownloadDebug.h
|
||||
|
||||
#ifndef __DOWNLOADDEBUG_H_
|
||||
#define __DOWNLOADDEBUG_H_
|
||||
|
||||
// BGC 3/27/03 - added this for disabling debug logging for "release" worldbuilder.
|
||||
// uncomment this line to remove logging from game spy code.
|
||||
//#define DISABLE_DEBUG_LOGGING
|
||||
|
||||
#if defined(NDEBUG) || defined(DISABLE_DEBUG_LOGGING)
|
||||
#define DEBUG_LOG(exp) ((void)0)
|
||||
#else
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#include <stdarg.h>
|
||||
extern void DebugCrash( const char *fmt, ... );
|
||||
extern void DebugLog( const char *fmt, ... );
|
||||
|
||||
/*
|
||||
Yeah, it's a sleazy global, since we can't reasonably add
|
||||
any args to DebugCrash due to the varargs nature of it.
|
||||
We'll just let it slide in this case...
|
||||
*/
|
||||
extern char* TheCurrentIgnoreCrashPtr;
|
||||
|
||||
#define DEBUG_CRASH(m) \
|
||||
do { \
|
||||
{ \
|
||||
static char ignoreCrash = 0; \
|
||||
if (!ignoreCrash) { \
|
||||
TheCurrentIgnoreCrashPtr = &ignoreCrash; \
|
||||
DebugCrash m ; \
|
||||
TheCurrentIgnoreCrashPtr = NULL; \
|
||||
} \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
#define DEBUG_LOG(x) do { DebugLog x; } while (0)
|
||||
#define DEBUG_ASSERTCRASH(c, m) do { { if (!(c)) DEBUG_CRASH(m); } } while (0)
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif // NDEBUG
|
||||
|
||||
#endif //__DOWNLOADDEBUG_H_
|
1848
Generals/Code/Libraries/Source/WWVegas/WWDownload/FTP.CPP
Normal file
1848
Generals/Code/Libraries/Source/WWVegas/WWDownload/FTP.CPP
Normal file
File diff suppressed because it is too large
Load diff
50
Generals/Code/Libraries/Source/WWVegas/WWDownload/Registry.h
Normal file
50
Generals/Code/Libraries/Source/WWVegas/WWDownload/Registry.h
Normal file
|
@ -0,0 +1,50 @@
|
|||
/*
|
||||
** Command & Conquer Generals(tm)
|
||||
** Copyright 2025 Electronic Arts Inc.
|
||||
**
|
||||
** This program 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.
|
||||
**
|
||||
** This program is distributed in the hope that it will be useful,
|
||||
** but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
** GNU General Public License for more details.
|
||||
**
|
||||
** You should have received a copy of the GNU General Public License
|
||||
** along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
// Registry.h
|
||||
// Simple interface for storing/retreiving registry values
|
||||
// Author: Matthew D. Campbell, December 2001
|
||||
|
||||
#pragma once
|
||||
|
||||
#ifndef __WWDOWNLOAD_REGISTRY_H__
|
||||
#define __WWDOWNLOAD_REGISTRY_H__
|
||||
|
||||
#include <string>
|
||||
|
||||
/**
|
||||
* Get a string from the registry
|
||||
*/
|
||||
bool GetStringFromRegistry(std::string path, std::string key, std::string& val);
|
||||
|
||||
/**
|
||||
* Get an unsigned int from the registry
|
||||
*/
|
||||
bool GetUnsignedIntFromRegistry(std::string path, std::string key, unsigned int& val);
|
||||
|
||||
/**
|
||||
* Store a string in the registry - returns true on success
|
||||
*/
|
||||
bool SetStringInRegistry(std::string path, std::string key, std::string val);
|
||||
|
||||
/**
|
||||
* Store an unsigned int in the registry - returns true on success
|
||||
*/
|
||||
bool SetUnsignedIntInRegistry(std::string path, std::string key, unsigned int val);
|
||||
|
||||
#endif // __WWDOWNLOAD_REGISTRY_H__
|
161
Generals/Code/Libraries/Source/WWVegas/WWDownload/WWDownload.dsp
Normal file
161
Generals/Code/Libraries/Source/WWVegas/WWDownload/WWDownload.dsp
Normal file
|
@ -0,0 +1,161 @@
|
|||
# Microsoft Developer Studio Project File - Name="WWDownload" - Package Owner=<4>
|
||||
# Microsoft Developer Studio Generated Build File, Format Version 6.00
|
||||
# ** DO NOT EDIT **
|
||||
|
||||
# TARGTYPE "Win32 (x86) Static Library" 0x0104
|
||||
|
||||
CFG=WWDownload - Win32 Debug
|
||||
!MESSAGE This is not a valid makefile. To build this project using NMAKE,
|
||||
!MESSAGE use the Export Makefile command and run
|
||||
!MESSAGE
|
||||
!MESSAGE NMAKE /f "WWDownload.mak".
|
||||
!MESSAGE
|
||||
!MESSAGE You can specify a configuration when running NMAKE
|
||||
!MESSAGE by defining the macro CFG on the command line. For example:
|
||||
!MESSAGE
|
||||
!MESSAGE NMAKE /f "WWDownload.mak" CFG="WWDownload - Win32 Debug"
|
||||
!MESSAGE
|
||||
!MESSAGE Possible choices for configuration are:
|
||||
!MESSAGE
|
||||
!MESSAGE "WWDownload - Win32 Release" (based on "Win32 (x86) Static Library")
|
||||
!MESSAGE "WWDownload - Win32 Debug" (based on "Win32 (x86) Static Library")
|
||||
!MESSAGE "WWDownload - Win32 Internal" (based on "Win32 (x86) Static Library")
|
||||
!MESSAGE
|
||||
|
||||
# Begin Project
|
||||
# PROP AllowPerConfigDependencies 0
|
||||
# PROP Scc_ProjName ""$/Gamespy/GOA/WWDownload", PHXAAAAA"
|
||||
# PROP Scc_LocalPath "."
|
||||
CPP=cl.exe
|
||||
RSC=rc.exe
|
||||
|
||||
!IF "$(CFG)" == "WWDownload - Win32 Release"
|
||||
|
||||
# PROP BASE Use_MFC 0
|
||||
# PROP BASE Use_Debug_Libraries 0
|
||||
# PROP BASE Output_Dir "Release"
|
||||
# PROP BASE Intermediate_Dir "Release"
|
||||
# PROP BASE Target_Dir ""
|
||||
# PROP Use_MFC 0
|
||||
# PROP Use_Debug_Libraries 0
|
||||
# PROP Output_Dir "Release"
|
||||
# PROP Intermediate_Dir "Release"
|
||||
# PROP Target_Dir ""
|
||||
# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_MBCS" /D "_LIB" /YX /FD /c
|
||||
# ADD CPP /nologo /G6 /MD /W3 /GX /O2 /Ob2 /I ".." /D "WIN32" /D "NDEBUG" /D "_MBCS" /D "_LIB" /Fr /YX /FD /c
|
||||
# ADD BASE RSC /l 0x409 /d "NDEBUG"
|
||||
# ADD RSC /l 0x409 /d "NDEBUG"
|
||||
BSC32=bscmake.exe
|
||||
# ADD BASE BSC32 /nologo
|
||||
# ADD BSC32 /nologo
|
||||
LIB32=link.exe -lib
|
||||
# ADD BASE LIB32 /nologo
|
||||
# ADD LIB32 /nologo /out:"..\..\..\lib\WWDownload.lib"
|
||||
|
||||
!ELSEIF "$(CFG)" == "WWDownload - Win32 Debug"
|
||||
|
||||
# PROP BASE Use_MFC 0
|
||||
# PROP BASE Use_Debug_Libraries 1
|
||||
# PROP BASE Output_Dir "Debug"
|
||||
# PROP BASE Intermediate_Dir "Debug"
|
||||
# PROP BASE Target_Dir ""
|
||||
# PROP Use_MFC 0
|
||||
# PROP Use_Debug_Libraries 1
|
||||
# PROP Output_Dir "Debug"
|
||||
# PROP Intermediate_Dir "Debug"
|
||||
# PROP Target_Dir ""
|
||||
# ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_MBCS" /D "_LIB" /YX /FD /GZ /c
|
||||
# ADD CPP /nologo /G6 /MDd /W3 /Gm /GX /ZI /Od /I ".." /D "WIN32" /D "_DEBUG" /D "_MBCS" /D "_LIB" /Fr /YX /FD /GZ /c
|
||||
# ADD BASE RSC /l 0x409 /d "_DEBUG"
|
||||
# ADD RSC /l 0x409 /d "_DEBUG"
|
||||
BSC32=bscmake.exe
|
||||
# ADD BASE BSC32 /nologo
|
||||
# ADD BSC32 /nologo
|
||||
LIB32=link.exe -lib
|
||||
# ADD BASE LIB32 /nologo
|
||||
# ADD LIB32 /nologo /out:"..\..\..\lib\WWDownloadDebug.lib"
|
||||
|
||||
!ELSEIF "$(CFG)" == "WWDownload - Win32 Internal"
|
||||
|
||||
# PROP BASE Use_MFC 0
|
||||
# PROP BASE Use_Debug_Libraries 0
|
||||
# PROP BASE Output_Dir "Internal"
|
||||
# PROP BASE Intermediate_Dir "Internal"
|
||||
# PROP BASE Target_Dir ""
|
||||
# PROP Use_MFC 0
|
||||
# PROP Use_Debug_Libraries 0
|
||||
# PROP Output_Dir "Internal"
|
||||
# PROP Intermediate_Dir "Internal"
|
||||
# PROP Target_Dir ""
|
||||
# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_MBCS" /D "_LIB" /YX /FD /c
|
||||
# ADD CPP /nologo /G6 /MD /W3 /GX /O2 /I ".." /D "WIN32" /D "DEBUG" /D "_MBCS" /D "_LIB" /Fr /YX /FD /c
|
||||
# ADD BASE RSC /l 0x409 /d "NDEBUG"
|
||||
# ADD RSC /l 0x409 /d "NDEBUG"
|
||||
BSC32=bscmake.exe
|
||||
# ADD BASE BSC32 /nologo
|
||||
# ADD BSC32 /nologo
|
||||
LIB32=link.exe -lib
|
||||
# ADD BASE LIB32 /nologo /out:"..\..\..\lib\WWDownload.lib"
|
||||
# ADD LIB32 /nologo /out:"..\..\..\lib\WWDownloadInternal.lib"
|
||||
|
||||
!ENDIF
|
||||
|
||||
# Begin Target
|
||||
|
||||
# Name "WWDownload - Win32 Release"
|
||||
# Name "WWDownload - Win32 Debug"
|
||||
# Name "WWDownload - Win32 Internal"
|
||||
# Begin Group "Source Files"
|
||||
|
||||
# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat"
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\Download.cpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\Ftp.cpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\registry.cpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\urlBuilder.cpp
|
||||
# End Source File
|
||||
# End Group
|
||||
# Begin Group "Header Files"
|
||||
|
||||
# PROP Default_Filter "h;hpp;hxx;hm;inl"
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\Download.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\DownloadDebug.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\DownloadDefs.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\Ftp.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\FtpDefs.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\Registry.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\urlBuilder.h
|
||||
# End Source File
|
||||
# End Group
|
||||
# End Target
|
||||
# End Project
|
|
@ -0,0 +1,61 @@
|
|||
/*
|
||||
** Command & Conquer Generals(tm)
|
||||
** Copyright 2025 Electronic Arts Inc.
|
||||
**
|
||||
** This program 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.
|
||||
**
|
||||
** This program is distributed in the hope that it will be useful,
|
||||
** but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
** GNU General Public License for more details.
|
||||
**
|
||||
** You should have received a copy of the GNU General Public License
|
||||
** along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef _DOWNLOADDEFS_H
|
||||
#define _DOWNLOADDEFS_H
|
||||
|
||||
// CDownload statuses
|
||||
|
||||
#define DOWNLOADSTATUS_NONE 0
|
||||
#define DOWNLOADSTATUS_GO 1
|
||||
#define DOWNLOADSTATUS_CONNECTING 2
|
||||
#define DOWNLOADSTATUS_LOGGINGIN 3
|
||||
#define DOWNLOADSTATUS_FINDINGFILE 4
|
||||
#define DOWNLOADSTATUS_QUERYINGRESUME 5
|
||||
#define DOWNLOADSTATUS_DOWNLOADING 6
|
||||
#define DOWNLOADSTATUS_DISCONNECTING 7
|
||||
#define DOWNLOADSTATUS_FINISHING 8
|
||||
#define DOWNLOADSTATUS_DONE 0
|
||||
|
||||
// CDownload return codes
|
||||
|
||||
#define DOWNLOAD_SUCCEEDED S_OK
|
||||
#define DOWNLOAD_PARAMERROR MAKE_HRESULT( SEVERITY_ERROR, FACILITY_ITF, 1 )
|
||||
#define DOWNLOAD_STATUSERROR MAKE_HRESULT( SEVERITY_ERROR, FACILITY_ITF, 2 )
|
||||
#define DOWNLOAD_NETWORKERROR MAKE_HRESULT( SEVERITY_ERROR, FACILITY_ITF, 3 )
|
||||
#define DOWNLOAD_FILEERROR MAKE_HRESULT( SEVERITY_ERROR, FACILITY_ITF, 4 )
|
||||
#define DOWNLOAD_REENTERERROR MAKE_HRESULT( SEVERITY_ERROR, FACILITY_ITF, 4 )
|
||||
|
||||
// CDownloadEvent return codes.
|
||||
|
||||
#define DOWNLOADEVENT_SUCCEEDED S_OK
|
||||
#define DOWNLOADEVENT_FAILED MAKE_HRESULT( SEVERITY_ERROR, FACILITY_ITF, 5 )
|
||||
#define DOWNLOADEVENT_RESUME S_OK
|
||||
#define DOWNLOADEVENT_DONOTRESUME MAKE_HRESULT( SEVERITY_ERROR, FACILITY_ITF, 6 )
|
||||
|
||||
// CDownloadEvent error codes for OnError()
|
||||
|
||||
#define DOWNLOADEVENT_NOSUCHSERVER 1
|
||||
#define DOWNLOADEVENT_COULDNOTCONNECT 2
|
||||
#define DOWNLOADEVENT_LOGINFAILED 3
|
||||
#define DOWNLOADEVENT_NOSUCHFILE 4
|
||||
#define DOWNLOADEVENT_LOCALFILEOPENFAILED 5
|
||||
#define DOWNLOADEVENT_TCPERROR 6
|
||||
#define DOWNLOADEVENT_DISCONNECTERROR 7
|
||||
|
||||
#endif
|
117
Generals/Code/Libraries/Source/WWVegas/WWDownload/ftp.h
Normal file
117
Generals/Code/Libraries/Source/WWVegas/WWDownload/ftp.h
Normal file
|
@ -0,0 +1,117 @@
|
|||
/*
|
||||
** Command & Conquer Generals(tm)
|
||||
** Copyright 2025 Electronic Arts Inc.
|
||||
**
|
||||
** This program 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.
|
||||
**
|
||||
** This program is distributed in the hope that it will be useful,
|
||||
** but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
** GNU General Public License for more details.
|
||||
**
|
||||
** You should have received a copy of the GNU General Public License
|
||||
** along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
// ftp.h : Declaration of the Cftp
|
||||
|
||||
#ifndef __FTP_H_
|
||||
#define __FTP_H_
|
||||
|
||||
|
||||
//#include "../resource.h" // main symbols
|
||||
|
||||
#include "winsock.h"
|
||||
#include "stdio.h"
|
||||
|
||||
#include "WWDownload/ftpdefs.h"
|
||||
|
||||
// FTP server return codes. See RFC 959
|
||||
|
||||
#define FTPREPLY_SERVEROK 220
|
||||
#define FTPREPLY_PASSWORD 331
|
||||
#define FTPREPLY_LOGGEDIN 230
|
||||
#define FTPREPLY_PORTOK 200
|
||||
#define FTPREPLY_TYPEOK 200
|
||||
#define FTPREPLY_RESTARTOK 350
|
||||
#define FTPREPLY_CWDOK 250
|
||||
#define FTPREPLY_OPENASCII 150
|
||||
#define FTPREPLY_OPENBINARY 150
|
||||
#define FTPREPLY_COMPLETE 226
|
||||
#define FTPREPLY_CONTROLCLOSED 421
|
||||
|
||||
// Temporary download file name
|
||||
|
||||
#define FTP_TEMPFILENAME "..\\__~DOWN_L~D"
|
||||
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
// Cftp
|
||||
class Cftp
|
||||
{
|
||||
private:
|
||||
friend class CDownload;
|
||||
|
||||
int m_iCommandSocket; // Socket for commands
|
||||
int m_iDataSocket; // Socket for data
|
||||
|
||||
struct sockaddr_in m_CommandSockAddr; // Address for commands
|
||||
struct sockaddr_in m_DataSockAddr; // Address for data
|
||||
|
||||
int m_iFilePos; // Byte offset into file
|
||||
int m_iBytesRead; // Number of bytes downloaded
|
||||
int m_iFileSize; // Total size of the file
|
||||
char m_szRemoteFilePath[128];
|
||||
char m_szRemoteFileName[128];
|
||||
char m_szLocalFilePath[128];
|
||||
char m_szLocalFileName[128];
|
||||
char m_szServerName[128];
|
||||
char m_szUserName[128];
|
||||
char m_szPassword[128];
|
||||
FILE * m_pfLocalFile;
|
||||
int m_iStatus;
|
||||
|
||||
int m_sendNewPortStatus;
|
||||
int m_findStart;
|
||||
|
||||
int SendData( char * pData, int iSize );
|
||||
int RecvData( char * pData, int iSize );
|
||||
int SendNewPort();
|
||||
int OpenDataConnection();
|
||||
void CloseDataConnection();
|
||||
int AsyncGetHostByName( char * szName, struct sockaddr_in &address );
|
||||
|
||||
// Convert a local filename into a temp filename to download into
|
||||
void GetDownloadFilename( const char* localname, char* downloadname);
|
||||
|
||||
void CloseSockets(void);
|
||||
void ZeroStuff(void);
|
||||
|
||||
|
||||
public:
|
||||
Cftp();
|
||||
virtual ~Cftp();
|
||||
|
||||
public:
|
||||
HRESULT ConnectToServer(LPCSTR szServerName);
|
||||
HRESULT DisconnectFromServer();
|
||||
|
||||
HRESULT LoginToServer( LPCSTR szUserName, LPCSTR szPassword );
|
||||
HRESULT LogoffFromServer( void );
|
||||
|
||||
HRESULT FindFile( LPCSTR szRemoteFileName, int * piSize );
|
||||
|
||||
HRESULT FileRecoveryPosition( LPCSTR szLocalFileName, LPCSTR szRegistryRoot );
|
||||
HRESULT RestartFrom( int i ) { m_iFilePos = i; return FTP_SUCCEEDED; };
|
||||
|
||||
HRESULT GetNextFileBlock( LPCSTR szLocalFileName, int * piTotalRead );
|
||||
|
||||
HRESULT RecvReply( LPCSTR pReplyBuffer, int iSize, int * piRetCode );
|
||||
HRESULT SendCommand( LPCSTR pCommand, int iSize );
|
||||
|
||||
};
|
||||
|
||||
#endif //__FTP_H_
|
30
Generals/Code/Libraries/Source/WWVegas/WWDownload/ftpdefs.h
Normal file
30
Generals/Code/Libraries/Source/WWVegas/WWDownload/ftpdefs.h
Normal file
|
@ -0,0 +1,30 @@
|
|||
/*
|
||||
** Command & Conquer Generals(tm)
|
||||
** Copyright 2025 Electronic Arts Inc.
|
||||
**
|
||||
** This program 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.
|
||||
**
|
||||
** This program is distributed in the hope that it will be useful,
|
||||
** but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
** GNU General Public License for more details.
|
||||
**
|
||||
** You should have received a copy of the GNU General Public License
|
||||
** along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef __FTPDEFS_H_INCLUDED__
|
||||
#define __FTPDEFS_H_INCLUDED__
|
||||
|
||||
|
||||
// CFtp return codes.
|
||||
|
||||
#define FTP_SUCCEEDED S_OK
|
||||
#define FTP_FAILED MAKE_HRESULT( SEVERITY_ERROR, FACILITY_ITF, 1 )
|
||||
#define FTP_TRYING MAKE_HRESULT( SEVERITY_ERROR, FACILITY_ITF, 2 )
|
||||
|
||||
|
||||
#endif
|
159
Generals/Code/Libraries/Source/WWVegas/WWDownload/registry.cpp
Normal file
159
Generals/Code/Libraries/Source/WWVegas/WWDownload/registry.cpp
Normal file
|
@ -0,0 +1,159 @@
|
|||
/*
|
||||
** Command & Conquer Generals(tm)
|
||||
** Copyright 2025 Electronic Arts Inc.
|
||||
**
|
||||
** This program 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.
|
||||
**
|
||||
** This program is distributed in the hope that it will be useful,
|
||||
** but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
** GNU General Public License for more details.
|
||||
**
|
||||
** You should have received a copy of the GNU General Public License
|
||||
** along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
// Registry.cpp
|
||||
// Simple interface for storing/retreiving registry values
|
||||
// Author: Matthew D. Campbell, December 2001
|
||||
|
||||
#include <string>
|
||||
|
||||
#define WIN32_LEAN_AND_MEAN
|
||||
#include <windows.h>
|
||||
|
||||
#include "Registry.h"
|
||||
|
||||
bool getStringFromRegistry(HKEY root, std::string path, std::string key, std::string& val)
|
||||
{
|
||||
HKEY handle;
|
||||
unsigned char buffer[256];
|
||||
unsigned long size = 256;
|
||||
unsigned long type;
|
||||
int returnValue;
|
||||
|
||||
if ((returnValue = RegOpenKeyEx( root, path.c_str(), 0, KEY_READ, &handle )) == ERROR_SUCCESS)
|
||||
{
|
||||
returnValue = RegQueryValueEx(handle, key.c_str(), NULL, &type, (unsigned char *) &buffer, &size);
|
||||
RegCloseKey( handle );
|
||||
}
|
||||
|
||||
if (returnValue == ERROR_SUCCESS)
|
||||
{
|
||||
val = (char *)buffer;
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool getUnsignedIntFromRegistry(HKEY root, std::string path, std::string key, unsigned int& val)
|
||||
{
|
||||
HKEY handle;
|
||||
unsigned long buffer;
|
||||
unsigned long size = sizeof(buffer);
|
||||
unsigned long type;
|
||||
int returnValue;
|
||||
|
||||
if ((returnValue = RegOpenKeyEx( root, path.c_str(), 0, KEY_READ, &handle )) == ERROR_SUCCESS)
|
||||
{
|
||||
returnValue = RegQueryValueEx(handle, key.c_str(), NULL, &type, (unsigned char *) &buffer, &size);
|
||||
RegCloseKey( handle );
|
||||
}
|
||||
|
||||
if (returnValue == ERROR_SUCCESS)
|
||||
{
|
||||
val = buffer;
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool setStringInRegistry( HKEY root, std::string path, std::string key, std::string val)
|
||||
{
|
||||
HKEY handle;
|
||||
unsigned long type;
|
||||
unsigned long returnValue;
|
||||
int size;
|
||||
|
||||
if ((returnValue = RegCreateKeyEx( root, path.c_str(), 0, "REG_NONE", REG_OPTION_NON_VOLATILE, KEY_WRITE, NULL, &handle, NULL )) == ERROR_SUCCESS)
|
||||
{
|
||||
type = REG_SZ;
|
||||
size = val.length()+1;
|
||||
returnValue = RegSetValueEx(handle, key.c_str(), 0, type, (unsigned char *)val.c_str(), size);
|
||||
RegCloseKey( handle );
|
||||
}
|
||||
|
||||
return (returnValue == ERROR_SUCCESS);
|
||||
}
|
||||
|
||||
bool setUnsignedIntInRegistry( HKEY root, std::string path, std::string key, unsigned int val)
|
||||
{
|
||||
HKEY handle;
|
||||
unsigned long type;
|
||||
unsigned long returnValue;
|
||||
int size;
|
||||
|
||||
if ((returnValue = RegCreateKeyEx( root, path.c_str(), 0, "REG_NONE", REG_OPTION_NON_VOLATILE, KEY_WRITE, NULL, &handle, NULL )) == ERROR_SUCCESS)
|
||||
{
|
||||
type = REG_DWORD;
|
||||
size = 4;
|
||||
returnValue = RegSetValueEx(handle, key.c_str(), 0, type, (unsigned char *)&val, size);
|
||||
RegCloseKey( handle );
|
||||
}
|
||||
|
||||
return (returnValue == ERROR_SUCCESS);
|
||||
}
|
||||
|
||||
bool GetStringFromRegistry(std::string path, std::string key, std::string& val)
|
||||
{
|
||||
std::string fullPath = "SOFTWARE\\Electronic Arts\\EA Games\\Generals";
|
||||
|
||||
fullPath.append(path);
|
||||
if (getStringFromRegistry(HKEY_LOCAL_MACHINE, fullPath.c_str(), key.c_str(), val))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
return getStringFromRegistry(HKEY_CURRENT_USER, fullPath.c_str(), key.c_str(), val);
|
||||
}
|
||||
|
||||
bool GetUnsignedIntFromRegistry(std::string path, std::string key, unsigned int& val)
|
||||
{
|
||||
std::string fullPath = "SOFTWARE\\Electronic Arts\\EA Games\\Generals";
|
||||
|
||||
fullPath.append(path);
|
||||
if (getUnsignedIntFromRegistry(HKEY_LOCAL_MACHINE, fullPath.c_str(), key.c_str(), val))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
return getUnsignedIntFromRegistry(HKEY_CURRENT_USER, fullPath.c_str(), key.c_str(), val);
|
||||
}
|
||||
|
||||
bool SetStringInRegistry( std::string path, std::string key, std::string val)
|
||||
{
|
||||
std::string fullPath = "SOFTWARE\\Electronic Arts\\EA Games\\Generals";
|
||||
fullPath.append(path);
|
||||
|
||||
if (setStringInRegistry( HKEY_LOCAL_MACHINE, fullPath, key, val))
|
||||
return true;
|
||||
|
||||
return setStringInRegistry( HKEY_CURRENT_USER, fullPath, key, val );
|
||||
}
|
||||
|
||||
bool SetUnsignedIntInRegistry( std::string path, std::string key, unsigned int val)
|
||||
{
|
||||
std::string fullPath = "SOFTWARE\\Electronic Arts\\EA Games\\Generals";
|
||||
fullPath.append(path);
|
||||
|
||||
if (setUnsignedIntInRegistry( HKEY_LOCAL_MACHINE, fullPath, key, val))
|
||||
return true;
|
||||
|
||||
return setUnsignedIntInRegistry( HKEY_CURRENT_USER, fullPath, key, val );
|
||||
}
|
||||
|
|
@ -0,0 +1,49 @@
|
|||
/*
|
||||
** Command & Conquer Generals(tm)
|
||||
** Copyright 2025 Electronic Arts Inc.
|
||||
**
|
||||
** This program 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.
|
||||
**
|
||||
** This program is distributed in the hope that it will be useful,
|
||||
** but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
** GNU General Public License for more details.
|
||||
**
|
||||
** You should have received a copy of the GNU General Public License
|
||||
** along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include <string>
|
||||
#include <stdio.h>
|
||||
#include "registry.h"
|
||||
|
||||
void FormatURLFromRegistry( std::string& gamePatchURL, std::string& mapPatchURL,
|
||||
std::string& configURL, std::string& motdURL )
|
||||
{
|
||||
std::string sku = "generals";
|
||||
std::string language = "english";
|
||||
unsigned int version = 0; // invalid version - can't get on with a corrupt reg.
|
||||
unsigned int mapVersion = 0; // invalid version - can't get on with a corrupt reg.
|
||||
std::string baseURL = "http://servserv.generals.ea.com/servserv/";
|
||||
baseURL.append(sku);
|
||||
baseURL.append("/");
|
||||
|
||||
GetStringFromRegistry("", "BaseURL", baseURL);
|
||||
GetStringFromRegistry("", "Language", language);
|
||||
GetUnsignedIntFromRegistry("", "Version", version);
|
||||
GetUnsignedIntFromRegistry("", "MapPackVersion", mapVersion);
|
||||
|
||||
char buf[256];
|
||||
_snprintf(buf, 256, "%s%s-%d.txt", baseURL.c_str(), language.c_str(), version);
|
||||
gamePatchURL = buf;
|
||||
_snprintf(buf, 256, "%smaps-%d.txt", baseURL.c_str(), mapVersion);
|
||||
mapPatchURL = buf;
|
||||
_snprintf(buf, 256, "%sconfig.txt", baseURL.c_str());
|
||||
configURL = buf;
|
||||
_snprintf(buf, 256, "%sMOTD-%s.txt", baseURL.c_str(), language.c_str());
|
||||
motdURL = buf;
|
||||
}
|
||||
|
|
@ -0,0 +1,24 @@
|
|||
/*
|
||||
** Command & Conquer Generals(tm)
|
||||
** Copyright 2025 Electronic Arts Inc.
|
||||
**
|
||||
** This program 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.
|
||||
**
|
||||
** This program is distributed in the hope that it will be useful,
|
||||
** but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
** GNU General Public License for more details.
|
||||
**
|
||||
** You should have received a copy of the GNU General Public License
|
||||
** along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef _URLBUILDER_H_
|
||||
#define _URLBUILDER_H_
|
||||
void FormatURLFromRegistry( std::string& gamePatchURL, std::string& mapPatchURL,
|
||||
std::string& configURL, std::string& motdURL );
|
||||
|
||||
#endif _URLBUILDER_H_
|
Reference in a new issue