Core/Groups: Implemented 10.1.7 ping system

This commit is contained in:
Shauren
2023-09-14 00:11:06 +02:00
parent 097b5f3ec0
commit c2f5ce2b03
9 changed files with 293 additions and 15 deletions

View File

@@ -2286,7 +2286,7 @@ CREATE TABLE `groups` (
`icon6` binary(16) NOT NULL,
`icon7` binary(16) NOT NULL,
`icon8` binary(16) NOT NULL,
`groupType` tinyint unsigned NOT NULL,
`groupType` smallint unsigned NOT NULL,
`difficulty` tinyint unsigned NOT NULL DEFAULT '1',
`raidDifficulty` tinyint unsigned NOT NULL DEFAULT '14',
`legacyRaidDifficulty` tinyint unsigned NOT NULL DEFAULT '3',
@@ -3710,7 +3710,8 @@ INSERT INTO `updates` VALUES
('2023_05_04_00_characters.sql','9AC370E51507F5BD368707E90D8F6BF0FF16CA09','ARCHIVED','2023-05-04 16:17:31',0),
('2023_05_19_00_characters.sql','5E0C9338554BAA481566EDFF3FE2FCEFF1B67DA9','ARCHIVED','2023-05-19 18:40:42',0),
('2023_07_14_00_characters.sql','BB44A95A9C4B0C16878A5316AC38E702A8AACDE2','ARCHIVED','2023-07-14 08:24:44',0),
('2023_08_26_00_characters.sql','FA50838609AB5E645FB2DCAC970BD5706F9EFAAF','RELEASED','2023-08-26 12:18:22',0);
('2023_08_26_00_characters.sql','FA50838609AB5E645FB2DCAC970BD5706F9EFAAF','RELEASED','2023-08-26 12:18:22',0),
('2023_09_14_00_characters.sql','DAC56929C724C2971A4476400F2439CBDFAF3C5C','RELEASED','2023-09-13 22:20:22',0);
/*!40000 ALTER TABLE `updates` ENABLE KEYS */;
UNLOCK TABLES;

View File

@@ -0,0 +1 @@
ALTER TABLE `groups` MODIFY `groupType` smallint unsigned NOT NULL AFTER `icon8`;

View File

@@ -173,7 +173,7 @@ bool Group::Create(Player* leader)
stmt->setBinary(index++, m_targetIcons[5].GetRawValue());
stmt->setBinary(index++, m_targetIcons[6].GetRawValue());
stmt->setBinary(index++, m_targetIcons[7].GetRawValue());
stmt->setUInt8(index++, uint8(m_groupFlags));
stmt->setUInt16(index++, m_groupFlags);
stmt->setUInt32(index++, uint8(m_dungeonDifficulty));
stmt->setUInt32(index++, uint8(m_raidDifficulty));
stmt->setUInt32(index++, uint8(m_legacyRaidDifficulty));
@@ -213,7 +213,7 @@ void Group::LoadGroupFromDB(Field* fields)
for (uint8 i = 0; i < TARGET_ICONS_COUNT; ++i)
m_targetIcons[i].SetRawValue(fields[4 + i].GetBinary());
m_groupFlags = GroupFlags(fields[12].GetUInt8());
m_groupFlags = GroupFlags(fields[12].GetUInt16());
if (m_groupFlags & GROUP_FLAG_RAID)
_initRaidSubGroupsCounter();
@@ -242,6 +242,9 @@ void Group::LoadMemberFromDB(ObjectGuid::LowType guidLow, uint8 memberFlags, uin
return;
}
if (m_groupFlags & GROUP_FLAG_EVERYONE_ASSISTANT)
memberFlags |= MEMBER_FLAG_ASSISTANT;
member.name = character->Name;
member.race = Races(character->Race);
member._class = character->Class;
@@ -266,7 +269,7 @@ void Group::ConvertToLFG()
{
CharacterDatabasePreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_UPD_GROUP_TYPE);
stmt->setUInt8(0, uint8(m_groupFlags));
stmt->setUInt16(0, m_groupFlags);
stmt->setUInt32(1, m_dbStoreId);
CharacterDatabase.Execute(stmt);
@@ -285,7 +288,7 @@ void Group::ConvertToRaid()
{
CharacterDatabasePreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_UPD_GROUP_TYPE);
stmt->setUInt8(0, uint8(m_groupFlags));
stmt->setUInt16(0, m_groupFlags);
stmt->setUInt32(1, m_dbStoreId);
CharacterDatabase.Execute(stmt);
@@ -304,7 +307,7 @@ void Group::ConvertToGroup()
if (m_memberSlots.size() > 5)
return; // What message error should we send?
m_groupFlags = GroupFlags(GROUP_FLAG_NONE);
m_groupFlags = GroupFlags(m_groupFlags & ~GROUP_FLAG_RAID);
if (m_subGroupsCounts)
{
@@ -316,7 +319,7 @@ void Group::ConvertToGroup()
{
CharacterDatabasePreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_UPD_GROUP_TYPE);
stmt->setUInt8(0, uint8(m_groupFlags));
stmt->setUInt16(0, m_groupFlags);
stmt->setUInt32(1, m_dbStoreId);
CharacterDatabase.Execute(stmt);
@@ -1847,5 +1850,40 @@ void Group::SetEveryoneIsAssistant(bool apply)
for (member_witerator itr = m_memberSlots.begin(); itr != m_memberSlots.end(); ++itr)
ToggleGroupMemberFlag(itr, MEMBER_FLAG_ASSISTANT, apply);
if (!isBGGroup() && !isBFGroup())
{
CharacterDatabasePreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_UPD_GROUP_TYPE);
stmt->setUInt16(0, m_groupFlags);
stmt->setUInt32(1, m_dbStoreId);
CharacterDatabase.Execute(stmt);
}
SendUpdate();
}
bool Group::IsRestrictPingsToAssistants() const
{
return (m_groupFlags & GROUP_FLAG_RESTRICT_PINGS) != 0;
}
void Group::SetRestrictPingsToAssistants(bool restrictPingsToAssistants)
{
if (restrictPingsToAssistants)
m_groupFlags = GroupFlags(m_groupFlags | GROUP_FLAG_RESTRICT_PINGS);
else
m_groupFlags = GroupFlags(m_groupFlags & ~GROUP_FLAG_RESTRICT_PINGS);
if (!isBGGroup() && !isBFGroup())
{
CharacterDatabasePreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_UPD_GROUP_TYPE);
stmt->setUInt16(0, m_groupFlags);
stmt->setUInt32(1, m_dbStoreId);
CharacterDatabase.Execute(stmt);
}
SendUpdate();
}

