/* * Ascent MMORPG Server * Copyright (C) 2005-2007 Ascent Team * * 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 * 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 . * */ #include "StdAfx.h" bool Channel::Join(Player *p, const char *pass) { m_Lock.Acquire(); bool ret = false; WorldPacket data(100); if(IsOn(p)) { MakeAlreadyOn(&data,p); SendToOne(&data,p); } else if(IsBanned(p->GetGUID())) { MakeYouAreBanned(&data); SendToOne(&data,p); } else if((password.length() > 0 && strcmp(pass,password.c_str())) || (strcmp(name.c_str(), sWorld.getGmClientChannel().c_str()) == 0 && !p->GetSession()->CanUseCommand('c'))) { MakeWrongPass(&data); SendToOne(&data,p); } else { PlayerInfo pinfo; pinfo.player = p; pinfo.muted = false; if(GetNumPlayers() == 0) pinfo.owner = true; else pinfo.owner = false; pinfo.moderator = false; MakeJoined(&data,p); p->JoinedChannel(this); if(announce && !m_DefaultChannel) SendToAll(&data); data.clear(); players[p] = pinfo; /*MakeYouJoined(&data,p); SendToOne(&data,p);*/ if(owner == NULL) { if(!IsDefaultChannel()) { SetOwner(p); players[p].moderator = false; } else if(p->GetSession()->CanUseCommand('c')) { SetOwner(p); players[p].moderator = true; } } ret = true; } m_Lock.Release(); return ret; } void Channel::Leave(Player *p, bool send) { m_Lock.Acquire(); WorldPacket data(100); if(!IsOn(p)) { MakeNotOn(&data); if(send) SendToOne(&data,p); } else { bool changeowner = (owner == p); //MakeYouLeft(&data); if(send) { //SendToOne(&data,p); p->LeftChannel(this); } //data.clear(); players.erase(p); MakeLeft(&data,p); if(announce && !m_DefaultChannel) SendToAll(&data); if(changeowner) { Player *newowner = players.size() > 0 ? players.begin()->second.player : NULL; SetOwner(newowner); } } m_Lock.Release(); } void Channel::KickOrBan(Player *good, const char *badname, bool ban) { m_Lock.Acquire(); WorldPacket data(100); if(!IsOn(good)) { MakeNotOn(&data); SendToOne(&data,good); } else if(!players[good].moderator && !good->GetSession()->CanUseCommand('c')) { MakeNotModerator(&data); SendToOne(&data,good); } else { Player *bad = objmgr.GetPlayer(badname); if(bad == NULL || !IsOn(bad)) { MakeNotOn(&data,badname); SendToOne(&data,good); } else if(!good->GetSession()->CanUseCommand('c') && bad == owner && good != owner) { MakeNotOwner(&data); SendToOne(&data,good); } else { bool changeowner = (owner == bad); if(ban && !IsBanned(bad->GetGUID())) { banned.push_back(bad->GetGUID()); MakeBanned(&data,good,bad); } else MakeKicked(&data,good,bad); SendToAll(&data); players.erase(bad); if(changeowner) { Player *newowner = players.size() > 0 ? good : NULL; SetOwner(newowner); } } } m_Lock.Release(); } void Channel::UnBan(Player *good, const char *badname) { m_Lock.Acquire(); WorldPacket data(100); if(!IsOn(good)) { MakeNotOn(&data); SendToOne(&data,good); } else if(!players[good].moderator && !good->GetSession()->CanUseCommand('c')) { MakeNotModerator(&data); SendToOne(&data,good); } else { Player *bad = objmgr.GetPlayer(badname); if(bad == NULL || !IsBanned(bad->GetGUID())) { MakeNotOn(&data,badname); // Change to message. Not sure what it is. SendToOne(&data,good); } else { banned.remove(bad->GetGUID()); MakeUnbanned(&data,good,bad); SendToAll(&data); } } m_Lock.Release(); } void Channel::Password(Player *p, const char *pass) { m_Lock.Acquire(); WorldPacket data(100); if(!IsOn(p)) { MakeNotOn(&data); SendToOne(&data,p); } else if(!players[p].moderator && !p->GetSession()->CanUseCommand('c')) { MakeNotModerator(&data); SendToOne(&data,p); } else { password = pass; MakeSetPassword(&data,p); SendToAll(&data); } m_Lock.Release(); } void Channel::SetMode(Player *p, const char *p2n, bool mod, bool set) { m_Lock.Acquire(); WorldPacket data(100); if(!IsOn(p)) { MakeNotOn(&data); SendToOne(&data,p); } else if(!players[p].moderator && !p->GetSession()->CanUseCommand('c')) { MakeNotModerator(&data); SendToOne(&data,p); } else { Player *newp = objmgr.GetPlayer(p2n); // PlayerInfo inf = players[newp]; if(p == owner && newp == owner && mod) { m_Lock.Release(); return; } if(newp == NULL || !IsOn(newp)) { MakeNotOn(&data,p2n); SendToOne(&data,p); } else if(owner == newp && owner != p) { MakeNotOwner(&data); SendToOne(&data,p); } else { if(mod) SetModerator(newp,set); else SetMute(newp,set); } } m_Lock.Release(); } void Channel::SetOwner(Player *p, const char *newname) { m_Lock.Acquire(); WorldPacket data(100); if(!IsOn(p)) { MakeNotOn(&data); SendToOne(&data,p); } else if(!p->GetSession()->CanUseCommand('c') && p != owner) { MakeNotOwner(&data); SendToOne(&data,p); } else { Player *newp = objmgr.GetPlayer(newname); if(newp == NULL || !IsOn(newp)) { MakeNotOn(&data,newname); SendToOne(&data,p); } else { MakeChangeOwner(&data,newp); if(!m_DefaultChannel) SendToAll(&data); SetModerator(newp,true); owner = newp; } } m_Lock.Release(); } void Channel::GetOwner(Player *p) { WorldPacket data(100); if(!IsOn(p)) { MakeNotOn(&data); SendToOne(&data,p); } else { MakeWhoOwner(&data); SendToOne(&data,p); } } void Channel::List(Player *p) { m_Lock.Acquire(); WorldPacket data(100); if(!IsOn(p)) { MakeNotOn(&data); SendToOne(&data,p); } else { data.Initialize(SMSG_CHANNEL_LIST); data << (uint8)3 << (uint32)players.size(); PlayerList::iterator i; for(i = players.begin(); i!=players.end(); i++) { data << i->first->GetGUID(); uint8 mode = 0x00; if(i->second.muted) mode |= 0x04; if(i->second.moderator) mode |= 0x02; data << mode; } SendToOne(&data,p); } m_Lock.Release(); } void Channel::Announce(Player *p) { WorldPacket data(100); if(!IsOn(p)) { MakeNotOn(&data); SendToOne(&data,p); } else if(!players[p].moderator && !p->GetSession()->CanUseCommand('c')) { MakeNotModerator(&data); SendToOne(&data,p); } else { announce = !announce; MakeAnnounce(&data,p,announce); SendToAll(&data); } } void Channel::Moderate(Player *p) { WorldPacket data(100); if(!IsOn(p)) { MakeNotOn(&data); SendToOne(&data,p); } else if(!players[p].moderator && !p->GetSession()->CanUseCommand('c')) { MakeNotModerator(&data); SendToOne(&data,p); } else { moderate = !moderate; MakeModerate(&data,p,moderate); SendToAll(&data); } } void Channel::Say(Player *p, const char *what, Player *t) { if(!IsOn(p)) { WorldPacket data(15); MakeNotOn(&data); SendToOne(&data,p); } else if(players[p].muted || (GetName() == "WorldDefense" && p->GetPVPRank() < 11)) { WorldPacket data(15); MakeYouCantSpeak(&data); SendToOne(&data,p); } else if(moderate && !players[p].moderator && !p->GetSession()->CanUseCommand('c')) { WorldPacket data(15); MakeNotModerator(&data); SendToOne(&data,p); } else { //Packet structure //uint8 type; //uint32 language; //uint32 PVP rank //uint64 guid; //uint32 len_of_text; //char text[]; //uint8 afk_state; uint32 messageLength = strlen((char*)what) + 1; WorldPacket data(40 + messageLength); data.Initialize(SMSG_MESSAGECHAT); data << (uint8)CHAT_MSG_CHANNEL; // CHAT_MESSAGE_CHANNEL data << (uint32)0; // Universal lang data << p->GetGUID(); data << uint32(0); // pvp rank?? data << name; data << p->GetGUID(); data << messageLength; data << what; data << (uint8)(p->bGMTagOn ? 4 : 0); if(t == NULL) SendToAll(&data); else SendToOne(&data, t); // Send the actual talking stuff. } } void Channel::SayFromIRC(const char* msg) { //Packet structure //uint8 type; //uint32 language; //uint32 PVP rank //uint64 guid; //uint32 len_of_text; //char text[]; //uint8 afk_state; uint32 messageLength = strlen((char*)msg) + 1; WorldPacket data(messageLength + 40); // uint8 afk = 0; data.Initialize(SMSG_MESSAGECHAT); data << (uint8)CHAT_MSG_CHANNEL; // CHAT_MESSAGE_CHANNEL data << (uint32)0; // Universal lang data << name.c_str(); data << (uint32)0; // pvp ranks data << (uint64)0; // was.. guid.. data << messageLength; data << msg; data << (uint8)0; SendToAll(&data); } void Channel::Invite(Player *p, const char *newname) { WorldPacket data(100); if(!IsOn(p)) { MakeNotOn(&data); SendToOne(&data,p); } else { Player *newp = objmgr.GetPlayer(newname); if(newp == NULL) { MakeNotOn(&data,newname); SendToOne(&data,p); } else if(IsOn(newp)) { MakeAlreadyOn(&data,newp); SendToOne(&data,p); } else { MakeInvited(&data,p); SendToOne(&data,newp); data.clear(); MakeYouInvited(&data,newp); SendToOne(&data,p); } } } bool Channel::IsDefaultChannel() { const char* cName = name.c_str(); if( !memcmp (cName, "General", 7) ) return true; if( !memcmp(cName, "LookingForGroup", 15) ) return true; if( !strncmp(cName, "LocalDefense", 12) ) return true; if( !strncmp(cName, "Trade", 5) ) return true; if( !strncmp(cName, "Guild Recruitment", 17) ) return true; if( !strncmp(cName, "WorldDefense", 12) ) return true; return false; } ChannelMgr::~ChannelMgr() { for(int i = 0; i < 2; ++i) { ChannelList::iterator itr = this->Channels[i].begin(); for(; itr != this->Channels[i].end(); ++itr) { delete itr->second; } Channels[i].clear(); } }