| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794 |
- /*
- ** 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/>.
- */
- //
- // This module takes care of all the Chat API stuff
- //
- #include <list>
- #include "GameSpy/ghttp/ghttp.h"
- #include "downloadManager.h"
- #include "chatapi.h"
- //#include "api/wolapi_i.c" // This should only be in one .cpp file
- #include <objbase.h>
- #include <windows.h>
- #include <initguid.h>
- #include <olectl.h>
- #include <mapicode.h>
- #include "resource.h"
- #include "winblows.h"
- #include <crtdbg.h>
- #include "process.h"
- #include "WWDownload/registry.h"
- #include "WWDownload/urlBuilder.h"
- #include "debug.h"
- enum EVENT_TYPES
- {
- NOUPDATE_EVENT=0, // don't need to update
- ABORT_EVENT,
- NUM_EVENTS // keep last
- };
- HANDLE Events[NUM_EVENTS];
- char g_UpdateString[256]; // for the filename
- char g_DLTimeRem[80];
- char g_DLBytesLeft[80];
- char g_DLBPS[80];
- int g_Finished=0;
- HWND g_DownloadWindow;
- HWND g_ContactWindow;
- HWND g_PrimaryWindow;
- static bool checkingForPatch = false;
- static int checksLeft = 0;
- static bool cantConnect = false;
- static std::list<QueuedDownload> queuedDownloads;
- BOOL CALLBACK downloadDialogProc( HWND hwndDlg, UINT uMsg, WPARAM wParam,
- LPARAM lParam );
- ///////////////////////////////////////////////////////////////////////////////////////
- static void startOnline( void );
- ///////////////////////////////////////////////////////////////////////////////////////
- QueuedDownload TheDownload;
- class DownloadManagerMunkee : public DownloadManager
- {
- public:
- DownloadManagerMunkee() { }
- virtual HRESULT OnError( int error );
- virtual HRESULT OnEnd();
- virtual HRESULT OnProgressUpdate( int bytesread, int totalsize, int timetaken, int timeleft );
- virtual HRESULT OnStatusUpdate( int status );
- virtual HRESULT downloadFile( std::string server, std::string username, std::string password, std::string file, std::string localfile, std::string regkey, bool tryResume );
- };
- ///////////////////////////////////////////////////////////////////////////////////////
- HRESULT DownloadManagerMunkee::downloadFile( std::string server, std::string username, std::string password, std::string file, std::string localfile, std::string regkey, bool tryResume )
- {
- /*
- if (staticTextFile)
- {
- UnicodeString fileString;
- fileString.translate(file);
- GadgetStaticTextSetText(staticTextFile, fileString);
- }
- */
- return DownloadManager::downloadFile( server, username, password, file, localfile, regkey, tryResume );
- }
- HRESULT DownloadManagerMunkee::OnError( int error )
- {
- HRESULT ret = DownloadManager::OnError( error );
- g_Finished = -1;
- return ret;
- }
- HRESULT DownloadManagerMunkee::OnEnd()
- {
- HRESULT ret = DownloadManager::OnEnd();
- g_Finished = 1;
- return ret;
- }
- HRESULT DownloadManagerMunkee::OnProgressUpdate( int bytesread, int totalsize, int timetaken, int timeleft )
- {
- HRESULT ret = DownloadManager::OnProgressUpdate( bytesread, totalsize, timetaken, timeleft );
- SendDlgItemMessage( g_DownloadWindow, IDC_PROGRESS, PBM_SETPOS, (WPARAM)(bytesread * 100) / totalsize, 0 );
- char temp[256];
- if( timeleft > 0 )
- {
- //DBGMSG("Bytes read: "<<bytesread<<". Time left: "<<timeleft<<" seconds");
- LoadString(Global_instance, TXT_TIME_REMAIN, temp, sizeof(temp));
- sprintf(g_DLTimeRem,temp,(timeleft/60),(timeleft%60));
- LoadString(Global_instance, TXT_BPS, temp, sizeof(temp));
- sprintf(g_DLBPS,temp,bytesread/timetaken);
- }
- LoadString(Global_instance, TXT_BYTES_READ, temp, sizeof(temp));
- sprintf(g_DLBytesLeft,temp,bytesread,totalsize);
- return ret;
- }
- HRESULT DownloadManagerMunkee::OnStatusUpdate( int status )
- {
- HRESULT ret = DownloadManager::OnStatusUpdate( status );
- SetWindowText(g_DownloadWindow, getStatusString().c_str());
- return ret;
- }
- ///////////////////////////////////////////////////////////////////////////////////////
- BOOL CALLBACK simpleDialogProc( HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam )
- {
- switch( uMsg )
- {
- case WM_INITDIALOG:
- return(TRUE);
- break;
- case WM_CLOSE:
- DestroyWindow(hwnd);
- PostQuitMessage(0);
- exit(0);
- break;
- }
- return(FALSE);
- }
- static void startOnline( void )
- {
- checkingForPatch = false;
- // Close that contacting window
- DestroyWindow(g_ContactWindow);
- g_ContactWindow=NULL;
- if (cantConnect)
- {
- MessageBox(NULL, "Can't Connect", "Command and Conquer Generals", MB_OK);
- exit(0);
- }
- else if (queuedDownloads.size())
- {
- if (MessageBox(NULL, "Patches Available. Download?", "Command and Conquer Generals", MB_YESNO) == IDYES)
- {
- DEBUG_LOG(("Downloading patches\n"));
- while (queuedDownloads.size())
- {
- TheDownload = queuedDownloads.front();
- queuedDownloads.pop_front();
- TheDownloadManager = new DownloadManagerMunkee;
- /**/
- int retVal = DialogBox(Global_instance, MAKEINTRESOURCE(IDD_DOWNLOAD_DIALOG), g_PrimaryWindow, downloadDialogProc);
- if (retVal)
- {
- DEBUG_LOG(("Error %d\n", GetLastError()));
- }
- /**/
- /*
- {
- //char *res = MAKEINTRESOURCE(IDD_CONNECTING);
- char *res = MAKEINTRESOURCE(IDD_DOWNLOAD_DIALOG1);
- g_DownloadWindow=CreateDialog(Global_instance,res,g_PrimaryWindow,simpleDialogProc);
- ShowWindow(g_DownloadWindow,SW_SHOWNORMAL);
- SetForegroundWindow(g_DownloadWindow);
- }
- */
- delete TheDownloadManager;
- TheDownloadManager = NULL;
- if (g_Finished != 1)
- {
- // Download failed
- //DBGMSG("Download failed: "<<retval);
- SetEvent(Events[ABORT_EVENT]);
- return;
- }
- }
- exit(0);
- }
- else
- {
- exit(0);
- }
- }
- else
- {
- MessageBox(NULL, "No Patches Available", "Command and Conquer Generals", MB_OK);
- exit(0);
- }
- }
- ///////////////////////////////////////////////////////////////////////////////////////
- static std::string trim(std::string s, const std::string& delim)
- {
- unsigned int i;
- i = s.find_first_not_of(delim);
- if (i != s.npos)
- {
- s = s.substr(i);
- }
- i = s.find_last_not_of(delim);
- if (i>=0 && i<s.npos)
- {
- s = s.substr(0, i+1);
- }
- return s;
- }
- ///////////////////////////////////////////////////////////////////////////////////////
- static std::string getNextLine(std::string in, std::string& remainder)
- {
- int lineEnd;
- lineEnd = in.find_first_of("\n\r", 0);
- if (lineEnd < 1)
- {
- remainder = "";
- return in;
- }
- std::string out = in.substr(0, lineEnd);
- remainder = in.substr(lineEnd+1);
- remainder = trim(remainder, "\r\n\t ");
- out = trim(out, "\r\t\n ");
- }
- ///////////////////////////////////////////////////////////////////////////////////////
- //-----------------------------------------------------------------------------
- inline const char* skipSeps(const char* p, const char* seps)
- {
- while (*p && strchr(seps, *p) != NULL)
- ++p;
- return p;
- }
- //-----------------------------------------------------------------------------
- inline const char* skipNonSeps(const char* p, const char* seps)
- {
- while (*p && strchr(seps, *p) == NULL)
- ++p;
- return p;
- }
- //-----------------------------------------------------------------------------
- bool nextToken(std::string& base, std::string& tok, const char* seps = NULL)
- {
- if (base.empty())
- return false;
- if (seps == NULL)
- seps = " \n\r\t";
- const char* start = skipSeps(base.c_str(), seps);
- const char* end = skipNonSeps(start, seps);
- if (end > start)
- {
- int len = end - start;
- char* tmp = new char[len+1];
- memcpy(tmp, start, len);
- tmp[len] = 0;
- tok = tmp;
- delete[] tmp;
- base = end;
- return true;
- }
- else
- {
- base = tok = "";
- return false;
- }
- }
- ///////////////////////////////////////////////////////////////////////////////////////
- static void queuePatch(bool mandatory, std::string downloadURL)
- {
- // downloadURL is of the form "ftp://ftp.ea.com:user@pass/pub/munkee/bananna.rtp"
- QueuedDownload q;
- bool success = true;
- std::string connectionType;
- success = success && nextToken(downloadURL, connectionType, ":");
- std::string server;
- success = success && nextToken(downloadURL, server, ":/");
- std::string user;
- success = success && nextToken(downloadURL, user, ":@");
- std::string pass;
- success = success && nextToken(downloadURL, pass, "@/");
- std::string filePath;
- success = success && nextToken(downloadURL, filePath, "");
- if (!success && !user.empty())
- {
- // no user/pass combo - move the file into it's proper place
- filePath = user;
- user = ""; // LFeenanEA - Credentials removed as per Security requirements
- pass = "";
- success = true;
- }
- std::string fileStr = filePath;
- unsigned int slashPos = filePath.find_last_of('/');
- std::string fileDir = "patches\\";
- std::string fileName = "";
- if (slashPos == filePath.npos)
- {
- fileName = filePath;
- }
- else
- {
- fileName = filePath.substr(slashPos+1);
- }
- fileDir.append(fileName);
- DEBUG_LOG(("download URL split: %d [%s] [%s] [%s] [%s] [%s] [%s] [%s]\n",
- success, connectionType.c_str(), server.c_str(), user.c_str(), pass.c_str(),
- filePath.c_str(), fileName.c_str(), fileDir.c_str()));
- if (!success)
- return;
- q.file = filePath;
- q.localFile = fileDir;
- q.password = pass;
- q.regKey = "";
- q.server = server;
- q.tryResume = true;
- q.userName = user;
- std::list<QueuedDownload>::iterator it = queuedDownloads.begin();
- while (it != queuedDownloads.end())
- {
- if (it->localFile == q.localFile)
- return; // don't add it if it exists already (because we can check multiple times)
- ++it;
- }
- queuedDownloads.push_back(q);
- }
- ///////////////////////////////////////////////////////////////////////////////////////
- static GHTTPBool patchCheckCallback( GHTTPRequest request, GHTTPResult result, char * buffer, int bufferLen, void * param )
- {
- --checksLeft;
- DEBUG_ASSERTCRASH(checksLeft>=0, ("Too many callbacks"));
- DEBUG_LOG(("Result=%d, buffer=[%s], len=%d\n", result, buffer, bufferLen));
- if (result != GHTTPSuccess)
- {
- cantConnect = true;
- if (!checksLeft)
- {
- startOnline();
- }
- return GHTTPTrue;
- }
- std::string message = buffer;
- std::string line;
- while (nextToken(message, line, "\r\n"))
- {
- std::string type, req, url;
- bool ok = true;
- ok = ok && nextToken(line, type, " ");
- ok = ok && nextToken(line, req, " ");
- ok = ok && nextToken(line, url, " ");
- if (ok && type == "patch")
- {
- DEBUG_LOG(("Saw a patch: %d/[%s]\n", atoi(req.c_str()), url.c_str()));
- queuePatch( atoi(req.c_str()), url );
- }
- else if (ok && type == "server")
- {
- }
- }
- if (!checksLeft)
- {
- startOnline();
- }
- return GHTTPTrue;
- }
- ///////////////////////////////////////////////////////////////////////////////////////
- static void StartPatchCheck( void )
- {
- checkingForPatch = true;
- std::string gameURL, mapURL;
- std::string configURL, motdURL;
- FormatURLFromRegistry(gameURL, mapURL, configURL, motdURL);
- std::string proxy;
- if (GetStringFromRegistry("", "Proxy", proxy))
- {
- if (!proxy.empty())
- {
- ghttpSetProxy(proxy.c_str());
- }
- }
- // check for a patch first
- checksLeft = 2;
- cantConnect = false;
- ghttpGet(gameURL.c_str(), GHTTPFalse, patchCheckCallback, NULL);
- ghttpGet(mapURL.c_str(), GHTTPFalse, patchCheckCallback, NULL);
- DEBUG_LOG(("Started looking for patches at '%s' && '%s'\n", gameURL.c_str(), mapURL.c_str()));
- }
- ///////////////////////////////////////////////////////////////////////////////////////
- BOOL CALLBACK downloadDialogProc( HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam )
- {
- // HRESULT res;
-
- int cmd = LOWORD(wParam);
- switch( uMsg )
- {
- case WM_COMMAND:
- if ( cmd == IDC_DLABORT )
- {
-
- char abort[128];
- char abortdload[256];
- LoadString(Global_instance, TXT_ABORT_DOWNLOAD, abortdload, sizeof(abortdload));
- LoadString(Global_instance, TXT_ABORT, abort, sizeof(abort));
-
- if (MessageBox(g_PrimaryWindow,abortdload,abort,MB_YESNO)==IDYES)
- {
- TheDownloadManager->reset();
-
- EndDialog( hwndDlg, g_Finished );
- DestroyWindow(hwndDlg);
- }
- }
- else
- {
- return FALSE;
- }
- break;
-
- case WM_INITDIALOG:
- //SetupDownload();
-
- SendMessage(hwndDlg, WM_SETICON,(WPARAM)ICON_SMALL,
- (LPARAM)LoadIcon(Global_instance, MAKEINTRESOURCE(IDI_ICON1)));
-
- g_DLTimeRem[0]=0;
- g_DLBytesLeft[0]=0;
- g_DLBPS[0]=0;
-
- //SetDlgItemText( hwndDlg, IDC_DOWNLOADTITLE, g_UpdateString);
- //SetWindowText(hwndDlg, g_UpdateString);
-
- SetDlgItemText( hwndDlg, IDC_TIMEREM, g_DLTimeRem);
- SetDlgItemText( hwndDlg, IDC_BYTESLEFT, g_DLBytesLeft);
- // SetDlgItemText( hwndDlg, IDC_BPS, g_DLBPS );
-
- // Work out the full file name
- //char fullpath[_MAX_PATH];
- //char localfile[_MAX_PATH];
- //sprintf( fullpath, "%s/%s", g_Update->patchpath,g_Update->patchfile);
- //sprintf(localfile,"%s\\%s",g_Update->localpath,g_Update->patchfile);
-
- // Create the directory
- //CreateDirectory((char *)g_Update->localpath, NULL );
-
- TheDownloadManager->downloadFile(TheDownload.server, TheDownload.userName, TheDownload.password,
- TheDownload.file, TheDownload.localFile, TheDownload.regKey, TheDownload.tryResume);
- /*
- res=pDownload->DownloadFile((char *)g_Update->server, (char *)g_Update->login, (char *)g_Update->password,
- fullpath, localfile, APP_REG_KEY);
-
- */
- g_DownloadWindow = hwndDlg;
- g_Finished = 0;
- SetTimer( hwndDlg, 1, 200, NULL ); // was 50
-
- break;
-
- case WM_TIMER:
- DEBUG_LOG(("TIMER\n"));
- if( g_Finished == 0 )
- {
- DEBUG_LOG(("Entering PumpMsgs\n"));
- TheDownloadManager->update();
- /*
- pDownload->PumpMessages();
- */
- DEBUG_LOG(("Done with PumpMsgs\n"));
- if (strlen(g_DLTimeRem))
- SetDlgItemText( hwndDlg, IDC_TIMEREM, g_DLTimeRem );
- if (strlen(g_DLBytesLeft))
- SetDlgItemText( hwndDlg, IDC_BYTESLEFT, g_DLBytesLeft );
- //if (strlen(g_DLBPS))
- // SetDlgItemText( hwndDlg, IDC_BPS, g_DLBPS );
- }
- else
- {
- DEBUG_LOG(("TIMER: Finished\n"));
- EndDialog( hwndDlg, g_Finished );
- DestroyWindow( hwndDlg );
- }
- break;
-
- case WM_DESTROY:
- KillTimer( hwndDlg, 1 );
- //ClosedownDownload();
-
- //DBGMSG("WM_DESTROY");
- break;
-
- case WM_SETFONT:
- return TRUE;
-
- default:
- return FALSE;
- }
- return TRUE;
- }
- DWORD dwChatAdvise;
- DWORD dwDownloadAdvise;
- //Update *g_Update;
- uint32 g_AppVer=-1;
- BOOL CALLBACK Download_Dialog_Proc( HWND hwndDlg, UINT uMsg, WPARAM wParam,
- LPARAM lParam );
- BOOL CALLBACK Simple_Dialog_Proc( HWND hwndDlg, UINT uMsg, WPARAM wParam,
- LPARAM lParam );
- HWND CreatePrimaryWin(void);
- char const * Fetch_String(int id);
- //
- // Create a primary window
- //
- HWND CreatePrimaryWin(void)
- {
- HWND hwnd;
- WNDCLASS wc;
- char name[256];
- sprintf(name,Fetch_String(TXT_TITLE));
- //DBGMSG("CreatePrimary: "<<name);
- /*
- ** set up and register window class
- */
- wc.style = CS_HREDRAW | CS_VREDRAW;
- wc.lpfnWndProc = DefWindowProc;
- wc.cbClsExtra = 0; // Don't need any extra class data
- wc.cbWndExtra = 0; // No extra win data
- wc.hInstance = Global_instance;
- wc.hIcon=LoadIcon(Global_instance, MAKEINTRESOURCE(IDI_ICON1));
- wc.hCursor = NULL; /////////LoadCursor( NULL, IDC_ARROW );
- wc.hbrBackground = NULL;
- wc.lpszMenuName = name;
- wc.lpszClassName = name;
- RegisterClass( &wc );
-
- /*
- ** create a window
- */
- hwnd = CreateWindowEx(
- WS_EX_APPWINDOW,
- name,
- name,
- WS_POPUP,
- 0, 0,
- //GetSystemMetrics( SM_CXSCREEN ),
- //GetSystemMetrics( SM_CYSCREEN ),
- 0,0,
- NULL,
- NULL,
- Global_instance,
- NULL );
- SendMessage(hwnd,WM_SETICON,(WPARAM)ICON_SMALL,
- (LPARAM)LoadIcon(Global_instance, MAKEINTRESOURCE(IDI_ICON1)));
- ShowWindow(hwnd,SW_SHOWNORMAL);
- return(hwnd);
- }
- //
- // Dispatch pending windows events
- //
- void DispatchEvents(void)
- {
- MSG msg;
- int counter=0;
- while(PeekMessage(&msg,NULL,0,0, PM_REMOVE))
- {
- TranslateMessage(&msg);
- DispatchMessage(&msg);
- counter++;
- if (counter==256) // just in case
- break;
- }
- }
- //
- // Check for patches
- //
- int main(int argc, char *argv[])
- {
- InitCommonControls();
- /*
- g_PrimaryWindow=CreatePrimaryWin(); // Create the main window
- DispatchEvents(); // process some win messages
- */
- /*
- // Check if they've registered before, if not ask them if they want to
- bool have_registered=false;
- if (RegOpenKeyEx(HKEY_LOCAL_MACHINE,REGISTER_REG_KEY,0,KEY_READ,&rKey)==ERROR_SUCCESS)
- {
- char username[64];
- valuesize=sizeof(username);
- if (RegQueryValueEx(rKey,"UserName",NULL,&type,(uint8 *)username,&valuesize)==ERROR_SUCCESS)
- have_registered=true;
- RegCloseKey(rKey);
- }
- if (!have_registered)
- {
- if (RegOpenKeyEx(HKEY_CLASSES_ROOT,NICK_REG_KEY,0,KEY_READ,&rKey)==ERROR_SUCCESS)
- {
- have_registered=true;
- RegCloseKey(rKey);
- }
- }
- if (!have_registered)
- {
- if (MessageBox(NULL,Fetch_String(TXT_REGNOW),Fetch_String(TXT_TITLE),MB_YESNO)==IDNO)
- have_registered=true; // pretend they've alredy registered
- }
- if (!have_registered)
- {
- // figure out where the registration app is installed & launch it, continue
- // after it exits.
- if (RegOpenKeyEx(HKEY_LOCAL_MACHINE,REGISTER_REG_APP,0,KEY_READ,&rKey)==ERROR_SUCCESS)
- {
- char regapp[300];
- valuesize=sizeof(regapp);
- if ((RegQueryValueEx(rKey,"InstallPath",NULL,&type,(uint8 *)regapp,&valuesize)==ERROR_SUCCESS)&&
- (strlen(regapp) > 8))
- {
- // Launch the process
- SHELLEXECUTEINFO info;
- memset(&info,0,sizeof(info));
- info.cbSize=sizeof(info);
- info.fMask=SEE_MASK_NOCLOSEPROCESS;
- info.hwnd=g_PrimaryWindow;
- info.lpVerb=NULL;
- info.lpFile=regapp;
- info.lpParameters=NULL;
- info.lpDirectory=".";
- info.nShow=SW_SHOW;
- ShellExecuteEx(&info);
- // Can't wait infinite or the other process will never create its window
- // Only Bill himself knows why this is happening
- while(1) // Wait for completion
- {
- DispatchEvents();
- if (WaitForSingleObject(info.hProcess,500)!=WAIT_TIMEOUT)
- break;
- }
- }
- RegCloseKey(rKey);
- }
- }
- // OK, done with that crap go on to the task at hand now....
- */
- // Find the game version
- g_AppVer = -1;
- if (!GetUnsignedIntFromRegistry("", "Version", g_AppVer))
- {
- MessageBox(g_PrimaryWindow,Fetch_String(TXT_INSTALL_PROBLEM),Fetch_String(TXT_ERROR),MB_OK);
- exit(0);
- }
- // OK, have the current game version now
- g_PrimaryWindow=CreatePrimaryWin(); // Create the main window
- DispatchEvents(); // process some win messages
- // Popup the "contacting" window
- g_ContactWindow=CreateDialog(Global_instance,MAKEINTRESOURCE(IDD_CONNECTING),g_PrimaryWindow,Simple_Dialog_Proc);
- ShowWindow(g_ContactWindow,SW_SHOWNORMAL);
- SetForegroundWindow(g_ContactWindow);
- DispatchEvents(); // process some win messages
- // Setup the Westwood Online stuff
- Startup_Chat();
- Update_If_Required();
- Shutdown_Chat();
- return(0);
- }
- typedef struct SRecord {
- int ID; // ID number of the string resource.
- int TimeStamp; // 'Time' that this string was last requested.
- char String[2048]; // Copy of string resource.
- SRecord(void) : ID(-1), TimeStamp(-1) {}
- } SRecord;
- /***********************************************************************************************
- * Fetch_String -- Fetches a string resource. *
- * *
- * Fetches a string resource and returns a pointer to its text. *
- * *
- * INPUT: id -- The ID number of the string resource to fetch. *
- * *
- * OUTPUT: Returns with a pointer to the actual text of the string resource. *
- * *
- * WARNINGS: none *
- * *
- * HISTORY: *
- * 12/25/1996 JLB : Created. *
- *=============================================================================================*/
- char const * Fetch_String(int id)
- {
- static SRecord _buffers[64];
- static int _time = 0;
- /*
- ** Determine if the string ID requested is valid. If not then return an empty string pointer.
- */
- if (id == -1 || id == TXT_NONE) return("");
- /*
- ** Adjust the 'time stamp' tracking value. This is an artificial value used merely to track
- ** the relative age of the strings requested.
- */
- _time = _time+1;
- /*
- ** Check to see if the requested string has already been fetched into a buffer. If so, then
- ** return a pointer to that string (update the time stamp as well).
- */
- for (int index = 0; index < ARRAY_SIZE(_buffers); index++) {
- if (_buffers[index].ID == id) {
- _buffers[index].TimeStamp = _time;
- return(_buffers[index].String);
- }
- }
- /*
- ** Find a suitable buffer to hold the string to be fetched. The buffer should either be
- ** empty or have the oldest fetched string.
- */
- int oldest = -1;
- int oldtime = -1;
- for (int text = 0; text < ARRAY_SIZE(_buffers); text++) {
- if (oldest == -1 || oldtime > _buffers[text].TimeStamp) {
- oldest = text;
- oldtime = _buffers[text].TimeStamp;
- if (oldtime == -1 || _buffers[text].ID == -1) break;
- }
- }
- /*
- ** A suitable buffer has been found so fetch the string resource and then return a pointer
- ** to the string.
- */
- char * stringptr = _buffers[oldest].String;
- _buffers[oldest].ID = id;
- _buffers[oldest].TimeStamp = _time;
-
- if (LoadString(Global_instance, id, stringptr, sizeof(_buffers[oldest].String)) == 0) {
- return("");
- }
-
- /******
- char resname[32];
- sprintf(resname,"#%d",id);
- HMODULE hmod=GetModuleHandle(NULL);
- HRSRC hrsrc=FindResourceEx(hmod, RT_STRING, MAKEINTRESOURCE(id), LANGID);
- if (hrsrc==0)
- {
- char message_buffer[256];
- FormatMessage( FORMAT_MESSAGE_FROM_SYSTEM, NULL, GetLastError(), MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), &message_buffer[0], 256, NULL );
-
- }
- HGLOBAL resdata=LoadResource(NULL,hrsrc);
- LPVOID vdata=LockResource(resdata);
- strcpy(stringptr,(char *)vdata);
- *********/
- stringptr[sizeof(_buffers[oldest].String)-1] = '\0';
- return(stringptr);
- }
- void LogMsg(char *msg)
- {
- #ifdef _DEBUG
- FILE *out=fopen("register.log","a");
- fprintf(out,"%s\n",msg);
- fflush(out);
- fclose(out);
- #endif
- }
- void Startup_Chat(void)
- {
- /*
- //////CComObject<CChatEventSink>* g_pChatSink;
- HRESULT hRes;
- g_pChatSink=NULL;
- CoCreateInstance(CLSID_Chat, NULL, CLSCTX_INPROC_SERVER,
- IID_IChat, (void**)&pChat);
- if (pChat==NULL)
- {
- char error[128];
- char apimissing[256];
- LoadString(Global_instance, TXT_API_MISSING, apimissing, sizeof(apimissing));
- LoadString(Global_instance, TXT_ERROR, error, sizeof(error));
- MessageBox(g_PrimaryWindow,apimissing,error,MB_OK);
- exit(-5);
- }
- g_pChatSink=new CChatEventSink;
- // Get a connection point from the chat class
- IConnectionPoint *pConnectionPoint=NULL;
- IConnectionPointContainer *pContainer=NULL;
- dwChatAdvise=0;
- hRes=pChat->QueryInterface(IID_IConnectionPointContainer,(void**)&pContainer);
- _ASSERTE(SUCCEEDED(hRes));
- hRes=pContainer->FindConnectionPoint(IID_IChatEvent,&pConnectionPoint);
- _ASSERTE(SUCCEEDED(hRes));
- hRes=pConnectionPoint->Advise((IChatEvent *)g_pChatSink,&dwChatAdvise);
- _ASSERTE(SUCCEEDED(hRes));
- pChat->SetAttributeValue("RegPath",APP_REG_KEY);
- // ADD pConnectionPoint->Release();
- */
- }
- void Shutdown_Chat(void)
- {
- /*
- /////AtlUnadvise(pChat, IID_IChatEvent, dwChatAdvise);
- IConnectionPoint *pConnectionPoint=NULL;
- IConnectionPointContainer *pContainer=NULL;
- HRESULT hRes;
- hRes=pChat->QueryInterface(IID_IConnectionPointContainer,(void**)&pContainer);
- _ASSERTE(SUCCEEDED(hRes));
- hRes=pContainer->FindConnectionPoint(IID_IChatEvent,&pConnectionPoint);
- _ASSERTE(SUCCEEDED(hRes));
- pConnectionPoint->Unadvise(dwChatAdvise);
- pChat->Release();
- /////delete(g_pChatSink); This appears to be bad....
- // ADD g_pChatSink->Release();
- // ADD pConnectionPoint->Release();
- // ADD pContainer->Release();
- */
- }
- //
- // Download a patch for the registration client if required
- // This uses the chat API for ver checking and FTP.
- //
- void Update_If_Required(void)
- {
- int retval;
- int i;
- // Create the events
- for (i=0; i<NUM_EVENTS; i++)
- Events[i]=CreateEvent(NULL,FALSE,FALSE,NULL);
- StartPatchCheck();
- while (1)
- {
- ghttpThink();
- MSG msg;
- while(PeekMessage(&msg,NULL,0,0, PM_REMOVE))
- {
- TranslateMessage(&msg);
- DispatchMessage(&msg);
- }
- retval=WaitForMultipleObjectsEx(NUM_EVENTS,Events,FALSE,50,FALSE);
- if (retval==WAIT_TIMEOUT)
- continue;
- //DBGMSG("An event was set");
- retval-=WAIT_OBJECT_0;
- break;
- }
- //DBGMSG("Out of the loop")
- if (retval==ABORT_EVENT)
- {
- exit(0);
- }
- else
- {
- //DBGMSG("NO update required");
- }
- //DBGMSG("Shutting down");
- // close all the event objects
- for (i=0; i<NUM_EVENTS; i++)
- CloseHandle(Events[i]);
- /*
- Startup_Chat();
- int retval;
- int i;
- // Create the events
- for (i=0; i<NUM_EVENTS; i++)
- Events[i]=CreateEvent(NULL,FALSE,FALSE,NULL);
- /// For Testing....
- ///pChat->RequestServerList(1000,262364,"register","regpas98",15);
- ///pChat->RequestServerList(1000,300,"register","regpas98",15);
- pChat->RequestServerList(g_AppSku,g_AppVer,"register","regpas98",40);
- while(1)
- {
- pChat->PumpMessages();
- MSG msg;
- while(PeekMessage(&msg,NULL,0,0, PM_REMOVE))
- {
- TranslateMessage(&msg);
- DispatchMessage(&msg);
- }
- retval=WaitForMultipleObjectsEx(NUM_EVENTS,Events,FALSE,50,FALSE);
- if (retval==WAIT_TIMEOUT)
- continue;
- //DBGMSG("An event was set");
- retval-=WAIT_OBJECT_0;
- break;
- }
- //DBGMSG("Out of the loop")
- if (retval==ABORT_EVENT)
- {
- exit(0);
- }
- else
- {
- //DBGMSG("NO update required");
- }
- //DBGMSG("Shutting down");
- // close all the event objects
- for (i=0; i<NUM_EVENTS; i++)
- CloseHandle(Events[i]);
- Shutdown_Chat();
- */
- }
- /*
- CChatEventSink::CChatEventSink()
- {
- m_cRef=0; // init the refrence count
- }
- ///////////////////////////////////////////////////////////
- //
- // Interface IUnknown Methods
- //
- ///////////////////////////////////////////////////////////
- //
- // QueryInterface
- //
- HRESULT __stdcall
- CChatEventSink::QueryInterface(const IID& iid, void** ppv)
- {
- if ((iid == IID_IUnknown) ||(iid == IID_IChatEvent))
- {
- *ppv = static_cast<IChatEvent*>(this) ;
- }
- else
- {
- *ppv = NULL;
- return E_NOINTERFACE;
- }
- (reinterpret_cast<IUnknown*>(*ppv))->AddRef() ;
- return S_OK ;
- }
- ///////////////////////////////////////////////////////////
- //
- // AddRef
- //
- ULONG __stdcall
- CChatEventSink::AddRef()
- {
- return InterlockedIncrement(&m_cRef) ;
- }
- ///////////////////////////////////////////////////////////
- //
- // Release
- //
- ULONG __stdcall
- CChatEventSink::Release()
- {
- if (InterlockedDecrement(&m_cRef) == 0)
- {
- delete this ;
- return 0 ;
- }
- return m_cRef;
- }
- ///// DOWNLOAD
- CDownloadEventSink::CDownloadEventSink()
- {
- m_cRef=0; // Ref counter
- }
- ///////////////////////////////////////////////////////////
- //
- // Interface IUnknown Methods
- //
- ///////////////////////////////////////////////////////////
- //
- // QueryInterface
- //
- HRESULT __stdcall
- CDownloadEventSink::QueryInterface(const IID& iid, void** ppv)
- {
- if ((iid == IID_IUnknown) ||(iid == IID_IDownloadEvent))
- {
- *ppv = static_cast<IDownloadEvent*>(this) ;
- }
- else
- {
- *ppv = NULL;
- return E_NOINTERFACE;
- }
- (reinterpret_cast<IUnknown*>(*ppv))->AddRef() ;
- return S_OK ;
- }
- ///////////////////////////////////////////////////////////
- //
- // AddRef
- //
- ULONG __stdcall
- CDownloadEventSink::AddRef()
- {
- return InterlockedIncrement(&m_cRef) ;
- }
- ///////////////////////////////////////////////////////////
- //
- // Release
- //
- ULONG __stdcall
- CDownloadEventSink::Release()
- {
- if (InterlockedDecrement(&m_cRef) == 0)
- {
- delete this ;
- return 0 ;
- }
- return m_cRef;
- }
- */
- //// FTP Download stuff
- void SetupDownload( void )
- {
- /*
- HRESULT hRes;
- g_pDownloadSink=NULL;
- CoCreateInstance(CLSID_Download, NULL, CLSCTX_INPROC_SERVER,
- IID_IDownload, (void**)&pDownload);
- _ASSERTE(pDownload);
- g_pDownloadSink=new CDownloadEventSink;
- // Get a connection point from the chat class
- IConnectionPoint *pConnectionPoint=NULL;
- IConnectionPointContainer *pContainer=NULL;
- dwDownloadAdvise = 0;
- hRes=pDownload->QueryInterface(IID_IConnectionPointContainer,(void**)&pContainer);
- _ASSERTE(SUCCEEDED(hRes));
- hRes=pContainer->FindConnectionPoint(IID_IDownloadEvent,&pConnectionPoint);
- _ASSERTE(SUCCEEDED(hRes));
- hRes=pConnectionPoint->Advise((IDownloadEvent *)g_pDownloadSink,&dwDownloadAdvise);
- _ASSERTE(SUCCEEDED(hRes));
- */
- }
- void ClosedownDownload( void )
- {
- /*
- // AtlUnadvise(pDownload, IID_IDownloadEvent, dwDownloadAdvise);
- IConnectionPoint *pConnectionPoint=NULL;
- IConnectionPointContainer *pContainer=NULL;
- HRESULT hRes;
- hRes=pDownload->QueryInterface(IID_IConnectionPointContainer,(void**)&pContainer);
- _ASSERTE(SUCCEEDED(hRes));
- hRes=pContainer->FindConnectionPoint(IID_IDownloadEvent,&pConnectionPoint);
- _ASSERTE(SUCCEEDED(hRes));
- pConnectionPoint->Unadvise(dwDownloadAdvise);
- pDownload->Release();
- //////delete(g_pDownloadSink); This appears to be bad....
- */
- }
- BOOL CALLBACK Download_Dialog_Proc( HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam )
- {
- // char fullpath[ 256 ];
- // char localfile[ 256];
- // HRESULT res;
- switch( uMsg )
- {
- case WM_COMMAND:
- switch( LOWORD( wParam ) )
- {
- case IDC_DLABORT:
- {
- char abort[128];
- char abortdload[256];
- LoadString(Global_instance, TXT_ABORT_DOWNLOAD, abortdload, sizeof(abortdload));
- LoadString(Global_instance, TXT_ABORT, abort, sizeof(abort));
- if (MessageBox(g_PrimaryWindow,abortdload,abort,MB_YESNO)==IDYES)
- {
- /*
- pDownload->Abort();
- */
- EndDialog( hwndDlg, g_Finished );
- DestroyWindow(hwndDlg);
- }
- }
- break;
- default:
- return FALSE;
- }
- break;
- case WM_INITDIALOG:
- SetupDownload();
- SendMessage(hwndDlg, WM_SETICON,(WPARAM)ICON_SMALL,
- (LPARAM)LoadIcon(Global_instance, MAKEINTRESOURCE(IDI_ICON1)));
- g_DLTimeRem[0]=0;
- g_DLBytesLeft[0]=0;
- g_DLBPS[0]=0;
- //SetDlgItemText( hwndDlg, IDC_DOWNLOADTITLE, g_UpdateString);
- //SetWindowText(hwndDlg, g_UpdateString);
- SetDlgItemText( hwndDlg, IDC_TIMEREM, g_DLTimeRem);
- SetDlgItemText( hwndDlg, IDC_BYTESLEFT, g_DLBytesLeft);
- // SetDlgItemText( hwndDlg, IDC_BPS, g_DLBPS );
- /*
- // Work out the full file name
- sprintf( fullpath, "%s/%s", g_Update->patchpath,g_Update->patchfile);
- sprintf(localfile,"%s\\%s",g_Update->localpath,g_Update->patchfile);
- // Create the directory
- CreateDirectory((char *)g_Update->localpath, NULL );
- res=pDownload->DownloadFile((char *)g_Update->server, (char *)g_Update->login, (char *)g_Update->password,
- fullpath, localfile, APP_REG_KEY);
- */
- g_DownloadWindow = hwndDlg;
- g_Finished = 0;
- SetTimer( hwndDlg, 1, 200, NULL ); // was 50
- break;
- case WM_TIMER:
- LogMsg("TIMER");
- if( g_Finished == 0 )
- {
- LogMsg("Entering PumpMsgs");
- /*
- pDownload->PumpMessages();
- */
- LogMsg("Done with PumpMsgs");
- if (strlen(g_DLTimeRem))
- SetDlgItemText( hwndDlg, IDC_TIMEREM, g_DLTimeRem );
- if (strlen(g_DLBytesLeft))
- SetDlgItemText( hwndDlg, IDC_BYTESLEFT, g_DLBytesLeft );
- //if (strlen(g_DLBPS))
- // SetDlgItemText( hwndDlg, IDC_BPS, g_DLBPS );
- }
- else
- {
- LogMsg("TIMER: Finished");
- EndDialog( hwndDlg, g_Finished );
- DestroyWindow( hwndDlg );
- }
- break;
- case WM_DESTROY:
- KillTimer( hwndDlg, 1 );
- ClosedownDownload();
- //DBGMSG("WM_DESTROY");
- break;
- case WM_SETFONT:
- return TRUE;
- default:
- return FALSE;
- }
- return TRUE;
- }
- // Whoeee this is an exciting one...
- BOOL CALLBACK Simple_Dialog_Proc( HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam )
- {
- switch( uMsg )
- {
- case WM_INITDIALOG:
- return(TRUE);
- break;
- case WM_CLOSE:
- DestroyWindow(hwnd);
- PostQuitMessage(0);
- exit(0);
- break;
- }
- return(FALSE);
- }
- /////////////////////////////////////////////////////////////////////////////
- // CDownloadEventSink
- //////////////////////////////////////////////////////////////////////////////
- /*
- STDMETHODIMP CDownloadEventSink::OnEnd(void)
- {
- LogMsg("Finished!");
- g_Finished = 1;
- return(S_OK);
- }
- STDMETHODIMP CDownloadEventSink::OnError(int error)
- {
- LogMsg("ERROR");
- g_Finished = -1;
- return(S_OK);
- }
- STDMETHODIMP CDownloadEventSink::OnProgressUpdate(int bytesread, int totalsize,
- int timetaken, int timeleft)
- {
- SendDlgItemMessage( g_DownloadWindow, IDC_PROGRESS, PBM_SETPOS, (WPARAM)(bytesread * 100) / totalsize, 0 );
- char temp[256];
- if( timeleft > 0 )
- {
- //DBGMSG("Bytes read: "<<bytesread<<". Time left: "<<timeleft<<" seconds");
- LoadString(Global_instance, TXT_TIME_REMAIN, temp, sizeof(temp));
- sprintf(g_DLTimeRem,temp,(timeleft/60),(timeleft%60));
- LoadString(Global_instance, TXT_BPS, temp, sizeof(temp));
- sprintf(g_DLBPS,temp,bytesread/timetaken);
- }
- LoadString(Global_instance, TXT_BYTES_READ, temp, sizeof(temp));
- sprintf(g_DLBytesLeft,temp,bytesread,totalsize);
- return(S_OK);
- }
- STDMETHODIMP CDownloadEventSink::OnStatusUpdate(int status)
- {
- switch( status )
- {
- case DOWNLOADSTATUS_CONNECTING:
- {
- //LogMsg( "Connecting..." );
- SetWindowText(g_DownloadWindow, Fetch_String(TXT_CONNECTING));
- }
- break;
- case DOWNLOADSTATUS_FINDINGFILE:
- //LogMsg( "Finding patch..." );
- SetWindowText(g_DownloadWindow, g_UpdateString);
- break;
- case DOWNLOADSTATUS_DOWNLOADING:
- //LogMsg( "Downloading patch..." );
- SetWindowText(g_DownloadWindow, g_UpdateString);
- break;
- default:
- //LogMsg("Unknown status update!");
- break;
- }
- return(S_OK);
- }
- //
- // Just tell the FTP module to go ahead and resume
- //
- STDMETHODIMP CDownloadEventSink::OnQueryResume(void)
- {
- return(DOWNLOADEVENT_RESUME);
- }
- /////////////////////////////////////////////////////////////////////////////
- // CChatEventSink
- //////////////////////////////////////////////////////////////////////////////
- STDMETHODIMP CChatEventSink::OnServerList(HRESULT res, Server* servers)
- {
- // If we get this, then we don't need to patch
- // Close that contacting window
- DestroyWindow(g_ContactWindow);
- g_ContactWindow=NULL;
- LogMsg("Server List");
- MessageBox(g_PrimaryWindow,Fetch_String(TXT_NO_PATCHES),Fetch_String(TXT_AUTO_UPDATE),MB_OK);
- SetEvent(Events[NOUPDATE_EVENT]);
- return(S_OK);
- }
- STDMETHODIMP CChatEventSink::OnServerBannedYou(HRESULT, time_t)
- {
- return(S_OK);
- }
- STDMETHODIMP CChatEventSink::OnPageSend(HRESULT)
- {
- return(S_OK);
- }
- STDMETHODIMP CChatEventSink::OnPaged(HRESULT, User *, LPCSTR)
- {
- return(S_OK);
- }
- STDMETHODIMP CChatEventSink::OnFind(HRESULT, Channel *)
- {
- return(S_OK);
- }
- STDMETHODIMP CChatEventSink::OnLogout(HRESULT, User *)
- {
- return(S_OK);
- }
- STDMETHODIMP CChatEventSink::OnBusy(HRESULT)
- {
- return(S_OK);
- }
- STDMETHODIMP CChatEventSink::OnIdle(HRESULT)
- {
- return(S_OK);
- }
- STDMETHODIMP CChatEventSink::OnConnection(HRESULT, LPCSTR)
- {
- return(S_OK);
- }
- STDMETHODIMP CChatEventSink::OnUserFlags(HRESULT,LPCSTR,unsigned int, unsigned int)
- {
- return(S_OK);
- }
- STDMETHODIMP CChatEventSink::OnChannelCreate(HRESULT, Channel *)
- {
- return(S_OK);
- }
- STDMETHODIMP CChatEventSink::OnChannelModify(HRESULT, Channel *)
- {
- return(S_OK);
- }
- STDMETHODIMP CChatEventSink::OnChannelJoin(HRESULT, Channel *, User *)
- {
- return(S_OK);
- }
- STDMETHODIMP CChatEventSink::OnChannelLeave(HRESULT, Channel *, User *)
- {
- return(S_OK);
- }
- STDMETHODIMP CChatEventSink::OnChannelTopic(HRESULT, Channel *, LPCSTR)
- {
- return(S_OK);
- }
- STDMETHODIMP CChatEventSink::OnChannelBan(HRESULT, LPCSTR, int)
- {
- return(S_OK);
- }
- STDMETHODIMP CChatEventSink::OnGroupList(HRESULT, Group *)
- {
- return(S_OK);
- }
- STDMETHODIMP CChatEventSink::OnPublicMessage(HRESULT, Channel *, User *, LPCSTR)
- {
- return(S_OK);
- }
- STDMETHODIMP CChatEventSink::OnPrivateMessage(HRESULT, User *,LPCSTR)
- {
- return(S_OK);
- }
- STDMETHODIMP CChatEventSink::OnSystemMessage(HRESULT, LPCSTR)
- {
- return(S_OK);
- }
- STDMETHODIMP CChatEventSink::OnUserLocale(long, struct User *)
- {
- return(S_OK);
- }
- STDMETHODIMP CChatEventSink::OnUserTeam(long, struct User *)
- {
- return(S_OK);
- }
- STDMETHODIMP CChatEventSink::OnSetLocale(long, enum Locale)
- {
- return(S_OK);
- }
- STDMETHODIMP CChatEventSink::OnSetTeam(long, int)
- {
- return(S_OK);
- }
- STDMETHODIMP CChatEventSink::OnNetStatus(HRESULT hr)
- {
- char string[60];
- sprintf(string,"NetStatus %ld",hr);
- LogMsg(string);
- if ((hr==CHAT_E_CON_NETDOWN)||(hr==CHAT_E_CON_LOOKUP_FAILED)||
- (hr==CHAT_E_CON_ERROR)||(hr==CHAT_E_TIMEOUT))
- {
- char error[128];
- char cantconn[256];
- LoadString(Global_instance, TXT_CANT_CONTACT, cantconn, sizeof(cantconn));
- LoadString(Global_instance, TXT_ERROR, error, sizeof(error));
- MessageBox(g_PrimaryWindow,cantconn,error,MB_OK);
- exit(-1);
- }
- return(S_OK);
- }
- STDMETHODIMP CChatEventSink::OnChannelList(HRESULT, Channel*)
- {
- return(S_OK);
- }
- STDMETHODIMP CChatEventSink::OnUserList(HRESULT, Channel*, User*)
- {
- return(S_OK);
- }
- //
- // We got a list of updates to apply
- //
- STDMETHODIMP CChatEventSink::OnUpdateList(HRESULT r, Update * updates)
- {
- Update *tmp;
- int numupdates=0;
- int i=0;
- int retval;
- static int alreadyGotOne=0;
- LogMsg("Update list");
- // Close that contacting window
- DestroyWindow(g_ContactWindow);
- g_ContactWindow=NULL;
- if( FAILED(r) )
- {
- LogMsg("Failed");
- SetEvent(Events[ABORT_EVENT]); // An error occurred, bail out
- }
- if( updates == NULL ) // shouldn't happen
- return S_OK;
- if (alreadyGotOne) // Should only get one update list
- return(S_OK);
- alreadyGotOne=1;
- // Count the updates;
- tmp = updates;
- while( tmp != NULL )
- {
- tmp = tmp->next;
- numupdates++;
- }
- // Got a list of updates - If an update is required, the user must either
- // patch or quit.
- tmp = updates;
- LogMsg("Found an update");
- // We have a required update
- char upreq[256];
- char title[128];
- LoadString(Global_instance, TXT_AN_UPGRADE_AVAILABLE, upreq, sizeof(upreq));
- strcat(upreq,"\n");
- LoadString(Global_instance, TXT_DOWNLOAD_NOW, upreq+strlen(upreq), sizeof(upreq));
- LoadString(Global_instance, TXT_UPGRADE_AVAILABLE, title, sizeof(title));
- if( MessageBox(g_PrimaryWindow,upreq,title, MB_YESNO ) == IDNO )
- {
- // If they don't want to patch now, just exit...
- //DBGMSG("Must patch to continue, so exit");
- exit(0);
- }
- // Do the downloads
- while( tmp != NULL )
- {
- g_Update = tmp;
- char dloading[256];
- LoadString(Global_instance, TXT_DOWNLOADING_FILE, dloading, sizeof(dloading));
- sprintf( g_UpdateString, dloading, ++i, numupdates );
- LogMsg("Creating Download dialog box");
- //if( (retval=DialogBox(Global_instance, MAKEINTRESOURCE(IDD_DOWNLOAD_DIALOG), g_PrimaryWindow,
- // (DLGPROC)Download_Dialog_Proc)) != 1 )
- retval=DialogBox(Global_instance, MAKEINTRESOURCE(IDD_DOWNLOAD_DIALOG), g_PrimaryWindow,(DLGPROC)Download_Dialog_Proc);
- if (g_Finished != 1)
- {
- // Download failed
- //DBGMSG("Download failed: "<<retval);
- SetEvent(Events[ABORT_EVENT]);
- return(E_FAIL);
- }
- tmp = tmp->next;
- }
- // Quit so the launcher can apply the patches
- exit(0);
- return(S_OK); // make silly compiler happy
- }
- STDMETHODIMP CChatEventSink::OnServerError(HRESULT, LPCSTR)
- {
- LogMsg("Server Error");
- return(S_OK);
- }
- STDMETHODIMP CChatEventSink::OnMessageOfTheDay(HRESULT, LPCSTR)
- {
- return(S_OK);
- }
- STDMETHODIMP CChatEventSink::OnPrivateAction(HRESULT, User *, LPCSTR)
- {
- return(S_OK);
- }
- STDMETHODIMP CChatEventSink::OnPublicAction(HRESULT, Channel *, User *, LPCSTR)
- {
- return(S_OK);
- }
- STDMETHODIMP CChatEventSink::OnPrivateGameOptions(HRESULT, User *, LPCSTR)
- {
- return(S_OK);
- }
- STDMETHODIMP CChatEventSink::OnPublicGameOptions(HRESULT, Channel *, User *, LPCSTR)
- {
- return(S_OK);
- }
- STDMETHODIMP CChatEventSink::OnGameStart(HRESULT, Channel *, User *, int)
- {
- return(S_OK);
- }
- STDMETHODIMP CChatEventSink::OnUserKick(HRESULT, Channel *, User *, User *)
- {
- return(S_OK);
- }
- STDMETHODIMP CChatEventSink::OnUserIP(HRESULT, User *)
- {
- return(S_OK);
- }
- STDMETHODIMP CChatEventSink::OnSquadInfo(HRESULT, unsigned long, Squad *)
- {
- return(S_OK);
- }
- */
|