View File

@@ -90,7 +90,7 @@ enum GroupType
GROUP_TYPE_WORLD_PVP = 4
};
enum GroupFlags
enum GroupFlags : uint16
{
GROUP_FLAG_NONE = 0x000,
GROUP_FLAG_FAKE_RAID = 0x001,
@@ -102,6 +102,7 @@ enum GroupFlags
GROUP_FLAG_EVERYONE_ASSISTANT = 0x040, // Script_IsEveryoneAssistant()
GROUP_FLAG_GUILD_GROUP = 0x100,
GROUP_FLAG_CROSS_FACTION = 0x200,
GROUP_FLAG_RESTRICT_PINGS = 0x400, // C_PartyInfo::Script_GetRestrictPings()
GROUP_MASK_BGRAID = GROUP_FLAG_FAKE_RAID | GROUP_FLAG_RAID,
};
@@ -170,6 +171,18 @@ struct RaidMarker
}
};
enum class PingSubjectType : uint8
{
Attack = 0,
Warning = 1,
Assist = 2,
OnMyWay = 3,
AlertThreat = 4,
AlertNotThreat = 5,
Max
};
/** request member stats checken **/
/// @todo uninvite people that not accepted invite
class TC_GAME_API Group
@@ -219,6 +232,8 @@ class TC_GAME_API Group
void SetLfgRoles(ObjectGuid guid, uint8 roles);
uint8 GetLfgRoles(ObjectGuid guid);
void SetEveryoneIsAssistant(bool apply);
bool IsRestrictPingsToAssistants() const;
void SetRestrictPingsToAssistants(bool restrictPingsToAssistants);
// Update
void UpdateReadyCheck(uint32 diff);

