aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorlinencloth <none@none>2010-10-16 12:59:53 +0200
committerlinencloth <none@none>2010-10-16 12:59:53 +0200
commitae213dd5805f9541fe3520c0180aa7b3f323f77a (patch)
tree92ef12722020e20bdad8d4c6be3c68ebc6dafebf
parent3bd1ee0665f8c48bc256fcbe30f447c1fa40bec8 (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.sql2
-rwxr-xr-xsrc/server/game/Chat/Channels/Channel.cpp19
-rwxr-xr-xsrc/server/game/DataStores/DBCStores.cpp12
-rwxr-xr-xsrc/server/game/DataStores/DBCStores.h4
-rwxr-xr-xsrc/server/game/DataStores/DBCfmt.h2
-rwxr-xr-xsrc/server/game/Entities/Player/Player.cpp104
-rwxr-xr-xsrc/server/game/Entities/Player/Player.h2
-rwxr-xr-xsrc/server/game/Miscellaneous/Language.h4
-rwxr-xr-xsrc/server/game/Server/Protocol/Handlers/ChannelHandler.cpp18
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())