diff options
author | linencloth <none@none> | 2010-10-16 12:59:53 +0200 |
---|---|---|
committer | linencloth <none@none> | 2010-10-16 12:59:53 +0200 |
commit | ae213dd5805f9541fe3520c0180aa7b3f323f77a (patch) | |
tree | 92ef12722020e20bdad8d4c6be3c68ebc6dafebf | |
parent | 3bd1ee0665f8c48bc256fcbe30f447c1fa40bec8 (diff) |
Core: Improve constant channel handling
- Implement area restrictions
- Disable constant channels in arenas
- Implement city requirement
- Implement global constant channels
- Fix some packets
--HG--
branch : trunk
-rw-r--r-- | sql/updates/10228_world_trinity_string.sql | 2 | ||||
-rwxr-xr-x | src/server/game/Chat/Channels/Channel.cpp | 19 | ||||
-rwxr-xr-x | src/server/game/DataStores/DBCStores.cpp | 12 | ||||
-rwxr-xr-x | src/server/game/DataStores/DBCStores.h | 4 | ||||
-rwxr-xr-x | src/server/game/DataStores/DBCfmt.h | 2 | ||||
-rwxr-xr-x | src/server/game/Entities/Player/Player.cpp | 104 | ||||
-rwxr-xr-x | src/server/game/Entities/Player/Player.h | 2 | ||||
-rwxr-xr-x | src/server/game/Miscellaneous/Language.h | 4 | ||||
-rwxr-xr-x | src/server/game/Server/Protocol/Handlers/ChannelHandler.cpp | 18 |
9 files changed, 118 insertions, 49 deletions
diff --git a/sql/updates/10228_world_trinity_string.sql b/sql/updates/10228_world_trinity_string.sql new file mode 100644 index 00000000000..b62a667d3bf --- /dev/null +++ b/sql/updates/10228_world_trinity_string.sql @@ -0,0 +1,2 @@ +DELETE FROM `trinity_string` WHERE `entry` = 819; +INSERT INTO `trinity_string` (`entry`, `content_default`) VALUES (819, "City"); diff --git a/src/server/game/Chat/Channels/Channel.cpp b/src/server/game/Chat/Channels/Channel.cpp index a39db43e55f..169ea0269e1 100755 --- a/src/server/game/Chat/Channels/Channel.cpp +++ b/src/server/game/Chat/Channels/Channel.cpp @@ -26,10 +26,8 @@ Channel::Channel(const std::string& name, uint32 channel_id, uint32 Team) : m_announce(true), m_moderate(false), m_name(name), m_password(""), m_flags(0), m_channelId(channel_id), m_ownerGUID(0), m_Team(Team) { // set special flags if built-in channel - ChatChannelsEntry const* ch = GetChannelEntryFor(channel_id); - if (ch) // it's built-in channel + if (ChatChannelsEntry const* ch = sChatChannelsStore.LookupEntry(channel_id)) // check whether it's a built-in channel { - channel_id = ch->ChannelID; // built-in channel m_announce = false; // no join/leave announces m_flags |= CHANNEL_FLAG_GENERAL; // for all built-in channels @@ -48,6 +46,7 @@ Channel::Channel(const std::string& name, uint32 channel_id, uint32 Team) } else // it's custom channel { + channel_id = 0; m_flags |= CHANNEL_FLAG_CUSTOM; //load not built in channel if saved std::string _name(name); @@ -852,7 +851,7 @@ void Channel::MakeYouLeft(WorldPacket *data) { MakeNotifyPacket(data, CHAT_YOU_LEFT_NOTICE); *data << uint32(GetChannelId()); - *data << uint8(0); // can be 0x00 and 0x01 + *data << uint8(IsConstant()); } // done 0x04 @@ -1090,7 +1089,11 @@ void Channel::JoinNotify(uint64 guid) data << uint8(GetFlags()); data << uint32(GetNumPlayers()); data << GetName(); - SendToAll(&data); + + if (IsConstant()) + SendToAllButOne(&data, guid); + else + SendToAll(&data); } void Channel::LeaveNotify(uint64 guid) @@ -1100,6 +1103,10 @@ void Channel::LeaveNotify(uint64 guid) data << uint8(GetFlags()); data << uint32(GetNumPlayers()); data << GetName(); - SendToAll(&data); + + if (IsConstant()) + SendToAllButOne(&data, guid); + else + SendToAll(&data); } diff --git a/src/server/game/DataStores/DBCStores.cpp b/src/server/game/DataStores/DBCStores.cpp index 5b281946af8..490f9b1b18a 100755 --- a/src/server/game/DataStores/DBCStores.cpp +++ b/src/server/game/DataStores/DBCStores.cpp @@ -729,18 +729,6 @@ ContentLevels GetContentLevelsForMapAndZone(uint32 mapid, uint32 zoneId) } } -ChatChannelsEntry const* GetChannelEntryFor(uint32 channel_id) -{ - // not sorted, numbering index from 0 - for (uint32 i = 0; i < sChatChannelsStore.GetNumRows(); ++i) - { - ChatChannelsEntry const* ch = sChatChannelsStore.LookupEntry(i); - if (ch && ch->ChannelID == channel_id) - return ch; - } - return NULL; -} - bool IsTotemCategoryCompatiableWith(uint32 itemTotemCategoryId, uint32 requiredTotemCategoryId) { if (requiredTotemCategoryId == 0) diff --git a/src/server/game/DataStores/DBCStores.h b/src/server/game/DataStores/DBCStores.h index 62a45fa65d2..ef6c22f626f 100755 --- a/src/server/game/DataStores/DBCStores.h +++ b/src/server/game/DataStores/DBCStores.h @@ -49,8 +49,6 @@ enum ContentLevels }; ContentLevels GetContentLevelsForMapAndZone(uint32 mapid, uint32 zoneId); -ChatChannelsEntry const* GetChannelEntryFor(uint32 channel_id); - bool IsTotemCategoryCompatiableWith(uint32 itemTotemCategoryId, uint32 requiredTotemCategoryId); void Zone2MapCoordinates(float &x, float &y, uint32 zone); @@ -75,7 +73,7 @@ extern DBCStorage <AuctionHouseEntry> sAuctionHouseStore; extern DBCStorage <BankBagSlotPricesEntry> sBankBagSlotPricesStore; extern DBCStorage <BarberShopStyleEntry> sBarberShopStyleStore; extern DBCStorage <BattlemasterListEntry> sBattlemasterListStore; -//extern DBCStorage <ChatChannelsEntry> sChatChannelsStore; -- accessed using function, no usable index +extern DBCStorage <ChatChannelsEntry> sChatChannelsStore; extern DBCStorage <CharStartOutfitEntry> sCharStartOutfitStore; extern DBCStorage <CharTitlesEntry> sCharTitlesStore; extern DBCStorage <ChrClassesEntry> sChrClassesStore; diff --git a/src/server/game/DataStores/DBCfmt.h b/src/server/game/DataStores/DBCfmt.h index 2089f7daa6b..cea1c2d9a7a 100755 --- a/src/server/game/DataStores/DBCfmt.h +++ b/src/server/game/DataStores/DBCfmt.h @@ -31,7 +31,7 @@ const char BarberShopStyleEntryfmt[]="nixxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxiii"; const char BattlemasterListEntryfmt[]="niiiiiiiiixssssssssssssssssxiixx"; const char CharStartOutfitEntryfmt[]="diiiiiiiiiiiiiiiiiiiiiiiiixxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"; const char CharTitlesEntryfmt[]="nxssssssssssssssssxxxxxxxxxxxxxxxxxxi"; -const char ChatChannelsEntryfmt[]="iixssssssssssssssssxxxxxxxxxxxxxxxxxx"; +const char ChatChannelsEntryfmt[]="nixssssssssssssssssxxxxxxxxxxxxxxxxxx"; // ChatChannelsEntryfmt, index not used (more compact store) const char ChrClassesEntryfmt[]="nxixxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxixii"; const char ChrRacesEntryfmt[]="nxixiixixxxxixssssssssssssssssxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxi"; diff --git a/src/server/game/Entities/Player/Player.cpp b/src/server/game/Entities/Player/Player.cpp index 1fc46ca92b2..61fc00b465c 100755 --- a/src/server/game/Entities/Player/Player.cpp +++ b/src/server/game/Entities/Player/Player.cpp @@ -5184,6 +5184,20 @@ void Player::RepopAtGraveyard() TeleportTo(m_homebindMapId, m_homebindX, m_homebindY, m_homebindZ, GetOrientation()); } +bool Player::CanJoinConstantChannelInZone(ChatChannelsEntry const* channel, AreaTableEntry const* zone) +{ + if (channel->flags & CHANNEL_DBC_FLAG_ZONE_DEP) + { + if (zone->flags & AREA_FLAG_ARENA_INSTANCE) + return false; + + if ((channel->flags & CHANNEL_DBC_FLAG_CITY_ONLY) && !(zone->flags & AREA_FLAG_CAPITAL)) + return false; + } + + return true; +} + void Player::JoinedChannel(Channel *c) { m_channels.push_back(c); @@ -5210,8 +5224,8 @@ void Player::CleanupChannels() void Player::UpdateLocalChannels(uint32 newZone) { - if (m_channels.empty()) - return; + if (GetSession()->PlayerLoading() && !IsBeingTeleportedFar()) + return; // The client handles it automatically after loading, but not after teleporting AreaTableEntry const* current_zone = GetAreaEntryByAreaID(newZone); if (!current_zone) @@ -5223,38 +5237,78 @@ void Player::UpdateLocalChannels(uint32 newZone) std::string current_zone_name = current_zone->area_name[GetSession()->GetSessionDbcLocale()]; - for (JoinedChannelsList::iterator i = m_channels.begin(), next; i != m_channels.end(); i = next) + for (uint32 i = 0; i < sChatChannelsStore.GetNumRows(); ++i) { - next = i; ++next; + if (ChatChannelsEntry const* channel = sChatChannelsStore.LookupEntry(i)) + { + if (!(channel->flags & CHANNEL_DBC_FLAG_ZONE_DEP)) + continue; // Not zone dependent, don't handle it here - // skip non built-in channels - if (!(*i)->IsConstant()) - continue; + if ((channel->flags & CHANNEL_DBC_FLAG_GUILD_REQ) && GetGuildId()) + continue; // Should not join to these channels automatically - ChatChannelsEntry const* ch = GetChannelEntryFor((*i)->GetChannelId()); - if (!ch) - continue; + Channel* usedChannel = NULL; - if ((ch->flags & 4) == 4) // global channel without zone name in pattern - continue; + for (JoinedChannelsList::iterator itr = m_channels.begin(); itr != m_channels.end(); ++itr) + { + if ((*itr)->GetChannelId() == i) + { + usedChannel = *itr; + break; + } + } - // new channel - char new_channel_name_buf[100]; - snprintf(new_channel_name_buf,100,ch->pattern[m_session->GetSessionDbcLocale()],current_zone_name.c_str()); - Channel* new_channel = cMgr->GetJoinChannel(new_channel_name_buf,ch->ChannelID); + Channel* removeChannel = NULL; + Channel* joinChannel = NULL; + bool sendRemove = true; - if ((*i) != new_channel) - { - new_channel->Join(GetGUID(),""); // will output Changed Channel: N. Name + if (CanJoinConstantChannelInZone(channel, current_zone)) + { + if (!(channel->flags & CHANNEL_DBC_FLAG_GLOBAL)) + { + if (channel->flags & CHANNEL_DBC_FLAG_CITY_ONLY && usedChannel) + continue; // Already on the channel, as city channel names are not changing + + char new_channel_name_buf[100]; + char const* currentNameExt; + + if (channel->flags & CHANNEL_DBC_FLAG_CITY_ONLY) + currentNameExt = sObjectMgr.GetTrinityStringForDBCLocale(LANG_CHANNEL_CITY); + else + currentNameExt = current_zone_name.c_str(); + + snprintf(new_channel_name_buf, 100, channel->pattern[m_session->GetSessionDbcLocale()], currentNameExt); + + joinChannel = cMgr->GetJoinChannel(new_channel_name_buf, channel->ChannelID); + if (usedChannel) + { + if (joinChannel != usedChannel) + { + removeChannel = usedChannel; + sendRemove = false; // Do not send leave channel, it already replaced at client + } + else + joinChannel = NULL; + } + } + else + joinChannel = cMgr->GetJoinChannel(channel->pattern[m_session->GetSessionDbcLocale()], channel->ChannelID); + } + else + removeChannel = usedChannel; + + if (joinChannel) + joinChannel->Join(GetGUID(), ""); // Changed Channel: ... or Joined Channel: ... - // leave old channel - (*i)->Leave(GetGUID(),false); // not send leave channel, it already replaced at client - std::string name = (*i)->GetName(); // store name, (*i)erase in LeftChannel - LeftChannel(*i); // remove from player's channel list - cMgr->LeftChannel(name); // delete if empty + if (removeChannel) + { + removeChannel->Leave(GetGUID(), sendRemove); // Leave old channel + std::string name = removeChannel->GetName(); // Store name, (*i)erase in LeftChannel + LeftChannel(removeChannel); // Remove from player's channel list + cMgr->LeftChannel(name); // Delete if empty + } } } - sLog.outDebug("Player: channels cleaned up!"); } void Player::LeaveLFGChannel() diff --git a/src/server/game/Entities/Player/Player.h b/src/server/game/Entities/Player/Player.h index eb8dc18eb56..4fa1ac08c98 100755 --- a/src/server/game/Entities/Player/Player.h +++ b/src/server/game/Entities/Player/Player.h @@ -1878,6 +1878,8 @@ class Player : public Unit, public GridObject<Player> void SetMovement(PlayerMovementType pType); + bool CanJoinConstantChannelInZone(ChatChannelsEntry const* channel, AreaTableEntry const* zone); + void JoinedChannel(Channel *c); void LeftChannel(Channel *c); void CleanupChannels(); diff --git a/src/server/game/Miscellaneous/Language.h b/src/server/game/Miscellaneous/Language.h index 396b6f77db9..876cef6cfbd 100755 --- a/src/server/game/Miscellaneous/Language.h +++ b/src/server/game/Miscellaneous/Language.h @@ -728,7 +728,9 @@ enum TrinityStrings LANG_COMMAND_CREATURETEMPLATE_NOTFOUND = 817, LANG_COMMAND_CREATURESTORAGE_NOTFOUND = 818, - // Room for in-game strings 819-999 not used + + LANG_CHANNEL_CITY = 819, + // Room for in-game strings 820-999 not used // Level 4 (CLI only commands) LANG_COMMAND_EXIT = 1000, diff --git a/src/server/game/Server/Protocol/Handlers/ChannelHandler.cpp b/src/server/game/Server/Protocol/Handlers/ChannelHandler.cpp index fbff42c3f8d..2a56dc31e74 100755 --- a/src/server/game/Server/Protocol/Handlers/ChannelHandler.cpp +++ b/src/server/game/Server/Protocol/Handlers/ChannelHandler.cpp @@ -27,7 +27,23 @@ void WorldSession::HandleJoinChannel(WorldPacket& recvPacket) uint8 unknown1, unknown2; std::string channelname, pass; - recvPacket >> channel_id >> unknown1 >> unknown2; + recvPacket >> channel_id; + + if (channel_id) + { + ChatChannelsEntry const* channel = sChatChannelsStore.LookupEntry(channel_id); + if (!channel) + return; + + AreaTableEntry const* current_zone = GetAreaEntryByAreaID(_player->GetZoneId()); + if (!current_zone) + return; + + if (!_player->CanJoinConstantChannelInZone(channel, current_zone)) + return; + } + + recvPacket >> unknown1 >> unknown2; recvPacket >> channelname; if (channelname.empty()) |