3474 lines
No EOL
76 KiB
C++
3474 lines
No EOL
76 KiB
C++
/*
|
|
** 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/>.
|
|
*/
|
|
|
|
/******************************************************************************
|
|
*
|
|
* NAME
|
|
* $Archive: /Commando/Code/WWOnline/WOLSession.cpp $
|
|
*
|
|
* DESCRIPTION
|
|
* WOLSession is the entryway to Westwood Online. An object of this type
|
|
* must exist in order to do anything WOL related. There should only be one
|
|
* instance of this; retrieve it via GetInstance.
|
|
*
|
|
* PROGRAMMER
|
|
* Steve Clinard & Denzil E. Long, Jr.
|
|
* $Author: Steve_t $
|
|
*
|
|
* VERSION INFO
|
|
* $Revision: 79 $
|
|
* $Modtime: 2/08/02 11:31a $
|
|
*
|
|
******************************************************************************/
|
|
|
|
#include <atlbase.h>
|
|
#include "WOLSession.h"
|
|
#include "WOLChatObserver.h"
|
|
#include "WOLNetUtilObserver.h"
|
|
#include "WOLProduct.h"
|
|
#include "WOLConnect.h"
|
|
#include "WOLServer.h"
|
|
#include "WaitCondition.h"
|
|
#include "WOLErrorUtil.h"
|
|
#include <WWDebug\WWDebug.h>
|
|
#include <stdlib.h>
|
|
|
|
#ifdef _MSC_VER
|
|
#pragma warning (push,3)
|
|
#endif
|
|
|
|
#include "systimer.h"
|
|
|
|
#ifdef _MSC_VER
|
|
#pragma warning (pop)
|
|
#endif
|
|
|
|
namespace WWOnline {
|
|
|
|
RefPtr<Session> Session::_mInstance;
|
|
|
|
/******************************************************************************
|
|
*
|
|
* NAME
|
|
* Session::GetInstance
|
|
*
|
|
* DESCRIPTION
|
|
* Retrieve instance to Westwood Online session
|
|
*
|
|
* INPUTS
|
|
* Create - True if session should be created.
|
|
*
|
|
* RESULT
|
|
* Session - Session instance
|
|
*
|
|
******************************************************************************/
|
|
|
|
RefPtr<Session> Session::GetInstance(bool okToCreate)
|
|
{
|
|
if (okToCreate && !_mInstance.IsValid())
|
|
{
|
|
_mInstance = new Session;
|
|
|
|
if (_mInstance->FinalizeCreate() == false)
|
|
{
|
|
_mInstance.Release();
|
|
}
|
|
}
|
|
|
|
return _mInstance;
|
|
}
|
|
|
|
|
|
/******************************************************************************
|
|
*
|
|
* NAME
|
|
* Session::Session
|
|
*
|
|
* DESCRIPTION
|
|
* Default constructor
|
|
*
|
|
* INPUTS
|
|
* NONE
|
|
*
|
|
* RESULT
|
|
* NONE
|
|
*
|
|
******************************************************************************/
|
|
|
|
Session::Session() :
|
|
mChatCookie(0),
|
|
mNetUtilCookie(0),
|
|
mCurrentConnectionStatus(ConnectionDisconnected),
|
|
mAutoRequestFlags(0),
|
|
mLadderPending(0),
|
|
mPingsPending(0),
|
|
mPingEnable(1),
|
|
mLastUserDataRequestTime(0),
|
|
mRequestedChannelType(-1),
|
|
mRequestingServerList(false),
|
|
mIgnoreServerLists(false),
|
|
mIsInsider(false),
|
|
mServerTime(0)
|
|
{
|
|
WWDEBUG_SAY(("WOL: Session instantiated\n"));
|
|
|
|
// Initailize COM
|
|
HRESULT hr = CoInitialize(NULL);
|
|
|
|
if (FAILED(hr))
|
|
{
|
|
WWDEBUG_SAY(("WOLERROR: CoInitialize() failed!\n"));
|
|
}
|
|
|
|
WWASSERT(SUCCEEDED(hr) && "CoInitialize() failed!");
|
|
}
|
|
|
|
|
|
/******************************************************************************
|
|
*
|
|
* NAME
|
|
* Session::FinalizeCreate
|
|
*
|
|
* DESCRIPTION
|
|
* Finalize session creation
|
|
*
|
|
* INPUTS
|
|
* NONE
|
|
*
|
|
* RESULT
|
|
* Success - True if successful.
|
|
*
|
|
******************************************************************************/
|
|
|
|
bool Session::FinalizeCreate(void)
|
|
{
|
|
WWDEBUG_SAY(("WOL: Session Create\n"));
|
|
Reset();
|
|
|
|
//---------------------------------------------------------------------------
|
|
// Create chat object
|
|
//---------------------------------------------------------------------------
|
|
WWDEBUG_SAY(("WOL: Creating IID_IChat object\n"));
|
|
WOL::IChat* chatObject = NULL;
|
|
HRESULT hr = CoCreateInstance(WOL::CLSID_Chat, NULL, CLSCTX_INPROC_SERVER,
|
|
WOL::IID_IChat, (void**)&chatObject);
|
|
|
|
if (FAILED(hr))
|
|
{
|
|
WWDEBUG_SAY(("WOLERROR: Failed to create IID_IChat\n"));
|
|
return false;
|
|
}
|
|
|
|
if (chatObject)
|
|
{
|
|
mChat = chatObject;
|
|
|
|
// Create chat events observer
|
|
WWDEBUG_SAY(("WOL: Creating chat events observer\n"));
|
|
CComPtr<ChatObserver> chatEvents;
|
|
chatEvents.Attach(new ChatObserver);
|
|
|
|
if (chatEvents == NULL)
|
|
{
|
|
WWDEBUG_SAY(("WOLERROR: Failed to create IChatEvents observer\n"));
|
|
return false;
|
|
}
|
|
|
|
chatEvents->Init(*this);
|
|
|
|
hr = mChat.Advise(chatEvents, WOL::IID_IChatEvent, &mChatCookie);
|
|
|
|
if (FAILED(hr))
|
|
{
|
|
WWDEBUG_SAY(("WOLERROR: Failed to advise IChatEvents observer\n"));
|
|
return false;
|
|
}
|
|
|
|
mChatEvents = chatEvents;
|
|
}
|
|
|
|
//---------------------------------------------------------------------------
|
|
// Create netutil object
|
|
//---------------------------------------------------------------------------
|
|
WWDEBUG_SAY(("WOL: Creating IID_INetUtil object\n"));
|
|
|
|
WOL::INetUtil* utilObject = NULL;
|
|
hr = CoCreateInstance(WOL::CLSID_NetUtil, NULL, CLSCTX_INPROC_SERVER,
|
|
WOL::IID_INetUtil, (void **)&utilObject);
|
|
|
|
if (FAILED(hr))
|
|
{
|
|
WWDEBUG_SAY(("WOLERROR: Failed to create IID_INetUtil\n"));
|
|
return false;
|
|
}
|
|
|
|
if (utilObject)
|
|
{
|
|
mNetUtil = utilObject;
|
|
|
|
// Create net utility events observer
|
|
WWDEBUG_SAY(("WOL: Creating netutil events observer\n"));
|
|
CComPtr<NetUtilObserver> utilEvents;
|
|
utilEvents.Attach(new NetUtilObserver);
|
|
|
|
if (utilEvents == NULL)
|
|
{
|
|
WWDEBUG_SAY(("WOLERROR: Failed to create INetUtilEvents observer\n"));
|
|
return false;
|
|
}
|
|
|
|
utilEvents->Init(*this);
|
|
|
|
hr = mNetUtil.Advise(utilEvents, WOL::IID_INetUtilEvent, &mNetUtilCookie);
|
|
|
|
if (FAILED(hr))
|
|
{
|
|
WWDEBUG_SAY(("WOLERROR: Failed to advise INetUtilEvents observer\n"));
|
|
return false;
|
|
}
|
|
|
|
mNetUtilEvents = utilEvents;
|
|
}
|
|
|
|
//---------------------------------------------------------------------------
|
|
// Setup for current product
|
|
//---------------------------------------------------------------------------
|
|
WWDEBUG_SAY(("WOL: Setting product SKU\n"));
|
|
RefPtrConst<Product> product = Product::Current();
|
|
|
|
if (!product.IsValid())
|
|
{
|
|
WWDEBUG_SAY(("WOLERROR: WOLProduct not initialized\n"));
|
|
return false;
|
|
}
|
|
|
|
const char* regPath = product->GetRegistryPath();
|
|
hr = mChat->SetAttributeValue("RegPath", regPath);
|
|
|
|
if (FAILED(hr))
|
|
{
|
|
WWDEBUG_SAY(("WOLERROR: SetAttributeValue(RegPath) HRESULT = %s\n", GetChatErrorString(hr)));
|
|
return false;
|
|
}
|
|
|
|
unsigned int sku = product->GetSKU();
|
|
hr = mChat->SetProductSKU(sku);
|
|
|
|
if (FAILED(hr))
|
|
{
|
|
WWDEBUG_SAY(("WOLERROR: SetProductSKU() HRESULT = %s\n", GetChatErrorString(hr)));
|
|
return false;
|
|
}
|
|
|
|
// Enable OnChannelTopic() to be called after OnChannelJoin()
|
|
hr = mChat->SetAttributeValue("AutoTopic", "true");
|
|
|
|
if (FAILED(hr))
|
|
{
|
|
WWDEBUG_SAY(("WOLERROR: SetAttributeValue(AutoTopic) HRESULT = %s\n", GetChatErrorString(hr)));
|
|
return false;
|
|
}
|
|
|
|
mPingRequests.reserve(8);
|
|
mUsers.reserve(32);
|
|
|
|
return true;
|
|
}
|
|
|
|
|
|
/******************************************************************************
|
|
*
|
|
* NAME
|
|
* Session::~Session
|
|
*
|
|
* DESCRIPTION
|
|
* Destructor
|
|
*
|
|
* INPUTS
|
|
* NONE
|
|
*
|
|
* RESULT
|
|
* NONE
|
|
*
|
|
******************************************************************************/
|
|
|
|
Session::~Session()
|
|
{
|
|
WWDEBUG_SAY(("WOL: Session destructing\n"));
|
|
Reset();
|
|
|
|
if (mIGRObject)
|
|
{
|
|
WWDEBUG_SAY(("WOL: Releasing IID_IIGROptions object\n"));
|
|
mIGRObject.Release();
|
|
}
|
|
|
|
if (mNetUtil)
|
|
{
|
|
WWDEBUG_SAY(("WOL: Releasing IID_INetUtil object\n"));
|
|
AtlUnadvise(mNetUtil, WOL::IID_INetUtilEvent, mNetUtilCookie);
|
|
mNetUtil.Release();
|
|
}
|
|
|
|
if (mChat)
|
|
{
|
|
WWDEBUG_SAY(("WOL: Releasing IID_IChat object\n"));
|
|
AtlUnadvise(mChat, WOL::IID_IChatEvent, mChatCookie);
|
|
mChat.Release();
|
|
}
|
|
|
|
CoUninitialize();
|
|
}
|
|
|
|
|
|
/******************************************************************************
|
|
*
|
|
* NAME
|
|
* Session::ReleaseReference
|
|
*
|
|
* DESCRIPTION
|
|
* Release reference count
|
|
*
|
|
* INPUTS
|
|
* NONE
|
|
*
|
|
* RESULT
|
|
* NONE
|
|
*
|
|
******************************************************************************/
|
|
|
|
void Session::ReleaseReference(void)
|
|
{
|
|
RefCounted::ReleaseReference();
|
|
|
|
// If there is only the singleton reference then release the object.
|
|
if (ReferenceCount() == 1)
|
|
{
|
|
_mInstance.Release();
|
|
}
|
|
}
|
|
|
|
|
|
/******************************************************************************
|
|
*
|
|
* NAME
|
|
* Session::Reset
|
|
*
|
|
* DESCRIPTION
|
|
* Reset the WWOnline session
|
|
*
|
|
* INPUTS
|
|
*
|
|
* RESULT
|
|
* NONE
|
|
*
|
|
******************************************************************************/
|
|
|
|
void Session::Reset(void)
|
|
{
|
|
ClearServers();
|
|
|
|
SquadData::Reset();
|
|
mChatChannels.clear();
|
|
mGameChannels.clear();
|
|
mPatchFiles.clear();
|
|
mUsers.clear();
|
|
mBuddies.clear();
|
|
mLocatePendingUsers.clear();
|
|
mLocatingUser.Release();
|
|
}
|
|
|
|
|
|
/******************************************************************************
|
|
*
|
|
* NAME
|
|
* Session::Process
|
|
*
|
|
* DESCRIPTION
|
|
* Perform periodic processing
|
|
*
|
|
* INPUTS
|
|
* NONE
|
|
*
|
|
* RESULT
|
|
*
|
|
******************************************************************************/
|
|
|
|
bool Session::Process(void)
|
|
{
|
|
if (mCurrentConnectionStatus == ConnectionConnected)
|
|
{
|
|
MakeLocateUserRequests();
|
|
}
|
|
|
|
DWORD theTime = TIMEGETTIME();
|
|
|
|
if (theTime < mLastUserDataRequestTime)
|
|
{
|
|
mLastUserDataRequestTime = theTime;
|
|
}
|
|
|
|
if (theTime >= (mLastUserDataRequestTime + 1000))
|
|
{
|
|
mLastUserDataRequestTime = theTime;
|
|
|
|
MakeSquadRequests();
|
|
MakeLocaleRequests();
|
|
MakeTeamRequests();
|
|
MakeLadderRequests();
|
|
}
|
|
|
|
MakePingRequests();
|
|
|
|
mChat->PumpMessages();
|
|
mNetUtil->PumpMessages();
|
|
|
|
return false;
|
|
}
|
|
|
|
|
|
/******************************************************************************
|
|
*
|
|
* NAME
|
|
* Session::GetNewServerList
|
|
*
|
|
* DESCRIPTION
|
|
* Get a new server list.
|
|
*
|
|
* INPUTS
|
|
* NONE
|
|
*
|
|
* RESULT
|
|
* Wait - Wait condition to process for serverlist.
|
|
*
|
|
******************************************************************************/
|
|
|
|
RefPtr<WaitCondition> Session::GetNewServerList(void)
|
|
{
|
|
return ServerListWait::Create(this);
|
|
}
|
|
|
|
|
|
/******************************************************************************
|
|
*
|
|
* NAME
|
|
* Session::RequestServerList
|
|
*
|
|
* DESCRIPTION
|
|
* Submit a request for server list.
|
|
*
|
|
* INPUTS
|
|
* NONE
|
|
*
|
|
* RESULT
|
|
* Success - True if request successful.
|
|
*
|
|
******************************************************************************/
|
|
|
|
bool Session::RequestServerList(bool ignore)
|
|
{
|
|
RefPtrConst<Product> product(Product::Current());
|
|
|
|
if (!product.IsValid())
|
|
{
|
|
WWASSERT(product.IsValid() && "WOLERROR: Product not initialized.");
|
|
return false;
|
|
}
|
|
|
|
mIgnoreServerLists = ignore;
|
|
mRequestingServerList = !ignore;
|
|
|
|
unsigned int sku = product->GetLanguageSKU();
|
|
unsigned int version = product->GetVersion();
|
|
|
|
HRESULT hr = mChat->RequestServerList(sku, version, "NoUser", "NoPass", 30000);
|
|
|
|
if (FAILED(hr))
|
|
{
|
|
WWDEBUG_SAY(("WOLERROR: RequestServerList() HRESULT = %s\n", GetChatErrorString(hr)));
|
|
}
|
|
|
|
return SUCCEEDED(hr);
|
|
}
|
|
|
|
|
|
/******************************************************************************
|
|
*
|
|
* NAME
|
|
* Session::LoginServer
|
|
*
|
|
* DESCRIPTION
|
|
* Log user onto server.
|
|
*
|
|
* INPUTS
|
|
* Server - Server to logon to.
|
|
* Login - Login information
|
|
*
|
|
* RESULT
|
|
* Wait - Wait condition to process for logging in.
|
|
*
|
|
******************************************************************************/
|
|
|
|
RefPtr<WaitCondition> Session::LoginServer(const RefPtr<IRCServerData>& server,
|
|
const RefPtr<LoginInfo>& login)
|
|
{
|
|
if (server.IsValid())
|
|
{
|
|
WWDEBUG_SAY(("WOL: LoginServer connecting to '%s'\n", server->GetName()));
|
|
}
|
|
else
|
|
{
|
|
WWDEBUG_SAY(("WOL: LoginServer disconnecting\n"));
|
|
}
|
|
|
|
//---------------------------------------------------------------------------
|
|
// If this is the current server, check state of connection
|
|
//---------------------------------------------------------------------------
|
|
if (mCurrentServer == server)
|
|
{
|
|
if (server.IsValid())
|
|
{
|
|
// If already connected to this server, just return with success.
|
|
// If connecting then wait for connection to finish.
|
|
if (ConnectionConnected == mCurrentConnectionStatus)
|
|
{
|
|
WWDEBUG_SAY(("WOL: LoginServer already connected.\n"));
|
|
RefPtr<SingleWait> wait = SingleWait::Create(WOLSTRING("WOL_CONNECTING"));
|
|
wait->EndWait(WaitCondition::ConditionMet, WOLSTRING("WOL_CONNECTED"));
|
|
return wait;
|
|
}
|
|
else if (ConnectionConnecting == mCurrentConnectionStatus)
|
|
{
|
|
WWDEBUG_SAY(("WOL: LoginServer already connecting.\n"));
|
|
return EventValueWait<ConnectionStatus>::CreateAndObserve(*this, ConnectionConnected, WOLSTRING("WOL_CONNECTING"));
|
|
}
|
|
}
|
|
else
|
|
{
|
|
// If already disconnected then just return with success. If disconnecting
|
|
// then wait for disconnect to finish.
|
|
if (ConnectionDisconnected == mCurrentConnectionStatus)
|
|
{
|
|
WWDEBUG_SAY(("WOL: LoginServer already disconnected.\n"));
|
|
RefPtr<SingleWait> wait = SingleWait::Create(WOLSTRING("WOL_DISCONNECTING"));
|
|
wait->EndWait(WaitCondition::ConditionMet, WOLSTRING("WOL_DISCONNECTED"));
|
|
return wait;
|
|
}
|
|
else if (ConnectionDisconnecting == mCurrentConnectionStatus)
|
|
{
|
|
WWDEBUG_SAY(("WOL: LoginServer already disconnecting.\n"));
|
|
return EventValueWait<ConnectionStatus>::CreateAndObserve(*this, ConnectionDisconnected, WOLSTRING("WOL_DISCONNECTING"));
|
|
}
|
|
}
|
|
}
|
|
|
|
// Clean up on server switch or disconnect
|
|
if (ConnectionConnected == mCurrentConnectionStatus)
|
|
{
|
|
WWDEBUG_SAY(("WOL: LoginServer disconnect cleanup.\n"));
|
|
|
|
mCurrentChannelStatus = ChannelLeft;
|
|
ChannelEvent chanEvent(mCurrentChannelStatus, mCurrentChannel);
|
|
NotifyObservers(chanEvent);
|
|
|
|
mCurrentChannel.Release();
|
|
mPendingChannel.Release();
|
|
|
|
mChatChannels.clear();
|
|
ChannelListEvent chatListEvent(ChannelListEvent::NewList, mChatChannels, 0);
|
|
NotifyObservers(chatListEvent);
|
|
|
|
RefPtrConst<Product> product = Product::Current();
|
|
WWASSERT(product.IsValid());
|
|
|
|
mGameChannels.clear();
|
|
ChannelListEvent gameListEvent(ChannelListEvent::NewList, mGameChannels, product->GetGameCode());
|
|
NotifyObservers(gameListEvent);
|
|
}
|
|
|
|
//---------------------------------------------------------------------------
|
|
// Process change of server connection
|
|
//---------------------------------------------------------------------------
|
|
RefPtr<SerialWait> serverWait = SerialWait::Create();
|
|
|
|
// If connecting or disconnecting, let that finish
|
|
if (ConnectionDisconnecting == mCurrentConnectionStatus)
|
|
{
|
|
WWDEBUG_SAY(("WOL: LoginServer wait for disconnect to finish.\n"));
|
|
RefPtr< EventValueWait<ConnectionStatus> > finish = EventValueWait<ConnectionStatus>::CreateAndObserve(*this, ConnectionDisconnected, WOLSTRING("WOL_DISCONNECTING"));
|
|
serverWait->Add(finish);
|
|
}
|
|
else if (ConnectionConnecting == mCurrentConnectionStatus)
|
|
{
|
|
WWDEBUG_SAY(("WOL: LoginServer wait for connect to finish.\n"));
|
|
RefPtr< EventValueWait<ConnectionStatus> > finish = EventValueWait<ConnectionStatus>::CreateAndObserve(*this, ConnectionConnected, WOLSTRING("WOL_DISCONNECTING"));
|
|
serverWait->Add(finish);
|
|
}
|
|
|
|
// If connected or connecting to another server then disconnect from that server
|
|
// before connecting to the new one.
|
|
if (mCurrentServer.IsValid() || (mPendingServer.IsValid() && (mPendingServer != server)))
|
|
{
|
|
WWDEBUG_SAY(("WOL: LoginServer changing servers.\n"));
|
|
|
|
if ((ConnectionConnected == mCurrentConnectionStatus) || (ConnectionConnecting == mCurrentConnectionStatus))
|
|
{
|
|
WWDEBUG_SAY(("WOL: LoginServer disconnect from current server.\n"));
|
|
RefPtr<DisconnectWait> disconnect = DisconnectWait::Create(this);
|
|
serverWait->Add(disconnect);
|
|
}
|
|
}
|
|
|
|
mPendingServer = server;
|
|
mPendingLogin = login;
|
|
|
|
// Server == NULL is just a logout
|
|
if (!server.IsValid())
|
|
{
|
|
return serverWait;
|
|
}
|
|
|
|
if (!login.IsValid())
|
|
{
|
|
WWASSERT(login.IsValid());
|
|
return serverWait;
|
|
}
|
|
|
|
// Finally, connect to desired server. Request to connect is embedded in Wait_Beginning
|
|
WWDEBUG_SAY(("WOL: LoginServer connect to new server.\n"));
|
|
|
|
RefPtr<ConnectWait> connect = ConnectWait::Create(this, server, login);
|
|
serverWait->Add(connect);
|
|
|
|
return serverWait;
|
|
}
|
|
|
|
|
|
/******************************************************************************
|
|
*
|
|
* NAME
|
|
* Session::Logout
|
|
*
|
|
* DESCRIPTION
|
|
* Log current user off.
|
|
*
|
|
* INPUTS
|
|
* NONE
|
|
*
|
|
* RESULT
|
|
* Wait - Wait condition to process for logout.
|
|
*
|
|
******************************************************************************/
|
|
|
|
RefPtr<WaitCondition> Session::Logout(void)
|
|
{
|
|
WWDEBUG_SAY(("WOL: Logout\n"));
|
|
return LoginServer(RefPtr<IRCServerData>(), RefPtr<LoginInfo>());
|
|
}
|
|
|
|
|
|
/******************************************************************************
|
|
*
|
|
* NAME
|
|
* Session::ClearServers
|
|
*
|
|
* DESCRIPTION
|
|
* Clear internal server lists
|
|
*
|
|
* INPUTS
|
|
* NONE
|
|
*
|
|
* RESULT
|
|
* NONE
|
|
*
|
|
******************************************************************************/
|
|
|
|
void Session::ClearServers(void)
|
|
{
|
|
mRequestingServerList = false;
|
|
mIgnoreServerLists = false;
|
|
|
|
mIRCServers.clear();
|
|
mLadderServer.Release();
|
|
mGameResultsServer.Release();
|
|
mWDTServer.Release();
|
|
mMGLServers.clear();
|
|
mPingServers.clear();
|
|
}
|
|
|
|
|
|
/******************************************************************************
|
|
*
|
|
* NAME
|
|
* Session::EnableProgressiveChannelList
|
|
*
|
|
* DESCRIPTION
|
|
* Enable / Disable the receipt of progressive channel lists.
|
|
*
|
|
* INPUTS
|
|
* Enable - True to enable; False to disable.
|
|
*
|
|
* RESULT
|
|
* Success - True if operation is successful.
|
|
*
|
|
******************************************************************************/
|
|
|
|
bool Session::EnableProgressiveChannelList(bool enable)
|
|
{
|
|
const char* onoff = ((enable == true) ? "true" : "false");
|
|
HRESULT hr = mChat->SetAttributeValue("IncrementalChannelLists", onoff);
|
|
return SUCCEEDED(hr);
|
|
}
|
|
|
|
|
|
/******************************************************************************
|
|
*
|
|
* NAME
|
|
* Session::RequestChannelList
|
|
*
|
|
* DESCRIPTION
|
|
*
|
|
* INPUTS
|
|
* Type - Channel type to request.
|
|
* AutoPing -
|
|
*
|
|
* RESULT
|
|
* Success - True if request successful.
|
|
*
|
|
******************************************************************************/
|
|
|
|
bool Session::RequestChannelList(int channelType, bool autoPing)
|
|
{
|
|
WWDEBUG_SAY(("WOL: RequestChannelList %d\n", channelType));
|
|
|
|
if (mRequestedChannelType != -1)
|
|
{
|
|
WWDEBUG_SAY(("WOLERROR: RequestChannelList already pending\n"));
|
|
return false;
|
|
}
|
|
|
|
HRESULT hr = mChat->RequestChannelList(channelType, autoPing);
|
|
|
|
if (SUCCEEDED(hr))
|
|
{
|
|
mRequestedChannelType = channelType;
|
|
return true;
|
|
}
|
|
|
|
WWDEBUG_SAY(("WOLERROR: RequestChannelList() HRESULT = %s\n", GetChatErrorString(hr)));
|
|
|
|
return false;
|
|
}
|
|
|
|
|
|
/******************************************************************************
|
|
*
|
|
* NAME
|
|
* Session::FindChannel
|
|
*
|
|
* DESCRIPTION
|
|
* Find a channel by name.
|
|
*
|
|
* INPUTS
|
|
* Name - Name of channel to look for.
|
|
*
|
|
* RESULT
|
|
* Channel -
|
|
*
|
|
******************************************************************************/
|
|
|
|
RefPtr<ChannelData> Session::FindChannel(const wchar_t* channelName)
|
|
{
|
|
if (channelName == NULL)
|
|
{
|
|
return NULL;
|
|
}
|
|
|
|
if (mCurrentChannel.IsValid())
|
|
{
|
|
const WideStringClass& name = mCurrentChannel->GetName();
|
|
|
|
if (name.Compare_No_Case(channelName) == 0)
|
|
{
|
|
return mCurrentChannel;
|
|
}
|
|
}
|
|
|
|
RefPtr<ChannelData> channel = FindChatChannel(channelName);
|
|
|
|
if (!channel.IsValid())
|
|
{
|
|
channel = FindGameChannel(channelName);
|
|
}
|
|
|
|
return channel;
|
|
}
|
|
|
|
|
|
RefPtr<ChannelData> Session::FindChannel(const char* channelName)
|
|
{
|
|
if (channelName == NULL)
|
|
{
|
|
return NULL;
|
|
}
|
|
|
|
if (mCurrentChannel.IsValid())
|
|
{
|
|
WOL::Channel& wolChannel = mCurrentChannel->GetData();
|
|
|
|
if (stricmp(channelName, (const char*)wolChannel.name) == 0)
|
|
{
|
|
return mCurrentChannel;
|
|
}
|
|
}
|
|
|
|
RefPtr<ChannelData> channel = FindChatChannel(channelName);
|
|
|
|
if (!channel.IsValid())
|
|
{
|
|
channel = FindGameChannel(channelName);
|
|
}
|
|
|
|
return channel;
|
|
}
|
|
|
|
|
|
/******************************************************************************
|
|
*
|
|
* NAME
|
|
* Session::JoinChannel
|
|
*
|
|
* DESCRIPTION
|
|
* Join the specified channel.
|
|
*
|
|
* INPUTS
|
|
* Channel - Channel to join.
|
|
*
|
|
* RESULT
|
|
* Wait - Wait condition to process for joining channel
|
|
*
|
|
******************************************************************************/
|
|
|
|
RefPtr<WaitCondition> Session::JoinChannel(const RefPtr<ChannelData>& channel,
|
|
const wchar_t* password)
|
|
{
|
|
// If we are not connected then we cannot join a channel.
|
|
if (mCurrentConnectionStatus != ConnectionConnected)
|
|
{
|
|
WWASSERT(mCurrentConnectionStatus == ConnectionConnected);
|
|
|
|
RefPtr<SingleWait> wait = SingleWait::Create(WOLSTRING("WOL_CHANNELJOIN"));
|
|
wait->EndWait(WaitCondition::Error, WOLSTRING("WOL_NOTCONNECTED"));
|
|
return wait;
|
|
}
|
|
|
|
// If we are already connected to the requested channel then done.
|
|
if (mCurrentChannel == channel)
|
|
{
|
|
RefPtr<SingleWait> wait = SingleWait::Create(WOLSTRING("WOL_CHANNELJOIN"));
|
|
wait->EndWait(WaitCondition::ConditionMet, WOLSTRING("WOL_CONNECTED"));
|
|
return wait;
|
|
}
|
|
|
|
// Use default product password if one is not provided
|
|
if (password == NULL)
|
|
{
|
|
RefPtrConst<Product> product = Product::Current();
|
|
WWASSERT(product.IsValid());
|
|
password = product->GetChannelPassword();
|
|
}
|
|
|
|
// Set up wait condition for joining channel
|
|
mPendingChannel = channel;
|
|
|
|
RefPtr<SerialWait> wait = SerialWait::Create();
|
|
|
|
if (wait.IsValid())
|
|
{
|
|
// Leave current channel
|
|
if (mCurrentChannel.IsValid())
|
|
{
|
|
RefPtr<WaitCondition> leaveWait = LeaveChannelWait::Create(this);
|
|
wait->Add(leaveWait);
|
|
}
|
|
|
|
// Join new channel
|
|
if (channel.IsValid())
|
|
{
|
|
RefPtr<WaitCondition> joinWait = JoinChannelWait::Create(this, channel, password);
|
|
wait->Add(joinWait);
|
|
}
|
|
}
|
|
|
|
return wait;
|
|
}
|
|
|
|
|
|
RefPtr<WaitCondition> Session::JoinChannel(const wchar_t* chanName, const wchar_t* password, int type)
|
|
{
|
|
// If we are not connected then we cannot join a channel.
|
|
if (mCurrentConnectionStatus != ConnectionConnected)
|
|
{
|
|
WWASSERT(mCurrentConnectionStatus == ConnectionConnected);
|
|
|
|
RefPtr<SingleWait> wait = SingleWait::Create(WOLSTRING("WOL_CHANNELJOIN"));
|
|
wait->EndWait(WaitCondition::Error, WOLSTRING("WOL_NOTCONNECTED"));
|
|
return wait;
|
|
}
|
|
|
|
// If we are already connected to the requested channel then done.
|
|
if (mCurrentChannel.IsValid())
|
|
{
|
|
const WideStringClass& curChanName = mCurrentChannel->GetName();
|
|
|
|
if (curChanName.Compare_No_Case(chanName) == 0)
|
|
{
|
|
RefPtr<SingleWait> wait = SingleWait::Create(WOLSTRING("WOL_CHANNELJOIN"));
|
|
wait->EndWait(WaitCondition::ConditionMet, WOLSTRING("WOL_CONNECTED"));
|
|
return wait;
|
|
}
|
|
}
|
|
|
|
// Use default product password if one is not provided
|
|
if (password == NULL)
|
|
{
|
|
RefPtrConst<Product> product = Product::Current();
|
|
WWASSERT(product.IsValid());
|
|
password = product->GetChannelPassword();
|
|
}
|
|
|
|
// Set up wait condition for joining channel
|
|
RefPtr<SerialWait> wait = SerialWait::Create();
|
|
|
|
if (wait.IsValid())
|
|
{
|
|
// Leave current channel
|
|
if (mCurrentChannel.IsValid())
|
|
{
|
|
RefPtr<WaitCondition> leaveWait = LeaveChannelWait::Create(this);
|
|
wait->Add(leaveWait);
|
|
}
|
|
|
|
if (chanName)
|
|
{
|
|
// Join new channel
|
|
RefPtr<WaitCondition> joinWait = JoinChannelWait::Create(this, chanName, password, type);
|
|
wait->Add(joinWait);
|
|
}
|
|
}
|
|
|
|
return wait;
|
|
}
|
|
|
|
|
|
/******************************************************************************
|
|
*
|
|
* NAME
|
|
* Session::RequestChannelJoin
|
|
*
|
|
* DESCRIPTION
|
|
*
|
|
* INPUTS
|
|
* NONE
|
|
*
|
|
* RESULT
|
|
* Success - True if request successful.
|
|
*
|
|
******************************************************************************/
|
|
|
|
bool Session::RequestChannelJoin(const RefPtr<ChannelData>& channel, const wchar_t* password)
|
|
{
|
|
if (channel.IsValid() && password)
|
|
{
|
|
WWDEBUG_SAY(("WOL: RequestChannelJoin C:%S P:%S\n", (const WCHAR*)channel->GetName(), password));
|
|
mPendingChannel = channel;
|
|
|
|
WOL::Channel& wolChannel = channel->GetData();
|
|
wcstombs((char*)wolChannel.key, password, sizeof(wolChannel.key));
|
|
|
|
// If the channel is not in the channel list then mark it as hidden.
|
|
RefPtr<ChannelData> inList = FindChannel(channel->GetName());
|
|
wolChannel.hidden = (inList.IsValid() ? 0 : 1);
|
|
|
|
HRESULT hr = mChat->RequestChannelJoin(&wolChannel);
|
|
|
|
if (FAILED(hr))
|
|
{
|
|
WWDEBUG_SAY(("WOLERROR: RequestChannelJoin() HRESULT = %s\n", GetChatErrorString(hr)));
|
|
}
|
|
|
|
return SUCCEEDED(hr);
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
|
|
/******************************************************************************
|
|
*
|
|
* NAME
|
|
* Session::LeaveChannel
|
|
*
|
|
* DESCRIPTION
|
|
*
|
|
* INPUTS
|
|
* NONE
|
|
*
|
|
* RESULT
|
|
* Wait - Wait condition to process for leaving channel
|
|
*
|
|
******************************************************************************/
|
|
|
|
RefPtr<WaitCondition> Session::LeaveChannel(void)
|
|
{
|
|
if (!mCurrentChannel.IsValid() || (ChannelJoined != mCurrentChannelStatus))
|
|
{
|
|
mCurrentChannel.Release();
|
|
mCurrentChannelStatus = ChannelLeft;
|
|
|
|
RefPtr<SingleWait> wait = SingleWait::Create(WOLSTRING("WOL_CHANNELLEAVE"));
|
|
wait->EndWait(WaitCondition::ConditionMet, WOLSTRING("WOL_CHANNELLEFT"));
|
|
return wait;
|
|
}
|
|
|
|
return LeaveChannelWait::Create(this);
|
|
}
|
|
|
|
|
|
bool Session::RequestLeaveChannel(void)
|
|
{
|
|
if (ChannelJoined == mCurrentChannelStatus)
|
|
{
|
|
HRESULT hr = mChat->RequestChannelLeave();
|
|
|
|
if (FAILED(hr))
|
|
{
|
|
WWDEBUG_SAY(("WOLERROR: RequestChannelLeave() failed HRESULT = %s\n", GetChatErrorString(hr)));
|
|
return false;
|
|
}
|
|
|
|
mCurrentChannelStatus = ChannelLeaving;
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
|
|
/******************************************************************************
|
|
*
|
|
* NAME
|
|
* Session::GetNewChatChannelList
|
|
*
|
|
* DESCRIPTION
|
|
* Request a new chat channel list.
|
|
*
|
|
* INPUTS
|
|
* NONE
|
|
*
|
|
* RESULT
|
|
* Wait - Wait condition to process for chat channel list.
|
|
*
|
|
******************************************************************************/
|
|
|
|
RefPtr<WaitCondition> Session::GetNewChatChannelList(void)
|
|
{
|
|
return ChannelListWait::Create(this, 0);
|
|
}
|
|
|
|
|
|
/******************************************************************************
|
|
*
|
|
* NAME
|
|
* Session::FindChatChannel
|
|
*
|
|
* DESCRIPTION
|
|
* Find a chat channel.
|
|
*
|
|
* INPUTS
|
|
* ChannelName - Name of channel to search for.
|
|
*
|
|
* RESULT
|
|
* Channel -
|
|
*
|
|
******************************************************************************/
|
|
|
|
RefPtr<ChannelData> Session::FindChatChannel(const wchar_t* channelName)
|
|
{
|
|
return FindChannelInList(mChatChannels, channelName);
|
|
}
|
|
|
|
|
|
RefPtr<ChannelData> Session::FindChatChannel(const char* channelName)
|
|
{
|
|
return FindChannelInList(mChatChannels, channelName);
|
|
}
|
|
|
|
|
|
/******************************************************************************
|
|
*
|
|
* NAME
|
|
* Session::GetNewGameChannelList
|
|
*
|
|
* DESCRIPTION
|
|
* Get new game channel list.
|
|
*
|
|
* INPUTS
|
|
* NONE
|
|
*
|
|
* RESULT
|
|
* Wait - Wait condition to process for obtaining new channel list.
|
|
*
|
|
******************************************************************************/
|
|
|
|
RefPtr<WaitCondition> Session::GetNewGameChannelList(void)
|
|
{
|
|
RefPtrConst<Product> product = Product::Current();
|
|
|
|
if (product.IsValid())
|
|
{
|
|
int channelType = product->GetGameCode();
|
|
return ChannelListWait::Create(this, channelType);
|
|
}
|
|
|
|
return NULL;
|
|
}
|
|
|
|
|
|
/******************************************************************************
|
|
*
|
|
* NAME
|
|
* Session::RequestGameChannelList
|
|
*
|
|
* DESCRIPTION
|
|
* Submit request for game channel list.
|
|
*
|
|
* INPUTS
|
|
* NONE
|
|
*
|
|
* RESULT
|
|
* Success - True if request successful.
|
|
*
|
|
******************************************************************************/
|
|
|
|
bool Session::RequestGameChannelList(void)
|
|
{
|
|
RefPtrConst<Product> product = Product::Current();
|
|
|
|
if (!product.IsValid())
|
|
{
|
|
WWASSERT(product.IsValid());
|
|
return false;
|
|
}
|
|
|
|
int channelType = product->GetGameCode();
|
|
|
|
return RequestChannelList(channelType, false);
|
|
}
|
|
|
|
|
|
/******************************************************************************
|
|
*
|
|
* NAME
|
|
* Session::FindGameChannel
|
|
*
|
|
* DESCRIPTION
|
|
* Find a game channel.
|
|
*
|
|
* INPUTS
|
|
* ChannelName - Name of channel to search for.
|
|
*
|
|
* RESULT
|
|
* Channel -
|
|
*
|
|
******************************************************************************/
|
|
|
|
RefPtr<ChannelData> Session::FindGameChannel(const wchar_t* channelName)
|
|
{
|
|
return FindChannelInList(mGameChannels, channelName);
|
|
}
|
|
|
|
|
|
RefPtr<ChannelData> Session::FindGameChannel(const char* channelName)
|
|
{
|
|
return FindChannelInList(mGameChannels, channelName);
|
|
}
|
|
|
|
|
|
/******************************************************************************
|
|
*
|
|
* NAME
|
|
* Session::CreateChannel
|
|
*
|
|
* DESCRIPTION
|
|
* Create a new channel.
|
|
*
|
|
* INPUTS
|
|
* Name - Name of new channel.
|
|
* Password - Password for channel.
|
|
*
|
|
* RESULT
|
|
* Wait - Wait condition to process for channel creation.
|
|
*
|
|
******************************************************************************/
|
|
|
|
RefPtr<WaitCondition> Session::CreateChannel(const wchar_t* name, const wchar_t* password, int type)
|
|
{
|
|
WWDEBUG_SAY(("WOL: CreateChannel '%S' Type %ld\n", name, type));
|
|
|
|
if (mCurrentConnectionStatus != ConnectionConnected)
|
|
{
|
|
WWASSERT(mCurrentConnectionStatus == ConnectionConnected);
|
|
|
|
RefPtr<SingleWait> wait = SingleWait::Create(WOLSTRING("WOL_CHANNELCREATE"));
|
|
wait->EndWait(WaitCondition::Error, WOLSTRING("WOL_NOTCONNECTED"));
|
|
return wait;
|
|
}
|
|
|
|
// If we are already connected to the requested channel then done.
|
|
if (mCurrentChannel.IsValid())
|
|
{
|
|
const WideStringClass& curChanName = mCurrentChannel->GetName();
|
|
|
|
if (curChanName.Compare_No_Case(name) == 0)
|
|
{
|
|
RefPtr<SingleWait> wait = SingleWait::Create(WOLSTRING("WOL_CHANNELCREATE"));
|
|
wait->EndWait(WaitCondition::Error, WOLSTRING("WOL_CONNECTED"));
|
|
return wait;
|
|
}
|
|
}
|
|
|
|
RefPtr<ChannelData> channel = ChannelData::Create(name, password, type);
|
|
|
|
// Set up wait condition for creating channel
|
|
mPendingChannel = channel;
|
|
RefPtr<SerialWait> wait = SerialWait::Create();
|
|
|
|
// Leave current channel
|
|
if (mCurrentChannel.IsValid())
|
|
{
|
|
RefPtr<WaitCondition> leave = LeaveChannelWait::Create(this);
|
|
wait->Add(leave);
|
|
}
|
|
|
|
// Create & Join channel
|
|
RefPtr<WaitCondition> create = CreateChannelWait::Create(this, channel, password);
|
|
wait->Add(create);
|
|
|
|
return wait;
|
|
}
|
|
|
|
|
|
/******************************************************************************
|
|
*
|
|
* NAME
|
|
* Session::CreateChannel
|
|
*
|
|
* DESCRIPTION
|
|
* Create a new channel
|
|
*
|
|
* INPUTS
|
|
* Channel - Channel data to create from.
|
|
* Password - Password for joining channel
|
|
*
|
|
* RESULT
|
|
* Wait - Wait condition to process for creating channel
|
|
*
|
|
******************************************************************************/
|
|
|
|
RefPtr<WaitCondition> Session::CreateChannel(const RefPtr<ChannelData>& channel,
|
|
const wchar_t* password)
|
|
{
|
|
WWASSERT(channel.IsValid());
|
|
WWDEBUG_SAY(("WOL: CreateChannel '%S'\n", (const WCHAR*)channel->GetName()));
|
|
|
|
if (mCurrentConnectionStatus != ConnectionConnected)
|
|
{
|
|
WWASSERT(mCurrentConnectionStatus == ConnectionConnected);
|
|
|
|
RefPtr<SingleWait> wait = SingleWait::Create(WOLSTRING("WOL_CHANNELCREATE"));
|
|
wait->EndWait(WaitCondition::Error, WOLSTRING("WOL_NOTCONNECTED"));
|
|
return wait;
|
|
}
|
|
|
|
// If we are already connected to the requested channel then done.
|
|
if (mCurrentChannel.IsValid())
|
|
{
|
|
const WideStringClass& curChanName = mCurrentChannel->GetName();
|
|
|
|
if (curChanName.Compare_No_Case(channel->GetName()) == 0)
|
|
{
|
|
RefPtr<SingleWait> wait = SingleWait::Create(WOLSTRING("WOL_CHANNELCREATE"));
|
|
wait->EndWait(WaitCondition::Error, WOLSTRING("WOL_CONNECTED"));
|
|
return wait;
|
|
}
|
|
}
|
|
|
|
mPendingChannel = channel;
|
|
|
|
// Set up wait condition for creating channel
|
|
RefPtr<SerialWait> wait = SerialWait::Create();
|
|
|
|
// Leave current channel
|
|
if (mCurrentChannel.IsValid())
|
|
{
|
|
RefPtr<WaitCondition> leave = LeaveChannelWait::Create(this);
|
|
wait->Add(leave);
|
|
}
|
|
|
|
// Create & join channel
|
|
RefPtr<WaitCondition> create = CreateChannelWait::Create(this, channel, password);
|
|
wait->Add(create);
|
|
|
|
return wait;
|
|
}
|
|
|
|
|
|
/******************************************************************************
|
|
*
|
|
* NAME
|
|
* Session::GetChannelTopic
|
|
*
|
|
* DESCRIPTION
|
|
* Get the topic of the current channel
|
|
*
|
|
* INPUTS
|
|
* NONE
|
|
*
|
|
* RESULT
|
|
* Topic - Channel topic or NULL if no topic or not in channel.
|
|
*
|
|
******************************************************************************/
|
|
|
|
const char* Session::GetChannelTopic(void) const
|
|
{
|
|
const RefPtr<ChannelData>& channel = GetCurrentChannel();
|
|
|
|
if (channel.IsValid())
|
|
{
|
|
return channel->GetTopic();
|
|
}
|
|
|
|
return NULL;
|
|
}
|
|
|
|
|
|
/******************************************************************************
|
|
*
|
|
* NAME
|
|
* Session::SendChannelTopic
|
|
*
|
|
* DESCRIPTION
|
|
* Send the topic of the current channel.
|
|
*
|
|
* INPUTS
|
|
* NONE
|
|
*
|
|
* RESULT
|
|
* True if request successful.
|
|
*
|
|
******************************************************************************/
|
|
|
|
bool Session::SendChannelTopic(void)
|
|
{
|
|
const RefPtr<ChannelData>& channel = GetCurrentChannel();
|
|
|
|
if (channel.IsValid())
|
|
{
|
|
const char* topic = channel->GetTopic();
|
|
|
|
if (topic)
|
|
{
|
|
HRESULT hr = mChat->RequestChannelTopic(topic);
|
|
|
|
if (SUCCEEDED(hr))
|
|
{
|
|
return true;
|
|
}
|
|
|
|
WWDEBUG_SAY(("WOLERROR: SendChannelTopic() HRESULT = %s\n", GetChatErrorString(hr)));
|
|
}
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
|
|
/******************************************************************************
|
|
*
|
|
* NAME
|
|
* Session::SendChannelExtraInfo
|
|
*
|
|
* DESCRIPTION
|
|
* Send the extra info for the current channel.
|
|
*
|
|
* INPUTS
|
|
* NONE
|
|
*
|
|
* RESULT
|
|
* True if request successful.
|
|
*
|
|
******************************************************************************/
|
|
|
|
bool Session::SendChannelExtraInfo(void)
|
|
{
|
|
const RefPtr<ChannelData>& channel = GetCurrentChannel();
|
|
|
|
if (channel.IsValid())
|
|
{
|
|
const char* exInfo = channel->GetExtraInfo();
|
|
|
|
if (exInfo)
|
|
{
|
|
HRESULT hr = mChat->SetChannelExInfo(exInfo);
|
|
|
|
if (SUCCEEDED(hr))
|
|
{
|
|
return true;
|
|
}
|
|
|
|
WWDEBUG_SAY(("WOLERROR: ChangeChannelExtraInfo() HRESULT = %s\n", GetChatErrorString(hr)));
|
|
}
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
|
|
/******************************************************************************
|
|
*
|
|
* NAME
|
|
* Session::RequestUserList
|
|
*
|
|
* DESCRIPTION
|
|
* Request a new user list for the current channel from the IRC server.
|
|
*
|
|
* INPUTS
|
|
* NONE
|
|
*
|
|
* RESULT
|
|
* Success - True if request successful.
|
|
*
|
|
******************************************************************************/
|
|
|
|
bool Session::RequestUserList(void)
|
|
{
|
|
HRESULT hr = mChat->RequestUserList();
|
|
|
|
if (FAILED(hr))
|
|
{
|
|
WWDEBUG_SAY(("WOLERROR: RequestUserList() HRESULT = %s\n", GetChatErrorString(hr)));
|
|
}
|
|
|
|
return SUCCEEDED(hr);
|
|
}
|
|
|
|
|
|
/******************************************************************************
|
|
*
|
|
* NAME
|
|
* Session::FindUser
|
|
*
|
|
* DESCRIPTION
|
|
* Search for a user in the user list by name.
|
|
*
|
|
* INPUTS
|
|
* Nickname - Name of user to look for.
|
|
*
|
|
* RESULT
|
|
* User - User, if found.
|
|
*
|
|
******************************************************************************/
|
|
|
|
RefPtr<UserData> Session::FindUser(const wchar_t* nickname)
|
|
{
|
|
// Check the current user first.
|
|
if (mCurrentUser.IsValid())
|
|
{
|
|
const WideStringClass& username = mCurrentUser->GetName();
|
|
|
|
if (username.Compare_No_Case(nickname) == 0)
|
|
{
|
|
return mCurrentUser;
|
|
}
|
|
}
|
|
|
|
// Check in channels user list
|
|
return FindUserInList(nickname, mUsers);
|
|
}
|
|
|
|
|
|
/******************************************************************************
|
|
*
|
|
* NAME
|
|
* Session::GetUserOrBuddy
|
|
*
|
|
* DESCRIPTION
|
|
* Search for a user in the user list by name.
|
|
*
|
|
* INPUTS
|
|
* Nickname - Name of user to look for.
|
|
*
|
|
* RESULT
|
|
* User - User, if found.
|
|
*
|
|
******************************************************************************/
|
|
|
|
RefPtr<UserData> Session::GetUserOrBuddy(const wchar_t* name)
|
|
{
|
|
RefPtr<UserData> user = FindUser(name);
|
|
|
|
if (!user.IsValid())
|
|
{
|
|
user = FindBuddy(name);
|
|
}
|
|
|
|
return user;
|
|
}
|
|
|
|
|
|
/******************************************************************************
|
|
*
|
|
* NAME
|
|
* Session::IsCurrentUser
|
|
*
|
|
* DESCRIPTION
|
|
* Check if the specified user is the one logged in.
|
|
*
|
|
* INPUTS
|
|
* User - User to check.
|
|
*
|
|
* RESULT
|
|
* True if specified user is the current one.
|
|
*
|
|
******************************************************************************/
|
|
|
|
bool Session::IsCurrentUser(const RefPtr<UserData>& user) const
|
|
{
|
|
return user.IsValid() && mCurrentUser.IsValid() &&
|
|
user->GetName() == mCurrentUser->GetName();
|
|
}
|
|
|
|
|
|
bool Session::IsCurrentUser(const wchar_t* username) const
|
|
{
|
|
if (username && mCurrentUser.IsValid())
|
|
{
|
|
const WideStringClass& name = mCurrentUser->GetName();
|
|
return (name.Compare_No_Case(username) == 0);
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
|
|
/******************************************************************************
|
|
*
|
|
* NAME
|
|
* Session::ChangeCurrentUserLocale
|
|
*
|
|
* DESCRIPTION
|
|
* Change the locale for the user currently logged in.
|
|
*
|
|
* INPUTS
|
|
* Locale - New locale
|
|
*
|
|
* RESULT
|
|
* True if successful.
|
|
*
|
|
******************************************************************************/
|
|
|
|
bool Session::ChangeCurrentUserLocale(WOL::Locale locale)
|
|
{
|
|
if (mCurrentUser.IsValid() && (mCurrentUser->GetLocale() != locale))
|
|
{
|
|
HRESULT hr = mChat->RequestSetLocale(locale);
|
|
|
|
if (SUCCEEDED(hr))
|
|
{
|
|
return true;
|
|
}
|
|
|
|
WWDEBUG_SAY(("WOLERROR: RequestSetLocale() HRESULT = %s\n", GetChatErrorString(hr)));
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
|
|
/******************************************************************************
|
|
*
|
|
* NAME
|
|
* Session::SquelchUser
|
|
*
|
|
* DESCRIPTION
|
|
* Enable / disable squelching (ignoring) of other users.
|
|
*
|
|
* INPUTS
|
|
* User - User to squelch / unsquelch
|
|
* OnOff - True to squelch; False unsquelch
|
|
*
|
|
* RESULT
|
|
* True if operation successful.
|
|
*
|
|
******************************************************************************/
|
|
|
|
bool Session::SquelchUser(const RefPtr<UserData>& user, bool onoff)
|
|
{
|
|
if (user.IsValid())
|
|
{
|
|
WWDEBUG_SAY(("WOL: SquelchUser '%S'\n", user->GetName()));
|
|
HRESULT hr = mChat->SetSquelch(&user->GetData(), onoff);
|
|
|
|
if (SUCCEEDED(hr))
|
|
{
|
|
user->Squelch(onoff);
|
|
return true;
|
|
}
|
|
|
|
WWDEBUG_SAY(("WOLERROR: SetSquelch() HRESULT = %s\n", GetChatErrorString(hr)));
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
|
|
/******************************************************************************
|
|
*
|
|
* NAME
|
|
* Session::KickUser
|
|
*
|
|
* DESCRIPTION
|
|
* Make a request to kick a user from the current channel. Kicking is only
|
|
* allowed for channel owners.
|
|
*
|
|
* INPUTS
|
|
* User - Name of user to kick from the channel
|
|
*
|
|
* RESULT
|
|
* True if operation successful.
|
|
*
|
|
******************************************************************************/
|
|
|
|
bool Session::KickUser(const wchar_t* username)
|
|
{
|
|
if (username)
|
|
{
|
|
RefPtr<UserData> user = FindUserInList(username, mUsers);
|
|
|
|
if (user.IsValid())
|
|
{
|
|
WWDEBUG_SAY(("WOL: KickUser '%S'\n", user->GetName()));
|
|
HRESULT hr = mChat->RequestUserKick(&user->GetData());
|
|
|
|
if (SUCCEEDED(hr))
|
|
{
|
|
return true;
|
|
}
|
|
|
|
WWDEBUG_SAY(("WOLERROR: RequestUserKick() HRESULT = %s\n", GetChatErrorString(hr)));
|
|
}
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
|
|
/******************************************************************************
|
|
*
|
|
* NAME
|
|
* Session::BanUser
|
|
*
|
|
* DESCRIPTION
|
|
* Make a request to ban / unban a user from the current channel.
|
|
* Banning is only allowed for channel owners.
|
|
*
|
|
* INPUTS
|
|
* User - Name of user to ban / unban from the channel
|
|
* Ban - True to ban; False to remove ban
|
|
*
|
|
* RESULT
|
|
* True if operation successful.
|
|
*
|
|
******************************************************************************/
|
|
|
|
bool Session::BanUser(const wchar_t* username, bool banned)
|
|
{
|
|
if (username)
|
|
{
|
|
WWDEBUG_SAY(("WOL: BanUser '%S'\n", username));
|
|
|
|
char ansiName[64];
|
|
wcstombs(ansiName, username, sizeof(ansiName));
|
|
|
|
HRESULT hr = mChat->RequestChannelBan(ansiName, banned);
|
|
|
|
if (SUCCEEDED(hr))
|
|
{
|
|
return true;
|
|
}
|
|
|
|
WWDEBUG_SAY(("WOLERROR: RequestChannelBan() HRESULT = %s\n", GetChatErrorString(hr)));
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
|
|
/******************************************************************************
|
|
*
|
|
* NAME
|
|
* Session::PageUser
|
|
*
|
|
* DESCRIPTION
|
|
* Send page message to the specified user.
|
|
*
|
|
* INPUTS
|
|
* User - User to page.
|
|
* Message - Message to send.
|
|
*
|
|
* RESULT
|
|
* True if operation successful.
|
|
*
|
|
******************************************************************************/
|
|
|
|
bool Session::PageUser(const wchar_t* username, const wchar_t* message)
|
|
{
|
|
if ((username && wcslen(username)) && (message && wcslen(message)))
|
|
{
|
|
WOL::User wolUser;
|
|
memset((void*)&wolUser, 0, sizeof(wolUser));
|
|
wcstombs((char*)&wolUser.name, username, sizeof(wolUser.name));
|
|
wolUser.name[sizeof(wolUser.name) - 1] = 0;
|
|
|
|
if (IsAnsiText(message))
|
|
{
|
|
char ansiMessage[1024];
|
|
wcstombs(ansiMessage, message, sizeof(ansiMessage));
|
|
|
|
HRESULT hr = mChat->RequestPage(&wolUser, ansiMessage);
|
|
|
|
if (FAILED(hr))
|
|
{
|
|
WWDEBUG_SAY(("WOLERROR: RequestPage() HRESULT = %s\n", GetChatErrorString(hr)));
|
|
}
|
|
|
|
return SUCCEEDED(hr);
|
|
}
|
|
else
|
|
{
|
|
HRESULT hr = mChat->RequestUnicodePage(&wolUser, message);
|
|
|
|
if (FAILED(hr))
|
|
{
|
|
WWDEBUG_SAY(("WOLERROR: RequestUnicodePage() HRESULT = %s\n", GetChatErrorString(hr)));
|
|
}
|
|
|
|
return SUCCEEDED(hr);
|
|
}
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
|
|
/******************************************************************************
|
|
*
|
|
* NAME
|
|
* Session::RequestLocateUser
|
|
*
|
|
* DESCRIPTION
|
|
* Locate the user on Westwood Online.
|
|
*
|
|
* INPUTS
|
|
* Name - Login name of the user to locate.
|
|
*
|
|
* RESULT
|
|
* True if operation successful.
|
|
*
|
|
******************************************************************************/
|
|
|
|
void Session::RequestLocateUser(const wchar_t* name)
|
|
{
|
|
if (name && wcslen(name))
|
|
{
|
|
// If we already have the user then submit it, otherwise create a new user entry.
|
|
RefPtr<UserData> user = GetUserOrBuddy(name);
|
|
|
|
if (!user.IsValid())
|
|
{
|
|
user = UserData::Create(name);
|
|
}
|
|
|
|
RequestLocateUser(user);
|
|
}
|
|
}
|
|
|
|
|
|
void Session::RequestLocateUser(const RefPtr<UserData>& user)
|
|
{
|
|
if (user.IsValid())
|
|
{
|
|
// If the user is already pending then do not add him again.
|
|
RefPtr<UserData> pending = FindUserInList(user->GetName(), mLocatePendingUsers);
|
|
|
|
if (pending.IsValid())
|
|
{
|
|
return;
|
|
}
|
|
|
|
// Is user currently being located then done
|
|
if (mLocatingUser.IsValid())
|
|
{
|
|
const WideStringClass& userName = user->GetName();
|
|
|
|
if (userName.Compare_No_Case(mLocatingUser->GetName()) == 0)
|
|
{
|
|
return;
|
|
}
|
|
}
|
|
|
|
// Add the user to the pending locate list
|
|
mLocatePendingUsers.push_back(user);
|
|
}
|
|
}
|
|
|
|
|
|
/******************************************************************************
|
|
*
|
|
* NAME
|
|
* Session::MakeLocateUserRequests
|
|
*
|
|
* DESCRIPTION
|
|
* Make a request to the server to locate users.
|
|
*
|
|
* INPUTS
|
|
* NONE
|
|
*
|
|
* RESULT
|
|
* NONE
|
|
*
|
|
******************************************************************************/
|
|
|
|
void Session::MakeLocateUserRequests(void)
|
|
{
|
|
if (!mLocatePendingUsers.empty() && !mLocatingUser.IsValid())
|
|
{
|
|
mLocatingUser = mLocatePendingUsers[0];
|
|
mLocatePendingUsers.erase(mLocatePendingUsers.begin());
|
|
|
|
HRESULT hr = mChat->RequestFind(&mLocatingUser->GetData());
|
|
|
|
if (FAILED(hr))
|
|
{
|
|
WWDEBUG_SAY(("WOLERROR: RequestFind() HRESULT = %s\n", GetChatErrorString(hr)));
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
/******************************************************************************
|
|
*
|
|
* NAME
|
|
* Session::RequestUserLocale
|
|
*
|
|
* DESCRIPTION
|
|
* Make a request to query a users locale. (IE: US, Germany, Korea)
|
|
*
|
|
* INPUTS
|
|
* Name - Name of user to query locale for.
|
|
*
|
|
* RESULT
|
|
* NONE
|
|
*
|
|
******************************************************************************/
|
|
|
|
void Session::RequestUserLocale(const wchar_t* username)
|
|
{
|
|
if (username && (wcslen(username) > 0))
|
|
{
|
|
// Make sure the user is not already in the list.
|
|
const unsigned int count = mLocaleRequests.size();
|
|
|
|
for (unsigned int index = 0; index < count; ++index)
|
|
{
|
|
if (mLocaleRequests[index].Compare_No_Case(username) == 0)
|
|
{
|
|
return;
|
|
}
|
|
}
|
|
|
|
mLocaleRequests.push_back(username);
|
|
}
|
|
}
|
|
|
|
|
|
/******************************************************************************
|
|
*
|
|
* NAME
|
|
* Session::MakeLocaleRequests
|
|
*
|
|
* DESCRIPTION
|
|
* Make request to server to query user locales.
|
|
*
|
|
* INPUTS
|
|
* NONE
|
|
*
|
|
* RESULT
|
|
* NONE
|
|
*
|
|
******************************************************************************/
|
|
|
|
void Session::MakeLocaleRequests(void)
|
|
{
|
|
if (!mLocaleRequests.empty())
|
|
{
|
|
const unsigned int count = min<unsigned int>(10, mLocaleRequests.size());
|
|
WOL::User* users = new WOL::User[count];
|
|
WWASSERT(users && "Failed to create temporary users array");
|
|
|
|
if (users)
|
|
{
|
|
for (unsigned int index = 0; index < count; ++index)
|
|
{
|
|
WideStringClass& username = mLocaleRequests[index];
|
|
WWDEBUG_SAY(("WOL: Requesting locale for '%S'\n", (const WCHAR*)username));
|
|
|
|
WOL::User& user = users[index];
|
|
wcstombs((char*)user.name, username, sizeof(user.name));
|
|
user.name[sizeof(user.name) - 1] = 0;
|
|
|
|
if (index == (count - 1))
|
|
{
|
|
user.next = NULL;
|
|
}
|
|
else
|
|
{
|
|
user.next = &users[index + 1];
|
|
}
|
|
}
|
|
|
|
HRESULT hr = mChat->RequestUserLocale(users);
|
|
|
|
// If request was successful then remove from the pending list.
|
|
if (SUCCEEDED(hr))
|
|
{
|
|
LocaleRequestColl::iterator first = mLocaleRequests.begin();
|
|
mLocaleRequests.erase(first, first + count);
|
|
}
|
|
else
|
|
{
|
|
WWDEBUG_SAY(("WOLERROR: RequestUserLocale() HRESULT = %s\n", GetChatErrorString(hr)));
|
|
}
|
|
|
|
delete []users;
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
/******************************************************************************
|
|
*
|
|
* NAME
|
|
* Session::RequestSquadInfoByID
|
|
*
|
|
* DESCRIPTION
|
|
* Request information about a squad by Squad ID.
|
|
*
|
|
* INPUTS
|
|
* SquadID - Identifier of squad
|
|
*
|
|
* RESULT
|
|
* NONE
|
|
*
|
|
******************************************************************************/
|
|
|
|
void Session::RequestSquadInfoByID(unsigned long squadID)
|
|
{
|
|
if (squadID != 0)
|
|
{
|
|
// MAGICK NUMBER -- itoa handles up to 33 digit numbers
|
|
wchar_t idString[34];
|
|
|
|
// MAGICK NUMBER - 10 - squadID is base 10.
|
|
_itow(squadID, idString, 10);
|
|
|
|
// Only add a request that is not already pending.
|
|
const unsigned int count = mSquadRequests.size();
|
|
|
|
for (unsigned int index = 0; index < count; ++index)
|
|
{
|
|
if (mSquadRequests[index] == idString)
|
|
{
|
|
return;
|
|
}
|
|
}
|
|
|
|
mSquadRequests.push_back(idString);
|
|
}
|
|
}
|
|
|
|
|
|
/******************************************************************************
|
|
*
|
|
* NAME
|
|
* Session::RequestSquadInfoByMemberName
|
|
*
|
|
* DESCRIPTION
|
|
* Request information about a squad by Member Name.
|
|
*
|
|
* INPUTS
|
|
* memberName - user name of a member
|
|
*
|
|
* RESULT
|
|
* NONE
|
|
*
|
|
******************************************************************************/
|
|
|
|
void Session::RequestSquadInfoByMemberName(const wchar_t* memberName)
|
|
{
|
|
if (memberName && (wcslen(memberName) > 0))
|
|
{
|
|
// Only add a request that is not already pending.
|
|
for (unsigned int index = 0; index < mSquadRequests.size(); index++)
|
|
{
|
|
if (mSquadRequests[index].Compare_No_Case(memberName) == 0)
|
|
{
|
|
return;
|
|
}
|
|
}
|
|
|
|
mSquadRequests.push_back(memberName);
|
|
}
|
|
}
|
|
|
|
|
|
/******************************************************************************
|
|
*
|
|
* NAME
|
|
* Session::MakeSquadRequests
|
|
*
|
|
* DESCRIPTION
|
|
* Make request to server to query squad information.
|
|
*
|
|
* INPUTS
|
|
* NONE
|
|
*
|
|
* RESULT
|
|
* NONE
|
|
*
|
|
******************************************************************************/
|
|
|
|
void Session::MakeSquadRequests(void)
|
|
{
|
|
if (!mSquadRequests.empty() && mSquadPending.empty())
|
|
{
|
|
// Send up to ten requests at a time.
|
|
unsigned int count = min<unsigned int>(10, mSquadRequests.size());
|
|
|
|
// Send each request in turn,
|
|
for (unsigned int index = 0; index < count; ++index)
|
|
{
|
|
const WideStringClass& request = mSquadRequests[index];
|
|
|
|
HRESULT hr = E_FAIL;
|
|
|
|
// Check to see if this is an ID or a name
|
|
// - names can't have the first character be a number so this works.
|
|
wchar_t firstChar = request[0];
|
|
|
|
if (iswdigit(firstChar))
|
|
{
|
|
unsigned int squadID = _wtoi(request);
|
|
WWDEBUG_SAY(("WOL: SquadInfo requested for ID %ld\n", squadID));
|
|
hr = mChat->RequestSquadInfo(squadID);
|
|
}
|
|
else
|
|
{
|
|
StringClass name(0, true);
|
|
request.Convert_To(name);
|
|
|
|
WWDEBUG_SAY(("WOL: SquadInfo requested for '%s'\n", (const char*)name));
|
|
hr = mChat->RequestSquadByName(name);
|
|
}
|
|
|
|
if (FAILED(hr))
|
|
{
|
|
WWDEBUG_SAY(("WOLERROR: RequestSquadInfo() HRESULT = %s\n", GetChatErrorString(hr)));
|
|
break;
|
|
}
|
|
|
|
mSquadPending.push_back(request);
|
|
}
|
|
|
|
SquadRequestColl::iterator first = mSquadRequests.begin();
|
|
mSquadRequests.erase(first, first + index);
|
|
}
|
|
}
|
|
|
|
|
|
/******************************************************************************
|
|
*
|
|
* NAME
|
|
* Session::RequestTeamInfo
|
|
*
|
|
* DESCRIPTION
|
|
* Make a request to query a users team information.
|
|
*
|
|
* INPUTS
|
|
* Name - Name of user to request team information for.
|
|
*
|
|
* RESULT
|
|
* NONE
|
|
*
|
|
******************************************************************************/
|
|
|
|
void Session::RequestTeamInfo(const wchar_t* username)
|
|
{
|
|
if (username && (wcslen(username) > 0))
|
|
{
|
|
for (unsigned int index = 0; index < mTeamRequests.size(); index++)
|
|
{
|
|
if (mTeamRequests[index].Compare_No_Case(username) == 0)
|
|
{
|
|
return;
|
|
}
|
|
}
|
|
|
|
mTeamRequests.push_back(username);
|
|
}
|
|
}
|
|
|
|
|
|
/******************************************************************************
|
|
*
|
|
* NAME
|
|
* Session::MakeTeamRequests
|
|
*
|
|
* DESCRIPTION
|
|
* Send team requests to the server.
|
|
*
|
|
* INPUTS
|
|
* NONE
|
|
*
|
|
* RESULT
|
|
* NONE
|
|
*
|
|
******************************************************************************/
|
|
|
|
void Session::MakeTeamRequests(void)
|
|
{
|
|
if (!mTeamRequests.empty())
|
|
{
|
|
WWDEBUG_SAY(("WOL: Requesting team information\n"));
|
|
|
|
unsigned int count = min<unsigned int>(10, mTeamRequests.size());
|
|
WOL::User* users = new WOL::User[count];
|
|
WWASSERT(users && "Failed to create temporary users array");
|
|
|
|
if (users)
|
|
{
|
|
for (unsigned int index = 0; index < count; index++)
|
|
{
|
|
WOL::User& user = users[index];
|
|
|
|
WideStringClass& username = mTeamRequests[index];
|
|
wcstombs((char*)user.name, username.Peek_Buffer(), sizeof(user.name));
|
|
user.name[sizeof(user.name) - 1] = 0;
|
|
|
|
if (index == count - 1)
|
|
{
|
|
user.next = NULL;
|
|
}
|
|
else
|
|
{
|
|
user.next = users + index + 1;
|
|
}
|
|
}
|
|
|
|
HRESULT hr = mChat->RequestUserTeam(users);
|
|
|
|
// If request was successful then remove from the pending list.
|
|
if (SUCCEEDED(hr))
|
|
{
|
|
TeamRequestColl::iterator first = mTeamRequests.begin();
|
|
mTeamRequests.erase(first, first + count);
|
|
}
|
|
else
|
|
{
|
|
WWDEBUG_SAY(("WOL: HRESULT = %s\n", GetChatErrorString(hr)));
|
|
}
|
|
|
|
delete []users;
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
/******************************************************************************
|
|
*
|
|
* NAME
|
|
* Session::RequestLadderInfo
|
|
*
|
|
* DESCRIPTION
|
|
* Request a users ladder information.
|
|
*
|
|
* INPUTS
|
|
* User - Name of user to request information for.
|
|
* Type - Type of ladder requesting
|
|
*
|
|
* RESULT
|
|
* NONE
|
|
*
|
|
******************************************************************************/
|
|
|
|
void Session::RequestLadderInfo(const wchar_t* name, unsigned long type)
|
|
{
|
|
if (name && (wcslen(name) > 0) && (type & LADDERTYPE_MASK))
|
|
{
|
|
WideStringClass request(64, true);
|
|
request = L"itc:";
|
|
|
|
// Clan ladder requests are mutually exclusive to other ladder requests
|
|
// because it requires the name of the clan, while the other requests use
|
|
// the users login name.
|
|
if (type & LadderType_Clan)
|
|
{
|
|
WWASSERT((type & (LadderType_Individual | LadderType_Team)) == 0);
|
|
request[2] = L'C';
|
|
}
|
|
else
|
|
{
|
|
if (type & LadderType_Individual)
|
|
{
|
|
request[0] = L'I';
|
|
}
|
|
|
|
if (type & LadderType_Team)
|
|
{
|
|
request[1] = L'T';
|
|
}
|
|
}
|
|
|
|
// Append the name to the request
|
|
request += name;
|
|
|
|
// Check if the request is already in the list.
|
|
LadderRequestList::iterator pending = mLadderRequests.begin();
|
|
|
|
while (pending != mLadderRequests.end())
|
|
{
|
|
if (request.Compare_No_Case(*pending) == 0)
|
|
{
|
|
return;
|
|
}
|
|
|
|
pending++;
|
|
}
|
|
|
|
WWDEBUG_SAY(("WOL: LadderInfo request added '%S'.\n", request));
|
|
mLadderRequests.push_back(request);
|
|
}
|
|
}
|
|
|
|
|
|
/******************************************************************************
|
|
*
|
|
* NAME
|
|
* Session::MakeLadderRequests
|
|
*
|
|
* DESCRIPTION
|
|
* Send ladder requests to the server.
|
|
*
|
|
* INPUTS
|
|
* NONE
|
|
*
|
|
* RESULT
|
|
* NONE
|
|
*
|
|
******************************************************************************/
|
|
|
|
void Session::MakeLadderRequests(void)
|
|
{
|
|
// If there are requests and nothing is pending then send the next request
|
|
if (!mLadderRequests.empty() && mLadderPending == 0)
|
|
{
|
|
RefPtrConst<Product> product = Product::Current();
|
|
|
|
if (mLadderServer.IsValid() && product.IsValid())
|
|
{
|
|
// Build a single key from up to 10 requests with the same request type.
|
|
char keys[256];
|
|
keys[0] = 0;
|
|
|
|
unsigned int count = 0;
|
|
LadderRequestList::iterator request = mLadderRequests.begin();
|
|
const WideStringClass& firstRequest = *request;
|
|
|
|
while ((count < 10) && (request != mLadderRequests.end()))
|
|
{
|
|
// Stop appending requests as soon as we encounter a different type.
|
|
if (wcsncmp(firstRequest, *request, 3) != 0)
|
|
{
|
|
break;
|
|
}
|
|
|
|
// Seperate key entries with a colon
|
|
if (count > 0)
|
|
{
|
|
strcat(keys, ":");
|
|
}
|
|
|
|
// The request name follows the type
|
|
WCHAR* widename = wcschr(*request, L':');
|
|
WWASSERT(widename != NULL && "Invalid Ladder Request");
|
|
widename++;
|
|
|
|
// Add the request
|
|
char name[64];
|
|
wcstombs(name, widename, 64);
|
|
strcat(keys, name);
|
|
|
|
// Next request
|
|
count++;
|
|
request++;
|
|
}
|
|
|
|
WWDEBUG_SAY(("WOL: LadderInfo requested for '%s'.\n", keys));
|
|
mLadderPending = count;
|
|
|
|
const char* hostAddr = mLadderServer->GetHostAddress();
|
|
unsigned int port = mLadderServer->GetPort();
|
|
unsigned long sku = product->GetLadderSKU();
|
|
|
|
// Request individual ladder
|
|
if (firstRequest[0] == L'I')
|
|
{
|
|
HRESULT hr = mNetUtil->RequestLadderList(hostAddr, port, keys, sku, -1, 0, 0);
|
|
|
|
if (FAILED(hr))
|
|
{
|
|
WWDEBUG_SAY(("WOLERROR: RequestLadderList (Individual) HRESULT = %s\n", GetNetUtilErrorString(hr)));
|
|
return;
|
|
}
|
|
|
|
mLadderPending |= LadderType_Individual;
|
|
}
|
|
|
|
// Request team ladder
|
|
if (firstRequest[1] == L'T')
|
|
{
|
|
HRESULT hr = mNetUtil->RequestLadderList(hostAddr, port, keys, (sku | LadderType_Team), -1, 0, 0);
|
|
|
|
if (FAILED(hr))
|
|
{
|
|
WWDEBUG_SAY(("WOLERROR: RequestLadderList (Team) HRESULT = %s\n", GetNetUtilErrorString(hr)));
|
|
return;
|
|
}
|
|
|
|
mLadderPending |= LadderType_Team;
|
|
}
|
|
|
|
// Request clan ladder
|
|
if (firstRequest[2] == L'C')
|
|
{
|
|
HRESULT hr = mNetUtil->RequestLadderList(hostAddr, port, keys, (sku | LadderType_Clan), -1, 0, 0);
|
|
|
|
if (FAILED(hr))
|
|
{
|
|
WWDEBUG_SAY(("WOLERROR: RequestLadderList (Clan) HRESULT = %s\n", GetNetUtilErrorString(hr)));
|
|
return;
|
|
}
|
|
|
|
mLadderPending |= LadderType_Clan;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
/******************************************************************************
|
|
*
|
|
* NAME
|
|
* Session::RequestUserDetails
|
|
*
|
|
* DESCRIPTION
|
|
* Request detailed information about the user (Ladder, Clan, Team, etc...)
|
|
*
|
|
* INPUTS
|
|
* User - User to request details for.
|
|
* RequestFlags - Flags indicating the type of information to request.
|
|
*
|
|
* RESULT
|
|
* NONE
|
|
*
|
|
******************************************************************************/
|
|
|
|
void Session::RequestUserDetails(const RefPtr<UserData>& user, unsigned long requestFlags)
|
|
{
|
|
if (user.IsValid())
|
|
{
|
|
if (requestFlags & REQUEST_SQUADINFO)
|
|
{
|
|
// Request squad information for the user.
|
|
unsigned int squadID = user->GetSquadID();
|
|
RefPtr<SquadData> squad = user->GetSquad();
|
|
|
|
bool requestSquad = (!squad.IsValid() && (squadID != 0));
|
|
bool changedSquad = (squad.IsValid() && (squadID != squad->GetID()));
|
|
|
|
if (requestSquad || changedSquad)
|
|
{
|
|
// Look for the squad in the local cache
|
|
squad = SquadData::FindByID(squadID);
|
|
user->SetSquad(squad);
|
|
|
|
// Request squad information if it is not in the local cache.
|
|
if (!squad.IsValid())
|
|
{
|
|
RequestSquadInfoByID(squadID);
|
|
}
|
|
else
|
|
{
|
|
UserEvent event(UserEvent::SquadInfo, user);
|
|
NotifyObservers(event);
|
|
}
|
|
}
|
|
}
|
|
|
|
// Request locale information for this user.
|
|
if ((requestFlags & REQUEST_LOCALE) && (user->GetLocale() == WOL::LOC_UNKNOWN))
|
|
{
|
|
RequestUserLocale(user->GetName());
|
|
}
|
|
|
|
// Request ladder information for this user.
|
|
if ((requestFlags & REQUEST_LADDERINFO) && !user->GetLadder().IsValid())
|
|
{
|
|
RequestLadderInfo(user->GetName(), LadderType_Team);
|
|
}
|
|
|
|
// Request team information for this user.
|
|
if ((requestFlags & REQUEST_TEAMINFO) && (user->GetTeam() == 0))
|
|
{
|
|
RequestTeamInfo(user->GetName());
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
/******************************************************************************
|
|
*
|
|
* NAME
|
|
* Session::AutoRequestUserDetails
|
|
*
|
|
* DESCRIPTION
|
|
*
|
|
* INPUTS
|
|
*
|
|
* RESULT
|
|
* NONE
|
|
*
|
|
******************************************************************************/
|
|
|
|
void Session::AutoRequestUserDetails(const RefPtr<UserData>& user)
|
|
{
|
|
RequestUserDetails(user, mAutoRequestFlags);
|
|
}
|
|
|
|
|
|
/******************************************************************************
|
|
*
|
|
* NAME
|
|
* Session::RequestBuddyList
|
|
*
|
|
* DESCRIPTION
|
|
* Send a request to the server for our buddy list.
|
|
*
|
|
* INPUTS
|
|
* NONE
|
|
*
|
|
* RESULT
|
|
* Success - True if request successful
|
|
*
|
|
******************************************************************************/
|
|
|
|
bool Session::RequestBuddyList(void)
|
|
{
|
|
HRESULT hr = mChat->RequestBuddyList();
|
|
|
|
if (FAILED(hr))
|
|
{
|
|
WWDEBUG_SAY(("WOLERROR: RequestBuddyList() failed HRESULT = %s\n", GetChatErrorString(hr)));
|
|
}
|
|
|
|
return SUCCEEDED(hr);
|
|
}
|
|
|
|
|
|
/******************************************************************************
|
|
*
|
|
* NAME
|
|
* Session::AddBuddy
|
|
*
|
|
* DESCRIPTION
|
|
* Send a request to the server to add a buddy to our buddy list.
|
|
*
|
|
* INPUTS
|
|
* Buddy - Name of buddy to add.
|
|
*
|
|
* RESULT
|
|
* True if request sent successfully
|
|
*
|
|
******************************************************************************/
|
|
|
|
bool Session::AddBuddy(const wchar_t* buddyName)
|
|
{
|
|
WOL::User wolUser;
|
|
memset((void*)&wolUser, 0, sizeof(wolUser));
|
|
wcstombs((char*)&wolUser.name, buddyName, sizeof(wolUser.name));
|
|
wolUser.name[sizeof(wolUser.name) - 1] = 0;
|
|
|
|
HRESULT hr = mChat->RequestBuddyAdd(&wolUser);
|
|
|
|
if (FAILED(hr))
|
|
{
|
|
WWDEBUG_SAY(("WOLERROR: RequestBuddyAdd() failed HRESULT = %s\n", GetChatErrorString(hr)));
|
|
}
|
|
|
|
return SUCCEEDED(hr);
|
|
}
|
|
|
|
|
|
/******************************************************************************
|
|
*
|
|
* NAME
|
|
* Session::RemoveBuddy
|
|
*
|
|
* DESCRIPTION
|
|
* Send a request to the server to remove a buddy from our buddy list.
|
|
*
|
|
* INPUTS
|
|
* Buddy - Name of buddy to remove.
|
|
*
|
|
* RESULT
|
|
* True if request sent successfully
|
|
*
|
|
******************************************************************************/
|
|
|
|
bool Session::RemoveBuddy(const wchar_t* buddyName)
|
|
{
|
|
WOL::User wolUser;
|
|
memset((void*)&wolUser, 0, sizeof(wolUser));
|
|
wcstombs((char*)&wolUser.name, buddyName, sizeof(wolUser.name));
|
|
wolUser.name[sizeof(wolUser.name) - 1] = 0;
|
|
|
|
HRESULT hr = mChat->RequestBuddyDelete(&wolUser);
|
|
|
|
if (FAILED(hr))
|
|
{
|
|
WWDEBUG_SAY(("WOLERROR: RequestBuddyDelete() failed HRESULT = %s\n", GetChatErrorString(hr)));
|
|
}
|
|
|
|
return SUCCEEDED(hr);
|
|
}
|
|
|
|
|
|
/******************************************************************************
|
|
*
|
|
* NAME
|
|
* Session::AllowFindPage
|
|
*
|
|
* DESCRIPTION
|
|
* Set flags to allow / disallow user from being found or paged.
|
|
*
|
|
* INPUTS
|
|
* AllowFind - True to allow user to be found; False to disallow.
|
|
* AllowPage - True to allow user to be paged; False to disallow.
|
|
*
|
|
* RESULT
|
|
* True if request successful
|
|
*
|
|
******************************************************************************/
|
|
|
|
bool Session::AllowFindPage(bool allowFind, bool allowPage)
|
|
{
|
|
HRESULT hr = mChat->SetFindPage(allowFind, allowPage);
|
|
|
|
if (FAILED(hr))
|
|
{
|
|
WWDEBUG_SAY(("WOLERROR: SetFindPage() failed HRESULT = %s\n", GetChatErrorString(hr)));
|
|
}
|
|
|
|
return SUCCEEDED(hr);
|
|
}
|
|
|
|
|
|
/******************************************************************************
|
|
*
|
|
* NAME
|
|
* Session::SetBadLanguageFilter
|
|
*
|
|
* DESCRIPTION
|
|
* Enable / Disable filtering of bad language.
|
|
*
|
|
* INPUTS
|
|
* Filter - True to enable filtering, false to disable.
|
|
*
|
|
* RESULT
|
|
* True if request successful
|
|
*
|
|
******************************************************************************/
|
|
|
|
bool Session::SetBadLanguageFilter(bool enabled)
|
|
{
|
|
HRESULT hr = mChat->SetLangFilter(enabled);
|
|
|
|
if (FAILED(hr))
|
|
{
|
|
WWDEBUG_SAY(("WOLERROR: SetLangFilter() failed HRESULT = %s\n", GetChatErrorString(hr)));
|
|
}
|
|
|
|
return SUCCEEDED(hr);
|
|
}
|
|
|
|
|
|
/******************************************************************************
|
|
*
|
|
* NAME
|
|
* Session::SendPublicMessage
|
|
*
|
|
* DESCRIPTION
|
|
* Send a public message to all users in our channel.
|
|
*
|
|
* INPUTS
|
|
* Message - Message to send
|
|
*
|
|
* RESULT
|
|
* True if request successful
|
|
*
|
|
******************************************************************************/
|
|
|
|
bool Session::SendPublicMessage(const char* message)
|
|
{
|
|
if (message)
|
|
{
|
|
return SUCCEEDED(mChat->RequestPublicMessage(message));
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
|
|
bool Session::SendPublicMessage(const wchar_t* message)
|
|
{
|
|
if (message)
|
|
{
|
|
if (IsAnsiText(message))
|
|
{
|
|
char ansiMessage[1024];
|
|
wcstombs(ansiMessage, message, sizeof(ansiMessage));
|
|
return SUCCEEDED(mChat->RequestPublicMessage(ansiMessage));
|
|
}
|
|
else
|
|
{
|
|
return SUCCEEDED(mChat->RequestPublicUnicodeMessage(message));
|
|
}
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
|
|
/******************************************************************************
|
|
*
|
|
* NAME
|
|
* Session::SendPublicAction
|
|
*
|
|
* DESCRIPTION
|
|
* Send an actions to all users in our channel.
|
|
*
|
|
* INPUTS
|
|
* Action - Action message
|
|
*
|
|
* RESULT
|
|
* True if request successful
|
|
*
|
|
******************************************************************************/
|
|
|
|
bool Session::SendPublicAction(const char* action)
|
|
{
|
|
if (action)
|
|
{
|
|
return SUCCEEDED(mChat->RequestPublicAction(action));
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
|
|
bool Session::SendPublicAction(const wchar_t* action)
|
|
{
|
|
if (action)
|
|
{
|
|
if (IsAnsiText(action))
|
|
{
|
|
char ansiAction[1024];
|
|
wcstombs(ansiAction, action, sizeof(ansiAction));
|
|
return SUCCEEDED(mChat->RequestPublicAction(ansiAction));
|
|
}
|
|
else
|
|
{
|
|
return SUCCEEDED(mChat->RequestPublicUnicodeAction(action));
|
|
}
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
|
|
/******************************************************************************
|
|
*
|
|
* NAME
|
|
* Session::SendPrivateMessage
|
|
*
|
|
* DESCRIPTION
|
|
* Send a private message to a single user.
|
|
*
|
|
* INPUTS
|
|
* Username - Name of user to send private message to.
|
|
* Message - Message to send.
|
|
*
|
|
* RESULT
|
|
* True if request successful
|
|
*
|
|
******************************************************************************/
|
|
|
|
bool Session::SendPrivateMessage(const wchar_t* username, const wchar_t* message)
|
|
{
|
|
if (username && message)
|
|
{
|
|
WOL::User user;
|
|
memset(&user, 0, sizeof(user));
|
|
wcstombs((char*)user.name, username, sizeof(user.name));
|
|
user.name[sizeof(user.name) - 1] = 0;
|
|
|
|
if (IsAnsiText(message))
|
|
{
|
|
char ansiMessage[512];
|
|
wcstombs(ansiMessage, message, sizeof(ansiMessage));
|
|
return SUCCEEDED(mChat->RequestPrivateMessage(&user, ansiMessage));
|
|
}
|
|
|
|
return SUCCEEDED(mChat->RequestPrivateUnicodeMessage(&user, message));
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
|
|
/******************************************************************************
|
|
*
|
|
* NAME
|
|
* Session::SendPrivateMessage
|
|
*
|
|
* DESCRIPTION
|
|
* Send a private message to a set of users.
|
|
*
|
|
* INPUTS
|
|
* Users - List of users to send message
|
|
* Message - Message to send.
|
|
*
|
|
* RESULT
|
|
* True if request successful
|
|
*
|
|
******************************************************************************/
|
|
|
|
bool Session::SendPrivateMessage(const UserList& users, const char* message)
|
|
{
|
|
if (!users.empty() && message)
|
|
{
|
|
NativeWOLUserList wolUsers(users);
|
|
return SUCCEEDED(mChat->RequestPrivateMessage(wolUsers, message));
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
|
|
bool Session::SendPrivateMessage(const UserList& users, const wchar_t* message)
|
|
{
|
|
if (!users.empty() && message)
|
|
{
|
|
NativeWOLUserList wolUsers(users);
|
|
|
|
if (IsAnsiText(message))
|
|
{
|
|
char ansiMessage[512];
|
|
wcstombs(ansiMessage, message, sizeof(ansiMessage));
|
|
return SUCCEEDED(mChat->RequestPrivateMessage(wolUsers, ansiMessage));
|
|
}
|
|
|
|
return SUCCEEDED(mChat->RequestPrivateUnicodeMessage(wolUsers, message));
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
|
|
/******************************************************************************
|
|
*
|
|
* NAME
|
|
* Session::SendPrivateAction
|
|
*
|
|
* DESCRIPTION
|
|
* Send a private action message to a set of users.
|
|
*
|
|
* INPUTS
|
|
* Users - List of users to send message to.
|
|
* Action - Action message to send.
|
|
*
|
|
* RESULT
|
|
* True if request successful
|
|
*
|
|
******************************************************************************/
|
|
|
|
bool Session::SendPrivateAction(const UserList& users, const char* action)
|
|
{
|
|
if (!users.empty() && action)
|
|
{
|
|
NativeWOLUserList wolUsers(users);
|
|
return SUCCEEDED(mChat->RequestPrivateAction(wolUsers, action));
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
|
|
bool Session::SendPrivateAction(const UserList& users, const wchar_t* action)
|
|
{
|
|
if (!users.empty() && action)
|
|
{
|
|
NativeWOLUserList wolUsers(users);
|
|
|
|
if (IsAnsiText(action))
|
|
{
|
|
char ansiAction[1024];
|
|
wcstombs(ansiAction, action, sizeof(ansiAction));
|
|
return SUCCEEDED(mChat->RequestPrivateAction(wolUsers, ansiAction));
|
|
}
|
|
|
|
return SUCCEEDED(mChat->RequestPrivateUnicodeAction(wolUsers, action));
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
|
|
/******************************************************************************
|
|
*
|
|
* NAME
|
|
* Session::SendPublicGameOptions
|
|
*
|
|
* DESCRIPTION
|
|
* Send public game options
|
|
*
|
|
* INPUTS
|
|
* Options - Options to send to all users in the channel.
|
|
*
|
|
* RESULT
|
|
* True if request successful
|
|
*
|
|
******************************************************************************/
|
|
|
|
bool Session::SendPublicGameOptions(const char* options)
|
|
{
|
|
if (options)
|
|
{
|
|
return SUCCEEDED(mChat->RequestPublicGameOptions(options));
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
|
|
/******************************************************************************
|
|
*
|
|
* NAME
|
|
* Session::SendPrivateGameOptions
|
|
*
|
|
* DESCRIPTION
|
|
*
|
|
* INPUTS
|
|
* Options - Options to send to specific users.
|
|
*
|
|
* RESULT
|
|
* True if request successful
|
|
*
|
|
******************************************************************************/
|
|
|
|
bool Session::SendPrivateGameOptions(const UserList& users, const char* options)
|
|
{
|
|
if (options)
|
|
{
|
|
for (unsigned int index = 0; index < users.size(); index++)
|
|
{
|
|
NativeWOLUserList wolUsers(users);
|
|
HRESULT hr = mChat->RequestPrivateGameOptions(wolUsers, options);
|
|
|
|
if (FAILED(hr))
|
|
{
|
|
return false;
|
|
}
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
|
|
bool Session::SendPrivateGameOptions(const wchar_t* user, const char* options)
|
|
{
|
|
if (user && options)
|
|
{
|
|
WOL::User wolUser;
|
|
memset(&wolUser, 0, sizeof(WOL::User));
|
|
wcstombs((char*)wolUser.name, user, sizeof(wolUser.name));
|
|
wolUser.name[sizeof(wolUser.name) - 1] = 0;
|
|
|
|
return SUCCEEDED(mChat->RequestPrivateGameOptions(&wolUser, options));
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
|
|
/******************************************************************************
|
|
*
|
|
* NAME
|
|
* Session::GetLocaleStrings
|
|
*
|
|
* DESCRIPTION
|
|
* Get a list of the WWOnline locale strings.
|
|
*
|
|
* INPUTS
|
|
* Strings - List to fill with locale name strings.
|
|
*
|
|
* RESULT
|
|
* NONE
|
|
*
|
|
******************************************************************************/
|
|
|
|
void Session::GetLocaleStrings(std::vector<WideStringClass>& localeStrings)
|
|
{
|
|
localeStrings.clear();
|
|
|
|
int numLocales = 0;
|
|
mChat->GetLocaleCount(&numLocales);
|
|
|
|
for (int index = 0; index < numLocales; index++)
|
|
{
|
|
const char* name = NULL;
|
|
mChat->GetLocaleString(&name, (WOL::Locale)index);
|
|
localeStrings.push_back(name);
|
|
}
|
|
}
|
|
|
|
|
|
/******************************************************************************
|
|
*
|
|
* NAME
|
|
* Session::SendGameResults
|
|
*
|
|
* DESCRIPTION
|
|
*
|
|
* INPUTS
|
|
* Packet - Game results packet to send.
|
|
* Length - Length of packet in bytes.
|
|
*
|
|
* RESULT
|
|
* True if request sent successfully
|
|
*
|
|
******************************************************************************/
|
|
|
|
bool Session::SendGameResults(unsigned char* packet, unsigned long length)
|
|
{
|
|
if (packet && mGameResultsServer.IsValid())
|
|
{
|
|
mNetUtil->SetGameResMD5(true);
|
|
|
|
const char* host = mGameResultsServer->GetHostAddress();
|
|
unsigned int port = mGameResultsServer->GetPort();
|
|
|
|
HRESULT hr = mNetUtil->RequestLargeGameresSend(host, port, packet, length);
|
|
|
|
if (FAILED(hr))
|
|
{
|
|
WWDEBUG_SAY(("WOLERROR: RequestLargeGameresSend() failed HRESULT = %s\n", GetChatErrorString(hr)));
|
|
}
|
|
|
|
return SUCCEEDED(hr);
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
|
|
/******************************************************************************
|
|
*
|
|
* NAME
|
|
* Session::EnablePinging
|
|
*
|
|
* DESCRIPTION
|
|
*
|
|
* INPUTS
|
|
*
|
|
* RESULT
|
|
* NONE
|
|
*
|
|
******************************************************************************/
|
|
|
|
void Session::EnablePinging(bool enable)
|
|
{
|
|
mPingEnable += ((enable == true) ? 1 : -1);
|
|
}
|
|
|
|
|
|
/******************************************************************************
|
|
*
|
|
* NAME
|
|
* Session::RequestPing
|
|
*
|
|
* DESCRIPTION
|
|
* Request a ping to the specified address.
|
|
*
|
|
* INPUTS
|
|
* Address - Address to ping (IE: irc.westwood.com)
|
|
* Timeout - Maximum time to allow for response.
|
|
*
|
|
* RESULT
|
|
* NONE
|
|
*
|
|
******************************************************************************/
|
|
|
|
void Session::RequestPing(const char* address, int timeout)
|
|
{
|
|
if (address)
|
|
{
|
|
// If the address is already pending then do not add it again.
|
|
std::vector<RawPing>::iterator iter = mPingRequests.begin();
|
|
|
|
while (iter != mPingRequests.end())
|
|
{
|
|
if (stricmp(iter->GetHostAddress(), address) == 0)
|
|
{
|
|
// WWDEBUG_SAY(("WOLWARNING: Ping request already pending %s\n", address));
|
|
return;
|
|
}
|
|
|
|
iter++;
|
|
}
|
|
|
|
WWDEBUG_SAY(("WOL: Adding ping request %s\n", address));
|
|
RawPing ping(address, 0, timeout);
|
|
mPingRequests.push_back(ping);
|
|
}
|
|
}
|
|
|
|
|
|
/******************************************************************************
|
|
*
|
|
* NAME
|
|
* Session::MakePingRequests
|
|
*
|
|
* DESCRIPTION
|
|
* Send out ping requests
|
|
*
|
|
* INPUTS
|
|
* NONE
|
|
*
|
|
* RESULT
|
|
* NONE
|
|
*
|
|
******************************************************************************/
|
|
|
|
void Session::MakePingRequests(void)
|
|
{
|
|
if (mPingEnable && (mPingRequests.size() > mPingsPending))
|
|
{
|
|
for (unsigned int index = 0; index < mPingRequests.size(); index++)
|
|
{
|
|
RawPing* ping = &mPingRequests[index];
|
|
|
|
if (ping->GetHandle() == -1)
|
|
{
|
|
int handle = 0;
|
|
|
|
HRESULT hr = mNetUtil->RequestPing(ping->GetHostAddress(), ping->GetTime(), &handle);
|
|
|
|
if (SUCCEEDED(hr))
|
|
{
|
|
WWDEBUG_SAY(("WOL: Pinging '%s' [%d]\n", ping->GetHostAddress(), handle));
|
|
ping->SetHandle(handle);
|
|
mPingsPending++;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
/******************************************************************************
|
|
*
|
|
* NAME
|
|
* Session::UpdatePingServerTime
|
|
*
|
|
* DESCRIPTION
|
|
* Update the ping time of a ping server.
|
|
*
|
|
* INPUTS
|
|
* Name - Host adddress of server to update.
|
|
* Time - Ping time.
|
|
*
|
|
* RESULT
|
|
* NONE
|
|
*
|
|
******************************************************************************/
|
|
|
|
void Session::UpdatePingServerTime(const char* name, int time)
|
|
{
|
|
if (name)
|
|
{
|
|
// Automatically update ping server times.
|
|
const PingServerList& pingers = GetPingServerList();
|
|
|
|
for (unsigned int index = 0; index < pingers.size(); index++)
|
|
{
|
|
const char* pinger = pingers[index]->GetHostAddress();
|
|
|
|
if (stricmp(name, pinger) == 0)
|
|
{
|
|
if (time < 0)
|
|
{
|
|
time = INT_MAX;
|
|
}
|
|
|
|
pingers[index]->SetPingTime(time);
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
/******************************************************************************
|
|
*
|
|
* NAME
|
|
* Session::RequestUserIP
|
|
*
|
|
* DESCRIPTION
|
|
* Ask the chat server for a users IP address
|
|
*
|
|
* INPUTS
|
|
* Name of user
|
|
*
|
|
* RESULT
|
|
* NONE
|
|
*
|
|
******************************************************************************/
|
|
|
|
bool Session::RequestUserIP(char *user_name)
|
|
{
|
|
if (user_name)
|
|
{
|
|
WOL::User wolUser;
|
|
memset(&wolUser, 0, sizeof(WOL::User));
|
|
strncpy((char*)wolUser.name, user_name, sizeof(wolUser.name));
|
|
wolUser.name[sizeof(wolUser.name) - 1] = 0;
|
|
|
|
return SUCCEEDED(mChat->RequestUserIP(&wolUser));
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
|
|
/******************************************************************************
|
|
*
|
|
* NAME
|
|
* Session::RequestInsiderStatus
|
|
*
|
|
* DESCRIPTION
|
|
* Used to ask the chat server for if the currently logged in user is
|
|
* an insider or not.
|
|
*
|
|
* INPUTS
|
|
* NONE
|
|
*
|
|
* RESULT
|
|
* NONE
|
|
*
|
|
******************************************************************************/
|
|
|
|
void Session::RequestInsiderStatus(void)
|
|
{
|
|
if (mChat != NULL && mCurrentUser.IsValid ())
|
|
{
|
|
WOL::User &user = mCurrentUser->GetData();
|
|
mChat->RequestInsiderStatus(&user);
|
|
}
|
|
}
|
|
|
|
|
|
/******************************************************************************
|
|
*
|
|
* NAME
|
|
* Session::RequestServerTime
|
|
*
|
|
* DESCRIPTION
|
|
* Used to ask the chat server for its current time.
|
|
*
|
|
* INPUTS
|
|
* NONE
|
|
*
|
|
* RESULT
|
|
* NONE
|
|
*
|
|
******************************************************************************/
|
|
|
|
void Session::RequestServerTime(void)
|
|
{
|
|
if (mChat != NULL)
|
|
{
|
|
mChat->RequestServerTime();
|
|
}
|
|
}
|
|
|
|
|
|
/******************************************************************************
|
|
*
|
|
* NAME
|
|
* Session::GetIGRObject
|
|
*
|
|
* DESCRIPTION
|
|
*
|
|
* INPUTS
|
|
* NONE
|
|
*
|
|
* RESULT
|
|
*
|
|
******************************************************************************/
|
|
|
|
const CComPtr<WOL::IIGROptions>& Session::GetIGRObject(void)
|
|
{
|
|
if (mIGRObject == NULL)
|
|
{
|
|
WWDEBUG_SAY(("WOL: Creating IID_IIGROptions object\n"));
|
|
WOL::IIGROptions* igrObject = NULL;
|
|
|
|
HRESULT hr = CoCreateInstance(WOL::CLSID_IGROptions, NULL, CLSCTX_INPROC_SERVER,
|
|
WOL::IID_IIGROptions, (void**)&igrObject);
|
|
|
|
if (SUCCEEDED(hr))
|
|
{
|
|
HRESULT hr = igrObject->Init();
|
|
|
|
if (S_FALSE == hr)
|
|
{
|
|
WWDEBUG_SAY(("WOLWARNING: IGR settings not found\n"));
|
|
}
|
|
}
|
|
else
|
|
{
|
|
WWDEBUG_SAY(("WOLERROR: Failed to create IID_IIGROptions\n"));
|
|
}
|
|
|
|
mIGRObject = igrObject;
|
|
}
|
|
|
|
return mIGRObject;
|
|
}
|
|
|
|
|
|
/******************************************************************************
|
|
*
|
|
* NAME
|
|
* Session::IsStoreLoginAllowed
|
|
*
|
|
* DESCRIPTION
|
|
* Check if it is okay to save users login information.
|
|
*
|
|
* INPUTS
|
|
* NONE
|
|
*
|
|
* RESULT
|
|
* True if allowed to save login information.
|
|
*
|
|
******************************************************************************/
|
|
|
|
bool Session::IsStoreLoginAllowed(void)
|
|
{
|
|
const CComPtr<WOL::IIGROptions>& igr = GetIGRObject();
|
|
|
|
if (igr)
|
|
{
|
|
HRESULT hr = igr->Is_Storing_Nicks_Allowed();
|
|
return (hr == S_OK);
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
|
|
/******************************************************************************
|
|
*
|
|
* NAME
|
|
* Session::IsAutoLoginAllowed
|
|
*
|
|
* DESCRIPTION
|
|
* Check if it is okay to automatically login users.
|
|
*
|
|
* INPUTS
|
|
* NONE
|
|
*
|
|
* RESULT
|
|
* True if allowed to auto login.
|
|
*
|
|
******************************************************************************/
|
|
|
|
bool Session::IsAutoLoginAllowed(void)
|
|
{
|
|
const CComPtr<WOL::IIGROptions>& igr = GetIGRObject();
|
|
|
|
if (igr)
|
|
{
|
|
HRESULT hr = igr->Is_Auto_Login_Allowed();
|
|
return (hr == S_OK);
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
|
|
/******************************************************************************
|
|
*
|
|
* NAME
|
|
* Session::IsRunRegAppAllowed
|
|
*
|
|
* DESCRIPTION
|
|
*
|
|
* INPUTS
|
|
* NONE
|
|
*
|
|
* RESULT
|
|
* True if allowed to run registration applet.
|
|
*
|
|
******************************************************************************/
|
|
|
|
bool Session::IsRunRegAppAllowed(void)
|
|
{
|
|
const CComPtr<WOL::IIGROptions>& igr = GetIGRObject();
|
|
|
|
if (igr)
|
|
{
|
|
HRESULT hr = igr->Is_Running_Reg_App_Allowed();
|
|
return (hr == S_OK);
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
|
|
/******************************************************************************
|
|
*
|
|
* NAME
|
|
* ChatAdvisement::Create
|
|
*
|
|
* DESCRIPTION
|
|
* Create a IChatEvents advisement
|
|
*
|
|
* INPUTS
|
|
* Chat - IChat object
|
|
* Sink - IChatEvents sink to advise.
|
|
*
|
|
* RESULT
|
|
* Advisement - Instance of advisement
|
|
*
|
|
******************************************************************************/
|
|
|
|
RefPtr<ChatAdvisement> ChatAdvisement::Create(const CComPtr<WOL::IChat>& chat,
|
|
const CComPtr<WOL::IChatEvent>& sink)
|
|
{
|
|
return new ChatAdvisement(chat, sink);
|
|
}
|
|
|
|
|
|
/******************************************************************************
|
|
*
|
|
* NAME
|
|
* ChatAdvisement::ChatAdvisement
|
|
*
|
|
* DESCRIPTION
|
|
* Constructor
|
|
*
|
|
* INPUTS
|
|
* Chat - IChat object
|
|
* Sink - IChatEvents sink to advise.
|
|
*
|
|
* RESULT
|
|
* NONE
|
|
*
|
|
******************************************************************************/
|
|
|
|
ChatAdvisement::ChatAdvisement(const CComPtr<WOL::IChat>& chat, const CComPtr<WOL::IChatEvent>& sink) :
|
|
mChat(chat),
|
|
mChatCookie(0)
|
|
{
|
|
if (mChat && sink)
|
|
{
|
|
AtlAdvise(mChat, sink, WOL::IID_IChatEvent, &mChatCookie);
|
|
}
|
|
}
|
|
|
|
|
|
/******************************************************************************
|
|
*
|
|
* NAME
|
|
* ChatAdvisement::~ChatAdvisement
|
|
*
|
|
* DESCRIPTION
|
|
* Destructor
|
|
*
|
|
* INPUTS
|
|
* NONE
|
|
*
|
|
* RESULT
|
|
* NONE
|
|
*
|
|
******************************************************************************/
|
|
|
|
ChatAdvisement::~ChatAdvisement()
|
|
{
|
|
if (mChat)
|
|
{
|
|
AtlUnadvise(mChat, WOL::IID_IChatEvent, mChatCookie);
|
|
}
|
|
}
|
|
|
|
} // namespace WWOnline
|