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/WOLChatMgr.cpp

1561 lines
33 KiB
C++
Raw Permalink Normal View History

/*
** 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/WOLChatMgr.cpp $
*
* DESCRIPTION
*
* PROGRAMMER
* Denzil E. Long, Jr.
* $Author: Denzil_l $
*
* VERSION INFO
* $Revision: 36 $
* $Modtime: 2/25/02 5:05p $
*
******************************************************************************/
#include "WOLChatMgr.h"
#include "WOLBuddyMgr.h"
#include "MPSettingsMgr.h"
#include "DlgWOLWait.h"
#include <WWOnline\WOLSession.h>
#include <WWOnline\WOLServer.h>
#include <WWOnline\WOLChannel.h>
#include <WWOnline\WOLProduct.h>
#include "String_IDs.h"
#include <WWTranslateDB\TranslateDB.h>
#include <WWDebug\WWDebug.h>
using namespace WWOnline;
WOLChatMgr* WOLChatMgr::_mInstance = NULL;
// Local prototypes
typedef void (*SlashCommandFunc)(const wchar_t*);
static void SlashCmdPage(const wchar_t*);
static void SlashCmdR(const wchar_t*);
static void SlashCmdLocate(const wchar_t*);
static void SlashCmdMsg(const wchar_t*);
static void SlashCmdInvite(const wchar_t*);
static void SlashCmdKick(const wchar_t*);
static void SlashCmdJoin(const wchar_t*);
static const wchar_t* Get_Parameter_From_String(const wchar_t* command_string, WideStringClass& parameter);
/******************************************************************************
*
* NAME
* WOLChatMgr::GetInstance
*
* DESCRIPTION
* Obtain Chat manager instance
*
* INPUTS
* Create - Okay to create chat manager if not already instantiated.
*
* RESULT
* Instance - Pointer to the chat manager.
*
******************************************************************************/
WOLChatMgr* WOLChatMgr::GetInstance(bool createOK)
{
if (_mInstance == NULL)
{
new WOLChatMgr;
if (_mInstance)
{
if (_mInstance->FinalizeCreate() == false)
{
_mInstance->Release_Ref();
}
}
}
else
{
_mInstance->Add_Ref();
}
return _mInstance;
}
/******************************************************************************
*
* NAME
* WOLChatMgr::WOLChatMgr
*
* DESCRIPTION
* Constructor
*
* INPUTS
* NONE
*
* RESULT
* NONE
*
******************************************************************************/
WOLChatMgr::WOLChatMgr()
{
WWDEBUG_SAY(("WOLChatMgr: Instantiated\n"));
_mInstance = this;
}
/******************************************************************************
*
* NAME
* WOLChatMgr::~WOLChatMgr
*
* DESCRIPTION
* Destructor
*
* INPUTS
* NONE
*
* RESULT
* NONE
*
******************************************************************************/
WOLChatMgr::~WOLChatMgr()
{
WWDEBUG_SAY(("WOLChatMgr: Destroyed\n"));
_mInstance = NULL;
}
/******************************************************************************
*
* NAME
* WOLChatMgr::FinalizeCreate
*
* DESCRIPTION
* Finalize object creation.
*
* INPUTS
* NONE
*
* RESULT
* True if successful
*
******************************************************************************/
bool WOLChatMgr::FinalizeCreate(void)
{
// Get reference to WWOnline session
mWOLSession = Session::GetInstance(false);
if (!mWOLSession.IsValid())
{
return false;
}
// Generate chat lobby prefex
RefPtr<Product> product = Product::Current();
if (!product.IsValid())
{
return false;
}
mLobbyPrefix.Format(L"Lob_%d_", product->GetGameCode());
return true;
}
/******************************************************************************
*
* NAME
* WOLChatMgr::Start
*
* DESCRIPTION
* Start receiving and processing chat messages.
*
* INPUTS
* NONE
*
* RESULT
* NONE
*
******************************************************************************/
void WOLChatMgr::Start(void)
{
if (mWOLSession.IsValid())
{
Observer<ServerError>::NotifyMe(*mWOLSession);
Observer<ChannelListEvent>::NotifyMe(*mWOLSession);
Observer<ChannelEvent>::NotifyMe(*mWOLSession);
Observer<UserEvent>::NotifyMe(*mWOLSession);
Observer<UserList>::NotifyMe(*mWOLSession);
Observer<ChatMessage>::NotifyMe(*mWOLSession);
}
}
/******************************************************************************
*
* NAME
* WOLChatMgr::Stop
*
* DESCRIPTION
* Suspend receiving and processing of chat messages.
*
* INPUTS
* NONE
*
* RESULT
* NONE
*
******************************************************************************/
void WOLChatMgr::Stop(void)
{
if (mWOLSession.IsValid())
{
Observer<ServerError>::StopObserving();
Observer<ChannelListEvent>::StopObserving();
Observer<ChannelEvent>::StopObserving();
Observer<UserEvent>::StopObserving();
Observer<UserList>::StopObserving();
Observer<ChatMessage>::StopObserving();
}
}
/******************************************************************************
*
* NAME
* WOLChatMgr::RefreshLobbyList
*
* DESCRIPTION
* Request an updated list of chat channels.
*
* INPUTS
* NONE
*
* RESULT
* NONE
*
******************************************************************************/
void WOLChatMgr::RefreshLobbyList(void)
{
mWOLSession->RequestChannelList(0, false);
}
/******************************************************************************
*
* NAME
* WOLChatMgr::GetLobbyList
*
* DESCRIPTION
* Get a list of available chat channels.
*
* INPUTS
* NONE
*
* RESULT
* Lobbies - List of valid chat channels.
*
******************************************************************************/
const LobbyList& WOLChatMgr::GetLobbyList(void)
{
return mLobbyList;
}
/******************************************************************************
*
* NAME
* WOLChatMgr::GetCurrentLobby
*
* DESCRIPTION
* Get the lobby we are currently joined.
*
* INPUTS
* NONE
*
* RESULT
* Lobby - Lobby currently joined to.
*
******************************************************************************/
const RefPtr<ChannelData>& WOLChatMgr::GetCurrentLobby(void)
{
return mWOLSession->GetCurrentChannel();
}
/******************************************************************************
*
* NAME
* WOLChatMgr::FindLobby
*
* DESCRIPTION
* Find a chat lobby with the specified name.
*
* INPUTS
* Name - Name of lobby to find.
*
* RESULT
* Lobby -
*
******************************************************************************/
const RefPtr<ChannelData> WOLChatMgr::FindLobby(const wchar_t* name)
{
return mWOLSession->FindChatChannel(name);
}
/******************************************************************************
*
* NAME
* WOLChatMgr::CreateLobby
*
* DESCRIPTION
* Create a channel lobby
*
* INPUTS
* Name - New lobby name
* Password - Password required to join lobby.
*
* RESULT
* NONE
*
******************************************************************************/
void WOLChatMgr::CreateLobby(const wchar_t* name, const wchar_t* password)
{
RefPtr<WaitCondition> wait = mWOLSession->CreateChannel(name, password, 0);
if (wait.IsValid())
{
WideStringClass message(255, true);
message.Format(TRANSLATE(IDS_CHAT_LOBBYCREATE), name);
DlgWOLWait::DoDialog((const wchar_t*)message, wait);
}
}
/******************************************************************************
*
* NAME
* WOLChatMgr::JoinLobby
*
* DESCRIPTION
* Join a channel lobby
*
* INPUTS
* Channel - Channel lobby to join
*
* RESULT
* NONE
*
******************************************************************************/
void WOLChatMgr::JoinLobby(const RefPtr<ChannelData>& channel)
{
if (channel.IsValid())
{
RefPtr<Product> product = Product::Current();
WWASSERT_PRINT(product.IsValid(), "WWOnline product not initialized.");
RefPtr<WaitCondition> wait = mWOLSession->JoinChannel(channel, product->GetChannelPassword());
if (wait.IsValid())
{
WideStringClass displayName(0, true);
GetLobbyDisplayName(channel, displayName);
WideStringClass message(0, true);
message.Format(TRANSLATE(IDS_CHAT_LOBBYJOIN), displayName);
DlgWOLWait::DoDialog((const wchar_t*)message, wait);
}
}
}
/******************************************************************************
*
* NAME
* WOLChatMgr::LeaveLobby
*
* DESCRIPTION
* Leave the current channel lobby.
*
* INPUTS
* NONE
*
* RESULT
* NONE
*
******************************************************************************/
void WOLChatMgr::LeaveLobby(void)
{
RefPtr<WaitCondition> wait = mWOLSession->LeaveChannel();
if (wait.IsValid())
{
const RefPtr<ChannelData>& channel = GetCurrentLobby();
WideStringClass lobbyName(0, true);
GetLobbyDisplayName(channel, lobbyName);
WideStringClass title(0, true);
title.Format(TRANSLATE(IDS_CHAT_LOBBYLEAVE), lobbyName);
DlgWOLWait::DoDialog(title, wait);
}
}
/******************************************************************************
*
* NAME
* WOLChatMgr::IsLobbyValid
*
* DESCRIPTION
* Check if the channel is a valid chat lobby.
*
* INPUTS
* Lobby - Lobby to validate
*
* RESULT
* True if lobby is a valid chat lobby.
*
******************************************************************************/
bool WOLChatMgr::IsLobbyValid(const RefPtr<ChannelData>& lobby)
{
if (lobby.IsValid())
{
const int unwantedFlags = CHAN_MODE_SECRET | CHAN_MODE_INVITEONLY | CHAN_MODE_BAN;
unsigned int lobbyFlags = lobby->GetFlags();
// Lobbies without these flags are valid chat lobbies.
if ((lobbyFlags & unwantedFlags) == 0)
{
// Lobbies that have the matching prefix are valid.
const wchar_t* lobbyName = lobby->GetName();
return (wcsnicmp(mLobbyPrefix, lobbyName, mLobbyPrefix.Get_Length()) == 0);
}
}
return false;
}
/******************************************************************************
*
* NAME
* WOLChatMgr::GetLobbyDisplayName
*
* DESCRIPTION
* Get the display name for the given lobby.
*
* INPUTS
* Lobby - Lobby to get display name for.
* Name - On return; display name for the lobby.
*
* RESULT
* NONE
*
******************************************************************************/
void WOLChatMgr::GetLobbyDisplayName(const RefPtr<ChannelData>& lobby, WideStringClass& outName)
{
if (lobby.IsValid() == false)
{
outName = L"";
return;
}
const wchar_t* name = lobby->GetName();
int prefixLength = mLobbyPrefix.Get_Length();
if (wcsnicmp(name, mLobbyPrefix, prefixLength) == 0)
{
const wchar_t* extName = (name + prefixLength);
// If the extended portion of the lobby name is a number then select a name
// from the Renegade lobby names provided. Otherwise use the extended portion
// as given.
if (*extName >= L'0' && *extName <= L'9')
{
static const wchar_t* _lobbies[8] =
{
TRANSLATE (IDS_MENU_LOBBY_NAME_01),
TRANSLATE (IDS_MENU_LOBBY_NAME_02),
TRANSLATE (IDS_MENU_LOBBY_NAME_03),
TRANSLATE (IDS_MENU_LOBBY_NAME_04),
TRANSLATE (IDS_MENU_LOBBY_NAME_05),
TRANSLATE (IDS_MENU_LOBBY_NAME_06),
TRANSLATE (IDS_MENU_LOBBY_NAME_07),
TRANSLATE (IDS_MENU_LOBBY_NAME_08),
};
int channelNumber = _wtol(extName);
int subnum = (channelNumber / 8);
int nameNumber = (channelNumber % 8);
const wchar_t* displayName = _lobbies[nameNumber];
if (subnum == 0)
{
outName = displayName;
}
else
{
outName.Format(L"%s_%d", displayName, (subnum + 1));
}
}
else
{
outName = extName;
}
}
}
/******************************************************************************
*
* NAME
* WOLChatMgr::FindUser
*
* DESCRIPTION
* Find a user with the specified name.
*
* INPUTS
* Name - Name of user to look for.
*
* RESULT
* User -
*
******************************************************************************/
const RefPtr<UserData> WOLChatMgr::FindUser(const wchar_t* name)
{
return mWOLSession->FindUser(name);
}
/******************************************************************************
*
* NAME
* WOLChatMgr::ClearUserInList
*
* DESCRIPTION
* Clear the list of users who have joined.
*
* INPUTS
* NONE
*
* RESULT
* NONE
*
******************************************************************************/
void WOLChatMgr::ClearUserInList(void)
{
mUserInList.clear();
}
/******************************************************************************
*
* NAME
* WOLChatMgr::ClearUserOutList
*
* DESCRIPTION
* Clear the list of users who have left.
*
* INPUTS
* NONE
*
* RESULT
* NONE
*
******************************************************************************/
void WOLChatMgr::ClearUserOutList(void)
{
mUserOutList.clear();
}
/******************************************************************************
*
* NAME
* WOLChatMgr::SquelchUser
*
* DESCRIPTION
* Enable / Disable receipt of messages from the specified user.
*
* INPUTS
* Name - Name of user
* Squelch - True to enable; false to disable
*
* RESULT
* True if request was successful.
*
******************************************************************************/
bool WOLChatMgr::SquelchUser(const RefPtr<UserData>& user, bool onoff)
{
bool success = mWOLSession->SquelchUser(user, onoff);
if (success)
{
int stringID = (onoff ? IDS_CHAT_SQUELCH_ON : IDS_CHAT_SQUELCH_OFF);
const wchar_t* text = TRANSLATE(stringID);
WideStringClass message(0, true);
message.Format(text, user->GetName());
AddMessage(NULL, message, true, true);
}
return success;
}
/******************************************************************************
*
* NAME
* WOLChatMgr::LocateUser
*
* DESCRIPTION
* Request the location status of a user.
*
* INPUTS
* Name - Name of user to locate
*
* RESULT
* NONE
*
******************************************************************************/
void WOLChatMgr::LocateUser(const wchar_t* name)
{
mLocatingUserName = name;
mLocatingUserName.Trim();
if (mLocatingUserName.Is_Empty() == false)
{
mWOLSession->RequestLocateUser(mLocatingUserName);
}
}
/******************************************************************************
*
* NAME
* WOLChatMgr::SendPublicMessage
*
* DESCRIPTION
* Send a message that everyone can see.
*
* INPUTS
* Message - Message to send
* IsAction - Is this message and action.
*
* RESULT
* NONE
*
******************************************************************************/
void WOLChatMgr::SendPublicMessage(const wchar_t* message, bool isAction)
{
if (ProcessCommand(message))
{
return;
}
if (isAction)
{
mWOLSession->SendPublicAction(message);
}
else
{
mWOLSession->SendPublicMessage(message);
}
const wchar_t* sender = NULL;
RefPtr<UserData> me = mWOLSession->GetCurrentUser();
if (me.IsValid())
{
sender = me->GetName();
}
AddMessage(sender, message, false, isAction);
}
/******************************************************************************
*
* NAME
* WOLChatMgr::SendPrivateMessage
*
* DESCRIPTION
* Send a message that only the specified user can see.
*
* INPUTS
* User - Users to send message to.
* Message - Message to send.
* IsAction - True if this is an emote action.
*
* RESULT
* NONE
*
******************************************************************************/
void WOLChatMgr::SendPrivateMessage(const RefPtr<UserData>& user,
const wchar_t* message, bool isAction)
{
if (ProcessCommand(message))
{
return;
}
UserList userList;
userList.push_back(user);
SendPrivateMessage(userList, message, isAction);
}
/******************************************************************************
*
* NAME
* WOLChatMgr::SendPrivateMessage
*
* DESCRIPTION
* Send a message that only a selected group of users can see.
*
* INPUTS
* User - List of users to send message to.
* Message - Message to send.
* IsAction - True if this is an emote action.
*
* RESULT
* NONE
*
******************************************************************************/
void WOLChatMgr::SendPrivateMessage(UserList& users, const wchar_t* message, bool isAction)
{
if (ProcessCommand(message))
{
return;
}
if (isAction)
{
mWOLSession->SendPrivateAction(users, message);
}
else
{
mWOLSession->SendPrivateMessage(users, message);
}
const wchar_t* sender = NULL;
RefPtr<UserData> me = mWOLSession->GetCurrentUser();
if (me.IsValid())
{
sender = me->GetName();
}
AddMessage(sender, message, true, isAction);
}
/******************************************************************************
*
* NAME
* WOLChatMgr::AddMessage
*
* DESCRIPTION
* Add a message to the chat messages pool.
*
* INPUTS
* Sender - User message originated from.
* Message - Text message
* IsPrivate - True if the message is private.
* IsAction - True if the message is an action.
*
* RESULT
* NONE
*
******************************************************************************/
void WOLChatMgr::AddMessage(const wchar_t* sender, const wchar_t* message, bool isPrivate, bool isAction)
{
ChatMessage msg(sender, message, isPrivate, isAction);
mMessageList.push_back(msg);
WOLChatMgrEvent event = MessageListChanged;
NotifyObservers(event);
}
/******************************************************************************
*
* NAME
* WOLChatMgr::PassesFilters
*
* DESCRIPTION
* Check message against user specified text filters.
*
* INPUTS
* Message - Chat message to filter.
*
* RESULT
* True if message should be displayed; False if it should be hidden.
*
******************************************************************************/
bool WOLChatMgr::PassesFilters(const ChatMessage& msg)
{
// Messages from the user and channel owners are never filtered.
if (msg.IsSenderMyself() || msg.IsSenderChannelOwner())
{
return true;
}
// All messages from squelched users are filtered
if (msg.IsSenderSquelched())
{
WWDEBUG_SAY(("WOLChatMgr: Filtered squelched message from %S\n",
(const WCHAR*)msg.GetSendersName()));
return false;
}
//---------------------------------------------------------------------------
// Buddy and Clan filtering
//---------------------------------------------------------------------------
bool testClan = MPSettingsMgrClass::Get_Option_Flag(MPSettingsMgrClass::OPTION_CLAN_CHAT_ONLY);
bool testBuddy = MPSettingsMgrClass::Get_Option_Flag(MPSettingsMgrClass::OPTION_BUDDY_CHAT_ONLY);
// If only interested in messages from clan members then filter out all
// messages from everybody else.
bool passesClan = true;
if (testClan)
{
RefPtr<UserData> user = mWOLSession->GetCurrentUser();
if (user.IsValid())
{
unsigned long clanID = user->GetSquadID();
passesClan = ((clanID == 0) || msg.IsSenderInClan(clanID));
}
}
// If only interested in messages from buddies then filter out all the
// messages that are not from users in the buddy list.
bool passesBuddy = true;
if (testBuddy)
{
WOLBuddyMgr* buddyMgr = WOLBuddyMgr::GetInstance(false);
if (buddyMgr)
{
passesBuddy = buddyMgr->IsBuddy(msg.GetSendersName());
buddyMgr->Release_Ref();
}
}
if (testClan && testBuddy)
{
if (!passesClan && !passesBuddy)
{
return false;
}
}
else if (testClan && !passesClan)
{
return false;
}
else if (testBuddy && !passesBuddy)
{
return false;
}
//---------------------------------------------------------------------------
// Western and Asian filtering
//---------------------------------------------------------------------------
// If we are filtering western text and the message is western then
// filter out the message.
bool showLatin = MPSettingsMgrClass::Get_Option_Flag(MPSettingsMgrClass::OPTION_DISPLAY_NONASIAN);
if (!showLatin && IsAnsiText(msg.GetMessage()))
{
WWDEBUG_SAY(("WOLChatMgr: Filtered latin text message\n"));
return false;
}
// If we are filtering asian text and the message is asian then filter out
// the message.
bool showAsian = MPSettingsMgrClass::Get_Option_Flag(MPSettingsMgrClass::OPTION_DISPLAY_ASIAN);
if (!showAsian && !IsAnsiText(msg.GetMessage()))
{
WWDEBUG_SAY(("WOLChatMgr: Filtered Asian text message\n"));
return false;
}
return true;
}
/******************************************************************************
*
* NAME
* WOLChatMgr::ClearMessageList
*
* DESCRIPTION
* Clear all the messages.
*
* INPUTS
* NONE
*
* RESULT
* NONE
*
******************************************************************************/
void WOLChatMgr::ClearMessageList(void)
{
mMessageList.clear();
}
/******************************************************************************
*
* NAME
* WOLChatMgr::HandleNotification(ServerError)
*
* DESCRIPTION
* Handle error conditions from the server.
*
* INPUTS
*
* RESULT
* NONE
*
******************************************************************************/
void WOLChatMgr::HandleNotification(ServerError& error)
{
switch (error.GetErrorCode())
{
case CHAT_E_NOT_OPER:
break;
case CHAT_E_BANNED:
{
Add_Ref();
WOLChatMgrEvent event = BannedFromChannel;
NotifyObservers(event);
Release_Ref();
}
break;
default:
{
const wchar_t* msg = error.GetDescription();
AddMessage(TRANSLATE(IDS_CHAT_SERVERERROR), msg, true, false);
}
break;
}
}
/******************************************************************************
*
* NAME
* WOLChatMgr::HandleNotification(ChannelListEvent)
*
* DESCRIPTION
* Handle channel list events.
*
* INPUTS
*
* RESULT
* NONE
*
******************************************************************************/
void WOLChatMgr::HandleNotification(ChannelListEvent& event)
{
if (event.GetEvent() == ChannelListEvent::NewList && event.GetChannelType() == 0)
{
mLobbyList.clear();
const ChannelList& channelList = event.Subject();
ChannelList::const_iterator iter = channelList.begin();
while (iter != channelList.end())
{
const RefPtr<ChannelData>& channel = (*iter);
// If this is a valid public chat lobby then add it to the list.
if (IsLobbyValid(channel))
{
mLobbyList.push_back(channel);
}
iter++;
}
Add_Ref();
WOLChatMgrEvent event = LobbyListChanged;
NotifyObservers(event);
Release_Ref();
}
}
/******************************************************************************
*
* NAME
* WOLChatMgr::HandleNotification(ChannelEvent)
*
* DESCRIPTION
* Handle channel events such as response to leaving or joining.
*
* INPUTS
*
* RESULT
* NONE
*
******************************************************************************/
void WOLChatMgr::HandleNotification(ChannelEvent& event)
{
ChannelStatus status = event.GetStatus();
switch (status)
{
case ChannelJoined:
case ChannelLeft:
{
const RefPtr<ChannelData>& channel = event.Subject();
WideStringClass displayName(0, true);
GetLobbyDisplayName(channel, displayName);
WideStringClass message(0, true);
if (status == ChannelJoined)
{
message.Format(TRANSLATE(IDS_CHAT_LOBBYJOINED), displayName);
}
else
{
message.Format(TRANSLATE(IDS_CHAT_LOBBYLEFT), displayName);
}
AddMessage(NULL, message, true, true);
Add_Ref();
WOLChatMgrEvent event = LobbyChanged;
NotifyObservers(event);
Release_Ref();
}
break;
case ChannelBanned:
{
Add_Ref();
WOLChatMgrEvent event = BannedFromChannel;
NotifyObservers(event);
Release_Ref();
}
break;
case ChannelKicked:
{
Add_Ref();
WOLChatMgrEvent event = KickedFromChannel;
NotifyObservers(event);
Release_Ref();
}
break;
default:
break;
}
}
/******************************************************************************
*
* NAME
* WOLChatMgr::HandleNotification(UserEvent)
*
* DESCRIPTION
* Handle user related events
*
* INPUTS
*
* RESULT
* NONE
*
******************************************************************************/
void WOLChatMgr::HandleNotification(UserEvent& userEvent)
{
UserEvent::Event event = userEvent.GetEvent();
switch (event)
{
case UserEvent::Join:
{
WWDEBUG_SAY(("WOLChatMgr: Received User Join Event\n"));
const RefPtr<UserData>& user = userEvent.Subject();
mUserInList.push_back(user);
mWOLSession->RequestUserDetails(user, (REQUEST_LOCALE|REQUEST_SQUADINFO));
Add_Ref();
WOLChatMgrEvent event = UserInListChanged;
NotifyObservers(event);
Release_Ref();
}
break;
case UserEvent::Kicked:
{
const RefPtr<UserData>& user = userEvent.Subject();
mUserOutList.push_back(user);
WideStringClass kickMsg(0, true);
kickMsg.Format(TRANSLATE(IDS_CHAT_USERKICKED), user->GetName());
AddMessage(NULL, kickMsg, true, true);
Add_Ref();
WOLChatMgrEvent event = UserOutListChanged;
NotifyObservers(event);
Release_Ref();
}
break;
case UserEvent::Leave:
{
mUserOutList.push_back(userEvent.Subject());
Add_Ref();
WOLChatMgrEvent event = UserOutListChanged;
NotifyObservers(event);
Release_Ref();
}
break;
case UserEvent::Banned:
{
WideStringClass banMsg(0, true);
banMsg.Format(TRANSLATE(IDS_CHAT_USERBANNED), userEvent.Subject()->GetName());
AddMessage(NULL, banMsg, true, true);
}
break;
case UserEvent::Located:
{
WWDEBUG_SAY(("WOLChatMgr: Received User Located Event\n"));
const RefPtr<UserData>& user = userEvent.Subject();
// Is this the user we were looking for?
if (mLocatingUserName.Compare_No_Case(user->GetName()) == 0)
{
// Build a string containing the user's name
WideStringClass message(0, true);
message.Format(TRANSLATE(IDS_CHAT_LOCATEDUSER), user->GetName());
// Append the description of the user's location
WideStringClass location(64, true);
WOLBuddyMgr::GetLocationDescription(user, location);
message += L" - ";
message += location;
// Add this message to the UI
AddMessage(NULL, message, true, false);
mLocatingUserName = L"";
}
}
break;
}
}
/******************************************************************************
*
* NAME
* WOLChatMgr::HandleNotification(UserList)
*
* DESCRIPTION
*
* INPUTS
*
* RESULT
* NONE
*
******************************************************************************/
void WOLChatMgr::HandleNotification(WWOnline::UserList& users)
{
mUserInList.clear();
mUserOutList.clear();
int count = users.size();
for (int index = 0; index < count; index++)
{
mWOLSession->RequestUserDetails(users[index], (REQUEST_LOCALE|REQUEST_SQUADINFO));
mUserInList.push_back(users[index]);
}
Add_Ref();
WOLChatMgrEvent event = UserInListChanged;
NotifyObservers(event);
Release_Ref();
}
/******************************************************************************
*
* NAME
* WOLChatMgr::HandleNotification(ChatMessage)
*
* DESCRIPTION
*
* INPUTS
*
* RESULT
* NONE
*
******************************************************************************/
void WOLChatMgr::HandleNotification(ChatMessage& chatMsg)
{
if (PassesFilters(chatMsg))
{
mMessageList.push_back(chatMsg);
Add_Ref();
WOLChatMgrEvent event = MessageListChanged;
NotifyObservers(event);
Release_Ref();
}
}
/******************************************************************************
*
* NAME
* WOLChatMgr::ProcessCommand(const wchar_t* message)
*
* DESCRIPTION
*
* INPUTS
*
* RESULT
* NONE
*
******************************************************************************/
bool WOLChatMgr::ProcessCommand(const wchar_t* message)
{
// Does this look like a command?
if (message && message[0] == L'/')
{
// Separate the parameters into individual strings
WideStringClass command(255, true);
const wchar_t* params = Get_Parameter_From_String(&message[1], command);
if (command.Get_Length() > 0)
{
static struct {const wchar_t* Token; SlashCommandFunc Dispatch;} _cmdDispatch[] =
{
{L"page", SlashCmdPage},
{L"r", SlashCmdR},
{L"locate", SlashCmdLocate},
{L"msg", SlashCmdMsg},
{L"invite", SlashCmdInvite},
{L"kick", SlashCmdKick},
{L"join", SlashCmdJoin},
{NULL, NULL},
};
int index = 0;
const wchar_t* token = _cmdDispatch[index].Token;
while (token)
{
if (command.Compare_No_Case(token) == 0)
{
_cmdDispatch[index].Dispatch(params);
return true;
}
++index;
token = _cmdDispatch[index].Token;
}
}
}
return false;
}
// Page a user
void SlashCmdPage(const wchar_t* param)
{
// Get the name parameter from the string
WideStringClass name(64, true);
WideStringClass pageMsg(0, true);
pageMsg = Get_Parameter_From_String(param, name);
pageMsg.Trim();
if (!name.Is_Empty() && !pageMsg.Is_Empty())
{
WOLBuddyMgr* buddyMgr = WOLBuddyMgr::GetInstance(false);
if (buddyMgr)
{
// Page the requested user
buddyMgr->PageUser(name, pageMsg);
buddyMgr->Release_Ref();
}
}
}
// Send a page reply
void SlashCmdR(const wchar_t* param)
{
WideStringClass reply(0, true);
reply = param;
reply.Trim();
if (reply.Is_Empty() == false)
{
WOLBuddyMgr* buddyMgr = WOLBuddyMgr::GetInstance(false);
if (buddyMgr)
{
const wchar_t* name = buddyMgr->GetLastPagersName();
if (name && wcslen(name))
{
// Reply to the last user who paged.
buddyMgr->PageUser(name, reply);
}
buddyMgr->Release_Ref();
}
}
}
// Locate a user
void SlashCmdLocate(const wchar_t* param)
{
// Try to find the specified user
WideStringClass name(64, true);
Get_Parameter_From_String(param, name);
if (name.Is_Empty() == false)
{
WOLChatMgr* chat = WOLChatMgr::GetInstance(false);
if (chat)
{
chat->LocateUser(name);
chat->Release_Ref();
}
}
}
// Send private message
void SlashCmdMsg(const wchar_t* param)
{
// Get the name parameter from the string
WideStringClass name(64, true);
WideStringClass message(0, true);
message = Get_Parameter_From_String(param, name);
message.Trim();
if (!name.Is_Empty() && !message.Is_Empty())
{
WOLChatMgr* chat = WOLChatMgr::GetInstance(false);
if (chat)
{
RefPtr<UserData> user = chat->FindUser(name);
if (user.IsValid())
{
chat->SendPrivateMessage(user, message, false);
}
chat->Release_Ref();
}
}
}
// Invite a user to our location
void SlashCmdInvite(const wchar_t* param)
{
// Get the name parameter from the string
WideStringClass name(64, true);
const wchar_t* msg = Get_Parameter_From_String(param, name);
if (name.Is_Empty() == false)
{
WOLBuddyMgr* buddyMgr = WOLBuddyMgr::GetInstance(false);
if (buddyMgr)
{
buddyMgr->InviteUser(name, msg);
buddyMgr->Release_Ref();
}
}
}
// Kick a user
void SlashCmdKick(const wchar_t* param)
{
// Get the name parameter from the string
WideStringClass name(64, true);
Get_Parameter_From_String(param, name);
if (name.Is_Empty() == false)
{
RefPtr<Session> wolSession = Session::GetInstance(false);
if (wolSession.IsValid())
{
wolSession->KickUser(name);
}
}
}
// Join a user
void SlashCmdJoin(const wchar_t* param)
{
// Get the name parameter from the string
WideStringClass name(64, true);
Get_Parameter_From_String(param, name);
if (name.Is_Empty() == false)
{
RefPtr<UserData> user;
RefPtr<Session> wolSession = Session::GetInstance(false);
if (wolSession.IsValid())
{
user = wolSession->FindUser(name);
}
// If the user we want to join is already in our user list then no need to join
if (user.IsValid() == false)
{
WOLBuddyMgr* buddyMgr = WOLBuddyMgr::GetInstance(false);
if (buddyMgr)
{
user = UserData::Create(name);
buddyMgr->JoinUser(user);
buddyMgr->Release_Ref();
}
}
}
}
/******************************************************************************
*
* NAME
* Get_Parameter_From_String
*
* DESCRIPTION
*
* INPUTS
* Command - Command string
* Param -
*
* RESULT
* NONE
*
******************************************************************************/
const wchar_t* Get_Parameter_From_String(const wchar_t* command, WideStringClass& param)
{
#define LOCAL_STRIP_WHITESPACE(str) \
while (str[0] != 0 && str[0] == L' ') {++str;}
// Strip off whitespace
LOCAL_STRIP_WHITESPACE(command);
const wchar_t* curr_pos = command;
// Look for the first whitespace break
while (curr_pos[0] != 0 && curr_pos[0] != L' ')
{
++curr_pos;
}
// Return the string contents to the caller
int length = ((curr_pos + 1) - command);
if (length > 0)
{
WCHAR* buffer = param.Get_Buffer(length + 1);
wcsncpy(buffer, command, length);
buffer[length - 1] = 0;
}
// Strip off whitespace
LOCAL_STRIP_WHITESPACE(curr_pos);
return curr_pos;
}