View File

@@ -649,3 +649,90 @@ void WorldSession::HandleClearRaidMarker(WorldPackets::Party::ClearRaidMarker& p
group->DeleteRaidMarker(packet.MarkerId);
}
namespace
{
bool CanSendPing(Player const& player, PingSubjectType type, Group const*& group)
{
if (type >= PingSubjectType::Max)
return false;
if (!player.GetSession()->CanSpeak())
return false;
group = player.GetGroup();
if (!group)
return false;
if (group->IsRestrictPingsToAssistants() && !group->IsLeader(player.GetGUID()) && !group->IsAssistant(player.GetGUID()))
return false;
return true;
}
}
void WorldSession::HandleSetRestrictPingsToAssistants(WorldPackets::Party::SetRestrictPingsToAssistants const& setRestrictPingsToAssistants)
{
Group* group = GetPlayer()->GetGroup(setRestrictPingsToAssistants.PartyIndex);
if (!group)
return;
if (!group->IsLeader(GetPlayer()->GetGUID()))
return;
group->SetRestrictPingsToAssistants(setRestrictPingsToAssistants.RestrictPingsToAssistants);
}
void WorldSession::HandleSendPingUnit(WorldPackets::Party::SendPingUnit const& pingUnit)
{
Group const* group = nullptr;
if (!CanSendPing(*_player, pingUnit.Type, group))
return;
Unit const* target = ObjectAccessor::GetUnit(*_player, pingUnit.TargetGUID);
if (!target || !_player->HaveAtClient(target))
return;
WorldPackets::Party::ReceivePingUnit broadcastPingUnit;
broadcastPingUnit.SenderGUID = _player->GetGUID();
broadcastPingUnit.TargetGUID = pingUnit.TargetGUID;
broadcastPingUnit.Type = pingUnit.Type;
broadcastPingUnit.PinFrameID = pingUnit.PinFrameID;
broadcastPingUnit.Write();
for (GroupReference const* itr = group->GetFirstMember(); itr != nullptr; itr = itr->next())
{
Player const* member = itr->GetSource();
if (_player == member || !_player->IsInMap(member))
continue;
member->SendDirectMessage(broadcastPingUnit.GetRawPacket());
}
}
void WorldSession::HandleSendPingWorldPoint(WorldPackets::Party::SendPingWorldPoint const& pingWorldPoint)
{
Group const* group = nullptr;
if (!CanSendPing(*_player, pingWorldPoint.Type, group))
return;
if (_player->GetMapId() != pingWorldPoint.MapID)
return;
WorldPackets::Party::ReceivePingWorldPoint broadcastPingWorldPoint;
broadcastPingWorldPoint.SenderGUID = _player->GetGUID();
broadcastPingWorldPoint.MapID = pingWorldPoint.MapID;
broadcastPingWorldPoint.Point = pingWorldPoint.Point;
broadcastPingWorldPoint.Type = pingWorldPoint.Type;
broadcastPingWorldPoint.PinFrameID = pingWorldPoint.PinFrameID;
broadcastPingWorldPoint.Write();
for (GroupReference const* itr = group->GetFirstMember(); itr != nullptr; itr = itr->next())
{
Player const* member = itr->GetSource();
if (_player == member || !_player->IsInMap(member))
continue;
member->SendDirectMessage(broadcastPingWorldPoint.GetRawPacket());
}
}

View File

