This repository has been archived on 2025-02-27. You can view files and clone it, but cannot push or open issues or pull requests.
CnC_Renegade/Code/Commando/WOLBuddyMgr.cpp

1496 lines
No EOL
32 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/>.
*/
/******************************************************************************
*
* FILE
* $Archive: /Commando/Code/Commando/WOLBuddyMgr.cpp $
*
* DESCRIPTION
*
* PROGRAMMER
* Denzil E. Long, Jr.
* $Author: Steve_t $
*
* VERSION INFO
* $Revision: 40 $
* $Modtime: 8/28/02 12:59p $
*
******************************************************************************/
#include "WOLBuddyMgr.h"
#include "_globals.h"
#include "GameInitMgr.h"
#include "MPSettingsMgr.h"
#include "DlgMPWolInvitation.h"
#include "DlgMPWolPageReply.h"
#include "DlgMessageBox.h"
#include "DlgPasswordPrompt.h"
#include "DlgMPWolChat.h"
#include "WOLChatMgr.h"
#include "WOLJoinGame.h"
#include "WOLGameInfo.h"
#include "consolemode.h"
#include <WWOnline\WOLChannel.h>
#include <WWOnline\WOLProduct.h>
#include <WWLib\Registry.h>
#include "String_IDs.h"
#include <WWTranslateDB\TranslateDB.h>
#include <WWDebug\WWDebug.h>
using namespace WWOnline;
static const int MAX_USERNAME_LEN = 64;
static const WCHAR INVITE_CMD[] = L"<WWINVITE>";
static const WCHAR DECLINE_CMD[] = L"<WWDECLINE>";
static const unsigned long INVITE_CMD_LEN = ((sizeof(INVITE_CMD) / sizeof(WCHAR)) - 1);
static const unsigned long DECLINE_CMD_LEN = ((sizeof(DECLINE_CMD) / sizeof(WCHAR)) - 1);
WOLBuddyMgr* WOLBuddyMgr::_mInstance = NULL;
/******************************************************************************
*
* NAME
* WOLBuddyMgr::GetInstance
*
* DESCRIPTION
* Obtain Buddy manager instance
*
* INPUTS
* Create - Okay to create buddy manager if not already instantiated.
*
* RESULT
* Instance -
*
******************************************************************************/
WOLBuddyMgr* WOLBuddyMgr::GetInstance(bool createOK)
{
if (_mInstance == NULL)
{
new WOLBuddyMgr;
if (_mInstance)
{
if (_mInstance->FinalizeCreate() == false)
{
_mInstance->Release_Ref();
}
}
}
else
{
_mInstance->Add_Ref();
}
return _mInstance;
}
/******************************************************************************
*
* NAME
* WOLBuddyMgr::WOLBuddyMgr
*
* DESCRIPTION
* Constructor
*
* INPUTS
* NONE
*
* RESULT
* NONE
*
******************************************************************************/
WOLBuddyMgr::WOLBuddyMgr() :
mHidePagedDialog(0)
{
WWDEBUG_SAY(("WOLBuddyMgr: Instantiated\n"));
_mInstance = this;
}
/******************************************************************************
*
* NAME
* WOLBuddyMgr::~WOLBuddyMgr
*
* DESCRIPTION
* Destructor
*
* INPUTS
* NONE
*
* RESULT
* NONE
*
******************************************************************************/
WOLBuddyMgr::~WOLBuddyMgr()
{
WWDEBUG_SAY(("WOLBuddyMgr: Destroyed\n"));
_mInstance = NULL;
}
/******************************************************************************
*
* NAME
* WOLBuddyMgr::FinalizeCreate
*
* DESCRIPTION
* Perform post creation initialization.
*
* INPUTS
* NONE
*
* RESULT
* True if successful
*
******************************************************************************/
bool WOLBuddyMgr::FinalizeCreate(void)
{
mWOLSession = Session::GetInstance(false);
if (!mWOLSession.IsValid())
{
return false;
}
Observer<BuddyEvent>::NotifyMe(*mWOLSession);
Observer<UserEvent>::NotifyMe(*mWOLSession);
Observer<PageMessage>::NotifyMe(*mWOLSession);
Observer<PageSendStatus>::NotifyMe(*mWOLSession);
LoadIgnoreList();
return true;
}
/******************************************************************************
*
* NAME
* WOLBuddyMgr::LoadIgnoreList
*
* DESCRIPTION
* Load the list of users to ignore.
*
* INPUTS
* NONE
*
* RESULT
* NONE
*
******************************************************************************/
void WOLBuddyMgr::LoadIgnoreList(void)
{
mIgnoreList.clear();
HKEY hKey;
LONG result = RegOpenKeyEx(HKEY_LOCAL_MACHINE, APPLICATION_SUB_KEY_NAME_IGNORE_LIST, 0, KEY_READ, &hKey);
if (ERROR_SUCCESS == result)
{
// Build a list of users to ignore
char valueName[128];
unsigned long valueSize = sizeof(valueName);
int index = 0;
while (RegEnumValue(hKey, index, valueName, &valueSize, 0, NULL, NULL, NULL) == ERROR_SUCCESS)
{
DWORD type = 0;
char name[MAX_USERNAME_LEN];
DWORD nameSize = sizeof(name);
result = RegQueryValueEx(hKey, valueName, NULL, &type, (LPBYTE)name, (DWORD*)&nameSize);
if ((ERROR_SUCCESS == result) && (REG_SZ == type) && strlen(name))
{
// Add the name to the ignore list
WideStringClass wideName(name);
mIgnoreList.push_back(wideName);
}
index++;
valueSize = sizeof(valueName);
}
RegCloseKey(hKey);
}
Add_Ref();
WOLBuddyMgrEvent event(IGNORELIST_CHANGED, this);
NotifyObservers(event);
Release_Ref();
}
/******************************************************************************
*
* NAME
* WOLBuddyMgr::SaveIgnoreList
*
* DESCRIPTION
* Save the list of users to ignore.
*
* INPUTS
* NONE
*
* RESULT
* NONE
*
******************************************************************************/
void WOLBuddyMgr::SaveIgnoreList(void)
{
if (mWOLSession->IsStoreLoginAllowed())
{
RegistryClass reg(APPLICATION_SUB_KEY_NAME_IGNORE_LIST);
if (reg.Is_Valid())
{
reg.Deleta_All_Values();
for (unsigned int index = 0; index < mIgnoreList.size(); ++index)
{
char valueName[64];
sprintf(valueName, "Ignore%d", (index + 1));
const WideStringClass& buddy = mIgnoreList[index];
char name[MAX_USERNAME_LEN];
wcstombs(name, buddy, sizeof(name));
reg.Set_String(valueName, (char*)name);
}
}
}
}
/******************************************************************************
*
* NAME
* WOLBuddyMgr::RefreshBuddyList
*
* DESCRIPTION
* Request the buddy list for the current login.
*
* INPUTS
* NONE
*
* RESULT
* NONE
*
******************************************************************************/
void WOLBuddyMgr::RefreshBuddyList(void)
{
mWOLSession->RequestBuddyList();
}
/******************************************************************************
*
* NAME
* WOLBuddyMgr::FindBuddy
*
* DESCRIPTION
* Find a user in our buddy list.
*
* INPUTS
* Name - Nickname of buddy to find.
*
* RESULT
* NONE
*
******************************************************************************/
const RefPtr<WWOnline::UserData> WOLBuddyMgr::FindBuddy(const WCHAR* name) const
{
return mWOLSession->FindBuddy(name);
}
/******************************************************************************
*
* NAME
* WOLBuddyMgr::AddBuddy
*
* DESCRIPTION
* Add a user to our buddy list.
*
* INPUTS
* Name - Nickname of user to add.
*
* RESULT
* NONE
*
******************************************************************************/
void WOLBuddyMgr::AddBuddy(const WCHAR* name)
{
if (IsBuddy(name) == false)
{
mWOLSession->AddBuddy(name);
}
}
/******************************************************************************
*
* NAME
* WOLBuddyMgr::RemoveBuddy
*
* DESCRIPTION
* Remove a user from our buddy list.
*
* INPUTS
* Name - Nickname of user to remove.
*
* RESULT
* NONE
*
******************************************************************************/
void WOLBuddyMgr::RemoveBuddy(const WCHAR* name)
{
mWOLSession->RemoveBuddy(name);
}
/******************************************************************************
*
* NAME
* WOLBuddyMgr::IsBuddy
*
* DESCRIPTION
* Check if a user is our buddy.
*
* INPUTS
* Name - Nickname of user to check.
*
* RESULT
* True if user is in our buddy list.
*
******************************************************************************/
bool WOLBuddyMgr::IsBuddy(const WCHAR* name) const
{
RefPtr<UserData> user = mWOLSession->FindBuddy(name);
return user.IsValid();
}
/******************************************************************************
*
* NAME
* WOLBuddyMgr::RefreshBuddyInfo
*
* DESCRIPTION
* Update the locations / status of our buddies.
*
* INPUTS
* NONE
*
* RESULT
* NONE
*
******************************************************************************/
void WOLBuddyMgr::RefreshBuddyInfo(void)
{
const UserList& buddies = mWOLSession->GetBuddyList();
const unsigned int count = buddies.size();
for (unsigned int index = 0; index < count; ++index)
{
const RefPtr<UserData>& buddy = buddies[index];
mWOLSession->RequestLocateUser(buddy);
if (!buddy->GetTeamLadder().IsValid())
{
mWOLSession->RequestLadderInfo(buddy->GetName(), LadderType_Team);
}
RefPtr<SquadData> squad = buddy->GetSquad();
if (squad.IsValid())
{
WideStringClass abbr(0, true);
abbr = squad->GetAbbr();
mWOLSession->RequestLadderInfo((const WCHAR*)abbr, LadderType_Clan);
}
}
}
/******************************************************************************
*
* NAME
* WOLBuddyMgr::GetBuddyLocationDescription
*
* DESCRIPTION
* Get a text description of where our buddy is located.
*
* INPUTS
* User - User to get description for.
* Description - String to receice description text.
*
* RESULT
* NONE
*
******************************************************************************/
void WOLBuddyMgr::GetLocationDescription(const RefPtr<UserData>& user, WideStringClass& description)
{
description = TRANSLATE(IDS_MP_WOL_BUDDY_UNKNOWN);
if (user.IsValid())
{
// Where is this user?
switch (user->GetLocation())
{
default:
case USERLOCATION_UNKNOWN:
description = TRANSLATE(IDS_MP_WOL_BUDDY_UNKNOWN);
break;
case USERLOCATION_OFFLINE:
description = TRANSLATE(IDS_MP_WOL_BUDDY_OFFLINE);
break;
case USERLOCATION_HIDING:
description = TRANSLATE(IDS_MP_WOL_BUDDY_HIDING);
break;
case USERLOCATION_NO_CHANNEL:
description = TRANSLATE(IDS_MP_WOL_BUDDY_NO_CHANNEL);
break;
case USERLOCATION_IN_CHANNEL:
{
const RefPtr<ChannelData>& channel = user->GetChannel();
if (channel.IsValid())
{
WideStringClass format(0, true);
WideStringClass channelName(0, true);
// Check to see what type of channel this is, chat or game.
if (channel->GetType() == 0)
{
format = TRANSLATE(IDS_MP_WOL_BUDDY_CHAT_ROOM);
WOLChatMgr* chatMgr = WOLChatMgr::GetInstance(false);
if (chatMgr)
{
chatMgr->GetLobbyDisplayName(channel, channelName);
chatMgr->Release_Ref();
}
}
else
{
format = TRANSLATE(IDS_MP_WOL_BUDDY_GAME);
channelName = channel->GetName();
}
description.Format(format, channelName);
}
}
break;
}
}
}
/******************************************************************************
*
* NAME
* WOLBuddyMgr::AddIgnore
*
* DESCRIPTION
* Add a user to our ignore list.
*
* INPUTS
* Name - Nickname of user to ignore.
*
* RESULT
* NONE
*
******************************************************************************/
void WOLBuddyMgr::AddIgnore(const WCHAR* name)
{
if (!IsIgnored(name))
{
WideStringClass ignore(0, true);
ignore = name;
ignore.Trim();
if (ignore.Get_Length() > 0)
{
WWDEBUG_SAY(("WOLBuddyMgr: Adding '%S' to ignore list.", name));
mIgnoreList.push_back(ignore);
SaveIgnoreList();
Add_Ref();
WOLBuddyMgrEvent event(IGNORELIST_CHANGED, this);
NotifyObservers(event);
Release_Ref();
}
}
}
/******************************************************************************
*
* NAME
* WOLBuddyMgr::RemoveIgnore
*
* DESCRIPTION
* Remove a user from our ignore list.
*
* INPUTS
* Name - Nickname of user to remove.
*
* RESULT
* NONE
*
******************************************************************************/
void WOLBuddyMgr::RemoveIgnore(const WCHAR* name)
{
IgnoreList::iterator iter = mIgnoreList.begin();
while (iter != mIgnoreList.end())
{
const WideStringClass& ignore = (*iter);
if (ignore.Compare_No_Case(name) == 0)
{
WWDEBUG_SAY(("WOLBuddyMgr: Removing '%S' from ignore list.", (const WCHAR*)ignore));
mIgnoreList.erase(iter);
SaveIgnoreList();
Add_Ref();
WOLBuddyMgrEvent event(IGNORELIST_CHANGED, this);
NotifyObservers(event);
Release_Ref();
break;
}
iter++;
}
}
/******************************************************************************
*
* NAME
* WOLBuddyMgr::IsIgnored
*
* DESCRIPTION
* Check if a user is being ignored.
*
* INPUTS
* Name - Nickname of user to check.
*
* RESULT
* True if user is being ignored.
*
******************************************************************************/
bool WOLBuddyMgr::IsIgnored(const WCHAR* name) const
{
for (unsigned int index = 0; index < mIgnoreList.size(); index++)
{
const WideStringClass& ignore = mIgnoreList[index];
if (ignore.Compare_No_Case(name) == 0)
{
return true;
}
}
return false;
}
/******************************************************************************
*
* NAME
* WOLBuddyMgr::PageUser
*
* DESCRIPTION
* Page a user.
*
* INPUTS
* Name - Nickname of user to page.
* Message - Message to send.
*
* RESULT
* NONE
*
******************************************************************************/
void WOLBuddyMgr::PageUser(const WCHAR* name, const WCHAR* message)
{
mWOLSession->PageUser(name, message);
}
/******************************************************************************
*
* NAME
* WOLBuddyMgr::ShowPagedDialog
*
* DESCRIPTION
*
* INPUTS
* NONE
*
* RESULT
* NONE
*
******************************************************************************/
void WOLBuddyMgr::ShowPagedDialog(void)
{
WWASSERT(mHidePagedDialog > 0 && "ShowPagedDialog() mismatch");
if (mHidePagedDialog > 0)
{
--mHidePagedDialog;
}
}
/******************************************************************************
*
* NAME
* WOLBuddyMgr::HidePagedDialog
*
* DESCRIPTION
*
* INPUTS
* NONE
*
* RESULT
* NONE
*
******************************************************************************/
void WOLBuddyMgr::HidePagedDialog(void)
{
++mHidePagedDialog;
}
/******************************************************************************
*
* NAME
* WOLBuddyMgr::ClearPageList
*
* DESCRIPTION
* Clear user pages.
*
* INPUTS
* NONE
*
* RESULT
* NONE
*
******************************************************************************/
void WOLBuddyMgr::ClearPageList(void)
{
mPageList.clear();
}
/******************************************************************************
*
* NAME
* WOLBuddyMgr::JoinUser
*
* DESCRIPTION
* Join the user in a chat or game channel.
*
* INPUTS
* Name - Nickname of user to join.
*
* RESULT
* NONE
*
******************************************************************************/
void WOLBuddyMgr::JoinUser(const RefPtr<UserData>& user)
{
// Release any current join request.
mPendingJoin.Release();
if (user.IsValid())
{
// Before we can join a user we must first find out their location.
// See UserEvent::Located in HandleNotification(UserEvent)
mPendingJoin = user;
mWOLSession->RequestLocateUser(user);
}
}
/******************************************************************************
*
* NAME
* WOLBuddyMgr::ProcessPendingJoin
*
* DESCRIPTION
* Process the pending join request. Once we have the location of the user
* we want to join we can then attempt to goto that location. If the user
* is not in a channel then the join request is aborted.
*
* INPUTS
* NONE
*
* RESULT
* NONE
*
******************************************************************************/
void WOLBuddyMgr::ProcessPendingJoin(void)
{
if (mPendingJoin.IsValid())
{
// Is the user in a place where we can join them?
if (mPendingJoin->GetLocation() == USERLOCATION_IN_CHANNEL)
{
const RefPtr<ChannelData>& channel = mPendingJoin->GetChannel();
if (channel.IsValid())
{
// If the channel to join is passworded then prompt the user to enter
// a password. The join will continue after the user enters a password.
// NOTE: See ReceiveSignal()
if ((channel->GetType() != 0) && channel->IsPassworded())
{
DlgPasswordPrompt::DoDialog(this);
}
else
{
// Go ahead and attempt to join the pending location.
GotoPendingJoinLocation(NULL);
}
return;
}
}
// If we got here then we cannot join the pending location. Abort the request
// and notify the user.
mPendingJoin.Release();
DlgMsgBox::DoDialog(IDS_WOL_ERROR, IDS_BUDDY_CANNOTJOIN, DlgMsgBox::Okay, NULL);
}
}
/******************************************************************************
*
* NAME
* WOLBuddyMgr::GotoPendingLocation
*
* DESCRIPTION
* Goto the pending chat lobby or game.
*
* INPUTS
* Password - Password to use to join chat lobby or game. Can be NULL if
* a password is not required.
*
* RESULT
* NONE
*
******************************************************************************/
void WOLBuddyMgr::GotoPendingJoinLocation(const wchar_t* password)
{
const RefPtr<ChannelData>& channel = mPendingJoin->GetChannel();
WWASSERT(channel.IsValid() && "Pending join channel invalid");
if (GameInitMgrClass::Is_Game_In_Progress())
{
GameInitMgrClass::End_Game();
}
// Determine if we should jump to a chat channel or game channel
if (channel->GetType() == 0)
{
MPWolChatMenuClass::DoDialog(channel);
}
else if (channel->GetType() == Product::Current()->GetGameCode())
{
GameInitMgrClass::Set_WOL_Return_Dialog(RenegadeDialogMgrClass::LOC_INTERNET_GAME_LIST);
WOLJoinGame::JoinTheGame(channel->GetName(), password, true);
}
mPendingJoin.Release();
}
/******************************************************************************
*
* NAME
* WOLBuddyMgr::ReceiveSignal(DlgPasswordPrompt)
*
* DESCRIPTION
* Handle receipt of signal that the user has entered a password to join
* the pending join channel.
*
* INPUTS
* PasswordDialog - Reference to password prompt dialog.
*
* RESULT
* NONE
*
******************************************************************************/
void WOLBuddyMgr::ReceiveSignal(DlgPasswordPrompt& passwordDialog)
{
GotoPendingJoinLocation(passwordDialog.GetPassword());
}
/******************************************************************************
*
* NAME
* WOLBuddyMgr::CanInviteUsers
*
* DESCRIPTION
* Check if we are in a position to invite users.
*
* INPUTS
* NONE
*
* RESULT
* NONE
*
******************************************************************************/
bool WOLBuddyMgr::CanInviteUsers(void) const
{
return (ChannelJoined == mWOLSession->GetChannelStatus());
}
/******************************************************************************
*
* NAME
* WOLBuddyMgr::InviteUser
*
* DESCRIPTION
* Invite a user to join our location (Chat or Game)
*
* INPUTS
* Name - Nickname of user to invite.
*
* RESULT
* NONE
*
******************************************************************************/
void WOLBuddyMgr::InviteUser(const WCHAR* username, const WCHAR* message)
{
WideStringClass name(0, true);
name = username;
name.Trim();
if (name.Get_Length() > 0)
{
if (message && (wcslen(message) > 0))
{
WideStringClass invitation(0, true);
invitation.Format(L"%s%s", INVITE_CMD, message);
PageUser(name, invitation);
}
else
{
PageUser(name, INVITE_CMD);
}
}
}
/******************************************************************************
*
* NAME
* WOLBuddyMgr::DeclineInvitation
*
* DESCRIPTION
* Decline an invitation to join a user.
*
* INPUTS
* Name - Nickname of user to decline.
*
* RESULT
* NONE
*
******************************************************************************/
void WOLBuddyMgr::DeclineInvitation(const WCHAR* username, DECLINE_REASON reason)
{
if (username && (wcslen(username) > 0))
{
// Build a decline "page"
WideStringClass response(0, true);
response.Format(L"%s%d", DECLINE_CMD, reason);
// Send the response
PageUser(username, response);
}
}
/******************************************************************************
*
* NAME
* WOLBuddyMgr::IsCommand
*
* DESCRIPTION
* Check if a message is a command.
*
* INPUTS
* Message - Message to check.
*
* RESULT
* True if message is a command
*
******************************************************************************/
bool WOLBuddyMgr::IsCommand(const WCHAR* message)
{
// All commands begin with "<WW"
return (message && (wcsstr(message, L"<WW") == message));
}
/******************************************************************************
*
* NAME
* WOLBuddyMgr::IsInvitation
*
* DESCRIPTION
* Check if a message is an invitation.
*
* INPUTS
* Message - Message to check.
*
* RESULT
* True if message is an invitation.
*
******************************************************************************/
bool WOLBuddyMgr::IsInvitation(const WCHAR* message)
{
return (message && (wcslen(message) >= INVITE_CMD_LEN) &&
(wcsncmp(message, INVITE_CMD, INVITE_CMD_LEN) == 0));
}
/******************************************************************************
*
* NAME
* WOLBuddyMgr::InvitationReceived
*
* DESCRIPTION
* Handle invitation page from another user.
*
* INPUTS
* Page - Invitation page.
*
* RESULT
* NONE
*
******************************************************************************/
void WOLBuddyMgr::InvitationReceived(PageMessage& page)
{
const WideStringClass& pagerName = page.GetPagersName();
// Check if we already have an invitation request from this user.
// If so then ignore any subsequent invitations from him.
PageMessageList::iterator iter = mInvitations.begin();
while (iter != mInvitations.end())
{
// If this is in response to a another users invitation to join
// then display the invitation since we now know were they are.
if (pagerName.Compare_No_Case((*iter).GetPagersName()) == 0)
{
return;
}
iter++;
}
// Before we can display the invitation we must first find out where the
// invitor is located. Once we have his location we can prompt the user.
// See UserEvent::Located handling in HandleNotification(UserEvent)
mInvitations.push_back(page);
mWOLSession->RequestLocateUser(pagerName);
}
/******************************************************************************
*
* NAME
* WOLBuddyMgr::DisplayInvitation
*
* DESCRIPTION
* Display an invitation from another user.
*
* INPUTS
* User - User inviting us.
*
* RESULT
* NONE
*
******************************************************************************/
void WOLBuddyMgr::DisplayInvitation(const RefPtr<UserData>& user, const WCHAR* message)
{
if (user->GetLocation() != USERLOCATION_IN_CHANNEL)
{
// Decline the invitation because the user is not in a channel.
DeclineInvitation(user->GetName(), DECLINE_NOTAPPLICABLE);
}
else
{
//-------------------------------------------------------------------------
// Compose the invitation message
//-------------------------------------------------------------------------
// Get the user's name
const WideStringClass& name = user->GetName();
// Build a textual description of the user's location
WideStringClass location(0, true);
GetLocationDescription(user, location);
// Format the invitation message
WideStringClass inviteMsg(0, true);
inviteMsg.Format(TRANSLATE(IDS_MP_WOL_INVITATION_FORMAT), (const WCHAR*)name, (const WCHAR*)location);
inviteMsg += L"\n";
inviteMsg += message;
if (!mHidePagedDialog)
{
// Display the invitation dialog
MPWolInvitationPopupClass* dialog = new MPWolInvitationPopupClass(user, inviteMsg);
WWASSERT(dialog && "Failed to create invitation dialog");
if (dialog)
{
dialog->Start_Dialog();
dialog->Release_Ref();
}
}
Add_Ref();
PageMessage invite(user->GetName(), inviteMsg);
WOLPagedEvent event(INVITATION_RECEIVED, &invite);
NotifyObservers(event);
Release_Ref();
}
}
/******************************************************************************
*
* NAME
* WOLBuddyMgr::IsInvitationDeclined
*
* DESCRIPTION
* Check if the invitation was declined.
*
* INPUTS
* Message - Message to check.
*
* RESULT
* True if nvitation was declined.
*
******************************************************************************/
bool WOLBuddyMgr::IsInvitationDeclined(const WCHAR *message)
{
return (message && (wcslen(message) >= DECLINE_CMD_LEN) &&
(wcsncmp(message, DECLINE_CMD, DECLINE_CMD_LEN) == 0));
}
/******************************************************************************
*
* NAME
* WOLBuddyMgr::InvitationDeclined
*
* DESCRIPTION
* Handle declined invitation.
*
* INPUTS
* Name - Nickname of user.
* Reason - Reason for declining.
*
* RESULT
* NONE
*
******************************************************************************/
void WOLBuddyMgr::InvitationDeclined(const WCHAR* username, DECLINE_REASON reason)
{
WideStringClass message(0, true);
// Build an appropriate message based on the reason
switch (reason)
{
default:
case DECLINE_BYUSER:
message = TRANSLATE(IDS_INVITE_DECLINE_BYUSER);
break;
case DECLINE_NOTBUDDY:
message.Format(TRANSLATE(IDS_INVITE_DECLINE_NOTBUDDY), username);
break;
case DECLINE_NOTAPPLICABLE:
message = TRANSLATE(IDS_INVITE_DECLINE_NOTAPPLICABLE);
break;
case DECLINE_BUSY:
message.Format(TRANSLATE(IDS_INVITE_DECLINE_BUSY), username);
break;
}
if (!mHidePagedDialog)
{
// Let the user know they've been declined
DlgMsgBox::DoDialog(NULL, message, DlgMsgBox::Okay, NULL);
}
Add_Ref();
PageMessage decline(username, message);
WOLPagedEvent event(INVITATION_DECLINED, &decline);
NotifyObservers(event);
Release_Ref();
}
/******************************************************************************
*
* NAME
* WOLBuddyMgr::HandleNotification(BuddyEvent)
*
* DESCRIPTION
* Handle buddy event notifications. (List, Add, Remove)
*
* INPUTS
* Event
*
* RESULT
* NONE
*
******************************************************************************/
void WOLBuddyMgr::HandleNotification(BuddyEvent& event)
{
bool listChanged = false;
if ((event.GetEvent() == BuddyEvent::NewList) || (event.GetEvent() == BuddyEvent::Added))
{
const UserList& buddies = event.Subject();
unsigned int count = buddies.size();
for (unsigned int index = 0; index < count; ++index)
{
const RefPtr<UserData>& buddy = buddies[index];
// Request details about the buddy
if (buddy.IsValid())
{
mWOLSession->RequestLocateUser(buddy);
// Request squad affliation for this user.
if (!buddy->GetSquad().IsValid())
{
mWOLSession->RequestSquadInfoByMemberName(buddy->GetName());
}
// Request ranking information for this user.
if (!buddy->GetTeamLadder().IsValid())
{
mWOLSession->RequestLadderInfo(buddy->GetName(), LadderType_Team);
}
}
}
listChanged = true;
}
else if (event.GetEvent() == BuddyEvent::Deleted)
{
listChanged = true;
}
if (listChanged)
{
Add_Ref();
WOLBuddyMgrEvent event(BUDDYLIST_CHANGED, this);
NotifyObservers(event);
Release_Ref();
}
}
/******************************************************************************
*
* NAME
* WOLBuddyMgr::HandleNotification(UserEvent)
*
* DESCRIPTION
*
* INPUTS
*
* RESULT
* NONE
*
******************************************************************************/
void WOLBuddyMgr::HandleNotification(UserEvent& event)
{
switch (event.GetEvent())
{
// Users location status obtained.
case UserEvent::Located:
{
const RefPtr<UserData>& user = event.Subject();
const WideStringClass& username = user->GetName();
// Try to find an invitation from this user.
bool foundInvitation = false;
PageMessageList::iterator iter = mInvitations.begin();
while (iter != mInvitations.end())
{
// If this is in response to a another users invitation to join them
// then display the invitation since we now know were they are.
if (username.Compare_No_Case((*iter).GetPagersName()) == 0)
{
const WCHAR* invite = (*iter).GetPageMessage();
DisplayInvitation(user, &invite[INVITE_CMD_LEN]);
mInvitations.erase(iter);
foundInvitation = true;
break;
}
iter++;
}
// Check if we requested to join a user.
if ((foundInvitation == false) && mPendingJoin.IsValid())
{
// If this is the user we requested to join then goto their
// location.
if (username.Compare_No_Case(mPendingJoin->GetName()) == 0)
{
ProcessPendingJoin();
return;
}
}
// Report buddy locations
if (IsBuddy(username))
{
Add_Ref();
WOLBuddyMgrEvent event(BUDDYINFO_CHANGED, this);
NotifyObservers(event);
Release_Ref();
}
}
break;
case UserEvent::SquadInfo:
case UserEvent::LadderInfo:
if (IsBuddy(event.Subject()->GetName()))
{
Add_Ref();
WOLBuddyMgrEvent event(BUDDYINFO_CHANGED, this);
NotifyObservers(event);
Release_Ref();
}
break;
default:
break;
}
}
/******************************************************************************
*
* NAME
* WOLBuddyMgr::HandleNotification(PageMessage)
*
* DESCRIPTION
* Handle pages from other users.
*
* INPUTS
* Page - Page message to process.
*
* RESULT
* NONE
*
******************************************************************************/
void WOLBuddyMgr::HandleNotification(PageMessage& page)
{
// Only accept pages from users we are not ignoring.
if (IsIgnored(page.GetPagersName()) == false)
{
const WideStringClass& pager = page.GetPagersName();
const WideStringClass& message = page.GetPageMessage();
mLastPagersName = pager;
if (ConsoleBox.Is_Exclusive()) {
if (((WideStringClass*)&message)->Is_ANSI()) {
WideStringClass temp(L"[Page] ", true);
temp += pager;
temp += L": ";
temp += message;
temp += L"\n";
Vector3 text_color(0.0f, 1.0f, 0.0f);
ConsoleBox.Add_Message(&temp, &text_color, true);
}
} else {
// If this page is not a command then show it to the user.
if (!IsCommand(message))
{
bool allowPages = MPSettingsMgrClass::Get_Option_Flag(MPSettingsMgrClass::OPTION_ALLOW_PAGES);
if (allowPages)
{
// Popup a page reply dialog for the player to respond to.
if (!mHidePagedDialog)
{
DlgWOLPageReply::DoDialog();
}
// Notify that there are new page.
Add_Ref();
WOLPagedEvent event(PAGE_RECEIVED, &page);
NotifyObservers(event);
Release_Ref();
}
}
else if (IsInvitation(message))
{
// A user has sent us an invitation
InvitationReceived(page);
}
else if (IsInvitationDeclined(message))
{
// A user declined our invitation.
DECLINE_REASON reason = DECLINE_BYUSER;
// Grab the reason code
const WCHAR* codeString = message + DECLINE_CMD_LEN;
int code = _wtoi(codeString);
if (code > DECLINE_MIN && code < DECLINE_MAX)
{
reason = (DECLINE_REASON)code;
}
// The user we invited has declined our invitation.
InvitationDeclined(pager, reason);
}
}
}
}
/******************************************************************************
*
* NAME
* WOLBuddyMgr::HandleNotification(PageSendStatus)
*
* DESCRIPTION
*
* INPUTS
* Status
*
* RESULT
* NONE
*
******************************************************************************/
void WOLBuddyMgr::HandleNotification(PageSendStatus& pageStatus)
{
WOLPagedAction action = PAGE_ERROR;
uint32 msgID = 0;
switch (pageStatus)
{
case PAGESEND_ERROR:
action = PAGE_ERROR;
msgID = IDS_PAGESEND_ERROR;
break;
case PAGESEND_OFFLINE:
action = PAGE_NOT_THERE;
msgID = IDS_PAGESEND_OFFLINE;
break;
case PAGESEND_HIDING:
action = PAGE_TURNED_OFF;
msgID = IDS_PAGESEND_HIDING;
break;
case PAGESEND_SENT:
default:
return;
}
// If the page was undeliverable then tell the user why.
if (!mHidePagedDialog && !DlgWOLPageReply::IsOpen())
{
DlgMsgBox::DoDialog(IDS_WOL_PAGEUSERERROR, msgID);
}
Add_Ref();
PageMessage page(NULL, TRANSLATE(msgID));
WOLPagedEvent event(action, &page);
NotifyObservers(event);
Release_Ref();
}