mirror of
https://github.com/EQEmu/Server.git
synced 2026-05-22 16:28:28 +00:00
svn -> git Migration
This commit is contained in:
@@ -0,0 +1,706 @@
|
||||
/*
|
||||
EQEMu: Everquest Server Emulator
|
||||
|
||||
Copyright (C) 2001-2008 EQEMu Development Team (http://eqemulator.net)
|
||||
|
||||
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; version 2 of the License.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY except by those people which sell it, which
|
||||
are required to give you total support for your newly bought product;
|
||||
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, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
|
||||
*/
|
||||
|
||||
#include "chatchannel.h"
|
||||
#include "clientlist.h"
|
||||
#include "database.h"
|
||||
#include "../common/MiscFunctions.h"
|
||||
#include <cstdlib>
|
||||
|
||||
extern Database database;
|
||||
extern uint32 ChatMessagesSent;
|
||||
|
||||
ChatChannel::ChatChannel(string inName, string inOwner, string inPassword, bool inPermanent, int inMinimumStatus) :
|
||||
DeleteTimer(0) {
|
||||
|
||||
Name = inName;
|
||||
|
||||
Owner = inOwner;
|
||||
|
||||
Password = inPassword;
|
||||
|
||||
Permanent = inPermanent;
|
||||
|
||||
MinimumStatus = inMinimumStatus;
|
||||
|
||||
Moderated = false;
|
||||
|
||||
_log(UCS__TRACE, "New ChatChannel created: Name: [%s], Owner: [%s], Password: [%s], MinStatus: %i",
|
||||
Name.c_str(), Owner.c_str(), Password.c_str(), MinimumStatus);
|
||||
|
||||
}
|
||||
|
||||
ChatChannel::~ChatChannel() {
|
||||
|
||||
LinkedListIterator<Client*> iterator(ClientsInChannel);
|
||||
|
||||
iterator.Reset();
|
||||
|
||||
while(iterator.MoreElements())
|
||||
iterator.RemoveCurrent(false);
|
||||
}
|
||||
|
||||
ChatChannel* ChatChannelList::CreateChannel(string Name, string Owner, string Password, bool Permanent, int MinimumStatus) {
|
||||
|
||||
ChatChannel *NewChannel = new ChatChannel(CapitaliseName(Name), Owner, Password, Permanent, MinimumStatus);
|
||||
|
||||
ChatChannels.Insert(NewChannel);
|
||||
|
||||
return NewChannel;
|
||||
}
|
||||
|
||||
ChatChannel* ChatChannelList::FindChannel(string Name) {
|
||||
|
||||
string NormalisedName = CapitaliseName(Name);
|
||||
|
||||
LinkedListIterator<ChatChannel*> iterator(ChatChannels);
|
||||
|
||||
iterator.Reset();
|
||||
|
||||
while(iterator.MoreElements()) {
|
||||
|
||||
ChatChannel *CurrentChannel = iterator.GetData();
|
||||
|
||||
if(CurrentChannel && (CurrentChannel->Name == NormalisedName))
|
||||
return iterator.GetData();
|
||||
|
||||
iterator.Advance();
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void ChatChannelList::SendAllChannels(Client *c) {
|
||||
|
||||
if(!c) return;
|
||||
|
||||
if(!c->CanListAllChannels()) {
|
||||
c->GeneralChannelMessage("You do not have permission to list all the channels.");
|
||||
return;
|
||||
}
|
||||
|
||||
c->GeneralChannelMessage("All current channels:");
|
||||
|
||||
int ChannelsInLine = 0;
|
||||
|
||||
LinkedListIterator<ChatChannel*> iterator(ChatChannels);
|
||||
|
||||
iterator.Reset();
|
||||
|
||||
string Message;
|
||||
|
||||
char CountString[10];
|
||||
|
||||
while(iterator.MoreElements()) {
|
||||
|
||||
ChatChannel *CurrentChannel = iterator.GetData();
|
||||
|
||||
if(!CurrentChannel || (CurrentChannel->GetMinStatus() > c->GetAccountStatus())) {
|
||||
|
||||
iterator.Advance();
|
||||
|
||||
continue;
|
||||
}
|
||||
|
||||
if(ChannelsInLine > 0)
|
||||
Message += ", ";
|
||||
|
||||
sprintf(CountString, "(%i)", CurrentChannel->MemberCount(c->GetAccountStatus()));
|
||||
|
||||
Message += CurrentChannel->GetName();
|
||||
|
||||
Message += CountString;
|
||||
|
||||
ChannelsInLine++;
|
||||
|
||||
if(ChannelsInLine == 6) {
|
||||
|
||||
c->GeneralChannelMessage(Message);
|
||||
|
||||
ChannelsInLine = 0;
|
||||
|
||||
Message.clear();
|
||||
}
|
||||
|
||||
iterator.Advance();
|
||||
}
|
||||
|
||||
if(ChannelsInLine > 0)
|
||||
c->GeneralChannelMessage(Message);
|
||||
|
||||
}
|
||||
|
||||
void ChatChannelList::RemoveChannel(ChatChannel *Channel) {
|
||||
|
||||
_log(UCS__TRACE, "RemoveChannel(%s)", Channel->GetName().c_str());
|
||||
|
||||
LinkedListIterator<ChatChannel*> iterator(ChatChannels);
|
||||
|
||||
iterator.Reset();
|
||||
|
||||
while(iterator.MoreElements()) {
|
||||
|
||||
if(iterator.GetData() == Channel) {
|
||||
|
||||
iterator.RemoveCurrent();
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
iterator.Advance();
|
||||
}
|
||||
}
|
||||
|
||||
void ChatChannelList::RemoveAllChannels() {
|
||||
|
||||
_log(UCS__TRACE, "RemoveAllChannels");
|
||||
|
||||
LinkedListIterator<ChatChannel*> iterator(ChatChannels);
|
||||
|
||||
iterator.Reset();
|
||||
|
||||
while(iterator.MoreElements())
|
||||
iterator.RemoveCurrent();
|
||||
}
|
||||
|
||||
int ChatChannel::MemberCount(int Status) {
|
||||
|
||||
int Count = 0;
|
||||
|
||||
LinkedListIterator<Client*> iterator(ClientsInChannel);
|
||||
|
||||
iterator.Reset();
|
||||
|
||||
while(iterator.MoreElements()) {
|
||||
|
||||
Client *ChannelClient = iterator.GetData();
|
||||
|
||||
if(ChannelClient && (!ChannelClient->GetHideMe() || (ChannelClient->GetAccountStatus() < Status)))
|
||||
Count++;
|
||||
|
||||
iterator.Advance();
|
||||
}
|
||||
|
||||
return Count;
|
||||
}
|
||||
|
||||
void ChatChannel::SetPassword(string inPassword) {
|
||||
|
||||
Password = inPassword;
|
||||
|
||||
if(Permanent)
|
||||
{
|
||||
RemoveApostrophes(Password);
|
||||
database.SetChannelPassword(Name, Password);
|
||||
}
|
||||
}
|
||||
|
||||
void ChatChannel::SetOwner(string inOwner) {
|
||||
|
||||
Owner = inOwner;
|
||||
|
||||
if(Permanent)
|
||||
database.SetChannelOwner(Name, Owner);
|
||||
}
|
||||
|
||||
void ChatChannel::AddClient(Client *c) {
|
||||
|
||||
if(!c) return;
|
||||
|
||||
DeleteTimer.Disable();
|
||||
|
||||
if(IsClientInChannel(c)) {
|
||||
|
||||
_log(UCS__ERROR, "Client %s already in channel %s", c->GetName().c_str(), GetName().c_str());
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
bool HideMe = c->GetHideMe();
|
||||
|
||||
int AccountStatus = c->GetAccountStatus();
|
||||
|
||||
_log(UCS__TRACE, "Adding %s to channel %s", c->GetName().c_str(), Name.c_str());
|
||||
|
||||
LinkedListIterator<Client*> iterator(ClientsInChannel);
|
||||
|
||||
iterator.Reset();
|
||||
|
||||
while(iterator.MoreElements()) {
|
||||
|
||||
Client *CurrentClient = iterator.GetData();
|
||||
|
||||
if(CurrentClient && CurrentClient->IsAnnounceOn())
|
||||
if(!HideMe || (CurrentClient->GetAccountStatus() > AccountStatus))
|
||||
CurrentClient->AnnounceJoin(this, c);
|
||||
|
||||
iterator.Advance();
|
||||
}
|
||||
|
||||
ClientsInChannel.Insert(c);
|
||||
|
||||
}
|
||||
|
||||
bool ChatChannel::RemoveClient(Client *c) {
|
||||
|
||||
if(!c) return false;
|
||||
|
||||
_log(UCS__TRACE, "RemoveClient %s from channel %s", c->GetName().c_str(), GetName().c_str());
|
||||
|
||||
bool HideMe = c->GetHideMe();
|
||||
|
||||
int AccountStatus = c->GetAccountStatus();
|
||||
|
||||
int PlayersInChannel = 0;
|
||||
|
||||
LinkedListIterator<Client*> iterator(ClientsInChannel);
|
||||
|
||||
iterator.Reset();
|
||||
|
||||
while(iterator.MoreElements()) {
|
||||
|
||||
Client *CurrentClient = iterator.GetData();
|
||||
|
||||
if(CurrentClient == c) {
|
||||
iterator.RemoveCurrent(false);
|
||||
}
|
||||
else if(CurrentClient) {
|
||||
|
||||
PlayersInChannel++;
|
||||
|
||||
if(CurrentClient->IsAnnounceOn())
|
||||
if(!HideMe || (CurrentClient->GetAccountStatus() > AccountStatus))
|
||||
CurrentClient->AnnounceLeave(this, c);
|
||||
|
||||
iterator.Advance();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
if((PlayersInChannel == 0) && !Permanent) {
|
||||
|
||||
if((Password.length() == 0) || (RuleI(Channels, DeleteTimer) == 0))
|
||||
return false;
|
||||
|
||||
_log(UCS__TRACE, "Starting delete timer for empty password protected channel %s", Name.c_str());
|
||||
|
||||
DeleteTimer.Start(RuleI(Channels, DeleteTimer) * 60000);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void ChatChannel::SendOPList(Client *c) {
|
||||
|
||||
if(!c) return;
|
||||
|
||||
c->GeneralChannelMessage("Channel " + Name + " op-list: (Owner=" + Owner + ")");
|
||||
|
||||
list<string>::iterator Iterator;
|
||||
|
||||
for(Iterator = Moderators.begin(); Iterator != Moderators.end(); Iterator++)
|
||||
c->GeneralChannelMessage((*Iterator));
|
||||
|
||||
}
|
||||
|
||||
void ChatChannel::SendChannelMembers(Client *c) {
|
||||
|
||||
if(!c) return;
|
||||
|
||||
char CountString[10];
|
||||
|
||||
sprintf(CountString, "(%i)", MemberCount(c->GetAccountStatus()));
|
||||
|
||||
string Message = "Channel " + GetName();
|
||||
|
||||
Message += CountString;
|
||||
|
||||
Message += " members:";
|
||||
|
||||
c->GeneralChannelMessage(Message);
|
||||
|
||||
int AccountStatus = c->GetAccountStatus();
|
||||
|
||||
Message.clear();
|
||||
|
||||
int MembersInLine = 0;
|
||||
|
||||
LinkedListIterator<Client*> iterator(ClientsInChannel);
|
||||
|
||||
iterator.Reset();
|
||||
|
||||
while(iterator.MoreElements()) {
|
||||
|
||||
Client *ChannelClient = iterator.GetData();
|
||||
|
||||
// Don't list hidden characters with status higher or equal than the character requesting the list.
|
||||
//
|
||||
if(!ChannelClient || (ChannelClient->GetHideMe() && (ChannelClient->GetAccountStatus() >= AccountStatus))) {
|
||||
iterator.Advance();
|
||||
continue;
|
||||
}
|
||||
|
||||
if(MembersInLine > 0)
|
||||
Message += ", ";
|
||||
|
||||
Message += ChannelClient->GetName();
|
||||
|
||||
MembersInLine++;
|
||||
|
||||
if(MembersInLine == 6) {
|
||||
|
||||
c->GeneralChannelMessage(Message);
|
||||
|
||||
MembersInLine = 0;
|
||||
|
||||
Message.clear();
|
||||
}
|
||||
|
||||
iterator.Advance();
|
||||
}
|
||||
|
||||
if(MembersInLine > 0)
|
||||
c->GeneralChannelMessage(Message);
|
||||
|
||||
}
|
||||
|
||||
void ChatChannel::SendMessageToChannel(string Message, Client* Sender) {
|
||||
|
||||
if(!Sender) return;
|
||||
|
||||
ChatMessagesSent++;
|
||||
|
||||
LinkedListIterator<Client*> iterator(ClientsInChannel);
|
||||
|
||||
iterator.Reset();
|
||||
|
||||
while(iterator.MoreElements()) {
|
||||
|
||||
Client *ChannelClient = iterator.GetData();
|
||||
|
||||
if(ChannelClient)
|
||||
{
|
||||
_log(UCS__TRACE, "Sending message to %s from %s",
|
||||
ChannelClient->GetName().c_str(), Sender->GetName().c_str());
|
||||
ChannelClient->SendChannelMessage(Name, Message, Sender);
|
||||
}
|
||||
|
||||
iterator.Advance();
|
||||
}
|
||||
}
|
||||
|
||||
void ChatChannel::SetModerated(bool inModerated) {
|
||||
|
||||
Moderated = inModerated;
|
||||
|
||||
LinkedListIterator<Client*> iterator(ClientsInChannel);
|
||||
|
||||
iterator.Reset();
|
||||
|
||||
while(iterator.MoreElements()) {
|
||||
|
||||
Client *ChannelClient = iterator.GetData();
|
||||
|
||||
if(ChannelClient) {
|
||||
|
||||
if(Moderated)
|
||||
ChannelClient->GeneralChannelMessage("Channel " + Name + " is now moderated.");
|
||||
else
|
||||
ChannelClient->GeneralChannelMessage("Channel " + Name + " is no longer moderated.");
|
||||
}
|
||||
|
||||
iterator.Advance();
|
||||
}
|
||||
|
||||
}
|
||||
bool ChatChannel::IsClientInChannel(Client *c) {
|
||||
|
||||
if(!c) return false;
|
||||
|
||||
LinkedListIterator<Client*> iterator(ClientsInChannel);
|
||||
|
||||
iterator.Reset();
|
||||
|
||||
while(iterator.MoreElements()) {
|
||||
|
||||
if(iterator.GetData() == c)
|
||||
return true;
|
||||
|
||||
iterator.Advance();
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
ChatChannel *ChatChannelList::AddClientToChannel(string ChannelName, Client *c) {
|
||||
|
||||
if(!c) return NULL;
|
||||
|
||||
if((ChannelName.length() > 0) && (isdigit(ChannelName[0]))) {
|
||||
|
||||
c->GeneralChannelMessage("The channel name can not begin with a number.");
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
string NormalisedName, Password;
|
||||
|
||||
string::size_type Colon = ChannelName.find_first_of(":");
|
||||
|
||||
if(Colon == string::npos)
|
||||
NormalisedName = CapitaliseName(ChannelName);
|
||||
else {
|
||||
NormalisedName = CapitaliseName(ChannelName.substr(0, Colon));
|
||||
|
||||
Password = ChannelName.substr(Colon + 1);
|
||||
}
|
||||
|
||||
if((NormalisedName.length() > 64) || (Password.length() > 64)) {
|
||||
|
||||
c->GeneralChannelMessage("The channel name or password cannot exceed 64 characters.");
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
_log(UCS__TRACE, "AddClient to channel [%s] with password [%s]", NormalisedName.c_str(), Password.c_str());
|
||||
|
||||
ChatChannel *RequiredChannel = FindChannel(NormalisedName);
|
||||
|
||||
if(!RequiredChannel)
|
||||
RequiredChannel = CreateChannel(NormalisedName, c->GetName(), Password, false, 0);
|
||||
|
||||
if(RequiredChannel->GetMinStatus() > c->GetAccountStatus()) {
|
||||
|
||||
string Message = "You do not have the required account status to join channel " + NormalisedName;
|
||||
|
||||
c->GeneralChannelMessage(Message);
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if(RequiredChannel->IsClientInChannel(c))
|
||||
return NULL;
|
||||
|
||||
if(RequiredChannel->IsInvitee(c->GetName())) {
|
||||
|
||||
RequiredChannel->AddClient(c);
|
||||
|
||||
RequiredChannel->RemoveInvitee(c->GetName());
|
||||
|
||||
return RequiredChannel;
|
||||
}
|
||||
|
||||
if(RequiredChannel->CheckPassword(Password) || RequiredChannel->IsOwner(c->GetName()) || RequiredChannel->IsModerator(c->GetName()) ||
|
||||
c->IsChannelAdmin()) {
|
||||
|
||||
RequiredChannel->AddClient(c);
|
||||
|
||||
return RequiredChannel;
|
||||
}
|
||||
|
||||
c->GeneralChannelMessage("Incorrect password for channel " + (NormalisedName));
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
ChatChannel *ChatChannelList::RemoveClientFromChannel(string inChannelName, Client *c) {
|
||||
|
||||
if(!c) return NULL;
|
||||
|
||||
string ChannelName = inChannelName;
|
||||
|
||||
if((inChannelName.length() > 0) && isdigit(ChannelName[0]))
|
||||
ChannelName = c->ChannelSlotName(atoi(inChannelName.c_str()));
|
||||
|
||||
ChatChannel *RequiredChannel = FindChannel(ChannelName);
|
||||
|
||||
if(!RequiredChannel)
|
||||
return NULL;
|
||||
|
||||
// RemoveClient will return false if there is no-one left in the channel, and the channel is not permanent and has
|
||||
// no password.
|
||||
//
|
||||
if(!RequiredChannel->RemoveClient(c))
|
||||
RemoveChannel(RequiredChannel);
|
||||
|
||||
return RequiredChannel;
|
||||
}
|
||||
|
||||
void ChatChannelList::Process() {
|
||||
|
||||
LinkedListIterator<ChatChannel*> iterator(ChatChannels);
|
||||
|
||||
iterator.Reset();
|
||||
|
||||
while(iterator.MoreElements()) {
|
||||
|
||||
ChatChannel *CurrentChannel = iterator.GetData();
|
||||
|
||||
if(CurrentChannel && CurrentChannel->ReadyToDelete()) {
|
||||
|
||||
_log(UCS__TRACE, "Empty temporary password protected channel %s being destroyed.",
|
||||
CurrentChannel->GetName().c_str());
|
||||
|
||||
RemoveChannel(CurrentChannel);
|
||||
}
|
||||
|
||||
iterator.Advance();
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
void ChatChannel::AddInvitee(string Invitee) {
|
||||
|
||||
if(!IsInvitee(Invitee)) {
|
||||
|
||||
Invitees.push_back(Invitee);
|
||||
|
||||
_log(UCS__TRACE, "Added %s as invitee to channel %s", Invitee.c_str(), Name.c_str());
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void ChatChannel::RemoveInvitee(string Invitee) {
|
||||
|
||||
list<string>::iterator Iterator;
|
||||
|
||||
for(Iterator = Invitees.begin(); Iterator != Invitees.end(); Iterator++) {
|
||||
|
||||
if((*Iterator) == Invitee) {
|
||||
|
||||
Invitees.erase(Iterator);
|
||||
|
||||
_log(UCS__TRACE, "Removed %s as invitee to channel %s", Invitee.c_str(), Name.c_str());
|
||||
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool ChatChannel::IsInvitee(string Invitee) {
|
||||
|
||||
list<string>::iterator Iterator;
|
||||
|
||||
for(Iterator = Invitees.begin(); Iterator != Invitees.end(); Iterator++) {
|
||||
|
||||
if((*Iterator) == Invitee)
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
void ChatChannel::AddModerator(string Moderator) {
|
||||
|
||||
if(!IsModerator(Moderator)) {
|
||||
|
||||
Moderators.push_back(Moderator);
|
||||
|
||||
_log(UCS__TRACE, "Added %s as moderator to channel %s", Moderator.c_str(), Name.c_str());
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void ChatChannel::RemoveModerator(string Moderator) {
|
||||
|
||||
list<string>::iterator Iterator;
|
||||
|
||||
for(Iterator = Moderators.begin(); Iterator != Moderators.end(); Iterator++) {
|
||||
|
||||
if((*Iterator) == Moderator) {
|
||||
|
||||
Moderators.erase(Iterator);
|
||||
|
||||
_log(UCS__TRACE, "Removed %s as moderator to channel %s", Moderator.c_str(), Name.c_str());
|
||||
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool ChatChannel::IsModerator(string Moderator) {
|
||||
|
||||
list<string>::iterator Iterator;
|
||||
|
||||
for(Iterator = Moderators.begin(); Iterator != Moderators.end(); Iterator++) {
|
||||
|
||||
if((*Iterator) == Moderator)
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
void ChatChannel::AddVoice(string inVoiced) {
|
||||
|
||||
if(!HasVoice(inVoiced)) {
|
||||
|
||||
Voiced.push_back(inVoiced);
|
||||
|
||||
_log(UCS__TRACE, "Added %s as voiced to channel %s", inVoiced.c_str(), Name.c_str());
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void ChatChannel::RemoveVoice(string inVoiced) {
|
||||
|
||||
list<string>::iterator Iterator;
|
||||
|
||||
for(Iterator = Voiced.begin(); Iterator != Voiced.end(); Iterator++) {
|
||||
|
||||
if((*Iterator) == inVoiced) {
|
||||
|
||||
Voiced.erase(Iterator);
|
||||
|
||||
_log(UCS__TRACE, "Removed %s as voiced to channel %s", inVoiced.c_str(), Name.c_str());
|
||||
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool ChatChannel::HasVoice(string inVoiced) {
|
||||
|
||||
list<string>::iterator Iterator;
|
||||
|
||||
for(Iterator = Voiced.begin(); Iterator != Voiced.end(); Iterator++) {
|
||||
|
||||
if((*Iterator) == inVoiced)
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
string CapitaliseName(string inString) {
|
||||
|
||||
string NormalisedName = inString;
|
||||
|
||||
for(unsigned int i = 0; i < NormalisedName.length(); i++) {
|
||||
|
||||
if(i == 0)
|
||||
NormalisedName[i] = toupper(NormalisedName[i]);
|
||||
else
|
||||
NormalisedName[i] = tolower(NormalisedName[i]);
|
||||
}
|
||||
|
||||
return NormalisedName;
|
||||
}
|
||||
Reference in New Issue
Block a user