@@ -728,3 +728,57 @@ WorldPacket const* WorldPackets::Party::BroadcastSummonResponse::Write()
return &_worldPacket;
}
void WorldPackets::Party::SetRestrictPingsToAssistants::Read()
{
bool hasPartyIndex = _worldPacket.ReadBit();
RestrictPingsToAssistants = _worldPacket.ReadBit();
if (hasPartyIndex)
_worldPacket >> PartyIndex.emplace();
}
void WorldPackets::Party::SendPingUnit::Read()
{
_worldPacket >> SenderGUID;
_worldPacket >> TargetGUID;
Type = _worldPacket.read<PingSubjectType, uint8>();
_worldPacket >> PinFrameID;
}
WorldPacket const* WorldPackets::Party::ReceivePingUnit::Write()
{
_worldPacket << SenderGUID;
_worldPacket << TargetGUID;
_worldPacket << uint8(Type);
_worldPacket << uint32(PinFrameID);
return &_worldPacket;
}
void WorldPackets::Party::SendPingWorldPoint::Read()
{
_worldPacket >> SenderGUID;
_worldPacket >> MapID;
_worldPacket >> Point;
Type = _worldPacket.read<PingSubjectType, uint8>();
_worldPacket >> PinFrameID;
}
WorldPacket const* WorldPackets::Party::ReceivePingWorldPoint::Write()
{
_worldPacket << SenderGUID;
_worldPacket << MapID;
_worldPacket << Point;
_worldPacket << uint8(Type);
_worldPacket << PinFrameID;
return &_worldPacket;
}
WorldPacket const* WorldPackets::Party::CancelPingPin::Write()
{
_worldPacket << SenderGUID;
_worldPacket << PinFrameID;
return &_worldPacket;
}

View File

@@ -665,6 +665,82 @@ namespace WorldPackets
ObjectGuid Target;
bool Accepted = false;
};
class SetRestrictPingsToAssistants final : public ClientPacket
{
public:
explicit SetRestrictPingsToAssistants(WorldPacket&& packet) : ClientPacket(CMSG_SET_RESTRICT_PINGS_TO_ASSISTANTS, std::move(packet)) { }
void Read() override;
Optional<uint8> PartyIndex;
bool RestrictPingsToAssistants = false;
};
class SendPingUnit final : public ClientPacket
{
public:
explicit SendPingUnit(WorldPacket&& packet) : ClientPacket(CMSG_SEND_PING_UNIT, std::move(packet)) { }
void Read() override;
ObjectGuid SenderGUID;
ObjectGuid TargetGUID;
PingSubjectType Type = PingSubjectType::Max;
uint32 PinFrameID = 0;
};
class ReceivePingUnit final : public ServerPacket
{
public:
ReceivePingUnit() : ServerPacket(SMSG_RECEIVE_PING_UNIT, 16 + 16 + 1 + 4) { }
WorldPacket const* Write() override;
ObjectGuid SenderGUID;
ObjectGuid TargetGUID;
PingSubjectType Type = PingSubjectType::Max;
uint32 PinFrameID = 0;
};
class SendPingWorldPoint final : public ClientPacket
{
public:
explicit SendPingWorldPoint(WorldPacket&& packet) : ClientPacket(CMSG_SEND_PING_WORLD_POINT, std::move(packet)) { }
void Read() override;
ObjectGuid SenderGUID;
uint32 MapID = 0;
TaggedPosition<Position::XYZ> Point;
PingSubjectType Type = PingSubjectType::Max;
uint32 PinFrameID = 0;
};
class ReceivePingWorldPoint final : public ServerPacket
{
public:
ReceivePingWorldPoint() : ServerPacket(SMSG_RECEIVE_PING_WORLD_POINT, 16 + 4 + 4 * 3 + 1 + 4) { }
WorldPacket const* Write() override;
ObjectGuid SenderGUID;
uint32 MapID = 0;
TaggedPosition<Position::XYZ> Point;
PingSubjectType Type = PingSubjectType::Max;
uint32 PinFrameID = 0;
};
class CancelPingPin final : public ServerPacket
{
public:
CancelPingPin() : ServerPacket(SMSG_CANCEL_PING_PIN, 16 + 4) { }
WorldPacket const* Write() override;
ObjectGuid SenderGUID;
uint32 PinFrameID = 0;
};
}
}

