| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902190319041905190619071908190919101911191219131914191519161917191819191920192119221923192419251926192719281929193019311932193319341935193619371938193919401941194219431944194519461947194819491950195119521953195419551956195719581959196019611962196319641965196619671968196919701971197219731974197519761977197819791980198119821983198419851986198719881989199019911992199319941995199619971998199920002001200220032004200520062007200820092010201120122013201420152016201720182019202020212022202320242025202620272028202920302031203220332034203520362037203820392040204120422043204420452046204720482049205020512052205320542055205620572058205920602061206220632064206520662067206820692070207120722073207420752076207720782079208020812082208320842085208620872088208920902091209220932094209520962097209820992100210121022103210421052106210721082109211021112112211321142115211621172118211921202121212221232124212521262127212821292130213121322133213421352136213721382139214021412142214321442145214621472148214921502151215221532154215521562157215821592160216121622163216421652166216721682169217021712172217321742175217621772178217921802181218221832184218521862187218821892190219121922193219421952196219721982199220022012202220322042205220622072208220922102211221222132214221522162217221822192220222122222223222422252226222722282229223022312232223322342235223622372238223922402241224222432244224522462247224822492250225122522253225422552256225722582259226022612262226322642265226622672268226922702271227222732274227522762277227822792280228122822283228422852286228722882289229022912292229322942295229622972298229923002301230223032304230523062307230823092310231123122313231423152316231723182319232023212322232323242325232623272328232923302331233223332334233523362337233823392340234123422343234423452346234723482349235023512352235323542355235623572358235923602361236223632364236523662367236823692370237123722373237423752376237723782379238023812382238323842385238623872388238923902391239223932394239523962397239823992400240124022403240424052406240724082409241024112412241324142415241624172418241924202421242224232424242524262427242824292430243124322433243424352436243724382439244024412442244324442445244624472448244924502451245224532454245524562457245824592460246124622463246424652466246724682469247024712472247324742475247624772478247924802481248224832484248524862487248824892490249124922493249424952496249724982499250025012502250325042505250625072508250925102511251225132514251525162517251825192520252125222523252425252526252725282529253025312532253325342535253625372538253925402541254225432544254525462547254825492550255125522553255425552556255725582559256025612562256325642565256625672568256925702571257225732574257525762577257825792580258125822583258425852586258725882589259025912592259325942595259625972598259926002601260226032604260526062607260826092610261126122613261426152616261726182619262026212622262326242625262626272628262926302631263226332634263526362637263826392640264126422643264426452646264726482649265026512652265326542655265626572658265926602661266226632664266526662667266826692670267126722673267426752676267726782679268026812682268326842685268626872688268926902691269226932694269526962697269826992700270127022703270427052706270727082709271027112712271327142715271627172718271927202721272227232724272527262727272827292730273127322733273427352736273727382739274027412742274327442745274627472748274927502751275227532754275527562757275827592760276127622763276427652766276727682769277027712772277327742775277627772778277927802781278227832784278527862787278827892790279127922793279427952796279727982799280028012802280328042805280628072808280928102811281228132814281528162817281828192820282128222823282428252826282728282829283028312832283328342835283628372838283928402841284228432844284528462847284828492850285128522853285428552856285728582859286028612862286328642865286628672868286928702871287228732874287528762877287828792880288128822883288428852886288728882889289028912892289328942895289628972898289929002901290229032904290529062907290829092910291129122913291429152916291729182919292029212922292329242925292629272928292929302931293229332934293529362937293829392940294129422943294429452946294729482949295029512952295329542955295629572958295929602961296229632964296529662967296829692970297129722973297429752976297729782979298029812982298329842985298629872988298929902991299229932994299529962997299829993000300130023003300430053006300730083009301030113012301330143015301630173018301930203021302230233024302530263027302830293030303130323033303430353036303730383039304030413042304330443045304630473048304930503051305230533054305530563057305830593060306130623063306430653066306730683069307030713072307330743075307630773078307930803081308230833084308530863087308830893090309130923093309430953096309730983099310031013102310331043105310631073108310931103111311231133114311531163117311831193120312131223123312431253126312731283129313031313132313331343135313631373138313931403141314231433144314531463147314831493150315131523153315431553156315731583159316031613162316331643165316631673168316931703171317231733174317531763177317831793180318131823183318431853186318731883189319031913192319331943195319631973198319932003201320232033204320532063207320832093210321132123213321432153216321732183219322032213222322332243225322632273228322932303231323232333234323532363237323832393240324132423243324432453246324732483249325032513252325332543255325632573258325932603261326232633264326532663267326832693270327132723273327432753276327732783279328032813282328332843285328632873288328932903291329232933294329532963297329832993300330133023303330433053306330733083309331033113312331333143315331633173318331933203321332233233324332533263327332833293330333133323333333433353336333733383339334033413342334333443345334633473348334933503351335233533354335533563357335833593360336133623363336433653366336733683369337033713372337333743375337633773378337933803381338233833384338533863387338833893390339133923393339433953396339733983399340034013402340334043405340634073408340934103411341234133414341534163417341834193420342134223423342434253426342734283429343034313432343334343435343634373438343934403441344234433444344534463447344834493450345134523453345434553456345734583459346034613462346334643465346634673468346934703471347234733474347534763477347834793480348134823483348434853486348734883489349034913492349334943495349634973498349935003501350235033504350535063507350835093510351135123513351435153516351735183519352035213522352335243525352635273528352935303531353235333534353535363537353835393540354135423543354435453546354735483549355035513552355335543555355635573558355935603561356235633564356535663567356835693570357135723573357435753576357735783579358035813582358335843585358635873588358935903591359235933594359535963597359835993600360136023603360436053606360736083609361036113612361336143615361636173618361936203621362236233624362536263627362836293630363136323633363436353636363736383639364036413642364336443645364636473648364936503651365236533654365536563657365836593660366136623663366436653666366736683669 |
- /*
- ** Command & Conquer Renegade(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/>.
- */
- /******************************************************************************
- *
- * FILE
- * $Archive: /Commando/Code/WWOnline/WOLChatObserver.cpp $
- *
- * DESCRIPTION
- * Westwood Online Chat events handling / dispatcher.
- *
- * PROGRAMMER
- * Denzil E. Long, Jr.
- * $Author: Byon_g $
- *
- * VERSION INFO
- * $Revision: 76 $
- * $Modtime: 10/31/02 3:15p $
- *
- ******************************************************************************/
- #pragma warning (disable : 4530)
- #include <atlbase.h>
- #include "WOLChatObserver.h"
- #include "WOLSession.h"
- #include "WOLProduct.h"
- #include "WOLServer.h"
- #include "WOLDownload.h"
- #include "WOLChannel.h"
- #include "WOLSquad.h"
- #include "WOLLadder.h"
- #include "WOLChatMsg.h"
- #include "WOLPageMsg.h"
- #include "WOLGameOptions.h"
- #include "WOLGame.h"
- #include "WOLErrorUtil.h"
- #include <wwlib\registry.h>
- #include <commando\_globals.h>
- #include "systimer.h"
- #include "specialbuilds.h"
- #include "simplevec.h"
- #include "..\commando\cnetwork.h"
- namespace WOL
- {
- #include <WOLAPI\chatdefs.h>
- }
- namespace WWOnline {
- /******************************************************************************
- *
- * NAME
- * ChatObserver::ChatObserver
- *
- * DESCRIPTION
- * Constructor
- *
- * INPUTS
- * NONE
- *
- * RESULT
- * NONE
- *
- ******************************************************************************/
- ChatObserver::ChatObserver() :
- mRefCount(1),
- mOuter(NULL)
- {
- WWDEBUG_SAY(("WOL: ChatObserver Instantiated\n"));
- }
- /******************************************************************************
- *
- * NAME
- * ChatObserver::~ChatObserver
- *
- * DESCRIPTION
- * Destructor
- *
- * INPUTS
- * NONE
- *
- * RESULT
- * NONE
- *
- ******************************************************************************/
- ChatObserver::~ChatObserver()
- {
- WWDEBUG_SAY(("WOL: ChatObserver Destroyed\n"));
- }
- /******************************************************************************
- *
- * NAME
- * ChatObserver::Init
- *
- * DESCRIPTION
- * Initialize chat observer
- *
- * INPUTS
- * Session - Outer session to associate this observer with.
- *
- * RESULT
- * NONE
- *
- ******************************************************************************/
- void ChatObserver::Init(Session& outer)
- {
- mOuter = &outer;
- }
- /****************************************************************************
- *
- * NAME
- * IUnknown::QueryInterface
- *
- * DESCRIPTION
- *
- * INPUTS
- *
- * RESULT
- * Error / Status result
- *
- ****************************************************************************/
- STDMETHODIMP ChatObserver::QueryInterface(const IID& iid, void** ppv)
- {
- if ((iid == IID_IUnknown) || (iid == WOL::IID_IChatEvent))
- {
- *ppv = static_cast<WOL::IChatEvent*>(this);
- }
- else
- {
- *ppv = NULL;
- return E_NOINTERFACE;
- }
- static_cast<IUnknown*>(*ppv)->AddRef();
- return S_OK;
- }
- /****************************************************************************
- *
- * NAME
- * IUnknown::AddRef
- *
- * DESCRIPTION
- * Increment objects reference count.
- *
- * INPUTS
- * NONE
- *
- * RESULT
- * RefCount - New reference count.
- *
- ****************************************************************************/
- ULONG STDMETHODCALLTYPE ChatObserver::AddRef(void)
- {
- InterlockedIncrement((LPLONG)&mRefCount);
- return mRefCount;
- }
- /****************************************************************************
- *
- * NAME
- * IUnknown::Release
- *
- * DESCRIPTION
- * Release reference to object.
- *
- * INPUTS
- * NONE
- *
- * RESULT
- * RefCount - Remaining references
- *
- ****************************************************************************/
- ULONG STDMETHODCALLTYPE ChatObserver::Release(void)
- {
- InterlockedDecrement((LPLONG)&mRefCount);
- if (mRefCount == 0)
- {
- delete this;
- return 0;
- }
- return mRefCount;
- }
- /******************************************************************************
- *
- * NAME
- * ChatObserver::OnServerList
- *
- * DESCRIPTION
- * Handle
- *
- * INPUTS
- * Result - Result / status code.
- * Servers - Server list.
- *
- * RESULT
- * Error / Status result
- *
- ******************************************************************************/
- STDMETHODIMP ChatObserver::OnServerList(HRESULT result, WOL::Server* servers)
- {
- if (mOuter == NULL)
- {
- WWDEBUG_SAY(("WOLERROR: Session not initialized\n"));
- WWASSERT(mOuter && "Session not initialized");
- return S_OK;
- }
- if (FAILED(result))
- {
- WWDEBUG_SAY(("WOLERROR: OnServerList '%s'\n", GetChatErrorString(result)));
- ServerError error(result, "WOL_SERVERLISTERROR");
- mOuter->NotifyObservers(error);
- return S_OK;
- }
- mOuter->mRequestingServerList = false;
- // If update list received, don't provide server list
- if (mOuter->mPatchFiles.size() > 0)
- {
- return S_OK;
- }
- // If we didn't really want a server list anyway then ignore it.
- if (mOuter->mIgnoreServerLists)
- {
- return S_OK;
- }
- // Process new server list.
- mOuter->ClearServers();
- // Clear out old server info from the registry.
- RegistryClass reg(APPLICATION_SUB_KEY_NAME_SERVER_LIST);
- reg.Deleta_All_Values();
- WOL::Server* curServer = servers;
- while (curServer)
- {
- WWDEBUG_SAY(("WOL: Server '%s:%s'\n", curServer->connlabel, curServer->name));
- if ((strcmp((char*)curServer->connlabel, "IRC") == 0) ||
- (strcmp((char*)curServer->connlabel, "IGS") == 0))
- {
- mOuter->mIRCServers.push_back(IRCServerData::Create(*curServer));
- }
- else if (strcmp((char*)curServer->connlabel, "LAD") == 0)
- {
- mOuter->mLadderServer = LadderServerData::Create(*curServer);
- }
- else if (strcmp((char*)curServer->connlabel, "GAM") == 0)
- {
- mOuter->mGameResultsServer = GameResultsServerData::Create(*curServer);
- }
- else if (strcmp((char*)curServer->connlabel, "WDT") == 0)
- {
- mOuter->mWDTServer = WDTServerData::Create(*curServer);
- }
- else if (strcmp((char*)curServer->connlabel, "MGL") == 0)
- {
- mOuter->mMGLServers.push_back(MGLServerData::Create(*curServer));
- }
- else if (strcmp((char*)curServer->connlabel, "PNG") == 0)
- {
- RefPtr<PingServerData> pinger = PingServerData::Create(*curServer);
- WWASSERT(pinger.IsValid());
- if (pinger.IsValid())
- {
- mOuter->mPingServers.push_back(pinger);
- // Automatcally request the ping time to this server.
- const char* address = pinger->GetHostAddress();
- mOuter->RequestPing(address);
- }
- }
- curServer = curServer->next;
- }
- // Notify others about the server list.
- mOuter->NotifyObservers(mOuter->mIRCServers);
- return S_OK;
- }
- /******************************************************************************
- *
- * NAME
- * ChatObserver::OnUpdateList
- *
- * DESCRIPTION
- * Handle application update requirement.
- *
- * INPUTS
- * Result - Error / status code.
- * Updates - List of updates.
- *
- * RESULT
- * Error / Status result
- *
- ******************************************************************************/
- STDMETHODIMP ChatObserver::OnUpdateList(HRESULT result, WOL::Update* updates)
- {
- WWDEBUG_SAY(("WOL: OnUpdateList received\n"));
- // Make sure WOLSession is initialized
- if (mOuter == NULL)
- {
- WWDEBUG_SAY(("WOLERROR: Session not initialized\n"));
- WWASSERT(mOuter && "Session not initialized");
- return S_OK;
- }
- // Clear any previous patch files
- mOuter->mPatchFiles.clear();
- // Report any error condition
- if (FAILED(result))
- {
- WWDEBUG_SAY(("WOLERROR: OnUpdateList '%s'\n", GetChatErrorString(result)));
- const char* errorString = "WOL_UPDATELISTERROR";
- if (result == CHAT_E_STATUSERROR)
- {
- errorString = "WOL_BADINSTALL";
- }
- ServerError error(result, errorString);
- mOuter->NotifyObservers(error);
- return S_OK;
- }
- // Process the patch updates
- WOL::Update* update = updates;
- while (update)
- {
- WWDEBUG_SAY(("WOL: Patch file '%s\\%s\\%s'\n",
- update->server, update->patchpath, update->patchfile));
- mOuter->mPatchFiles.push_back(Download::Create(*update));
- update = update->next;
- }
- // If there are updates then notify the client.
- if (updates)
- {
- // If updates are received, do not provide list of servers
- mOuter->ClearServers();
- ServerError error(CHAT_E_MUSTPATCH, "WOL_PATCHREQUIRED");
- mOuter->NotifyObservers(error);
- }
- return S_OK;
- }
- /******************************************************************************
- *
- * NAME
- * ChatObserver::OnServerError
- *
- * DESCRIPTION
- *
- * INPUTS
- * Result - Error / status code.
- * Text - Error text description.
- *
- * RESULT
- * Error / Status result
- *
- ******************************************************************************/
- STDMETHODIMP ChatObserver::OnServerError(HRESULT result, LPCSTR errorText)
- {
- if (mOuter == NULL)
- {
- WWDEBUG_SAY(("WOLERROR: Session not initialized\n"));
- WWASSERT(mOuter && "Session not initialized");
- return S_OK;
- }
- if (SUCCEEDED(result))
- {
- ServerError error(-1, "WOL_SERVERERROR");
- mOuter->NotifyObservers(error);
- return S_OK;
- }
- WWDEBUG_SAY(("WOLERROR: OnServerError '%s' %s\n", GetChatErrorString(result), errorText));
- if (result != CHAT_E_UNKNOWNRESPONSE)
- {
- ServerError error(result, GetChatErrorString(result));
- mOuter->NotifyObservers(error);
- }
- return S_OK;
- }
- /******************************************************************************
- *
- * NAME
- * ChatObserver::OnConnection
- *
- * DESCRIPTION
- *
- * INPUTS
- * Status - Connection error / status code.
- * MOTD - Message of the day text.
- *
- * RESULT
- * Error / Status result
- *
- ******************************************************************************/
- STDMETHODIMP ChatObserver::OnConnection(HRESULT result, LPCSTR motd)
- {
- if (mOuter == NULL)
- {
- WWDEBUG_SAY(("WOLERROR: Session not initialized\n"));
- WWASSERT(mOuter && "Session not initialized");
- return S_OK;
- }
- const char* errorText = NULL;
- switch (result)
- {
- // Connection successful
- case S_OK:
- {
- WWDEBUG_SAY(("WOL: Connected to server.\n"));
- mOuter->GetChatObject()->SetClientVersion(WOLAPI_BUILD_VERSION);
-
- mOuter->mCurrentConnectionStatus = ConnectionConnected;
- mOuter->mCurrentServer = mOuter->mPendingServer;
- mOuter->mCurrentLogin = mOuter->mPendingLogin;
- mOuter->mPendingServer.Release();
- mOuter->mPendingLogin.Release();
- // Check if the loginname is in the userlist. If not then create
- // a user for the login.
- RefPtr<LoginInfo> login = mOuter->mCurrentLogin;
- if (login.IsValid())
- {
- const WideStringClass& loginName = login->GetNickname();
- // Setup the current user for this session.
- RefPtr<UserData> user = mOuter->GetUserOrBuddy(loginName);
- if (!user.IsValid())
- {
- user = UserData::Create(loginName);
- }
- // Setup the current user
- WWASSERT(user.IsValid() && "OnConnection: Failed to create user");
- user->SetLocale(login->GetLocale());
- mOuter->mCurrentUser = user;
- // Request information about the current user.
- mOuter->RequestUserLocale(loginName);
- mOuter->RequestSquadInfoByMemberName(loginName);
- mOuter->RequestLadderInfo(loginName, LadderType_Team);
- mOuter->mLastUserDataRequestTime = TIMEGETTIME();
- }
- // Notify others about the connection
- mOuter->NotifyObservers(mOuter->mCurrentConnectionStatus);
- // Notify others about the message of the day.
- mOuter->mMessageOfTheDay = motd;
- MessageOfTheDayEvent motdEvent(mOuter->mMessageOfTheDay);
- mOuter->NotifyObservers(motdEvent);
- // Request insider status information and server time information
- mOuter->RequestInsiderStatus();
- mOuter->RequestServerTime();
- return S_OK;
- }
- break;
- case CHAT_E_NICKINUSE:
- errorText = "WOL_NICKINUSE";
- break;
- case CHAT_E_BADPASS:
- errorText = "WOL_BADPASSWORD";
- break;
- case CHAT_E_BANNED:
- errorText = "WOL_BANNED";
- break;
- case CHAT_E_DISABLED:
- errorText = "WOL_ACCOUNTDISABLED";
- break;
- case CHAT_E_SERIALBANNED:
- errorText = "WOL_SERIALBANNED";
- break;
- case CHAT_E_SERIALDUP:
- errorText = "WOL_SERIALDUPLICATE";
- break;
- case CHAT_E_SERIALUNKNOWN:
- errorText = "WOL_SERIALUNKNOWN";
- break;
- case CHAT_E_SKUSERIALMISMATCH:
- errorText = "WOL_SERIALSKUMISMATCH";
- break;
- default:
- errorText = "WOL_CONNECTERROR";
- break;
- }
- // We should only get here if the connection failed.
- mOuter->mPendingServer.Release();
- mOuter->mCurrentServer.Release();
- mOuter->mPendingLogin.Release();
- mOuter->mCurrentLogin.Release();
- mOuter->mCurrentConnectionStatus = ConnectionDisconnected;
- WWDEBUG_SAY(("WOLERROR: OnConnection '%s'\n", GetChatErrorString(result)));
- ServerError error(result, errorText);
- mOuter->NotifyObservers(error);
- mOuter->NotifyObservers(mOuter->mCurrentConnectionStatus);
- return S_OK;
- }
- /******************************************************************************
- *
- * NAME
- * ChatObserver::OnMessageOfTheDay
- *
- * DESCRIPTION
- *
- * INPUTS
- * Result - Error / status code.
- *
- * RESULT
- * Error / Status result
- *
- ******************************************************************************/
- STDMETHODIMP ChatObserver::OnMessageOfTheDay(HRESULT, LPCSTR messageOfTheDay)
- {
- if (mOuter == NULL)
- {
- WWDEBUG_SAY(("WOLERROR: Session not initialized\n"));
- WWASSERT(mOuter && "Session not initialized");
- return S_OK;
- }
- // Notify other about the message of the day.
- mOuter->mMessageOfTheDay = messageOfTheDay;
- MessageOfTheDayEvent motdEvent(mOuter->mMessageOfTheDay);
- mOuter->NotifyObservers(motdEvent);
- return S_OK;
- }
- /******************************************************************************
- *
- * NAME
- * ChatObserver::OnChannelList
- *
- * DESCRIPTION
- * Handle receipt of new channel list.
- *
- * INPUTS
- * Result - Error / status code
- * Channels - Linked list of channels
- *
- * RESULT
- * Error / Status result
- *
- ******************************************************************************/
- STDMETHODIMP ChatObserver::OnChannelList(HRESULT result, WOL::Channel* inChannels)
- {
- if (mOuter == NULL)
- {
- WWDEBUG_SAY(("WOLERROR: Session not initialized\n"));
- WWASSERT(mOuter && "Session not initialized");
- return S_OK;
- }
- // Report any error conditions
- if (FAILED(result))
- {
- WWDEBUG_SAY(("WOLERROR: OnChannelList '%s'\n", GetChatErrorString(result)));
- ChannelList empty;
- ChannelListEvent error(ChannelListEvent::Error, empty, -1);
- mOuter->NotifyObservers(error);
- return S_OK;
- }
- // If this is a ping list then update the latency of each channel.
- if (result == CHAT_S_PINGLIST)
- {
- WWDEBUG_SAY(("WOL: OnChannelList (PingList)\n"));
- WOL::Channel* wolChannel = inChannels;
- while (wolChannel)
- {
- const RefPtr<ChannelData>& channel = mOuter->FindChannel((const char*)wolChannel->name);
- if (channel.IsValid())
- {
- channel->SetLatency(wolChannel->latency);
- }
- wolChannel = wolChannel->next;
- }
- return S_OK;
- }
- // Get code for game channels
- RefPtrConst<Product> product = Product::Current();
- WWASSERT(product.IsValid() && "WOLProduct not initialized");
- int gameCode = -1;
- if (product.IsValid())
- {
- gameCode = product->GetGameCode();
- }
- else
- {
- WWDEBUG_SAY(("WOLERROR: WOLProduct not initialized.\n"));
- }
- // Create the new channel lists
- ChannelList chatChannels;
- ChannelList gameChannels;
- WOL::Channel* wolChannel = inChannels;
- while (wolChannel)
- {
- WWDEBUG_SAY(("WOL: Channel '%s:%ld'\n", (const char*)wolChannel->name, wolChannel->type));
- ChannelList* curList = NULL;
- ChannelList* newList = NULL;
- if (wolChannel->type == 0)
- {
- curList = &mOuter->mChatChannels;
- newList = &chatChannels;
- }
- else if (wolChannel->type == gameCode)
- {
- curList = &mOuter->mGameChannels;
- newList = &gameChannels;
- }
- else
- {
- continue;
- }
- WWASSERT(curList != NULL);
- WWASSERT(newList != NULL);
- ChannelList::iterator iter = FindChannelNode(*curList, (const char*)wolChannel->name);
- if (iter != curList->end())
- {
- RefPtr<ChannelData> channel = *iter;
- WWASSERT(channel.IsValid());
- channel->UpdateData(*wolChannel);
- ChannelList::iterator end = newList->end();
- newList->splice(end, *curList, iter);
- }
- else
- {
- RefPtr<ChannelData> channel = ChannelData::Create(*wolChannel);
- WWASSERT(channel.IsValid());
- newList->push_back(channel);
- }
- wolChannel = wolChannel->next;
- }
- // Replace lists
- mOuter->mChatChannels.swap(chatChannels);
- mOuter->mGameChannels.swap(gameChannels);
- // Notify other about the new channel lists
- ChannelListEvent chatListEvent(ChannelListEvent::NewList, mOuter->mChatChannels, 0);
- mOuter->NotifyObservers(chatListEvent);
- ChannelListEvent gameListEvent(ChannelListEvent::NewList, mOuter->mGameChannels, gameCode);
- mOuter->NotifyObservers(gameListEvent);
- return S_OK;
- }
- /******************************************************************************
- *
- * NAME
- * ChatObserver::OnChannelCreate
- *
- * DESCRIPTION
- *
- * INPUTS
- * Result - Error / status code.
- *
- * RESULT
- * Error / Status result
- *
- ******************************************************************************/
- STDMETHODIMP ChatObserver::OnChannelCreate(HRESULT result, WOL::Channel* inChannel)
- {
- if (mOuter == NULL)
- {
- WWDEBUG_SAY(("WOLERROR: Session not initialized\n"));
- WWASSERT(mOuter && "Session not initialized");
- return S_OK;
- }
- // Handle failure condition
- if (FAILED(result))
- {
- WWDEBUG_SAY(("WOLERROR: OnChannelCreate '%s'\n", GetChatErrorString(result)));
- ChannelStatus status = GetChannelStatusFromHResult(result);
- mOuter->mCurrentChannelStatus = status;
- // Notify others about the channel creation failure
- ChannelEvent error(status, mOuter->mPendingChannel);
- mOuter->NotifyObservers(error);
- mOuter->mPendingChannel.Release();
- mOuter->mCurrentChannel.Release();
- return S_OK;
- }
- WWASSERT(inChannel != NULL && "OnChannelCreate parameter error");
- WWDEBUG_SAY(("WOL: Created channel '%s'\n", (char*)inChannel->name));
- // Make sure we have the channel to create pending.
- if (!mOuter->mPendingChannel.IsValid())
- {
- WWASSERT(mOuter->mPendingChannel.IsValid());
- return S_OK;
- }
- // Check if the created channel matches the pending one.
- wchar_t channelName[64];
- mbstowcs(channelName, (const char*)inChannel->name, sizeof(inChannel->name));
- const WideStringClass& pendingName = mOuter->mPendingChannel->GetName();
- if (pendingName.Compare_No_Case(channelName) != 0)
- {
- WWASSERT("OnChannelCreate: Channel name mismatch");
- return S_OK;
- }
- // Verify current login is valid
- RefPtr<LoginInfo> login = mOuter->mCurrentLogin;
- if (!login.IsValid())
- {
- WWASSERT(login.IsValid() && "OnChannelCreate: No login");
- return S_OK;
- }
- // Get or create user who created the channel
- RefPtr<UserData> user = mOuter->GetUserOrBuddy(login->GetNickname());
- if (!user.IsValid())
- {
- user = UserData::Create(login->GetNickname());
- }
- if (!user.IsValid())
- {
- WWASSERT(user.IsValid() && "OnChannelCreate: Unable to find or create user");
- return S_OK;
- }
- // The pending channel now becomes the current channel.
- mOuter->mCurrentChannel = mOuter->mPendingChannel;
- mOuter->mPendingChannel.Release();
- mOuter->mCurrentChannel->UpdateData(*inChannel);
- mOuter->mCurrentChannelStatus = ChannelJoined;
- // Notify others the channel was created
- ChannelEvent createdEvent(ChannelCreated, mOuter->mCurrentChannel);
- mOuter->NotifyObservers(createdEvent);
- // Add the logged in user to the userlist
- mOuter->mUsers.push_back(user);
- // Notify others that the logged in user has joined the newly created channel.
- UserEvent event(UserEvent::Join, user);
- mOuter->NotifyObservers(event);
- return S_OK;
- }
- /******************************************************************************
- *
- * NAME
- * ChatObserver::OnChannelJoin
- *
- * DESCRIPTION
- * User has joined a channel.
- *
- * INPUTS
- * Result - Error / status code
- * Channel - Channel joined
- * User - User joining channel.
- *
- * RESULT
- * Error / Status result
- *
- ******************************************************************************/
- STDMETHODIMP ChatObserver::OnChannelJoin(HRESULT result, WOL::Channel* inChannel,
- WOL::User* inUser)
- {
- if (mOuter == NULL)
- {
- WWDEBUG_SAY(("WOLERROR: Session not initialized\n"));
- WWASSERT(mOuter && "Session not initialized");
- return S_OK;
- }
- // Handle failure conditions
- if (FAILED(result))
- {
- WWDEBUG_SAY(("WOLERROR: OnChannelJoin '%s'\n", GetChatErrorString(result)));
- ChannelStatus status = GetChannelStatusFromHResult(result);
- mOuter->mCurrentChannelStatus = status;
- // Get the channel we are attempting to join
- RefPtr<ChannelData> badChannel = mOuter->mPendingChannel;
- if (badChannel.IsValid() == false)
- {
- badChannel = mOuter->mCurrentChannel;
- }
- mOuter->mPendingChannel.Release();
- mOuter->mCurrentChannel.Release();
- // Notify others the reason for the channel join failure.
- ChannelEvent error(status, badChannel);
- mOuter->NotifyObservers(error);
- return S_OK;
- }
- WWASSERT(inChannel != NULL && "OnChannelJoin parameter error");
- WWASSERT(inUser != NULL && "OnChannelJoin parameter error");
- struct in_addr addr;
- addr.S_un.S_addr = inUser->ipaddr;
- WWDEBUG_SAY(("WOL: User '%s' @ %s joining channel '%s'\n", (char*)inUser->name, inet_ntoa(addr), (char*)inChannel->name));
- // Verify that the current login is valid
- if (!mOuter->mCurrentLogin.IsValid())
- {
- WWASSERT(mOuter->mCurrentLogin.IsValid() && "OnChannelJoin: No login");
- return S_OK;
- }
- // Get or create the user who is joining.
- wchar_t inUsername[64];
- mbstowcs(inUsername, (char*)inUser->name, sizeof(inUser->name));
- RefPtr<UserData> user = mOuter->GetUserOrBuddy(inUsername);
- if (!user.IsValid())
- {
- user = UserData::Create(*inUser);
- }
- else
- {
- user->UpdateData(*inUser);
- }
- if (!user.IsValid())
- {
- WWASSERT(user.IsValid() && "OnChannelJoin: No user");
- return S_OK;
- }
- // Get channel name
- wchar_t channelName[64];
- mbstowcs(channelName, (const char*)inChannel->name, sizeof(inChannel->name));
- // Is the logged in user joining this channel?
- const WideStringClass& loginName = mOuter->mCurrentLogin->GetNickname();
- if (loginName.Compare_No_Case(inUsername) == 0)
- {
- // Verify that we are wanting to join a channel
- if (!mOuter->mPendingChannel.IsValid())
- {
- WWASSERT(mOuter->mPendingChannel.IsValid() && "OnChannelJoin: Unknown channel.");
- return S_OK;
- }
- // Verify that the channel joined is the one we were expecting to join.
- const WideStringClass& pendingChannelName = mOuter->mPendingChannel->GetName();
- if (pendingChannelName.Compare_No_Case(channelName) != 0)
- {
- WWASSERT(!"OnChannelJoin: Pending channel mismatch");
- return S_OK;
- }
- // The pending channel becomes the current channel
- mOuter->mPendingChannel->UpdateData(*inChannel);
- mOuter->mCurrentChannel = mOuter->mPendingChannel;
- mOuter->mPendingChannel.Release();
- mOuter->mCurrentChannelStatus = ChannelJoined;
- // Notify others that we have joined the channel
- ChannelEvent event(ChannelJoined, mOuter->mCurrentChannel);
- mOuter->NotifyObservers(event);
- }
- else
- {
- WWDEBUG_SAY(("WOL: OnChannelJoin other user '%S'\n", inUsername));
- }
- mOuter->AutoRequestUserDetails(user);
- // Make sure the current channel is valid
- if (!mOuter->mCurrentChannel.IsValid())
- {
- WWASSERT(mOuter->mCurrentChannel.IsValid());
- return S_OK;
- }
- // Verify that the channel joined is the current one.
- const WideStringClass& curChannelName = mOuter->mCurrentChannel->GetName();
- if (curChannelName.Compare_No_Case(channelName) != 0)
- {
- WWASSERT(!"OnChannelJoin: Channel mismatch");
- return S_OK;
- }
- // Increment user count for this channel
- mOuter->mCurrentChannel->GetData().currentUsers++;
- // Get the time they joined the channel. They have 2 mins to get into the game or they are kicked.
- user->mKickTimer = TIMEGETTIME();
- // Add the user to the user list
- mOuter->mUsers.push_back(user);
- // Notify others that a user joined the current channel.
- UserEvent event(UserEvent::Join, user);
- mOuter->NotifyObservers(event);
- return S_OK;
- }
- /******************************************************************************
- *
- * NAME
- * ChatObserver::OnChannelLeave
- *
- * DESCRIPTION
- *
- * INPUTS
- * Result - Error / status code.
- *
- * RESULT
- * Error / Status result
- *
- ******************************************************************************/
- STDMETHODIMP ChatObserver::OnChannelLeave(HRESULT result, WOL::Channel* inChannel, WOL::User* inUser)
- {
- if (mOuter == NULL)
- {
- WWDEBUG_SAY(("WOLERROR: Session not initialized\n"));
- WWASSERT(mOuter && "Session not initialized");
- return S_OK;
- }
- // Handle error condition
- if (FAILED(result))
- {
- WWDEBUG_SAY(("WOLERROR: OnChannelLeave '%s'\n", GetChatErrorString(result)));
- ChannelStatus status = GetChannelStatusFromHResult(result);
- mOuter->mCurrentChannelStatus = status;
- ChannelEvent error(status, mOuter->mCurrentChannel);
- mOuter->NotifyObservers(error);
- return S_OK;
- }
- WWASSERT(inChannel != NULL && "OnChannelLeave: Parameter error");
- WWASSERT(inUser != NULL && "OnChannelLeave: Parameter error");
- WWDEBUG_SAY(("WOL: User '%s' leaving channel '%s'\n", (char*)inUser->name, (char*)inChannel->name));
- // If we are not logged in then ignore.
- if (!mOuter->mCurrentLogin.IsValid())
- {
- WWASSERT(mOuter->mCurrentLogin.IsValid());
- return S_OK;
- }
- // Get the current channel we are connected to. If we are not connected to any
- // channel then ignore.
- if (!mOuter->mCurrentChannel.IsValid())
- {
- WWASSERT(mOuter->mCurrentChannel.IsValid());
- return S_OK;
- }
- // There is a bug in WOLAPI (no surprise here!) that results in the leaving
- // channel being empty if the channel was join explicitly (without picking it
- // from the channel list) as in the case of quickmatch games. Therefore it is
- // necessary to check for this condition here. If the channel name is empty then
- // we MUST ASSUME that the channel we are leaving is the one we are currently
- // connected to.
- wchar_t channelName[64];
- const WideStringClass& curChannelName = mOuter->mCurrentChannel->GetName();
- if (strlen((const char*)inChannel->name) == 0)
- {
- wcsncpy(channelName, curChannelName, (sizeof(channelName) / sizeof(wchar_t)));
- }
- else
- {
- mbstowcs(channelName, (const char*)inChannel->name, sizeof(inChannel->name));
- }
- // If the leaving channel is not the channel we are connected to then ignore.
- if (curChannelName.Compare_No_Case(channelName) != 0)
- {
- WWASSERT(!"OnChannelLeave: Channel mismatch.");
- return S_OK;
- }
- // Decrement user count for this channel
- WWASSERT(mOuter->mCurrentChannel->GetCurrentUsers() > 0);
- mOuter->mCurrentChannel->GetData().currentUsers--;
- // If current user is leaving then disconnect from the channel clear the user list.
- wchar_t inUsername[64];
- mbstowcs(inUsername, (char*)inUser->name, sizeof(inUser->name));
- const WideStringClass& nickname = mOuter->mCurrentLogin->GetNickname();
- if (nickname.Compare_No_Case(inUsername) == 0)
- {
- RefPtr<ChannelData> leftChannel = mOuter->mCurrentChannel;
- mOuter->mCurrentChannelStatus = ChannelLeft;
- mOuter->mCurrentChannel.Release();
- // Notify others that we have left the channel
- ChannelEvent event(ChannelLeft, leftChannel);
- mOuter->NotifyObservers(event);
- mOuter->mUsers.clear();
- mOuter->NotifyObservers(mOuter->mUsers);
- }
- else
- {
- // If some other user is leaving then notify that he left the channel.
- RefPtr<UserData> leavingUser = RemoveUserInList(inUsername, mOuter->mUsers);
- if (leavingUser.IsValid())
- {
- UserEvent event(UserEvent::Leave, leavingUser);
- mOuter->NotifyObservers(event);
- }
- }
- return S_OK;
- }
- /******************************************************************************
- *
- * NAME
- * ChatObserver::OnChannelTopic
- *
- * DESCRIPTION
- *
- * INPUTS
- * Result - Error / status code.
- *
- * RESULT
- * Error / Status result
- *
- ******************************************************************************/
- STDMETHODIMP ChatObserver::OnChannelTopic(HRESULT result, WOL::Channel* inChannel, LPCSTR topic)
- {
- if (mOuter == NULL)
- {
- WWDEBUG_SAY(("WOLERROR: Session not initialized\n"));
- WWASSERT(mOuter && "Session not initialized");
- return S_OK;
- }
- // Handle error condition
- if (FAILED(result))
- {
- WWDEBUG_SAY(("WOLERROR: OnChannelTopic '%s'\n", GetChatErrorString(result)));
- return S_OK;
- }
- // If inputs are invalid then ignore
- if (inChannel == NULL)
- {
- WWASSERT(inChannel);
- return S_OK;
- }
- WWDEBUG_SAY(("WOL: Channel '%s' Topic changed.\nExInfo: %s\nTopic: %s\n",
- (const char*)inChannel->name, (const char*)inChannel->exInfo, topic));
- wchar_t channelName[64];
- mbstowcs(channelName, (const char*)inChannel->name, sizeof(inChannel->name));
- RefPtr<ChannelData> channel = mOuter->FindChannel(channelName);
- if (channel.IsValid())
- {
- #ifndef FREEDEDICATEDSERVER
- channel->SetTopic(topic);
- channel->SetExtraInfo((const char*)inChannel->exInfo);
- ChannelEvent event(ChannelNewData, channel);
- mOuter->NotifyObservers(event);
- #else
- bool bad_topic = false;
- if (strcmp(topic, channel->GetTopic()) != 0) {
- bad_topic = true;
- WWDEBUG_SAY(("Bad topic. Old = %s, new = %s\n", channel->GetTopic(), topic));
- }
- if (strcmp((char*)&inChannel->exInfo[0], channel->GetExtraInfo()) != 0) {
- bad_topic = true;
- WWDEBUG_SAY(("Bad exInfo. Old = %s, new = %s\n", channel->GetExtraInfo(), inChannel->exInfo));
- }
- if (bad_topic) {
- mOuter->SendChannelTopic();
- }
- #endif
- }
- return S_OK;
- }
- /******************************************************************************
- *
- * NAME
- * ChatObserver::OnPrivateAction
- *
- * DESCRIPTION
- *
- * INPUTS
- * Result - Error / status code.
- *
- * RESULT
- * Error / Status result
- *
- ******************************************************************************/
- STDMETHODIMP ChatObserver::OnPrivateAction(HRESULT result, WOL::User* user, LPCSTR message)
- {
- if (mOuter == NULL)
- {
- WWDEBUG_SAY(("WOLERROR: Session not initialized\n"));
- WWASSERT(mOuter && "Session not initialized");
- return S_OK;
- }
- if (FAILED(result))
- {
- WWDEBUG_SAY(("WOLERROR: OnPrivateAction '%s'\n", GetChatErrorString(result)));
- }
- else
- {
- ChatMessage msg(user, message, true, true);
- mOuter->NotifyObservers(msg);
- }
- return S_OK;
- }
- /******************************************************************************
- *
- * NAME
- * ChatObserver::OnPublicAction
- *
- * DESCRIPTION
- *
- * INPUTS
- * Result - Error / status code.
- *
- * RESULT
- * Error / Status result
- *
- ******************************************************************************/
- STDMETHODIMP ChatObserver::OnPublicAction(HRESULT result, WOL::Channel*, WOL::User* user, LPCSTR message)
- {
- if (mOuter == NULL)
- {
- WWDEBUG_SAY(("WOLERROR: Session not initialized\n"));
- WWASSERT(mOuter && "Session not initialized");
- return S_OK;
- }
- if (FAILED(result))
- {
- WWDEBUG_SAY(("WOLERROR: OnPublicAction '%s'\n", GetChatErrorString(result)));
- }
- else
- {
- ChatMessage msg(user, message, false, true);
- mOuter->NotifyObservers(msg);
- }
- return S_OK;
- }
- /******************************************************************************
- *
- * NAME
- * ChatObserver::OnUserList
- *
- * DESCRIPTION
- *
- * INPUTS
- * Result - Error / status code.
- *
- * RESULT
- * Error / Status result
- *
- ******************************************************************************/
- STDMETHODIMP ChatObserver::OnUserList(HRESULT result, WOL::Channel* inChannel, WOL::User* inUsers)
- {
- if (mOuter == NULL)
- {
- WWDEBUG_SAY(("WOLERROR: Session not initialized\n"));
- WWASSERT(mOuter && "Session not initialized");
- return S_OK;
- }
- if (FAILED(result))
- {
- WWDEBUG_SAY(("WOLERROR: OnUserList '%s'\n", GetChatErrorString(result)));
- ServerError error(result, "WOL_USERLISTERROR");
- mOuter->NotifyObservers(error);
- return S_OK;
- }
- if (inChannel == NULL)
- {
- WWDEBUG_SAY(("WOLERROR: NULL channel\n"));
- WWASSERT(inChannel != NULL);
- return S_OK;
- }
- if (!mOuter->mCurrentChannel.IsValid())
- {
- WWDEBUG_SAY(("WOLERROR: UserList no current channel\n"));
- WWASSERT(!"OnUserList: No current channel");
- return S_OK;
- }
- // Verify the channel the user list is for against the channel we are in.
- wchar_t channelName[64];
- mbstowcs(channelName, (const char*)inChannel->name, sizeof(inChannel->name));
- const WideStringClass& curChannelName = mOuter->mCurrentChannel->GetName();
- if (curChannelName.Compare_No_Case(channelName) != 0)
- {
- WWDEBUG_SAY(("WOLERROR: UserList channel mismatch\n"));
- WWASSERT(!"OnUserList: Channel mismatch");
- return S_OK;
- }
- // Process the users.
- UserList userList;
- WOL::User* curUser = inUsers;
- while (curUser)
- {
- wchar_t name[64];
- mbstowcs(name, (const char*)curUser->name, sizeof(curUser->name));
- // If the user is not already in our list then create them.
- RefPtr<UserData> user = mOuter->GetUserOrBuddy(name);
- if (!user.IsValid())
- {
- user = UserData::Create(*curUser);
- }
- else
- {
- user->UpdateData(*curUser);
- }
- if (user.IsValid())
- {
- userList.push_back(user);
- // If we are connected to a game channel then request detailed
- // information about the users.
- if (mOuter->mCurrentChannel.IsValid() && (mOuter->mCurrentChannel->GetType() != 0))
- {
- mOuter->AutoRequestUserDetails(user);
- }
- }
- curUser = curUser->next;
- }
- // Update the user count for this channel.
- RefPtr<ChannelData> channel = mOuter->FindChannel((const char*)inChannel->name);
- if (channel.IsValid())
- {
- channel->GetData().currentUsers = userList.size();
- }
- // Update the user list
- mOuter->mUsers.swap(userList);
- userList.clear();
- mOuter->NotifyObservers(mOuter->mUsers);
- return S_OK;
- }
- /******************************************************************************
- *
- * NAME
- * ChatObserver::OnPublicMessage
- *
- * DESCRIPTION
- *
- * INPUTS
- * Result - Error / status code.
- *
- * RESULT
- * Error / Status result
- *
- ******************************************************************************/
- STDMETHODIMP ChatObserver::OnPublicMessage(HRESULT result, WOL::Channel*, WOL::User* user, LPCSTR message)
- {
- if (mOuter == NULL)
- {
- WWDEBUG_SAY(("WOLERROR: Session not initialized\n"));
- WWASSERT(mOuter && "Session not initialized");
- return S_OK;
- }
- if (FAILED(result))
- {
- WWDEBUG_SAY(("WOLERROR: OnPublicMessage '%s'\n", GetChatErrorString(result)));
- }
- else
- {
- ChatMessage msg(user, message, false, false);
- mOuter->NotifyObservers(msg);
- }
- return S_OK;
- }
- /******************************************************************************
- *
- * NAME
- * ChatObserver::OnPrivateMessage
- *
- * DESCRIPTION
- *
- * INPUTS
- * Result - Error / status code.
- *
- * RESULT
- * Error / Status result
- *
- ******************************************************************************/
- STDMETHODIMP ChatObserver::OnPrivateMessage(HRESULT result, WOL::User* user, LPCSTR message)
- {
- if (mOuter == NULL)
- {
- WWDEBUG_SAY(("WOLERROR: Session not initialized\n"));
- WWASSERT(mOuter && "Session not initialized");
- return S_OK;
- }
- if (FAILED(result))
- {
- WWDEBUG_SAY(("WOLERROR: OnPrivateMessage '%s'\n", GetChatErrorString(result)));
- }
- else
- {
- ChatMessage msg(user, message, true, false);
- mOuter->NotifyObservers(msg);
- }
- return S_OK;
- }
- /******************************************************************************
- *
- * NAME
- * ChatObserver::OnSystemMessage
- *
- * DESCRIPTION
- *
- * INPUTS
- * Result - Error / status code.
- *
- * RESULT
- * Error / Status result
- *
- ******************************************************************************/
- STDMETHODIMP ChatObserver::OnSystemMessage(HRESULT result, LPCSTR message)
- {
- if (mOuter == NULL)
- {
- WWDEBUG_SAY(("WOLERROR: Session not initialized\n"));
- WWASSERT(mOuter && "Session not initialized");
- return S_OK;
- }
- if (FAILED(result))
- {
- WWDEBUG_SAY(("WOLERROR: OnSystemMessage '%s'\n", GetChatErrorString(result)));
- }
- else
- {
- ChatMessage msg(NULL, message, false, false);
- mOuter->NotifyObservers(msg);
- }
- return S_OK;
- }
- /******************************************************************************
- *
- * NAME
- * ChatObserver::OnNetStatus
- *
- * DESCRIPTION
- *
- * INPUTS
- * Result - Error / status code.
- *
- * RESULT
- * Error / Status result
- *
- ******************************************************************************/
- STDMETHODIMP ChatObserver::OnNetStatus(HRESULT result)
- {
- if (mOuter == NULL)
- {
- WWDEBUG_SAY(("WOLERROR: Session not initialized\n"));
- WWASSERT(mOuter && "Session not initialized");
- return S_OK;
- }
- ConnectionStatus status = mOuter->mCurrentConnectionStatus;
- switch (result)
- {
- case CHAT_E_CON_LOOKUP_FAILED:
- case CHAT_E_CON_ERROR:
- case CHAT_E_TIMEOUT:
- case CHAT_S_CON_DISCONNECTED:
- mOuter->mRequestingServerList = false;
- mOuter->mCurrentServer.Release();
- status = ConnectionDisconnected;
- if (mOuter->mCurrentChannelStatus == ChannelJoined)
- {
- // We can't be in a channel without a WOL connection.
- WWDEBUG_SAY(("WOL: Leaving channel due to chat connection loss\n"));
- mOuter->mCurrentChannel.Release();
- mOuter->mPendingChannel.Release();
- mOuter->mCurrentChannelStatus = ChannelLeft;
- }
- break;
- case CHAT_S_CON_DISCONNECTING:
- status = ConnectionDisconnecting;
- break;
- case CHAT_S_CON_CONNECTING:
- status = ConnectionConnecting;
- break;
- case CHAT_S_CON_CONNECTED:
- break;
- default:
- WWDEBUG_SAY(("WOL: OnNetStatus '%s'\n", GetChatErrorString(result)));
- break;
- }
- if (status != mOuter->mCurrentConnectionStatus)
- {
- mOuter->mCurrentConnectionStatus = status;
- if (status == ConnectionDisconnected)
- {
- mOuter->NotifyObservers(status);
- }
- }
- return S_OK;
- }
- /******************************************************************************
- *
- * NAME
- * ChatObserver::OnLogout
- *
- * DESCRIPTION
- * Handle other users that have logged out.
- *
- * NOTE: This does not get called for the logged in user. When the logged in
- * user logs out OnNetStatus() is called with CHAT_S_CON_DISCONNECTED.
- *
- * INPUTS
- * Result - Error / status code.
- * User - User that logged out.
- *
- * RESULT
- * Error / Status result
- *
- ******************************************************************************/
- STDMETHODIMP ChatObserver::OnLogout(HRESULT result, WOL::User* inUser)
- {
- if (FAILED(result))
- {
- WWDEBUG_SAY(("WOLERROR: OnLogout '%s'\n", GetChatErrorString(result)));
- return S_OK;
- }
- // Remove the logged out user from the session
- if (inUser)
- {
- WWDEBUG_SAY(("WOL: User '%s' logged out\n", (char*)inUser->name));
- wchar_t name[64];
- mbstowcs(name, (char*)inUser->name, sizeof(inUser->name));
- // If some other user is leaving then notify that he left the channel.
- RefPtr<UserData> leavingUser = RemoveUserInList(name, mOuter->mUsers);
- if (leavingUser.IsValid())
- {
- // Decrement user count for this channel
- if (mOuter->mCurrentChannel.IsValid())
- {
- WWASSERT(mOuter->mCurrentChannel->GetData().currentUsers > 0);
- mOuter->mCurrentChannel->GetData().currentUsers--;
- }
- UserEvent event(UserEvent::Leave, leavingUser);
- mOuter->NotifyObservers(event);
- }
- }
- return S_OK;
- }
- /*
- ** HACK. Private game options spam control.
- */
- class PrivateGameOptionsTrackingClass
- {
- public:
- char UserName[256];
- DynamicVectorClass<unsigned long> Times;
- bool operator == (PrivateGameOptionsTrackingClass const &whatever);
- bool operator != (PrivateGameOptionsTrackingClass const &whatever);
- };
- DynamicVectorClass<PrivateGameOptionsTrackingClass*> OptionsTracking;
- bool PrivateGameOptionsTrackingClass::operator == (PrivateGameOptionsTrackingClass const &whatever)
- {
- if (stricmp(UserName, whatever.UserName) == 0) {
- return(true);
- }
- return(false);
- }
- bool PrivateGameOptionsTrackingClass::operator != (PrivateGameOptionsTrackingClass const &whatever)
- {
- if (stricmp(UserName, whatever.UserName) == 0) {
- return(false);
- }
- return(true);
- }
- bool Is_Options_Spammer(char *user_name, int &count)
- {
- int index = -1;
- count = 0;
- for (int i=0 ; i<OptionsTracking.Count() ; i++) {
- if (stricmp(OptionsTracking[i]->UserName, user_name) == 0) {
- index = i;
- break;
- }
- }
- if (index == -1) {
-
- /*
- ** See if there are any old ones we can remove.
- */
- for (int i=OptionsTracking.Count() - 1 ; i >= 0 ; i--) {
- if (OptionsTracking[i]->Times.Count() == 0) {
- delete OptionsTracking[i];
- OptionsTracking.Delete(i);
- index = i;
- break;
- }
- }
-
-
- PrivateGameOptionsTrackingClass *options = new PrivateGameOptionsTrackingClass;
- strncpy(options->UserName, user_name, 255);
- options->UserName[255] = 0;
- OptionsTracking.Add(options);
- index = OptionsTracking.Count() - 1;
- }
- unsigned long time = TIMEGETTIME();
- OptionsTracking[index]->Times.Add(time);
- unsigned long old_time = time - 4000;
- if (old_time < time) {
-
- /*
- ** Remove times older than 5 secs.
- */
- int c = OptionsTracking[index]->Times.Count();
- for (int i=0 ; i<c ; i++) {
- if (OptionsTracking[index]->Times[0] < old_time) {
- OptionsTracking[index]->Times.Delete(0);
- } else {
- break;
- }
- }
- count = OptionsTracking[index]->Times.Count();
- if (OptionsTracking[index]->Times.Count() > 16) {
- return(true);
- }
-
-
- } else {
- while (OptionsTracking.Count()) {
- delete OptionsTracking[0];
- OptionsTracking.Delete(0);
- }
- }
-
- return(false);
-
- }
- void ChatObserver::Kick_Spammer(WOL::User *wol_user)
- {
- /*
- ** Get the IP of the spammer.
- */
- const UserList& user_list = mOuter->GetUserList();
- const unsigned int count = user_list.size();
- unsigned long ip = 0;
- for (unsigned int index = 0; index < count; index++) {
- const RefPtr<UserData>& user = user_list[index];
- if (user.IsValid()) {
- WOL::User userdata = user->GetData();
- if (stricmp((char*)wol_user->name, (char*)userdata.name) == 0) {
- ip = userdata.ipaddr;
- break;
- }
- }
- }
-
- /*
- ** Ban em, ban em all.
- */
- for (index = 0; index < count; index++) {
- const RefPtr<UserData>& user = user_list[index];
- if (user.IsValid()) {
- WOL::User userdata = user->GetData();
- if (userdata.ipaddr == ip) {
- WideStringClass widey((char*)userdata.name, true);
- const RefPtr<LoginInfo>& login = mOuter->GetCurrentLogin();
- WideStringClass myname(L"", true);
- if (login.IsValid()) {
- myname = login->GetNickname();
- }
- if (widey.Compare_No_Case(myname) != 0) {
- mOuter->BanUser(widey.Peek_Buffer(), true);
- mOuter->KickUser(widey.Peek_Buffer());
- WWDEBUG_SAY(("WOL: '%s' banned for options spamming\n", (char*)(char*)userdata.name));
- }
- }
- }
- }
- WideStringClass widey((char*)wol_user->name, true);
- mOuter->BanUser(widey.Peek_Buffer(), true);
- mOuter->KickUser(widey.Peek_Buffer());
- WWDEBUG_SAY(("WOL: '%s' banned for options spamming\n", (char*)wol_user->name));
- }
- /******************************************************************************
- *
- * NAME
- * ChatObserver::OnPrivateGameOptions
- *
- * DESCRIPTION
- *
- * INPUTS
- * Result - Error / status code.
- *
- * RESULT
- * Error / Status result
- *
- ******************************************************************************/
- STDMETHODIMP ChatObserver::OnPrivateGameOptions(HRESULT result, WOL::User* inUser, LPCSTR options)
- {
- if (mOuter == NULL)
- {
- WWDEBUG_SAY(("WOLERROR: Session not initialized\n"));
- WWASSERT(mOuter && "Session not initialized");
- return S_OK;
- }
- if (FAILED(result))
- {
- WWDEBUG_SAY(("WOLERROR: OnPrivateGameOptions '%s'\n", GetChatErrorString(result)));
- return S_OK;
- }
- // Parameter check
- if ((inUser == NULL) || (options == NULL))
- {
- WWASSERT(inUser != NULL);
- WWASSERT(options != NULL);
- return S_OK;
- }
- WWDEBUG_SAY(("WOL: (time %d) PrivateGameOptions from '%s' : %s\n", TIMEGETTIME(), (char*)inUser->name, options));
-
- if (cNetwork::I_Am_Server()) {
-
- int count = 0;
- bool is_spammer = Is_Options_Spammer((char*)inUser->name, count);
- bool is_rginfo = (strstr(options, "RGINFO") == NULL) ? false : true;
- if (is_spammer) {
- if (count > 16 && count < 19) {
- Kick_Spammer(inUser);
- }
- } else {
- if (is_rginfo && count > 2) {
- WWDEBUG_SAY(("WOL: Ignoring RGINFO from '%s' \n", (char*)inUser->name));
- } else {
- GameOptionsMessage gameOptions(inUser, NULL, options, true);
- mOuter->NotifyObservers(gameOptions);
- }
- }
- } else {
- GameOptionsMessage gameOptions(inUser, NULL, options, true);
- mOuter->NotifyObservers(gameOptions);
- }
- return S_OK;
- }
- /******************************************************************************
- *
- * NAME
- * ChatObserver::OnPublicGameOptions
- *
- * DESCRIPTION
- *
- * INPUTS
- * Result - Error / status code.
- *
- * RESULT
- * Error / Status result
- *
- ******************************************************************************/
- STDMETHODIMP ChatObserver::OnPublicGameOptions(HRESULT result, WOL::Channel* inChannel,
- WOL::User* inUser, LPCSTR options)
- {
- if (mOuter == NULL)
- {
- WWDEBUG_SAY(("WOLERROR: Session not initialized\n"));
- WWASSERT(mOuter && "Session not initialized");
- return S_OK;
- }
- if (FAILED(result))
- {
- WWDEBUG_SAY(("WOLERROR: OnPrivateGameOptions '%s'\n", GetChatErrorString(result)));
- return S_OK;
- }
- // Parameter check
- if ((inChannel == NULL) || (inUser == NULL) || (options == NULL))
- {
- WWDEBUG_SAY(("WOLERROR: OnPublicGameOptions invalid parameters\n"));
- WWASSERT(inChannel != NULL);
- WWASSERT(inUser != NULL);
- WWASSERT(options != NULL);
- return S_OK;
- }
- // Only acknowledge options for the channel we are in.
- wchar_t inChannelName[64];
- mbstowcs(inChannelName, (char*)inChannel->name, sizeof(inChannel->name));
- RefPtr<ChannelData> channel = mOuter->FindChannel(inChannelName);
- if (!channel.IsValid() || (channel != mOuter->mCurrentChannel))
- {
- WWDEBUG_SAY(("WOLERROR: OnPublicGameOptions channel mismatch\n"));
- return S_OK;
- }
- // Make sure this is from a user we know about.
- wchar_t inUsername[64];
- mbstowcs(inUsername, (char*)inUser->name, sizeof(inUser->name));
- RefPtr<UserData> user = mOuter->FindUser(inUsername);
- if (!user.IsValid())
- {
- WWDEBUG_SAY(("WOLERROR: OnPublicGameOptions unknown user\n"));
- WWASSERT(user.IsValid() && "Received game options from unknown user");
- return S_OK;
- }
- // Only handle options from other users.
- if (mOuter->mCurrentUser != user)
- {
- WWDEBUG_SAY(("WOL: PublicGameOptions [%s] from '%s': %s\n", (char*)inChannel->name, (char*)inUser->name, options));
- #ifdef FREEDEDICATEDSERVER
- int count = 0;
- if (Is_Options_Spammer((char*)inUser->name, count)) {
- if (count > 16 && count < 19) {
- Kick_Spammer(inUser);
- }
- }
- #endif
- GameOptionsMessage gameOptions(inUser, inChannel, options, false);
- mOuter->NotifyObservers(gameOptions);
- }
- return S_OK;
- }
- /******************************************************************************
- *
- * NAME
- * ChatObserver::OnGameStart
- *
- * DESCRIPTION
- *
- * INPUTS
- * Result - Error / status code.
- *
- * RESULT
- * Error / Status result
- *
- ******************************************************************************/
- STDMETHODIMP ChatObserver::OnGameStart(HRESULT result, WOL::Channel* inChannel,
- WOL::User* inUsers, int gameID)
- {
- if (mOuter == NULL)
- {
- WWDEBUG_SAY(("WOLERROR: Session not initialized\n"));
- WWASSERT(mOuter && "Session not initialized");
- return S_OK;
- }
- // Handle error condition
- if (FAILED(result))
- {
- WWDEBUG_SAY(("WOLERROR: OnGameStart '%s'\n", GetChatErrorString(result)));
- GameStartEvent gameStart(result);
- mOuter->NotifyObservers(gameStart);
- return S_OK;
- }
- // Ignore if parameters are invalid
- if (inChannel == NULL || inUsers == NULL)
- {
- WWDEBUG_SAY(("WOL: OnGameStart Invalid parameters\n"));
- return S_OK;
- }
- WWDEBUG_SAY(("WOL: OnGameStart GameID %ld, Channel '%s'\n", gameID, (char*)inChannel->name));
- // Make sure the channel is the one we have joined.
- bool channelOkay = false;
- if (mOuter->mCurrentChannel.IsValid())
- {
- wchar_t chanName[64];
- mbstowcs(chanName, (const char*)inChannel->name, sizeof(inChannel->name));
- const WideStringClass& name = mOuter->mCurrentChannel->GetName();
- channelOkay = (name.Compare_No_Case(chanName) == 0);
- }
- // The game start is invalid if this is not the channel we expect.
- if (channelOkay == false)
- {
- WWDEBUG_SAY(("WOLERROR: OnGameStart channel mismatch\n"));
- GameStartEvent gameStart(E_INVALIDARG);
- mOuter->NotifyObservers(gameStart);
- return S_OK;
- }
- // Process the game start
- UserList userList;
- WOL::User* curUser = inUsers;
- while (curUser)
- {
- WWDEBUG_SAY(("WOL: OnGameStart Player '%s'\n", (char*)curUser->name));
- wchar_t name[64];
- mbstowcs(name, (const char*)curUser->name, sizeof(curUser->name));
- // Get user from current list. If not in list then create new user.
- RefPtr<UserData> user = mOuter->FindUser(name);
- if (!user.IsValid())
- {
- user = UserData::Create(*curUser);
- }
- if (user.IsValid())
- {
- userList.push_back(user);
- }
- curUser = curUser->next;
- }
- GameStartEvent gameStart(mOuter->mCurrentChannel, userList, gameID);
- mOuter->NotifyObservers(gameStart);
- return S_OK;
- }
- /******************************************************************************
- *
- * NAME
- * ChatObserver::OnUserKick
- *
- * DESCRIPTION
- * Handle response to user kick request.
- *
- * INPUTS
- * Result - Error / status code.
- *
- * RESULT
- * Error / Status result
- *
- ******************************************************************************/
- STDMETHODIMP ChatObserver::OnUserKick(HRESULT result, WOL::Channel* inChannel,
- WOL::User* inUser, WOL::User* kicker)
- {
- if (mOuter == NULL)
- {
- WWDEBUG_SAY(("WOLERROR: Session not initialized\n"));
- WWASSERT(mOuter && "Session not initialized");
- return S_OK;
- }
- // Handle error condition
- if (FAILED(result))
- {
- WWDEBUG_SAY(("WOLERROR: OnUserKick '%s'\n", GetChatErrorString(result)));
- return S_OK;
- }
- // Check parameters
- if ((inChannel == NULL) || (inUser == NULL))
- {
- WWASSERT(inChannel);
- WWASSERT(inUser);
- WWDEBUG_SAY(("WOLWARNING: Cannot handle user kick because CHANNEL or USER is NULL\n"));
- return S_OK;
- }
- WWDEBUG_SAY(("WOL: '%s' has been kicked from channel '%s' by '%s'\n",
- (char*)inUser->name, (char*)inChannel->name, (char*)kicker->name));
- // If we are not connected to a channel then ignore.
- if (!mOuter->mCurrentChannel.IsValid())
- {
- WWDEBUG_SAY(("WOLWARNING: OnUserKick not in a channel\n"));
- return S_OK;
- }
- // If the channel is not the channel we are connected to then ignore.
- wchar_t channelName[64];
- mbstowcs(channelName, (const char*)inChannel->name, sizeof(inChannel->name));
- const WideStringClass& curChannelName = mOuter->mCurrentChannel->GetName();
- if (curChannelName.Compare_No_Case(channelName) != 0)
- {
- WWDEBUG_SAY(("WOLWARNING: OnUserKick channel mismatch\n"));
- return S_OK;
- }
- // Decrement user count for this channel
- WWASSERT(mOuter->mCurrentChannel->GetData().currentUsers > 0);
- mOuter->mCurrentChannel->GetData().currentUsers--;
- // If current user is kicked then disconnect from the channel and clear the user list.
- if (inUser->flags & CHAT_USER_MYSELF)
- {
- mOuter->mCurrentChannelStatus = ChannelKicked;
- // Release the current channel since we have been kicked
- RefPtr<ChannelData> channel = mOuter->mCurrentChannel;
- mOuter->mCurrentChannel.Release();
- // Notify others that we have been kicked from the channel.
- ChannelEvent event(ChannelKicked, channel);
- mOuter->NotifyObservers(event);
- // Clear the user list then notify others that the user list is now empty.
- mOuter->mUsers.clear();
- mOuter->NotifyObservers(mOuter->mUsers);
- }
- else
- {
- // Remove kicked user from the userlist
- wchar_t username[64];
- mbstowcs(username, (char*)inUser->name, sizeof(inUser->name));
- RefPtr<UserData> kickedUser = RemoveUserInList(username, mOuter->mUsers);
- // Notify others that the user was kicked
- if (kickedUser.IsValid())
- {
- UserEvent event(UserEvent::Kicked, kickedUser);
- mOuter->NotifyObservers(event);
- }
- }
- return S_OK;
- }
- /******************************************************************************
- *
- * NAME
- * ChatObserver::OnUserIP
- *
- * DESCRIPTION
- *
- * INPUTS
- * Result - Error / status code.
- *
- * RESULT
- * Error / Status result
- *
- ******************************************************************************/
- STDMETHODIMP ChatObserver::OnUserIP(HRESULT result, WOL::User* user)
- {
- if (mOuter == NULL)
- {
- WWDEBUG_SAY(("WOLERROR: Session not initialized\n"));
- WWASSERT(mOuter && "Session not initialized");
- return S_OK;
- }
- if (FAILED(result))
- {
- WWDEBUG_SAY(("WOLERROR: OnUserIP '%s'\n", GetChatErrorString(result)));
- if (user)
- {
- UserIPEvent event(UserIPEvent::Error, *user);
- mOuter->NotifyObservers(event);
- }
-
- return S_OK;
- }
- if (user)
- {
- UserIPEvent event(UserIPEvent::GotIP, *user);
- mOuter->NotifyObservers(event);
- }
- return S_OK;
- }
- /******************************************************************************
- *
- * NAME
- * ChatObserver::OnFind
- *
- * DESCRIPTION
- *
- * INPUTS
- * Result - Error / status code.
- *
- * RESULT
- * Error / Status result
- *
- ******************************************************************************/
- STDMETHODIMP ChatObserver::OnFind(HRESULT result, WOL::Channel* wolChannel)
- {
- if (mOuter == NULL)
- {
- WWDEBUG_SAY(("WOLERROR: Session not initialized\n"));
- WWASSERT(mOuter && "Session not initialized");
- return S_OK;
- }
- if (FAILED(result))
- {
- WWDEBUG_SAY(("WOLERROR: OnFind '%s'\n", GetChatErrorString(result)));
- UserEvent event(UserEvent::Located, RefPtr<UserData>());
- mOuter->NotifyObservers(event);
- mOuter->mLocatingUser.Release();
- return S_OK;
- }
- const RefPtr<UserData>& user = mOuter->mLocatingUser;
- if (user.IsValid())
- {
- UserLocation location = USERLOCATION_UNKNOWN;
- RefPtr<ChannelData> userChannel;
- if (wolChannel)
- {
- location = USERLOCATION_IN_CHANNEL;
- // Look for the channel in our existing list
- userChannel = mOuter->FindChannel((const char*)wolChannel->name);
- // Create the channel if we don't already have it.
- if (userChannel.IsValid() == false)
- {
- userChannel = ChannelData::Create(*wolChannel);
- }
- }
- else
- {
- switch (result)
- {
- default:
- case CHAT_S_FIND_NOCHAN:
- location = USERLOCATION_NO_CHANNEL;
- break;
- case CHAT_S_FIND_NOTHERE:
- location = USERLOCATION_OFFLINE;
- break;
- case CHAT_S_FIND_OFF:
- location = USERLOCATION_HIDING;
- break;
- }
- }
- user->SetLocation(location);
- user->SetChannel(userChannel);
- // Notify others about the users location.
- UserEvent event(UserEvent::Located, user);
- mOuter->NotifyObservers(event);
- }
- mOuter->mLocatingUser.Release();
- return S_OK;
- }
- /******************************************************************************
- *
- * NAME
- * ChatObserver::OnPageSend
- *
- * DESCRIPTION
- *
- * INPUTS
- * Result - Error / status code.
- *
- * RESULT
- * Error / Status result
- *
- ******************************************************************************/
- STDMETHODIMP ChatObserver::OnPageSend(HRESULT result)
- {
- PageSendStatus status = PAGESEND_ERROR;
- switch (result)
- {
- default:
- case E_FAIL:
- status = PAGESEND_ERROR;
- break;
- case CHAT_S_PAGE_NOTHERE:
- status = PAGESEND_OFFLINE;
- break;
- case CHAT_S_PAGE_OFF:
- status = PAGESEND_HIDING;
- break;
- case S_OK:
- status = PAGESEND_SENT;
- break;
- }
- mOuter->NotifyObservers(status);
- return S_OK;
- }
- /******************************************************************************
- *
- * NAME
- * ChatObserver::OnPaged
- *
- * DESCRIPTION
- * Handle being paged by user.
- *
- * INPUTS
- * Result - Error / status code.
- * User - User who initiated page.
- * Text - Page message
- *
- * RESULT
- * Error / Status result
- *
- ******************************************************************************/
- STDMETHODIMP ChatObserver::OnPaged(HRESULT result, WOL::User* user, LPCSTR text)
- {
- if (mOuter == NULL)
- {
- WWDEBUG_SAY(("WOLERROR: Session not initialized\n"));
- WWASSERT(mOuter && "Session not initialized");
- return S_OK;
- }
- if (FAILED(result))
- {
- WWDEBUG_SAY(("WOLERROR: OnPaged '%s'\n", GetChatErrorString(result)));
- return S_OK;
- }
- if (user && text)
- {
- PageMessage page((const char*)&user->name[0], text);
- mOuter->NotifyObservers(page);
- }
- return S_OK;
- }
- /******************************************************************************
- *
- * NAME
- * ChatObserver::OnServerBannedYou
- *
- * DESCRIPTION
- * The login has been banned from the server.
- *
- * INPUTS
- * Result - Error / status code.
- * LiftedTime - Time banned will be lifted.
- *
- * RESULT
- * Error / Status result
- *
- ******************************************************************************/
- STDMETHODIMP ChatObserver::OnServerBannedYou(HRESULT, WOL::time_t liftedTime)
- {
- if (mOuter == NULL)
- {
- WWDEBUG_SAY(("WOLERROR: Session not initialized\n"));
- WWASSERT(mOuter && "Session not initialized");
- return S_OK;
- }
- WWDEBUG_SAY(("WOL: OnServerBannedYou\n"));
- ServerError event(CHAT_E_BANNED, "WOL_BANNED", liftedTime);
- mOuter->NotifyObservers(event);
- return S_OK;
- }
- /******************************************************************************
- *
- * NAME
- * ChatObserver::OnChannelBan
- *
- * DESCRIPTION
- *
- * INPUTS
- * Result - Error / status code.
- *
- * RESULT
- * Error / Status result
- *
- ******************************************************************************/
- STDMETHODIMP ChatObserver::OnChannelBan(HRESULT result, LPCSTR username, int banned)
- {
- if (mOuter == NULL)
- {
- WWDEBUG_SAY(("WOLERROR: Session not initialized\n"));
- WWASSERT(mOuter && "Session not initialized");
- return S_OK;
- }
- if (FAILED(result))
- {
- WWDEBUG_SAY(("WOLERROR: OnChannelBan '%s'\n", GetChatErrorString(result)));
- return S_OK;
- }
- WWDEBUG_SAY(("WOL: '%s' has been %s\n", username, banned ? "banned" : "unbanned"));
- if (banned && username)
- {
- wchar_t name[64];
- mbstowcs(name, username, 63);
- RefPtr<UserData> user = mOuter->GetUserOrBuddy(name);
- if (!user.IsValid())
- {
- user = UserData::Create(name);
- }
- UserEvent event(UserEvent::Banned, user);
- mOuter->NotifyObservers(event);
- }
- return S_OK;
- }
- /******************************************************************************
- *
- * NAME
- * ChatObserver::OnUserFlags
- *
- * DESCRIPTION
- *
- * INPUTS
- * Result - Error / status code.
- *
- * RESULT
- * Error / Status result
- *
- ******************************************************************************/
- STDMETHODIMP ChatObserver::OnUserFlags(HRESULT result, LPCSTR username, unsigned int flags, unsigned int mask)
- {
- if (mOuter == NULL)
- {
- WWDEBUG_SAY(("WOLERROR: Session not initialized\n"));
- WWASSERT(mOuter && "Session not initialized");
- return S_OK;
- }
- if (FAILED(result))
- {
- WWDEBUG_SAY(("WOLERROR: OnUserFlags '%s'\n", GetChatErrorString(result)));
- return S_OK;
- }
- // Find the user and update their flag settings
- wchar_t name[64];
- mbstowcs(name, username, 63);
- RefPtr<UserData> user = mOuter->GetUserOrBuddy(name);
- if (user.IsValid())
- {
- unsigned int userflags = user->GetData().flags;
- user->GetData().flags = ((userflags & mask) | flags);
- UserEvent event(UserEvent::NewData, user);
- mOuter->NotifyObservers(event);
- }
- return S_OK;
- }
- /******************************************************************************
- *
- * NAME
- * ChatObserver::OnSquadInfo
- *
- * DESCRIPTION
- * Handle receipt of squad information.
- *
- * INPUTS
- * Result - Error / status code.
- * WOLSquad - WOLAPI squad structure
- *
- * RESULT
- * Error / Status result
- *
- ******************************************************************************/
- STDMETHODIMP ChatObserver::OnSquadInfo(HRESULT result, unsigned long squadID, WOL::Squad* inSquad)
- {
- if (mOuter == NULL)
- {
- WWDEBUG_SAY(("WOLERROR: Session not initialized\n"));
- WWASSERT(mOuter && "Session not initialized");
- return S_OK;
- }
- // Requested squad not found.
- if (CHAT_E_NONESUCH == result)
- {
- if (!mOuter->mSquadPending.empty())
- {
- RefPtr<SquadData> squad;
- ProcessSquadRequest(squad);
- return S_OK;
- }
- }
- if (FAILED(result))
- {
- WWDEBUG_SAY(("WOLERROR: OnSquadInfo '%s'\n", GetChatErrorString(result)));
- return S_OK;
- }
- WOL::Squad* wolSquad = inSquad;
- while (wolSquad)
- {
- // WWDEBUG_SAY(("WOL: OnSquadInfo ID %ld, Name '%s', Abbr '%s'\n", inSquad->id, inSquad->name, inSquad->abbreviation));
- // If the squad is already in the local cache then update it.
- // Otherwise create and cache a local copy if this squad information.
- RefPtr<SquadData> squad = SquadData::FindByID(wolSquad->id);
- if (squad.IsValid())
- {
- squad->UpdateData(*wolSquad);
- }
- else
- {
- squad = SquadData::Create(*wolSquad);
- // Automatically request ladder information for this squad.
- if (squad.IsValid())
- {
- wchar_t abbr[64];
- mbstowcs(abbr, squad->GetAbbr(), 64);
- abbr[63] = 0;
- mOuter->RequestLadderInfo(abbr, LadderType_Clan);
- }
- }
- if (squad.IsValid())
- {
- // Assign this squad to any users that are members.
- AssignSquadToUsers(mOuter->GetUserList(), squad);
- AssignSquadToUsers(mOuter->GetBuddyList(), squad);
- ProcessSquadRequest(squad);
- }
- wolSquad = wolSquad->next;
- }
- return S_OK;
- }
- void ChatObserver::AssignSquadToUsers(const UserList& users, const RefPtr<SquadData>& squad)
- {
- // Assign the squad to users who are its members.
- const unsigned int userCount = users.size();
- for (unsigned int index = 0; index < userCount; ++index)
- {
- const RefPtr<UserData>& user = users[index];
- if (user.IsValid() && (user->GetSquadID() == squad->GetID()))
- {
- user->SetSquad(squad);
- // Notify others that this user received squad information
- UserEvent event(UserEvent::SquadInfo, user);
- mOuter->NotifyObservers(event);
- }
- }
- }
- void ChatObserver::ProcessSquadRequest(const RefPtr<SquadData>& squad)
- {
- // Process any particular squad requests that have been made.
- if (!mOuter->mSquadPending.empty())
- {
- // Get the first pending squad request from the queue and see if it's a request by ID or Name.
- const WideStringClass& pending = mOuter->mSquadPending[0];
- if (squad.IsValid())
- {
- WWDEBUG_SAY(("WOL: Squad %s found for %S\n", squad->GetAbbr(), (const WCHAR*)pending));
- // First character of user names cannot be numbers. Therefore if it is a number
- // then process the request by ID. Otherwise process the request by name.
- wchar_t firstChar = pending[0];
- if (iswdigit(firstChar))
- {
- unsigned int pendingID = _wtoi(pending);
- if (squad->GetID() == pendingID)
- {
- SquadEvent squadEvent(NULL, squad);
- mOuter->NotifyObservers(squadEvent);
- }
- else
- {
- WWDEBUG_SAY(("WOLWARNING: OnSquadInfo PendingID '%u' doesn't match CurrentID '%u'\n", pendingID, squad->GetID()));
- }
- }
- else
- {
- RefPtr<UserData> user = mOuter->GetUserOrBuddy(pending);
- if (user.IsValid())
- {
- user->SetSquad(squad);
- UserEvent event(UserEvent::SquadInfo, user);
- mOuter->NotifyObservers(event);
- }
- // Must be a user name that we requested by
- SquadEvent squadEvent(pending, squad);
- mOuter->NotifyObservers(squadEvent);
- }
- }
- else
- {
- WWDEBUG_SAY(("WOL: Squad not found for '%S'\n", (const WCHAR*)pending));
- }
- Session::SquadRequestColl::iterator first = mOuter->mSquadPending.begin();
- mOuter->mSquadPending.erase(first);
- }
- }
- /******************************************************************************
- *
- * NAME
- * ChatObserver::OnUserLocale
- *
- * DESCRIPTION
- *
- * INPUTS
- * Result - Error / status code.
- *
- * RESULT
- * Error / Status result
- *
- ******************************************************************************/
- STDMETHODIMP ChatObserver::OnUserLocale(HRESULT result, WOL::User* inUsers)
- {
- if (mOuter == NULL)
- {
- WWDEBUG_SAY(("WOLERROR: Session not initialized\n"));
- WWASSERT(mOuter && "Session not initialized");
- return S_OK;
- }
- if (FAILED(result))
- {
- WWDEBUG_SAY(("WOLERROR: OnUserLocale '%s'\n", GetChatErrorString(result)));
- return S_OK;
- }
- WOL::User* wolUser = inUsers;
- while (wolUser)
- {
- WWDEBUG_SAY(("WOL: OnUserLocale '%s' %ld\n", wolUser->name, wolUser->locale));
- WOL::Locale locale = wolUser->locale;
- WWASSERT(locale >= WOL::LOC_UNKNOWN && locale <= WOL::LOC_TURKEY && "OnUserLocale Locale out of range!");
- // Update the users locale.
- wchar_t username[64];
- mbstowcs(username, (const char*)wolUser->name, sizeof(wolUser->name));
- RefPtr<UserData> user = mOuter->GetUserOrBuddy(username);
- if (user.IsValid() && (user->GetLocale() != locale))
- {
- // If the current user's requested locale is different than the player's
- // login locale then update the locale in the WWOnline database to match
- // the login locale.
- if (mOuter->IsCurrentUser(user))
- {
- const RefPtr<LoginInfo>& login = mOuter->GetCurrentLogin();
- WWASSERT(login.IsValid() && "OnUserLocale: Login not set");
- if (login.IsValid())
- {
- WOL::Locale loginLocale = login->GetLocale();
- if (locale != loginLocale)
- {
- mOuter->ChangeCurrentUserLocale(loginLocale);
- }
- }
- }
- // Update the locale for this user.
- user->SetLocale(locale);
- UserEvent event(UserEvent::Locale, user);
- mOuter->NotifyObservers(event);
- }
- wolUser = wolUser->next;
- }
- return S_OK;
- }
- /******************************************************************************
- *
- * NAME
- * ChatObserver::OnSetLocale
- *
- * DESCRIPTION
- * Handle response to IChat::RequestSetLocale
- *
- * INPUTS
- * Result - Error / status code.
- * Locale - New locale for current user.
- *
- * RESULT
- * Error / Status result
- *
- ******************************************************************************/
- STDMETHODIMP ChatObserver::OnSetLocale(HRESULT result, WOL::Locale locale)
- {
- if (FAILED(result))
- {
- WWDEBUG_SAY(("WOLERROR: OnSetLocale '%s'\n", GetChatErrorString(result)));
- return S_OK;
- }
- WWASSERT(mOuter && "Session not initialized");
- // Verify that the locale is what we expected.
- const RefPtr<LoginInfo>& login = mOuter->GetCurrentLogin();
- WWASSERT(login.IsValid() && "OnSetLocale: Invalid Login");
- if (login.IsValid() && (login->GetLocale() != locale))
- {
- WWDEBUG_SAY(("WOLERROR: OnSetLocale - Mismatch with login locale\n"));
- WWASSERT(login->GetLocale() == locale && "OnSetLocale: Mismatch with login locale");
- }
- // Set the current users locale to the newly requested one.
- RefPtr<UserData> user = mOuter->GetCurrentUser();
- if (user.IsValid())
- {
- user->SetLocale(locale);
- UserEvent event(UserEvent::Locale, user);
- mOuter->NotifyObservers(event);
- }
- else
- {
- WWDEBUG_SAY(("WOLERROR: OnSetLocale Invalid current user\n"));
- WWASSERT(user.IsValid() && "OnSetLocale Invalid current user");
- }
- return S_OK;
- }
- /******************************************************************************
- *
- * NAME
- * ChatObserver::OnUserTeam
- *
- * DESCRIPTION
- *
- * INPUTS
- * Result - Error / status code.
- *
- * RESULT
- * Error / Status result
- *
- ******************************************************************************/
- STDMETHODIMP ChatObserver::OnUserTeam(HRESULT result, WOL::User* inUsers)
- {
- if (mOuter == NULL)
- {
- WWDEBUG_SAY(("WOLERROR: Session not initialized\n"));
- WWASSERT(mOuter && "Session not initialized");
- return S_OK;
- }
- if (FAILED(result))
- {
- WWDEBUG_SAY(("WOLERROR: OnUserTeam '%s'\n", GetChatErrorString(result)));
- return S_OK;
- }
- WOL::User* wolUser = inUsers;
- while (wolUser)
- {
- WWDEBUG_SAY(("WOL: OnUserTeam '%s' %ld\n", wolUser->name, wolUser->locale));
- // Update the users locale.
- wchar_t username[64];
- mbstowcs(username, (const char*)wolUser->name, sizeof(wolUser->name));
- RefPtr<UserData> user = mOuter->GetUserOrBuddy(username);
- if (user.IsValid())
- {
- user->SetTeam(wolUser->team);
- UserEvent event(UserEvent::NewData, user);
- mOuter->NotifyObservers(event);
- }
- wolUser = wolUser->next;
- }
- return S_OK;
- }
- /******************************************************************************
- *
- * NAME
- * ChatObserver::OnSetTeam
- *
- * DESCRIPTION
- *
- * INPUTS
- * Result - Error / status code.
- *
- * RESULT
- * Error / Status result
- *
- ******************************************************************************/
- STDMETHODIMP ChatObserver::OnSetTeam(HRESULT result, int team)
- {
- if (mOuter == NULL)
- {
- WWDEBUG_SAY(("WOLERROR: Session not initialized\n"));
- WWASSERT(mOuter && "Session not initialized");
- return S_OK;
- }
- if (FAILED(result))
- {
- WWDEBUG_SAY(("WOLERROR: OnSetTeam '%s'\n", GetChatErrorString(result)));
- return S_OK;
- }
- RefPtr<UserData> user = mOuter->GetCurrentUser();
- if (user.IsValid())
- {
- user->SetTeam(team);
- UserEvent event(UserEvent::NewData, user);
- mOuter->NotifyObservers(event);
- }
- return S_OK;
- }
- /******************************************************************************
- *
- * NAME
- * ChatObserver::OnBuddyList
- *
- * DESCRIPTION
- *
- * INPUTS
- * Result - Result / status code.
- * Buddies - User list of buddies.
- *
- * RESULT
- * Error / Status result
- *
- ******************************************************************************/
- STDMETHODIMP ChatObserver::OnBuddyList(HRESULT result, WOL::User* inUsers)
- {
- if (mOuter == NULL)
- {
- WWDEBUG_SAY(("WOLERROR: Session not initialized\n"));
- WWASSERT(mOuter && "Session not initialized");
- return S_OK;
- }
- if (FAILED(result))
- {
- WWDEBUG_SAY(("WOLERROR: OnBuddyList '%s'\n", GetChatErrorString(result)));
- UserList buddies;
- BuddyEvent event(BuddyEvent::NewList, buddies);
- mOuter->NotifyObservers(event);
- return S_OK;
- }
- WWDEBUG_SAY(("WOL: OnBuddyList\n"));
- // Generate new list
- UserList buddies;
- WOL::User* wolUser = inUsers;
- while (wolUser)
- {
- WideStringClass name(64, true);
- name = (char*)wolUser->name;
- // First look for buddy in our old list.
- RefPtr<UserData> buddy = mOuter->FindBuddy(name);
- // Create a new buddy if we don't already know about him.
- if (buddy.IsValid() == false)
- {
- buddy = UserData::Create(*wolUser);
- }
- if (buddy.IsValid())
- {
- buddies.push_back(buddy);
- }
- wolUser = wolUser->next;
- }
- mOuter->mBuddies = buddies;
- BuddyEvent event(BuddyEvent::NewList, mOuter->mBuddies);
- mOuter->NotifyObservers(event);
- return S_OK;
- }
- /******************************************************************************
- *
- * NAME
- * ChatObserver::OnBuddyAdd
- *
- * DESCRIPTION
- *
- * INPUTS
- * Result - Result / status code.
- * Buddies - User list of buddies added.
- *
- * RESULT
- * Error / Status result
- *
- ******************************************************************************/
- STDMETHODIMP ChatObserver::OnBuddyAdd(HRESULT result, WOL::User* inUsers)
- {
- if (mOuter == NULL)
- {
- WWDEBUG_SAY(("WOLERROR: Session not initialized\n"));
- WWASSERT(mOuter && "Session not initialized");
- return S_OK;
- }
- if (FAILED(result))
- {
- WWDEBUG_SAY(("WOLERROR: OnBuddyAdd '%s'\n", GetChatErrorString(result)));
- UserList addList;
- BuddyEvent event(BuddyEvent::Added, addList);
- mOuter->NotifyObservers(event);
- return S_OK;
- }
- // Generate new list
- UserList addList;
- WOL::User* wolUser = inUsers;
- while (wolUser)
- {
- WideStringClass name(64, true);
- name = (char*)wolUser->name;
- // First look for buddy in our old list.
- RefPtr<UserData> buddy = mOuter->FindBuddy(name);
- // Create a new buddy if we don't already know about him.
- if (buddy.IsValid() == false)
- {
- buddy = UserData::Create(*wolUser);
- if (buddy.IsValid())
- {
- mOuter->mBuddies.push_back(buddy);
- addList.push_back(buddy);
- }
- }
- wolUser = wolUser->next;
- }
- if (addList.size() > 0)
- {
- BuddyEvent event(BuddyEvent::Added, addList);
- mOuter->NotifyObservers(event);
- }
- return S_OK;
- }
- /******************************************************************************
- *
- * NAME
- * ChatObserver::OnBuddyDelete
- *
- * DESCRIPTION
- *
- * INPUTS
- * Result - Result / status code.
- * Buddies - User list of buddies removed
- *
- * RESULT
- * Error / Status result
- *
- ******************************************************************************/
- STDMETHODIMP ChatObserver::OnBuddyDelete(HRESULT result, WOL::User* inUsers)
- {
- if (mOuter == NULL)
- {
- WWDEBUG_SAY(("WOLERROR: Session not initialized\n"));
- WWASSERT(mOuter && "Session not initialized");
- return S_OK;
- }
- if (FAILED(result))
- {
- WWDEBUG_SAY(("WOLERROR: OnBuddyDelete '%s'\n", GetChatErrorString(result)));
- return S_OK;
- }
- // Generate new list
- UserList deleteList;
- WOL::User* wolUser = inUsers;
- while (wolUser)
- {
- WideStringClass name(64, true);
- name = (char*)wolUser->name;
- RefPtr<UserData> buddy = RemoveUserInList(name, mOuter->mBuddies);
- if (buddy.IsValid())
- {
- deleteList.push_back(buddy);
- }
- wolUser = wolUser->next;
- }
- if (deleteList.size() > 0)
- {
- BuddyEvent event(BuddyEvent::Deleted, deleteList);
- mOuter->NotifyObservers(event);
- }
- return S_OK;
- }
- /******************************************************************************
- *
- * NAME
- * ChatObserver::OnPublicUnicodeMesssage
- *
- * DESCRIPTION
- *
- * INPUTS
- * Result - Error / status code.
- *
- * RESULT
- * Error / Status result
- *
- ******************************************************************************/
- STDMETHODIMP ChatObserver::OnPublicUnicodeMessage(HRESULT result, WOL::Channel*,
- WOL::User* user, const unsigned short* message)
- {
- if (mOuter == NULL)
- {
- WWDEBUG_SAY(("WOLERROR: Session not initialized\n"));
- WWASSERT(mOuter && "Session not initialized");
- return S_OK;
- }
- if (FAILED(result))
- {
- WWDEBUG_SAY(("WOLERROR: OnPublicUnicodeMessage '%s'\n", GetChatErrorString(result)));
- }
- else
- {
- ChatMessage msg(user, message, false, false);
- mOuter->NotifyObservers(msg);
- }
- return S_OK;
- }
- /******************************************************************************
- *
- * NAME
- * ChatObserver::OnPrivateUnicodeMessage
- *
- * DESCRIPTION
- *
- * INPUTS
- * Result - Error / status code.
- *
- * RESULT
- * Error / Status result
- *
- ******************************************************************************/
- STDMETHODIMP ChatObserver::OnPrivateUnicodeMessage(HRESULT result, WOL::User* user,
- const unsigned short* message)
- {
- if (mOuter == NULL)
- {
- WWDEBUG_SAY(("WOLERROR: Session not initialized\n"));
- WWASSERT(mOuter && "Session not initialized");
- return S_OK;
- }
- if (FAILED(result))
- {
- WWDEBUG_SAY(("WOLERROR: OnPrivateUnicodeMessage '%s'\n", GetChatErrorString(result)));
- }
- else
- {
- ChatMessage msg(user, message, true, false);
- mOuter->NotifyObservers(msg);
- }
- return S_OK;
- }
- /******************************************************************************
- *
- * NAME
- * ChatObserver::OnPrivateUnicodeAction
- *
- * DESCRIPTION
- *
- * INPUTS
- * Result - Error / status code.
- *
- * RESULT
- * Error / Status result
- *
- ******************************************************************************/
- STDMETHODIMP ChatObserver::OnPrivateUnicodeAction(HRESULT result, WOL::User* user,
- const unsigned short* message)
- {
- if (mOuter == NULL)
- {
- WWDEBUG_SAY(("WOLERROR: Session not initialized\n"));
- WWASSERT(mOuter && "Session not initialized");
- return S_OK;
- }
- if (FAILED(result))
- {
- WWDEBUG_SAY(("WOLERROR: OnPrivateUnicodeAction '%s'\n", GetChatErrorString(result)));
- }
- else
- {
- ChatMessage msg(user, message, true, true);
- mOuter->NotifyObservers(msg);
- }
- return S_OK;
- }
- /******************************************************************************
- *
- * NAME
- * ChatObserver::OnPublicUnicodeAction
- *
- * DESCRIPTION
- *
- * INPUTS
- * Result - Error / status code.
- *
- * RESULT
- * Error / Status result
- *
- ******************************************************************************/
- STDMETHODIMP ChatObserver::OnPublicUnicodeAction(HRESULT result, WOL::Channel*,
- WOL::User* user, const unsigned short* message)
- {
- if (mOuter == NULL)
- {
- WWDEBUG_SAY(("WOLERROR: Session not initialized\n"));
- WWASSERT(mOuter && "Session not initialized");
- return S_OK;
- }
- if (FAILED(result))
- {
- WWDEBUG_SAY(("WOLERROR: OnPublicUnicodeAction '%s'\n", GetChatErrorString(result)));
- }
- else
- {
- ChatMessage msg(user, message, false, true);
- mOuter->NotifyObservers(msg);
- }
- return S_OK;
- }
- /******************************************************************************
- *
- * NAME
- * ChatObserver::OnPagedUnicode
- *
- * DESCRIPTION
- *
- * INPUTS
- * Result - Error / status code.
- *
- * RESULT
- * Error / Status result
- *
- ******************************************************************************/
- STDMETHODIMP ChatObserver::OnPagedUnicode(HRESULT result, WOL::User* user, const unsigned short* text)
- {
- if (mOuter == NULL)
- {
- WWDEBUG_SAY(("WOLERROR: Session not initialized\n"));
- WWASSERT(mOuter && "Session not initialized");
- return S_OK;
- }
- if (FAILED(result))
- {
- WWDEBUG_SAY(("WOLERROR: OnPagedUnicode '%s'\n", GetChatErrorString(result)));
- return S_OK;
- }
- if (user && text)
- {
- wchar_t name[64];
- mbstowcs(name, (const char*)&user->name[0], sizeof(user->name));
- PageMessage page(name, text);
- mOuter->NotifyObservers(page);
- }
- return S_OK;
- }
- /******************************************************************************
- *
- * NAME
- * ChatObserver::OnServerTime
- *
- * DESCRIPTION
- *
- * INPUTS
- * Result - Error / status code.
- *
- * RESULT
- * Error / Status result
- *
- ******************************************************************************/
- STDMETHODIMP ChatObserver::OnServerTime(HRESULT result, WOL::time_t server_time)
- {
- if (mOuter == NULL)
- {
- WWDEBUG_SAY(("WOLERROR: Session not initialized\n"));
- WWASSERT(mOuter && "Session not initialized");
- return S_OK;
- }
- if (FAILED(result))
- {
- WWDEBUG_SAY(("WOLERROR: OnServerTime '%s'\n", GetChatErrorString(result)));
- return S_OK;
- }
- mOuter->mServerTime = server_time;
- return S_OK;
- }
- /******************************************************************************
- *
- * NAME
- * ChatObserver::OnInsiderStatus
- *
- * DESCRIPTION
- *
- * INPUTS
- * Result - Error / status code.
- *
- * RESULT
- * Error / Status result
- *
- ******************************************************************************/
- STDMETHODIMP ChatObserver::OnInsiderStatus(HRESULT result, WOL::User* wolUsers)
- {
- if (mOuter == NULL)
- {
- WWDEBUG_SAY(("WOLERROR: Session not initialized\n"));
- WWASSERT(mOuter && "Session not initialized");
- return S_OK;
- }
- if (FAILED(result))
- {
- WWDEBUG_SAY(("WOLERROR: OnInsiderStatus '%s'\n", GetChatErrorString(result)));
- return S_OK;
- }
- if (wolUsers != NULL)
- {
- // Get the name of the currently logged in user
- RefPtr<UserData> curr_user = mOuter->GetCurrentUser();
-
- // Convert the WOL user's name to a wide character string
- WideStringClass wide_name(0, true);
- wide_name.Convert_From((const char*)wolUsers[0].name);
- // Check to see if we got information back about the current user
- if (curr_user->GetName().Compare_No_Case(wide_name) == 0)
- {
- mOuter->mIsInsider = wolUsers[0].squadname[0] != '0';
- }
- }
- return S_OK;
- }
- /******************************************************************************
- *
- * NAME
- * ChatObserver::OnSetLocalIP
- *
- * DESCRIPTION
- *
- * INPUTS
- * Result - Error / status code.
- *
- * RESULT
- * Error / Status result
- *
- ******************************************************************************/
- STDMETHODIMP ChatObserver::OnSetLocalIP(HRESULT, LPCSTR)
- {
- WWDEBUG_SAY(("WOLWARNING: OnSetLocalIP not implemented\n"));
- return S_OK;
- }
- /******************************************************************************
- *
- * NAME
- * ChatObserver::OnChannelBegin
- *
- * DESCRIPTION
- *
- * INPUTS
- *
- * RESULT
- * Error / Status result
- *
- ******************************************************************************/
- STDMETHODIMP ChatObserver::OnChannelListBegin(HRESULT result)
- {
- if (mOuter == NULL)
- {
- WWDEBUG_SAY(("WOLERROR: Session not initialized\n"));
- WWASSERT(mOuter && "Session not initialized");
- return S_OK;
- }
- if (FAILED(result))
- {
- WWDEBUG_SAY(("WOLERROR: OnChannelListBegin '%s'\n", GetChatErrorString(result)));
- ChannelList empty;
- ChannelListEvent error(ChannelListEvent::Error, empty, -1);
- mOuter->NotifyObservers(error);
- return S_OK;
- }
- WWDEBUG_SAY(("WOL: OnChannelListBegin %d\n", mOuter->mRequestedChannelType));
- mOuter->mIncommingChatChannels.clear();
- mOuter->mIncommingGameChannels.clear();
- WWASSERT(mOuter->mRequestedChannelType >= 0);
- return S_OK;
- }
- /******************************************************************************
- *
- * NAME
- * ChatObserver::OnChannelListEntry
- *
- * DESCRIPTION
- *
- * INPUTS
- *
- * RESULT
- * Error / Status result
- *
- ******************************************************************************/
- STDMETHODIMP ChatObserver::OnChannelListEntry(HRESULT result, WOL::Channel* wolChannel)
- {
- if (mOuter == NULL)
- {
- WWDEBUG_SAY(("WOLERROR: Session not initialized\n"));
- WWASSERT(mOuter && "Session not initialized");
- return S_OK;
- }
- if (FAILED(result) || (wolChannel == NULL) || (wolChannel->type != mOuter->mRequestedChannelType))
- {
- WWDEBUG_SAY(("WOLERROR: OnChannelListEntry '%s'\n", GetChatErrorString(result)));
- ChannelList empty;
- ChannelListEvent error(ChannelListEvent::Error, empty, -1);
- mOuter->NotifyObservers(error);
- return S_OK;
- }
- WWDEBUG_SAY(("WOL: ChannelEntry '%s:%ld'\n", (const char*)wolChannel->name, wolChannel->type));
- // Get code for game channels
- RefPtrConst<Product> product = Product::Current();
- WWASSERT(product.IsValid() && "WOLProduct not initialized");
- int gameCode = product->GetGameCode();
- ChannelList* list = NULL;
- if (wolChannel->type == 0)
- {
- list = &mOuter->mChatChannels;
- }
- else if (wolChannel->type == gameCode)
- {
- list = &mOuter->mGameChannels;
- }
- else
- {
- return S_OK;
- }
- // Process the channel
- ChannelList inList;
- ChannelList outList;
- // Check if the channel exists in the current list. If the channel exists in
- // the current list then update the channel. Otherwise the channel is new,
- // therefore we need to add it.
- ChannelList::iterator iter = FindChannelNode(*list, (const char*)wolChannel->name);
- // If the channel already exists then just update it.
- if (iter != list->end())
- {
- // Update the channel data.
- RefPtr<ChannelData> channel = *iter;
- WWASSERT(channel.IsValid());
- channel->UpdateData(*wolChannel);
- // Channels arrive alphabetically. Therefore if there are any channels
- // in the list before this one then those channels are no longer around.
- // So move those channels into the out list.
- if (iter != list->begin())
- {
- #ifdef _DEBUG
- ChannelList::iterator remIter = list->begin();
- while (remIter != iter)
- {
- WWDEBUG_SAY(("WOL: Removing Channel '%S'\n", (*remIter)->GetName()));
- remIter++;
- }
- #endif
- ChannelList::iterator end = outList.end();
- outList.splice(end, *list, list->begin(), iter);
- }
- // Move the channel into the new list.
- ChannelList::iterator end = inList.end();
- inList.splice(end, *list, iter);
- }
- else
- {
- // Create the new channel and add it to the new list.
- RefPtr<ChannelData> channel = ChannelData::Create(*wolChannel);
- WWASSERT(channel.IsValid());
- inList.push_back(channel);
- }
- // Notify others about the channel changes
- if (inList.empty() == false)
- {
- ChannelListEvent inEvent(ChannelListEvent::Update, inList, wolChannel->type);
- mOuter->NotifyObservers(inEvent);
- }
- if (outList.empty() == false)
- {
- ChannelListEvent outEvent(ChannelListEvent::Remove, outList, wolChannel->type);
- mOuter->NotifyObservers(outEvent);
- }
- if (wolChannel->type == 0)
- {
- ChannelList::iterator end = mOuter->mIncommingChatChannels.end();
- mOuter->mIncommingChatChannels.splice(end, inList);
- }
- else
- {
- ChannelList::iterator end = mOuter->mIncommingGameChannels.end();
- mOuter->mIncommingGameChannels.splice(end, inList);
- }
- return S_OK;
- }
- /******************************************************************************
- *
- * NAME
- * ChatObserver::OnChannelListEnd
- *
- * DESCRIPTION
- *
- * INPUTS
- *
- * RESULT
- * Error / Status result
- *
- ******************************************************************************/
- STDMETHODIMP ChatObserver::OnChannelListEnd(HRESULT result)
- {
- if (mOuter == NULL)
- {
- WWDEBUG_SAY(("WOLERROR: Session not initialized\n"));
- WWASSERT(mOuter && "Session not initialized");
- return S_OK;
- }
- if (FAILED(result))
- {
- WWDEBUG_SAY(("WOLERROR: OnChannelListEnd '%s'\n", GetChatErrorString(result)));
- ChannelList empty;
- ChannelListEvent error(ChannelListEvent::Error, empty, -1);
- mOuter->NotifyObservers(error);
- return S_OK;
- }
- WWDEBUG_SAY(("WOL: OnChannelListEnd %d\n", mOuter->mRequestedChannelType));
- WWASSERT(mOuter->mRequestedChannelType >= 0);
- // Replace lists
- ChannelList* channelList = NULL;
- ChannelList* newList = NULL;
- int channelType = 0;
- if (mOuter->mRequestedChannelType == 0)
- {
- channelList = &mOuter->mChatChannels;
- newList = &mOuter->mIncommingChatChannels;
- }
- else
- {
- RefPtr<Product> product = Product::Current();
- WWASSERT(product.IsValid());
- channelType = product->GetGameCode();
- channelList = &mOuter->mGameChannels;
- newList = &mOuter->mIncommingGameChannels;
- }
- WWASSERT(channelList != NULL);
- WWASSERT(newList != NULL);
- // Any leftover channels were not in the new list. So, send a
- // notification that these channels are being removed then remove them.
- if (!channelList->empty())
- {
- ChannelListEvent outEvent(ChannelListEvent::Remove, *channelList, channelType);
- mOuter->NotifyObservers(outEvent);
- channelList->clear();
- }
-
- // Swap in the new channel list
- channelList->swap(*newList);
- // Send notification about the new channel list.
- ChannelListEvent listEvent(ChannelListEvent::NewList, *channelList, channelType);
- mOuter->NotifyObservers(listEvent);
- mOuter->mRequestedChannelType = -1;
- return S_OK;
- }
- } // namespace WWOnline
|