| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679 |
- /*
- ** Command & Conquer Generals Zero Hour(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/>.
- */
- ////////////////////////////////////////////////////////////////////////////////
- // //
- // (c) 2001-2003 Electronic Arts Inc. //
- // //
- ////////////////////////////////////////////////////////////////////////////////
- // FILE: BuddyThread.cpp //////////////////////////////////////////////////////
- // GameSpy Presence & Messaging (Buddy) thread
- // This thread communicates with GameSpy's buddy server
- // and talks through a message queue with the rest of
- // the game.
- // Author: Matthew D. Campbell, June 2002
- #include "PreRTS.h" // This must go first in EVERY cpp file int the GameEngine
- #include "GameNetwork/GameSpy/BuddyThread.h"
- #include "GameNetwork/GameSpy/PeerThread.h"
- #include "GameNetwork/GameSpy/PersistentStorageThread.h"
- #include "GameNetwork/GameSpy/ThreadUtils.h"
- #include "Common/StackDump.h"
- #include "mutex.h"
- #include "thread.h"
- #ifdef _INTERNAL
- // for occasional debugging...
- //#pragma optimize("", off)
- //#pragma MESSAGE("************************************** WARNING, optimization disabled for debugging purposes")
- #endif
- //-------------------------------------------------------------------------
- typedef std::queue<BuddyRequest> RequestQueue;
- typedef std::queue<BuddyResponse> ResponseQueue;
- class BuddyThreadClass;
- class GameSpyBuddyMessageQueue : public GameSpyBuddyMessageQueueInterface
- {
- public:
- virtual ~GameSpyBuddyMessageQueue();
- GameSpyBuddyMessageQueue();
- virtual void startThread( void );
- virtual void endThread( void );
- virtual Bool isThreadRunning( void );
- virtual Bool isConnected( void );
- virtual Bool isConnecting( void );
- virtual void addRequest( const BuddyRequest& req );
- virtual Bool getRequest( BuddyRequest& req );
- virtual void addResponse( const BuddyResponse& resp );
- virtual Bool getResponse( BuddyResponse& resp );
- virtual GPProfile getLocalProfileID( void );
- BuddyThreadClass* getThread( void );
- private:
- MutexClass m_requestMutex;
- MutexClass m_responseMutex;
- RequestQueue m_requests;
- ResponseQueue m_responses;
- BuddyThreadClass *m_thread;
- };
- GameSpyBuddyMessageQueueInterface* GameSpyBuddyMessageQueueInterface::createNewMessageQueue( void )
- {
- return NEW GameSpyBuddyMessageQueue;
- }
- GameSpyBuddyMessageQueueInterface *TheGameSpyBuddyMessageQueue;
- #define MESSAGE_QUEUE ((GameSpyBuddyMessageQueue *)TheGameSpyBuddyMessageQueue)
- //-------------------------------------------------------------------------
- class BuddyThreadClass : public ThreadClass
- {
- public:
- BuddyThreadClass() : ThreadClass() { m_isNewAccount = m_isdeleting = m_isConnecting = m_isConnected = false; m_profileID = 0; m_lastErrorCode = 0; }
- void Thread_Function();
- void errorCallback( GPConnection *con, GPErrorArg *arg );
- void messageCallback( GPConnection *con, GPRecvBuddyMessageArg *arg );
- void connectCallback( GPConnection *con, GPConnectResponseArg *arg );
- void requestCallback( GPConnection *con, GPRecvBuddyRequestArg *arg );
- void statusCallback( GPConnection *con, GPRecvBuddyStatusArg *arg );
- Bool isConnecting( void ) { return m_isConnecting; }
- Bool isConnected( void ) { return m_isConnected; }
- GPProfile getLocalProfileID( void ) { return m_profileID; }
- private:
- Bool m_isNewAccount;
- Bool m_isConnecting;
- Bool m_isConnected;
- GPProfile m_profileID;
- Int m_lastErrorCode;
- Bool m_isdeleting;
- std::string m_nick, m_email, m_pass;
- };
- static enum CallbackType
- {
- CALLBACK_CONNECT,
- CALLBACK_ERROR,
- CALLBACK_RECVMESSAGE,
- CALLBACK_RECVREQUEST,
- CALLBACK_RECVSTATUS,
- CALLBACK_MAX
- };
- void callbackWrapper( GPConnection *con, void *arg, void *param )
- {
- CallbackType info = (CallbackType)(Int)param;
- BuddyThreadClass *thread = MESSAGE_QUEUE->getThread() ? MESSAGE_QUEUE->getThread() : NULL /*(TheGameSpyBuddyMessageQueue)?TheGameSpyBuddyMessageQueue->getThread():NULL*/;
- if (!thread)
- return;
- switch (info)
- {
- case CALLBACK_CONNECT:
- thread->connectCallback( con, (GPConnectResponseArg *)arg );
- break;
- case CALLBACK_ERROR:
- thread->errorCallback( con, (GPErrorArg *)arg );
- break;
- case CALLBACK_RECVMESSAGE:
- thread->messageCallback( con, (GPRecvBuddyMessageArg *)arg );
- break;
- case CALLBACK_RECVREQUEST:
- thread->requestCallback( con, (GPRecvBuddyRequestArg *)arg );
- break;
- case CALLBACK_RECVSTATUS:
- thread->statusCallback( con, (GPRecvBuddyStatusArg *)arg );
- break;
- }
- }
- //-------------------------------------------------------------------------
- GameSpyBuddyMessageQueue::GameSpyBuddyMessageQueue()
- {
- m_thread = NULL;
- }
- GameSpyBuddyMessageQueue::~GameSpyBuddyMessageQueue()
- {
- endThread();
- }
- void GameSpyBuddyMessageQueue::startThread( void )
- {
- if (!m_thread)
- {
- m_thread = NEW BuddyThreadClass;
- m_thread->Execute();
- }
- else
- {
- if (!m_thread->Is_Running())
- {
- m_thread->Execute();
- }
- }
- }
- void GameSpyBuddyMessageQueue::endThread( void )
- {
- if (m_thread)
- delete m_thread;
- m_thread = NULL;
- }
- Bool GameSpyBuddyMessageQueue::isThreadRunning( void )
- {
- return (m_thread) ? m_thread->Is_Running() : false;
- }
- Bool GameSpyBuddyMessageQueue::isConnected( void )
- {
- return (m_thread) ? m_thread->isConnected() : false;
- }
- Bool GameSpyBuddyMessageQueue::isConnecting( void )
- {
- return (m_thread) ? m_thread->isConnecting() : false;
- }
- void GameSpyBuddyMessageQueue::addRequest( const BuddyRequest& req )
- {
- MutexClass::LockClass m(m_requestMutex);
- if (m.Failed())
- return;
- m_requests.push(req);
- }
- Bool GameSpyBuddyMessageQueue::getRequest( BuddyRequest& req )
- {
- MutexClass::LockClass m(m_requestMutex, 0);
- if (m.Failed())
- return false;
- if (m_requests.empty())
- return false;
- req = m_requests.front();
- m_requests.pop();
- return true;
- }
- void GameSpyBuddyMessageQueue::addResponse( const BuddyResponse& resp )
- {
- MutexClass::LockClass m(m_responseMutex);
- if (m.Failed())
- return;
- m_responses.push(resp);
- }
- Bool GameSpyBuddyMessageQueue::getResponse( BuddyResponse& resp )
- {
- MutexClass::LockClass m(m_responseMutex, 0);
- if (m.Failed())
- return false;
- if (m_responses.empty())
- return false;
- resp = m_responses.front();
- m_responses.pop();
- return true;
- }
- BuddyThreadClass* GameSpyBuddyMessageQueue::getThread( void )
- {
- return m_thread;
- }
- GPProfile GameSpyBuddyMessageQueue::getLocalProfileID( void )
- {
- return (m_thread) ? m_thread->getLocalProfileID() : 0;
- }
- //-------------------------------------------------------------------------
- void BuddyThreadClass::Thread_Function()
- {
- try {
- _set_se_translator( DumpExceptionInfo ); // Hook that allows stack trace.
- GPConnection gpCon;
- GPConnection *con = &gpCon;
- gpInitialize( con, 0 );
- m_isConnected = m_isConnecting = false;
- gpSetCallback( con, GP_ERROR, callbackWrapper, (void *)CALLBACK_ERROR );
- gpSetCallback( con, GP_RECV_BUDDY_MESSAGE, callbackWrapper, (void *)CALLBACK_RECVMESSAGE );
- gpSetCallback( con, GP_RECV_BUDDY_REQUEST, callbackWrapper, (void *)CALLBACK_RECVREQUEST );
- gpSetCallback( con, GP_RECV_BUDDY_STATUS, callbackWrapper, (void *)CALLBACK_RECVSTATUS );
- GPEnum lastStatus = GP_OFFLINE;
- std::string lastStatusString;
- BuddyRequest incomingRequest;
- while ( running )
- {
- // deal with requests
- if (TheGameSpyBuddyMessageQueue->getRequest(incomingRequest))
- {
- switch (incomingRequest.buddyRequestType)
- {
- case BuddyRequest::BUDDYREQUEST_LOGIN:
- m_isConnecting = true;
- m_nick = incomingRequest.arg.login.nick;
- m_email = incomingRequest.arg.login.email;
- m_pass = incomingRequest.arg.login.password;
- m_isConnected = (gpConnect( con, incomingRequest.arg.login.nick, incomingRequest.arg.login.email,
- incomingRequest.arg.login.password, (incomingRequest.arg.login.hasFirewall)?GP_FIREWALL:GP_NO_FIREWALL,
- GP_BLOCKING, callbackWrapper, (void *)CALLBACK_CONNECT ) == GP_NO_ERROR);
- m_isConnecting = false;
- break;
- case BuddyRequest::BUDDYREQUEST_RELOGIN:
- m_isConnecting = true;
- m_isConnected = (gpConnect( con, m_nick.c_str(), m_email.c_str(), m_pass.c_str(), GP_FIREWALL,
- GP_BLOCKING, callbackWrapper, (void *)CALLBACK_CONNECT ) == GP_NO_ERROR);
- m_isConnecting = false;
- break;
- case BuddyRequest::BUDDYREQUEST_DELETEACCT:
- m_isdeleting = true;
- gpDeleteProfile( con );
- break;
- case BuddyRequest::BUDDYREQUEST_LOGOUT:
- m_isConnecting = m_isConnected = false;
- gpDisconnect( con );
- break;
- case BuddyRequest::BUDDYREQUEST_MESSAGE:
- {
- std::string s = WideCharStringToMultiByte( incomingRequest.arg.message.text );
- DEBUG_LOG(("Sending a buddy message to %d [%s]\n", incomingRequest.arg.message.recipient, s.c_str()));
- gpSendBuddyMessage( con, incomingRequest.arg.message.recipient, s.c_str() );
- }
- break;
- case BuddyRequest::BUDDYREQUEST_LOGINNEW:
- {
- m_isConnecting = true;
- m_nick = incomingRequest.arg.login.nick;
- m_email = incomingRequest.arg.login.email;
- m_pass = incomingRequest.arg.login.password;
- m_isNewAccount = TRUE;
- m_isConnected = (gpConnectNewUser( con, incomingRequest.arg.login.nick, incomingRequest.arg.login.email,
- incomingRequest.arg.login.password, (incomingRequest.arg.login.hasFirewall)?GP_FIREWALL:GP_NO_FIREWALL,
- GP_BLOCKING, callbackWrapper, (void *)CALLBACK_CONNECT ) == GP_NO_ERROR);
- if (m_isNewAccount) // if we didn't re-login
- {
- gpSetInfoMask( con, GP_MASK_NONE ); // don't share info
- }
- m_isConnecting = false;
- }
- break;
- case BuddyRequest::BUDDYREQUEST_ADDBUDDY:
- {
- std::string s = WideCharStringToMultiByte( incomingRequest.arg.addbuddy.text );
- gpSendBuddyRequest( con, incomingRequest.arg.addbuddy.id, s.c_str() );
- }
- break;
- case BuddyRequest::BUDDYREQUEST_DELBUDDY:
- {
- gpDeleteBuddy( con, incomingRequest.arg.profile.id );
- }
- break;
- case BuddyRequest::BUDDYREQUEST_OKADD:
- {
- gpAuthBuddyRequest( con, incomingRequest.arg.profile.id );
- }
- break;
- case BuddyRequest::BUDDYREQUEST_DENYADD:
- {
- gpDenyBuddyRequest( con, incomingRequest.arg.profile.id );
- }
- case BuddyRequest::BUDDYREQUEST_SETSTATUS:
- {
- //don't blast our 'Loading' status with 'Online'.
- if (lastStatus == GP_PLAYING && lastStatusString == "Loading" && incomingRequest.arg.status.status == GP_ONLINE)
- break;
- DEBUG_LOG(("BUDDYREQUEST_SETSTATUS: status is now %d:%s/%s\n",
- incomingRequest.arg.status.status, incomingRequest.arg.status.statusString, incomingRequest.arg.status.locationString));
- gpSetStatus( con, incomingRequest.arg.status.status, incomingRequest.arg.status.statusString,
- incomingRequest.arg.status.locationString );
- lastStatus = incomingRequest.arg.status.status;
- lastStatusString = incomingRequest.arg.status.statusString;
- }
- break;
- }
- }
- // update the network
- GPEnum isConnected = GP_CONNECTED;
- GPResult res = GP_NO_ERROR;
- res = gpIsConnected( con, &isConnected );
- if ( isConnected == GP_CONNECTED && res == GP_NO_ERROR )
- gpProcess( con );
- // end our timeslice
- Switch_Thread();
- }
- gpDestroy( con );
- } catch ( ... ) {
- DEBUG_CRASH(("Exception in buddy thread!"));
- }
- }
- void BuddyThreadClass::errorCallback( GPConnection *con, GPErrorArg *arg )
- {
- // log the error
- DEBUG_LOG(("GPErrorCallback\n"));
- m_lastErrorCode = arg->errorCode;
- char errorCodeString[256];
- char resultString[256];
- #define RESULT(x) case x: strcpy(resultString, #x); break;
- switch(arg->result)
- {
- RESULT(GP_NO_ERROR)
- RESULT(GP_MEMORY_ERROR)
- RESULT(GP_PARAMETER_ERROR)
- RESULT(GP_NETWORK_ERROR)
- RESULT(GP_SERVER_ERROR)
- default:
- strcpy(resultString, "Unknown result!");
- }
- #undef RESULT
- #define ERRORCODE(x) case x: strcpy(errorCodeString, #x); break;
- switch(arg->errorCode)
- {
- ERRORCODE(GP_GENERAL)
- ERRORCODE(GP_PARSE)
- ERRORCODE(GP_NOT_LOGGED_IN)
- ERRORCODE(GP_BAD_SESSKEY)
- ERRORCODE(GP_DATABASE)
- ERRORCODE(GP_NETWORK)
- ERRORCODE(GP_FORCED_DISCONNECT)
- ERRORCODE(GP_CONNECTION_CLOSED)
- ERRORCODE(GP_LOGIN)
- ERRORCODE(GP_LOGIN_TIMEOUT)
- ERRORCODE(GP_LOGIN_BAD_NICK)
- ERRORCODE(GP_LOGIN_BAD_EMAIL)
- ERRORCODE(GP_LOGIN_BAD_PASSWORD)
- ERRORCODE(GP_LOGIN_BAD_PROFILE)
- ERRORCODE(GP_LOGIN_PROFILE_DELETED)
- ERRORCODE(GP_LOGIN_CONNECTION_FAILED)
- ERRORCODE(GP_LOGIN_SERVER_AUTH_FAILED)
- ERRORCODE(GP_NEWUSER)
- ERRORCODE(GP_NEWUSER_BAD_NICK)
- ERRORCODE(GP_NEWUSER_BAD_PASSWORD)
- ERRORCODE(GP_UPDATEUI)
- ERRORCODE(GP_UPDATEUI_BAD_EMAIL)
- ERRORCODE(GP_NEWPROFILE)
- ERRORCODE(GP_NEWPROFILE_BAD_NICK)
- ERRORCODE(GP_NEWPROFILE_BAD_OLD_NICK)
- ERRORCODE(GP_UPDATEPRO)
- ERRORCODE(GP_UPDATEPRO_BAD_NICK)
- ERRORCODE(GP_ADDBUDDY)
- ERRORCODE(GP_ADDBUDDY_BAD_FROM)
- ERRORCODE(GP_ADDBUDDY_BAD_NEW)
- ERRORCODE(GP_ADDBUDDY_ALREADY_BUDDY)
- ERRORCODE(GP_AUTHADD)
- ERRORCODE(GP_AUTHADD_BAD_FROM)
- ERRORCODE(GP_AUTHADD_BAD_SIG)
- ERRORCODE(GP_STATUS)
- ERRORCODE(GP_BM)
- ERRORCODE(GP_BM_NOT_BUDDY)
- ERRORCODE(GP_GETPROFILE)
- ERRORCODE(GP_GETPROFILE_BAD_PROFILE)
- ERRORCODE(GP_DELBUDDY)
- ERRORCODE(GP_DELBUDDY_NOT_BUDDY)
- ERRORCODE(GP_DELPROFILE)
- ERRORCODE(GP_DELPROFILE_LAST_PROFILE)
- ERRORCODE(GP_SEARCH)
- ERRORCODE(GP_SEARCH_CONNECTION_FAILED)
- default:
- strcpy(errorCodeString, "Unknown error code!");
- }
- #undef ERRORCODE
- if(arg->fatal)
- {
- DEBUG_LOG(( "-----------\n"));
- DEBUG_LOG(( "GP FATAL ERROR\n"));
- DEBUG_LOG(( "-----------\n"));
- }
- else
- {
- DEBUG_LOG(( "-----\n"));
- DEBUG_LOG(( "GP ERROR\n"));
- DEBUG_LOG(( "-----\n"));
- }
- DEBUG_LOG(( "RESULT: %s (%d)\n", resultString, arg->result));
- DEBUG_LOG(( "ERROR CODE: %s (0x%X)\n", errorCodeString, arg->errorCode));
- DEBUG_LOG(( "ERROR STRING: %s\n", arg->errorString));
- if (arg->fatal == GP_FATAL)
- {
- BuddyResponse errorResponse;
- errorResponse.buddyResponseType = BuddyResponse::BUDDYRESPONSE_DISCONNECT;
- errorResponse.result = arg->result;
- errorResponse.arg.error.errorCode = arg->errorCode;
- errorResponse.arg.error.fatal = arg->fatal;
- strncpy(errorResponse.arg.error.errorString, arg->errorString, MAX_BUDDY_CHAT_LEN);
- errorResponse.arg.error.errorString[MAX_BUDDY_CHAT_LEN-1] = 0;
- m_isConnecting = m_isConnected = false;
- TheGameSpyBuddyMessageQueue->addResponse( errorResponse );
- if (m_isdeleting)
- {
- PeerRequest req;
- req.peerRequestType = PeerRequest::PEERREQUEST_LOGOUT;
- TheGameSpyPeerMessageQueue->addRequest( req );
- m_isdeleting = false;
- }
- }
- }
- static void getNickForMessage( GPConnection *con, GPGetInfoResponseArg *arg, void *param )
- {
- BuddyResponse *resp = (BuddyResponse *)param;
- strcpy(resp->arg.message.nick, arg->nick);
- }
- void BuddyThreadClass::messageCallback( GPConnection *con, GPRecvBuddyMessageArg *arg )
- {
- BuddyResponse messageResponse;
- messageResponse.buddyResponseType = BuddyResponse::BUDDYRESPONSE_MESSAGE;
- messageResponse.profile = arg->profile;
- // get info about the person asking to be our buddy
- gpGetInfo( con, arg->profile, GP_CHECK_CACHE, GP_BLOCKING, (GPCallback)getNickForMessage, &messageResponse);
- std::wstring s = MultiByteToWideCharSingleLine( arg->message );
- wcsncpy(messageResponse.arg.message.text, s.c_str(), MAX_BUDDY_CHAT_LEN);
- messageResponse.arg.message.text[MAX_BUDDY_CHAT_LEN-1] = 0;
- messageResponse.arg.message.date = arg->date;
- DEBUG_LOG(("Got a buddy message from %d [%ls]\n", arg->profile, s.c_str()));
- TheGameSpyBuddyMessageQueue->addResponse( messageResponse );
- }
- void BuddyThreadClass::connectCallback( GPConnection *con, GPConnectResponseArg *arg )
- {
- BuddyResponse loginResponse;
- if (arg->result == GP_NO_ERROR)
- {
- loginResponse.buddyResponseType = BuddyResponse::BUDDYRESPONSE_LOGIN;
- loginResponse.result = arg->result;
- loginResponse.profile = arg->profile;
- TheGameSpyBuddyMessageQueue->addResponse( loginResponse );
- m_profileID = arg->profile;
- if (!TheGameSpyPeerMessageQueue->isConnected() && !TheGameSpyPeerMessageQueue->isConnecting())
- {
- DEBUG_LOG(("Buddy connect: trying chat connect\n"));
- PeerRequest req;
- req.peerRequestType = PeerRequest::PEERREQUEST_LOGIN;
- req.nick = m_nick.c_str();
- req.password = m_pass;
- req.email = m_email;
- req.login.profileID = arg->profile;
- TheGameSpyPeerMessageQueue->addRequest(req);
- }
- }
- else
- {
- if (!TheGameSpyPeerMessageQueue->isConnected() && !TheGameSpyPeerMessageQueue->isConnecting())
- {
- if (m_lastErrorCode == GP_NEWUSER_BAD_NICK)
- {
- m_isNewAccount = FALSE;
- // they just hit 'create account' instead of 'log in'. Fix them.
- DEBUG_LOG(("User Error: Create Account instead of Login. Fixing them...\n"));
- BuddyRequest req;
- req.buddyRequestType = BuddyRequest::BUDDYREQUEST_LOGIN;
- strcpy(req.arg.login.nick, m_nick.c_str());
- strcpy(req.arg.login.email, m_email.c_str());
- strcpy(req.arg.login.password, m_pass.c_str());
- req.arg.login.hasFirewall = true;
- TheGameSpyBuddyMessageQueue->addRequest( req );
- return;
- }
- DEBUG_LOG(("Buddy connect failed (%d/%d): posting a failed chat connect\n", arg->result, m_lastErrorCode));
- PeerResponse resp;
- resp.peerResponseType = PeerResponse::PEERRESPONSE_DISCONNECT;
- resp.discon.reason = DISCONNECT_COULDNOTCONNECT;
- switch (m_lastErrorCode)
- {
- case GP_LOGIN_TIMEOUT:
- resp.discon.reason = DISCONNECT_GP_LOGIN_TIMEOUT;
- break;
- case GP_LOGIN_BAD_NICK:
- resp.discon.reason = DISCONNECT_GP_LOGIN_BAD_NICK;
- break;
- case GP_LOGIN_BAD_EMAIL:
- resp.discon.reason = DISCONNECT_GP_LOGIN_BAD_EMAIL;
- break;
- case GP_LOGIN_BAD_PASSWORD:
- resp.discon.reason = DISCONNECT_GP_LOGIN_BAD_PASSWORD;
- break;
- case GP_LOGIN_BAD_PROFILE:
- resp.discon.reason = DISCONNECT_GP_LOGIN_BAD_PROFILE;
- break;
- case GP_LOGIN_PROFILE_DELETED:
- resp.discon.reason = DISCONNECT_GP_LOGIN_PROFILE_DELETED;
- break;
- case GP_LOGIN_CONNECTION_FAILED:
- resp.discon.reason = DISCONNECT_GP_LOGIN_CONNECTION_FAILED;
- break;
- case GP_LOGIN_SERVER_AUTH_FAILED:
- resp.discon.reason = DISCONNECT_GP_LOGIN_SERVER_AUTH_FAILED;
- break;
- case GP_NEWUSER_BAD_NICK:
- resp.discon.reason = DISCONNECT_GP_NEWUSER_BAD_NICK;
- break;
- case GP_NEWUSER_BAD_PASSWORD:
- resp.discon.reason = DISCONNECT_GP_NEWUSER_BAD_PASSWORD;
- break;
- case GP_NEWPROFILE_BAD_NICK:
- resp.discon.reason = DISCONNECT_GP_NEWPROFILE_BAD_NICK;
- break;
- case GP_NEWPROFILE_BAD_OLD_NICK:
- resp.discon.reason = DISCONNECT_GP_NEWPROFILE_BAD_OLD_NICK;
- break;
- }
- TheGameSpyPeerMessageQueue->addResponse(resp);
- }
- }
- }
- // -----------------------
- static void getInfoResponseForRequest( GPConnection *con, GPGetInfoResponseArg *arg, void *param )
- {
- BuddyResponse *resp = (BuddyResponse *)param;
- resp->profile = arg->profile;
- strcpy(resp->arg.request.nick, arg->nick);
- strcpy(resp->arg.request.email, arg->email);
- strcpy(resp->arg.request.countrycode, arg->countrycode);
- }
- void BuddyThreadClass::requestCallback( GPConnection *con, GPRecvBuddyRequestArg *arg )
- {
- BuddyResponse response;
- response.buddyResponseType = BuddyResponse::BUDDYRESPONSE_REQUEST;
- response.profile = arg->profile;
- // get info about the person asking to be our buddy
- gpGetInfo( con, arg->profile, GP_CHECK_CACHE, GP_BLOCKING, (GPCallback)getInfoResponseForRequest, &response);
- std::wstring s = MultiByteToWideCharSingleLine( arg->reason );
- wcsncpy(response.arg.request.text, s.c_str(), GP_REASON_LEN);
- response.arg.request.text[GP_REASON_LEN-1] = 0;
- TheGameSpyBuddyMessageQueue->addResponse( response );
- }
- // -----------------------
- static void getInfoResponseForStatus(GPConnection * connection, GPGetInfoResponseArg * arg, void * param)
- {
- BuddyResponse *resp = (BuddyResponse *)param;
- resp->profile = arg->profile;
- strcpy(resp->arg.status.nick, arg->nick);
- strcpy(resp->arg.status.email, arg->email);
- strcpy(resp->arg.status.countrycode, arg->countrycode);
- }
- void BuddyThreadClass::statusCallback( GPConnection *con, GPRecvBuddyStatusArg *arg )
- {
- BuddyResponse response;
- // get user's name
- response.buddyResponseType = BuddyResponse::BUDDYRESPONSE_STATUS;
- gpGetInfo( con, arg->profile, GP_CHECK_CACHE, GP_BLOCKING, (GPCallback)getInfoResponseForStatus, &response);
- // get user's status
- GPBuddyStatus status;
- gpGetBuddyStatus( con, arg->index, &status );
- strcpy(response.arg.status.location, status.locationString);
- strcpy(response.arg.status.statusString, status.statusString);
- response.arg.status.status = status.status;
- DEBUG_LOG(("Got buddy status for %d(%s) - status %d\n", status.profile, response.arg.status.nick, status.status));
- // relay to UI
- TheGameSpyBuddyMessageQueue->addResponse( response );
- }
- //-------------------------------------------------------------------------
|