View File

@@ -847,8 +847,8 @@ void OpcodeTable::Initialize()
DEFINE_HANDLER(CMSG_SEND_CHARACTER_CLUB_INVITATION, STATUS_UNHANDLED, PROCESS_THREADUNSAFE, &WorldSession::Handle_NULL);
DEFINE_HANDLER(CMSG_SEND_CONTACT_LIST, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleContactListOpcode);
DEFINE_HANDLER(CMSG_SEND_MAIL, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleSendMail);
DEFINE_HANDLER(CMSG_SEND_PING_UNIT, STATUS_UNHANDLED, PROCESS_THREADUNSAFE, &WorldSession::Handle_NULL);
DEFINE_HANDLER(CMSG_SEND_PING_WORLD_POINT, STATUS_UNHANDLED, PROCESS_THREADUNSAFE, &WorldSession::Handle_NULL);
DEFINE_HANDLER(CMSG_SEND_PING_UNIT, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleSendPingUnit);
DEFINE_HANDLER(CMSG_SEND_PING_WORLD_POINT, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleSendPingWorldPoint);
DEFINE_HANDLER(CMSG_SEND_TEXT_EMOTE, STATUS_LOGGEDIN, PROCESS_INPLACE, &WorldSession::HandleTextEmoteOpcode);
DEFINE_HANDLER(CMSG_SERVER_TIME_OFFSET_REQUEST, STATUS_AUTHED, PROCESS_INPLACE, &WorldSession::HandleServerTimeOffsetRequest);
DEFINE_HANDLER(CMSG_SET_ACHIEVEMENTS_HIDDEN, STATUS_UNHANDLED, PROCESS_INPLACE, &WorldSession::Handle_NULL);
@@ -881,7 +881,7 @@ void OpcodeTable::Initialize()
DEFINE_HANDLER(CMSG_SET_PREFERRED_CEMETERY, STATUS_UNHANDLED, PROCESS_INPLACE, &WorldSession::Handle_NULL);
DEFINE_HANDLER(CMSG_SET_PVP, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleSetPvP);
DEFINE_HANDLER(CMSG_SET_RAID_DIFFICULTY, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleSetRaidDifficultyOpcode);
DEFINE_HANDLER(CMSG_SET_RESTRICT_PINGS_TO_ASSISTANTS, STATUS_UNHANDLED, PROCESS_THREADUNSAFE, &WorldSession::Handle_NULL);
DEFINE_HANDLER(CMSG_SET_RESTRICT_PINGS_TO_ASSISTANTS, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleSetRestrictPingsToAssistants);
DEFINE_HANDLER(CMSG_SET_ROLE, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleSetRoleOpcode);
DEFINE_HANDLER(CMSG_SET_SAVED_INSTANCE_EXTEND, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleSetSavedInstanceExtend);
DEFINE_HANDLER(CMSG_SET_SELECTION, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleSetSelectionOpcode);
@@ -1166,7 +1166,7 @@ void OpcodeTable::Initialize()
DEFINE_SERVER_OPCODE_HANDLER(SMSG_CANCEL_AUTO_REPEAT, STATUS_NEVER, CONNECTION_TYPE_REALM);
DEFINE_SERVER_OPCODE_HANDLER(SMSG_CANCEL_COMBAT, STATUS_NEVER, CONNECTION_TYPE_REALM);
DEFINE_SERVER_OPCODE_HANDLER(SMSG_CANCEL_ORPHAN_SPELL_VISUAL, STATUS_NEVER, CONNECTION_TYPE_REALM);
DEFINE_SERVER_OPCODE_HANDLER(SMSG_CANCEL_PING_PIN, STATUS_UNHANDLED, CONNECTION_TYPE_INSTANCE);
DEFINE_SERVER_OPCODE_HANDLER(SMSG_CANCEL_PING_PIN, STATUS_NEVER, CONNECTION_TYPE_REALM);
DEFINE_SERVER_OPCODE_HANDLER(SMSG_CANCEL_PRELOAD_WORLD, STATUS_UNHANDLED, CONNECTION_TYPE_REALM);
DEFINE_SERVER_OPCODE_HANDLER(SMSG_CANCEL_SCENE, STATUS_NEVER, CONNECTION_TYPE_INSTANCE);
DEFINE_SERVER_OPCODE_HANDLER(SMSG_CANCEL_SPELL_VISUAL, STATUS_NEVER, CONNECTION_TYPE_REALM);
@@ -1928,8 +1928,8 @@ void OpcodeTable::Initialize()
DEFINE_SERVER_OPCODE_HANDLER(SMSG_REALM_LOOKUP_INFO, STATUS_UNHANDLED, CONNECTION_TYPE_REALM);
DEFINE_SERVER_OPCODE_HANDLER(SMSG_REALM_QUERY_RESPONSE, STATUS_NEVER, CONNECTION_TYPE_REALM);
DEFINE_SERVER_OPCODE_HANDLER(SMSG_REATTACH_RESURRECT, STATUS_UNHANDLED, CONNECTION_TYPE_REALM);
DEFINE_SERVER_OPCODE_HANDLER(SMSG_RECEIVE_PING_UNIT, STATUS_UNHANDLED, CONNECTION_TYPE_INSTANCE);
DEFINE_SERVER_OPCODE_HANDLER(SMSG_RECEIVE_PING_WORLD_POINT, STATUS_UNHANDLED, CONNECTION_TYPE_INSTANCE);
DEFINE_SERVER_OPCODE_HANDLER(SMSG_RECEIVE_PING_UNIT, STATUS_NEVER, CONNECTION_TYPE_REALM);
DEFINE_SERVER_OPCODE_HANDLER(SMSG_RECEIVE_PING_WORLD_POINT, STATUS_NEVER, CONNECTION_TYPE_REALM);
DEFINE_SERVER_OPCODE_HANDLER(SMSG_RECRAFT_ITEM_RESULT, STATUS_UNHANDLED, CONNECTION_TYPE_REALM);
DEFINE_SERVER_OPCODE_HANDLER(SMSG_RECRUIT_A_FRIEND_FAILURE, STATUS_NEVER, CONNECTION_TYPE_REALM);
DEFINE_SERVER_OPCODE_HANDLER(SMSG_REFRESH_COMPONENT, STATUS_UNHANDLED, CONNECTION_TYPE_REALM);

View File

@@ -590,6 +590,9 @@ namespace WorldPackets
class SwapSubGroups;
class RaidMarkersChanged;
class ClearRaidMarker;
class SetRestrictPingsToAssistants;
class SendPingUnit;
class SendPingWorldPoint;
}
namespace Pet
@@ -1344,6 +1347,9 @@ class TC_GAME_API WorldSession
void HandleInitiateRolePoll(WorldPackets::Party::InitiateRolePoll& packet);
void HandleSetEveryoneIsAssistant(WorldPackets::Party::SetEveryoneIsAssistant& packet);
void HandleClearRaidMarker(WorldPackets::Party::ClearRaidMarker& packet);
void HandleSetRestrictPingsToAssistants(WorldPackets::Party::SetRestrictPingsToAssistants const& setRestrictPingsToAssistants);
void HandleSendPingUnit(WorldPackets::Party::SendPingUnit const& pingUnit);
void HandleSendPingWorldPoint(WorldPackets::Party::SendPingWorldPoint const& pingWorldPoint);
void HandlePetitionBuy(WorldPackets::Petition::PetitionBuy& packet);
void HandlePetitionShowSignatures(WorldPackets::Petition::PetitionShowSignatures& packet);