diff --git a/src/Client/World/Channel.cpp b/src/Client/World/Channel.cpp index 39b55a4..4130f6a 100644 --- a/src/Client/World/Channel.cpp +++ b/src/Client/World/Channel.cpp @@ -3,6 +3,53 @@ #include #include "Channel.h" +enum NotifyTypes +{ + JOINED = 0x00, + LEFT = 0x01, + YOUJOINED = 0x02, + YOULEFT = 0x03, + WRONGPASS = 0x04, + NOTON1 = 0x05, // Not on channel channel name. + NOTMOD = 0x06, + SETPASS = 0x07, + CHANGEOWNER = 0x08, + NOTON2 = 0x09, // Player %s is not on channel. + NOTOWNER = 0x0A, + WHOOWNER = 0x0B, + MODECHANGE = 0x0C, + ANNOUNCEON = 0x0D, + ANNOUNCEOFF = 0x0E, + MODERATED = 0x0F, + UNMODERATED = 0x10, + YOUCANTSPEAK = 0x11, + KICKED = 0x12, + YOUAREBANNED = 0x13, + BANNED = 0x14, + UNBANNED = 0x15, + UNKNOWN1 = 0x16, // is not banned + ALREADYON = 0x17, + INVITED = 0x18, + WRONGALLIANCE = 0x19, // target is in the wrong alliance for channel name + UNKNOWN2 = 0x1A, // wrong alliance for channel name + UNKNOWN3 = 0x1B, // invalid channel name + ISNOTMODERATED = 0x1C, + YOUINVITED = 0x1D, + UNKNOWN4 = 0x1E, // %s has been banned. + UNKNOWN5 = 0x1F, // The number of messages that can be sent to this channel is limited, please wait to send another message. + UNKNOWN6 = 0x20 // You are in not the correct area for this channel. +}; + +enum PlayerChannelModes +{ + // 0x01 = ?? + MODERATOR = 0x02, + MUTED = 0x04 +}; + +typedef std::map ChannelPlayerList; + + void Channel::Join(std::string channel, std::string password) { if (IsOnChannel(channel)) @@ -11,6 +58,7 @@ void Channel::Join(std::string channel, std::string password) // Send join channel request WorldPacket worldPacket; worldPacket.SetOpcode(CMSG_JOIN_CHANNEL); + worldPacket << (uint32)0 << (uint8)0; // new since 2.0.x // uint32: some channel ID? server answers us with that number later if channel joined worldPacket << channel << password; _worldSession->SendWorldPacket(worldPacket); } @@ -24,6 +72,7 @@ void Channel::Leave(std::string channel) // Send leave channel request WorldPacket worldPacket; worldPacket.SetOpcode(CMSG_LEAVE_CHANNEL); + worldPacket << (uint32)0; // new since 2.0.x worldPacket << channel; _worldSession->SendWorldPacket(worldPacket); return; @@ -127,3 +176,54 @@ void Channel::HandleNotifyOpcode(WorldPacket &packet) printf("\n"); */ } + +void Channel::RequestList(std::string ch) +{ + if(!IsOnChannel(ch)) + logdebug("Requesting list of not joined channel '%s'",ch.c_str()); + WorldPacket wp; + wp.SetOpcode(CMSG_CHANNEL_LIST); + wp << ch; + _worldSession->SendWorldPacket(wp); +} + +void Channel::HandleListRequest(WorldPacket& recvPacket) +{ + ChannelPlayerList cpl; + uint8 unk; + uint32 size; + uint64 guid; + uint8 mode; + recvPacket >> unk >> size; + for(uint32 i = 0; i < size; i++) + { + recvPacket >> guid >> mode; + cpl[guid] = mode; + } + + // now we could do something with that list, but for now, only request names of unknown players + std::string pname; + bool muted,mod; + log("Player channel list, %u players:",size); + for(ChannelPlayerList::iterator i = cpl.begin(); i != cpl.end(); i++) + { + pname = _worldSession->plrNameCache.GetName(i->first); + mode = i->second; + if(pname.empty()) + { + pname=""; + _worldSession->SendQueryPlayerName(i->first); + } + muted = mode & MUTED; + mod = mode & MODERATOR; + + while(pname.length()<12) + pname += " "; // for better formatting + + log("%s ["I64FMT"] %s %s",pname.c_str(),i->first,muted?"(muted)":"",mod?"(moderator)":""); + } +} + + + + diff --git a/src/Client/World/Channel.h b/src/Client/World/Channel.h index 6f734da..39f35fc 100644 --- a/src/Client/World/Channel.h +++ b/src/Client/World/Channel.h @@ -19,6 +19,8 @@ public: void Say(std::string channel, std::string text, uint32 lang); bool IsOnChannel(std::string channel); void HandleNotifyOpcode(WorldPacket &packet); + void HandleListRequest(WorldPacket &packet); + void RequestList(std::string); // TODO: Add Kick/Ban/Mode/Owner/Mute/Invite and all that stuff diff --git a/src/Client/World/WorldSession.cpp b/src/Client/World/WorldSession.cpp index cd808a1..09f355b 100644 --- a/src/Client/World/WorldSession.cpp +++ b/src/Client/World/WorldSession.cpp @@ -199,6 +199,7 @@ OpcodeHandler *WorldSession::_GetOpcodeHandlerTable() const {SMSG_INITIAL_SPELLS, &WorldSession::_HandleInitialSpellsOpcode}, {SMSG_LEARNED_SPELL, &WorldSession::_HandleLearnedSpellOpcode}, {SMSG_REMOVED_SPELL, &WorldSession::_HandleLearnedSpellOpcode}, + {SMSG_CHANNEL_LIST, &WorldSession::_HandleChannelListOpcode}, // table termination { 0, NULL } @@ -426,7 +427,6 @@ void WorldSession::_HandleMessageChatOpcode(WorldPacket& recvPacket) if (type == CHAT_MSG_CHANNEL) { recvPacket >> channel; // extract channel name - recvPacket >> unk; } recvPacket >> target_guid; @@ -695,3 +695,8 @@ void WorldSession::_HandleRemovedSpellOpcode(WorldPacket& recvPacket) logdebug("Unlearned spell: id=%u",spellid); } +void WorldSession::_HandleChannelListOpcode(WorldPacket& recvPacket) +{ + _channels->HandleListRequest(recvPacket); +} + diff --git a/src/Client/World/WorldSession.h b/src/Client/World/WorldSession.h index 8de886b..e911cf3 100644 --- a/src/Client/World/WorldSession.h +++ b/src/Client/World/WorldSession.h @@ -95,6 +95,7 @@ private: void _HandleInitialSpellsOpcode(WorldPacket& recvPacket); void _HandleLearnedSpellOpcode(WorldPacket& recvPacket); void _HandleRemovedSpellOpcode(WorldPacket& recvPacket); + void _HandleChannelListOpcode(WorldPacket& recvPacket); void _MovementUpdate(uint8 objtypeid, uint64 guid, WorldPacket& recvPacket); // Helper for _HandleUpdateObjectOpcode void _ValuesUpdate(uint64 uguid, WorldPacket& recvPacket); // ...