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
This commit is contained in:
@@ -0,0 +1,2 @@
|
|||||||
|
DELETE FROM `trinity_string` WHERE `entry` = 819;
|
||||||
|
INSERT INTO `trinity_string` (`entry`, `content_default`) VALUES (819, "City");
|
||||||
@@ -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)
|
: 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
|
// set special flags if built-in channel
|
||||||
ChatChannelsEntry const* ch = GetChannelEntryFor(channel_id);
|
if (ChatChannelsEntry const* ch = sChatChannelsStore.LookupEntry(channel_id)) // check whether it's a built-in channel
|
||||||
if (ch) // it's built-in channel
|
|
||||||
{
|
{
|
||||||
channel_id = ch->ChannelID; // built-in channel
|
|
||||||
m_announce = false; // no join/leave announces
|
m_announce = false; // no join/leave announces
|
||||||
|
|
||||||
m_flags |= CHANNEL_FLAG_GENERAL; // for all built-in channels
|
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
|
else // it's custom channel
|
||||||
{
|
{
|
||||||
|
channel_id = 0;
|
||||||
m_flags |= CHANNEL_FLAG_CUSTOM;
|
m_flags |= CHANNEL_FLAG_CUSTOM;
|
||||||
//load not built in channel if saved
|
//load not built in channel if saved
|
||||||
std::string _name(name);
|
std::string _name(name);
|
||||||
@@ -852,7 +851,7 @@ void Channel::MakeYouLeft(WorldPacket *data)
|
|||||||
{
|
{
|
||||||
MakeNotifyPacket(data, CHAT_YOU_LEFT_NOTICE);
|
MakeNotifyPacket(data, CHAT_YOU_LEFT_NOTICE);
|
||||||
*data << uint32(GetChannelId());
|
*data << uint32(GetChannelId());
|
||||||
*data << uint8(0); // can be 0x00 and 0x01
|
*data << uint8(IsConstant());
|
||||||
}
|
}
|
||||||
|
|
||||||
// done 0x04
|
// done 0x04
|
||||||
@@ -1090,6 +1089,10 @@ void Channel::JoinNotify(uint64 guid)
|
|||||||
data << uint8(GetFlags());
|
data << uint8(GetFlags());
|
||||||
data << uint32(GetNumPlayers());
|
data << uint32(GetNumPlayers());
|
||||||
data << GetName();
|
data << GetName();
|
||||||
|
|
||||||
|
if (IsConstant())
|
||||||
|
SendToAllButOne(&data, guid);
|
||||||
|
else
|
||||||
SendToAll(&data);
|
SendToAll(&data);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1100,6 +1103,10 @@ void Channel::LeaveNotify(uint64 guid)
|
|||||||
data << uint8(GetFlags());
|
data << uint8(GetFlags());
|
||||||
data << uint32(GetNumPlayers());
|
data << uint32(GetNumPlayers());
|
||||||
data << GetName();
|
data << GetName();
|
||||||
|
|
||||||
|
if (IsConstant())
|
||||||
|
SendToAllButOne(&data, guid);
|
||||||
|
else
|
||||||
SendToAll(&data);
|
SendToAll(&data);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -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)
|
bool IsTotemCategoryCompatiableWith(uint32 itemTotemCategoryId, uint32 requiredTotemCategoryId)
|
||||||
{
|
{
|
||||||
if (requiredTotemCategoryId == 0)
|
if (requiredTotemCategoryId == 0)
|
||||||
|
|||||||
@@ -49,8 +49,6 @@ enum ContentLevels
|
|||||||
};
|
};
|
||||||
ContentLevels GetContentLevelsForMapAndZone(uint32 mapid, uint32 zoneId);
|
ContentLevels GetContentLevelsForMapAndZone(uint32 mapid, uint32 zoneId);
|
||||||
|
|
||||||
ChatChannelsEntry const* GetChannelEntryFor(uint32 channel_id);
|
|
||||||
|
|
||||||
bool IsTotemCategoryCompatiableWith(uint32 itemTotemCategoryId, uint32 requiredTotemCategoryId);
|
bool IsTotemCategoryCompatiableWith(uint32 itemTotemCategoryId, uint32 requiredTotemCategoryId);
|
||||||
|
|
||||||
void Zone2MapCoordinates(float &x, float &y, uint32 zone);
|
void Zone2MapCoordinates(float &x, float &y, uint32 zone);
|
||||||
@@ -75,7 +73,7 @@ extern DBCStorage <AuctionHouseEntry> sAuctionHouseStore;
|
|||||||
extern DBCStorage <BankBagSlotPricesEntry> sBankBagSlotPricesStore;
|
extern DBCStorage <BankBagSlotPricesEntry> sBankBagSlotPricesStore;
|
||||||
extern DBCStorage <BarberShopStyleEntry> sBarberShopStyleStore;
|
extern DBCStorage <BarberShopStyleEntry> sBarberShopStyleStore;
|
||||||
extern DBCStorage <BattlemasterListEntry> sBattlemasterListStore;
|
extern DBCStorage <BattlemasterListEntry> sBattlemasterListStore;
|
||||||
//extern DBCStorage <ChatChannelsEntry> sChatChannelsStore; -- accessed using function, no usable index
|
extern DBCStorage <ChatChannelsEntry> sChatChannelsStore;
|
||||||
extern DBCStorage <CharStartOutfitEntry> sCharStartOutfitStore;
|
extern DBCStorage <CharStartOutfitEntry> sCharStartOutfitStore;
|
||||||
extern DBCStorage <CharTitlesEntry> sCharTitlesStore;
|
extern DBCStorage <CharTitlesEntry> sCharTitlesStore;
|
||||||
extern DBCStorage <ChrClassesEntry> sChrClassesStore;
|
extern DBCStorage <ChrClassesEntry> sChrClassesStore;
|
||||||
|
|||||||
@@ -31,7 +31,7 @@ const char BarberShopStyleEntryfmt[]="nixxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxiii";
|
|||||||
const char BattlemasterListEntryfmt[]="niiiiiiiiixssssssssssssssssxiixx";
|
const char BattlemasterListEntryfmt[]="niiiiiiiiixssssssssssssssssxiixx";
|
||||||
const char CharStartOutfitEntryfmt[]="diiiiiiiiiiiiiiiiiiiiiiiiixxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx";
|
const char CharStartOutfitEntryfmt[]="diiiiiiiiiiiiiiiiiiiiiiiiixxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx";
|
||||||
const char CharTitlesEntryfmt[]="nxssssssssssssssssxxxxxxxxxxxxxxxxxxi";
|
const char CharTitlesEntryfmt[]="nxssssssssssssssssxxxxxxxxxxxxxxxxxxi";
|
||||||
const char ChatChannelsEntryfmt[]="iixssssssssssssssssxxxxxxxxxxxxxxxxxx";
|
const char ChatChannelsEntryfmt[]="nixssssssssssssssssxxxxxxxxxxxxxxxxxx";
|
||||||
// ChatChannelsEntryfmt, index not used (more compact store)
|
// ChatChannelsEntryfmt, index not used (more compact store)
|
||||||
const char ChrClassesEntryfmt[]="nxixxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxixii";
|
const char ChrClassesEntryfmt[]="nxixxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxixii";
|
||||||
const char ChrRacesEntryfmt[]="nxixiixixxxxixssssssssssssssssxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxi";
|
const char ChrRacesEntryfmt[]="nxixiixixxxxixssssssssssssssssxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxi";
|
||||||
|
|||||||
@@ -5184,6 +5184,20 @@ void Player::RepopAtGraveyard()
|
|||||||
TeleportTo(m_homebindMapId, m_homebindX, m_homebindY, m_homebindZ, GetOrientation());
|
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)
|
void Player::JoinedChannel(Channel *c)
|
||||||
{
|
{
|
||||||
m_channels.push_back(c);
|
m_channels.push_back(c);
|
||||||
@@ -5210,8 +5224,8 @@ void Player::CleanupChannels()
|
|||||||
|
|
||||||
void Player::UpdateLocalChannels(uint32 newZone)
|
void Player::UpdateLocalChannels(uint32 newZone)
|
||||||
{
|
{
|
||||||
if (m_channels.empty())
|
if (GetSession()->PlayerLoading() && !IsBeingTeleportedFar())
|
||||||
return;
|
return; // The client handles it automatically after loading, but not after teleporting
|
||||||
|
|
||||||
AreaTableEntry const* current_zone = GetAreaEntryByAreaID(newZone);
|
AreaTableEntry const* current_zone = GetAreaEntryByAreaID(newZone);
|
||||||
if (!current_zone)
|
if (!current_zone)
|
||||||
@@ -5223,38 +5237,78 @@ void Player::UpdateLocalChannels(uint32 newZone)
|
|||||||
|
|
||||||
std::string current_zone_name = current_zone->area_name[GetSession()->GetSessionDbcLocale()];
|
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 ((channel->flags & CHANNEL_DBC_FLAG_GUILD_REQ) && GetGuildId())
|
||||||
if (!(*i)->IsConstant())
|
continue; // Should not join to these channels automatically
|
||||||
continue;
|
|
||||||
|
|
||||||
ChatChannelsEntry const* ch = GetChannelEntryFor((*i)->GetChannelId());
|
Channel* usedChannel = NULL;
|
||||||
if (!ch)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
if ((ch->flags & 4) == 4) // global channel without zone name in pattern
|
for (JoinedChannelsList::iterator itr = m_channels.begin(); itr != m_channels.end(); ++itr)
|
||||||
continue;
|
{
|
||||||
|
if ((*itr)->GetChannelId() == i)
|
||||||
|
{
|
||||||
|
usedChannel = *itr;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Channel* removeChannel = NULL;
|
||||||
|
Channel* joinChannel = NULL;
|
||||||
|
bool sendRemove = true;
|
||||||
|
|
||||||
|
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
|
||||||
|
|
||||||
// new channel
|
|
||||||
char new_channel_name_buf[100];
|
char new_channel_name_buf[100];
|
||||||
snprintf(new_channel_name_buf,100,ch->pattern[m_session->GetSessionDbcLocale()],current_zone_name.c_str());
|
char const* currentNameExt;
|
||||||
Channel* new_channel = cMgr->GetJoinChannel(new_channel_name_buf,ch->ChannelID);
|
|
||||||
|
|
||||||
if ((*i) != new_channel)
|
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)
|
||||||
{
|
{
|
||||||
new_channel->Join(GetGUID(),""); // will output Changed Channel: N. Name
|
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;
|
||||||
|
|
||||||
// leave old channel
|
if (joinChannel)
|
||||||
(*i)->Leave(GetGUID(),false); // not send leave channel, it already replaced at client
|
joinChannel->Join(GetGUID(), ""); // Changed Channel: ... or Joined Channel: ...
|
||||||
std::string name = (*i)->GetName(); // store name, (*i)erase in LeftChannel
|
|
||||||
LeftChannel(*i); // remove from player's channel list
|
if (removeChannel)
|
||||||
cMgr->LeftChannel(name); // delete if empty
|
{
|
||||||
|
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()
|
void Player::LeaveLFGChannel()
|
||||||
|
|||||||
@@ -1878,6 +1878,8 @@ class Player : public Unit, public GridObject<Player>
|
|||||||
|
|
||||||
void SetMovement(PlayerMovementType pType);
|
void SetMovement(PlayerMovementType pType);
|
||||||
|
|
||||||
|
bool CanJoinConstantChannelInZone(ChatChannelsEntry const* channel, AreaTableEntry const* zone);
|
||||||
|
|
||||||
void JoinedChannel(Channel *c);
|
void JoinedChannel(Channel *c);
|
||||||
void LeftChannel(Channel *c);
|
void LeftChannel(Channel *c);
|
||||||
void CleanupChannels();
|
void CleanupChannels();
|
||||||
|
|||||||
@@ -728,7 +728,9 @@ enum TrinityStrings
|
|||||||
|
|
||||||
LANG_COMMAND_CREATURETEMPLATE_NOTFOUND = 817,
|
LANG_COMMAND_CREATURETEMPLATE_NOTFOUND = 817,
|
||||||
LANG_COMMAND_CREATURESTORAGE_NOTFOUND = 818,
|
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)
|
// Level 4 (CLI only commands)
|
||||||
LANG_COMMAND_EXIT = 1000,
|
LANG_COMMAND_EXIT = 1000,
|
||||||
|
|||||||
@@ -27,7 +27,23 @@ void WorldSession::HandleJoinChannel(WorldPacket& recvPacket)
|
|||||||
uint8 unknown1, unknown2;
|
uint8 unknown1, unknown2;
|
||||||
std::string channelname, pass;
|
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;
|
recvPacket >> channelname;
|
||||||
|
|
||||||
if (channelname.empty())
|
if (channelname.empty())
|
||||||
|
|||||||
Reference in New Issue
Block a user