aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorFabian <Fabi@users.noreply.github.com>2024-02-12 16:42:08 +0100
committerGitHub <noreply@github.com>2024-02-12 16:42:08 +0100
commit9fa521194b374cc55953e7a9ab6d531fdd39a838 (patch)
tree0e19b0a292f9154c1d2d09674452fdbd3509604a /src
parent13398a9710e3414bc1ad4aacd3ec0bfed9ef2593 (diff)
Core/Guilds: Implemented club basics to restore old guild functionality (#29587)
* Updated BGS status names enum. Values bigger than 0x0000AFCD & some others are preserved for compatibility reasons. They were not in the client by default. * Added services & service methods required for guilds. * Allow club stream messages the usage of LANG_UNIVERSAL. Co-authored-by: Shauren <shauren.trinity@gmail.com>
Diffstat (limited to 'src')
-rw-r--r--src/server/game/Entities/Player/Player.cpp2
-rw-r--r--src/server/game/Guilds/Guild.cpp173
-rw-r--r--src/server/game/Guilds/Guild.h33
-rw-r--r--src/server/game/Handlers/CharacterHandler.cpp9
-rw-r--r--src/server/game/Handlers/ChatHandler.cpp68
-rw-r--r--src/server/game/Miscellaneous/SharedDefines.h23
-rw-r--r--src/server/game/Server/Packets/BattlenetPackets.cpp13
-rw-r--r--src/server/game/Server/Packets/CharacterPackets.cpp2
-rw-r--r--src/server/game/Server/Packets/QueryPackets.cpp2
-rw-r--r--src/server/game/Server/WorldSession.h2
-rw-r--r--src/server/game/Services/ClubMembershipService.cpp84
-rw-r--r--src/server/game/Services/ClubMembershipService.h40
-rw-r--r--src/server/game/Services/ClubService.cpp391
-rw-r--r--src/server/game/Services/ClubService.h51
-rw-r--r--src/server/game/Services/ClubUtils.cpp25
-rw-r--r--src/server/game/Services/ClubUtils.h28
-rw-r--r--src/server/game/Services/WorldserverGameUtilitiesService.h2
-rw-r--r--src/server/game/Services/WorldserverServiceDispatcher.cpp4
-rw-r--r--src/server/game/Services/WorldserverServiceDispatcher.h4
-rw-r--r--src/server/proto/BattlenetRpcErrorCodes.h410
20 files changed, 1117 insertions, 249 deletions
diff --git a/src/server/game/Entities/Player/Player.cpp b/src/server/game/Entities/Player/Player.cpp
index d4888150eb1..15e94f7bdd9 100644
--- a/src/server/game/Entities/Player/Player.cpp
+++ b/src/server/game/Entities/Player/Player.cpp
@@ -43,6 +43,7 @@
#include "ChatPackets.h"
#include "ChatTextBuilder.h"
#include "CinematicMgr.h"
+#include "ClubUtils.h"
#include "CombatLogPackets.h"
#include "CombatPackets.h"
#include "Common.h"
@@ -17791,6 +17792,7 @@ bool Player::LoadFromDB(ObjectGuid guid, CharacterDatabaseQueryHolder const& hol
SetUpdateFieldValue(m_values.ModifyValue(&Player::m_playerData).ModifyValue(&UF::PlayerData::WowAccount), GetSession()->GetAccountGUID());
SetUpdateFieldValue(m_values.ModifyValue(&Player::m_playerData).ModifyValue(&UF::PlayerData::BnetAccount), GetSession()->GetBattlenetAccountGUID());
+ SetUpdateFieldValue(m_values.ModifyValue(&Player::m_playerData).ModifyValue(&UF::PlayerData::GuildClubMemberID), Battlenet::Services::Clubs::CreateClubMemberId(guid));
if (!IsValidGender(fields.gender))
{
diff --git a/src/server/game/Guilds/Guild.cpp b/src/server/game/Guilds/Guild.cpp
index c36c3510919..db5f1b07806 100644
--- a/src/server/game/Guilds/Guild.cpp
+++ b/src/server/game/Guilds/Guild.cpp
@@ -24,9 +24,12 @@
#include "CharacterCache.h"
#include "Chat.h"
#include "ChatPackets.h"
+#include "ClubMembershipService.h"
+#include "ClubService.h"
+#include "ClubUtils.h"
#include "Config.h"
-#include "DatabaseEnv.h"
#include "DB2Stores.h"
+#include "DatabaseEnv.h"
#include "GameTime.h"
#include "GuildMgr.h"
#include "GuildPackets.h"
@@ -40,6 +43,8 @@
#include "SocialMgr.h"
#include "World.h"
#include "WorldSession.h"
+#include "club_listener.pb.h"
+#include "club_membership_listener.pb.h"
size_t const MAX_GUILD_BANK_TAB_TEXT_LEN = 500;
@@ -1194,8 +1199,27 @@ void Guild::Disband()
// Call scripts before guild data removed from database
sScriptMgr->OnGuildDisband(this);
- WorldPackets::Guild::GuildEventDisbanded packet;
- BroadcastPacket(packet.Write());
+ WorldPackets::Guild::GuildEventDisbanded guildEventDisbanded;
+ guildEventDisbanded.Write();
+
+ // Notify the members of club removal.
+ club::v1::UnsubscribeNotification unsubscribeNotification;
+ unsubscribeNotification.set_club_id(GetId());
+
+ BroadcastWorker([&](Player const* member)
+ {
+ member->SendDirectMessage(guildEventDisbanded.GetRawPacket());
+
+ // Unsubscribe the removed player from the club to ensure interface updates.
+ Battlenet::WorldserverService<club::v1::ClubListener>(member->GetSession()).OnUnsubscribe(&unsubscribeNotification, true, true);
+
+ // Finally notify the client about leaving the club.
+ club::v1::membership::ClubRemovedNotification clubRemovedNotification;
+ clubRemovedNotification.set_allocated_member_id(Battlenet::Services::ClubMembershipService::CreateClubMemberId(member->GetGUID()).release());
+ clubRemovedNotification.set_club_id(GetId());
+ clubRemovedNotification.set_reason(club::v1::ClubRemovedReason::CLUB_REMOVED_REASON_DESTROYED_BY_MEMBER);
+ Battlenet::WorldserverService<club::v1::membership::ClubMembershipListener>(member->GetSession()).OnClubRemoved(&clubRemovedNotification, true, true);
+ });
CharacterDatabaseTransaction trans = CharacterDatabase.BeginTransaction();
// Remove all members
@@ -1333,6 +1357,7 @@ void Guild::HandleRoster(WorldSession* session)
memberData.ClassID = member.GetClass();
memberData.Gender = member.GetGender();
memberData.RaceID = member.GetRace();
+ memberData.GuildClubMemberID = Battlenet::Services::Clubs::CreateClubMemberId(member.GetGUID());
memberData.Authenticated = false;
memberData.SorEligible = false;
@@ -2356,11 +2381,20 @@ void Guild::SendEventNewLeader(Member* newLeader, Member* oldLeader, bool isSelf
{
WorldPackets::Guild::GuildEventNewLeader eventPacket;
eventPacket.SelfPromoted = isSelfPromoted;
+
+ club::v1::MemberRoleChangedNotification memberRoleChangeNotification;
+ memberRoleChangeNotification.set_club_id(GetId());
+
if (newLeader)
{
eventPacket.NewLeaderGUID = newLeader->GetGUID();
eventPacket.NewLeaderName = newLeader->GetName();
eventPacket.NewLeaderVirtualRealmAddress = GetVirtualRealmAddress();
+
+ // Owner/GuildMaster role is always 1.
+ club::v1::RoleAssignment* newLeaderRoleAssignment = memberRoleChangeNotification.add_assignment();
+ newLeaderRoleAssignment->set_allocated_member_id(Battlenet::Services::ClubMembershipService::CreateClubMemberId(newLeader->GetGUID()).release());
+ newLeaderRoleAssignment->add_role(AsUnderlyingType(ClubRoleIdentifier::Owner));
}
if (oldLeader)
@@ -2368,9 +2402,21 @@ void Guild::SendEventNewLeader(Member* newLeader, Member* oldLeader, bool isSelf
eventPacket.OldLeaderGUID = oldLeader->GetGUID();
eventPacket.OldLeaderName = oldLeader->GetName();
eventPacket.OldLeaderVirtualRealmAddress = GetVirtualRealmAddress();
+
+ // Non owner members in guilds get the lowest club/community role after a guild master change.
+ club::v1::RoleAssignment* oldLeaderRoleAssignment = memberRoleChangeNotification.add_assignment();
+ oldLeaderRoleAssignment->set_allocated_member_id(Battlenet::Services::ClubMembershipService::CreateClubMemberId(oldLeader->GetGUID()).release());
+ oldLeaderRoleAssignment->add_role(AsUnderlyingType(ClubRoleIdentifier::Member));
}
- BroadcastPacket(eventPacket.Write());
+ eventPacket.Write();
+
+ // We have to send old guild and new club packets so we use a custom broadcast loop here.
+ BroadcastWorker([&](Player const* member)
+ {
+ member->SendDirectMessage(eventPacket.GetRawPacket());
+ Battlenet::WorldserverService<club::v1::ClubListener>(member->GetSession()).OnMemberRoleChanged(&memberRoleChangeNotification, true, true);
+ });
}
void Guild::SendEventPlayerLeft(Member* leaver, Member* remover, bool isRemoved) const
@@ -2388,7 +2434,46 @@ void Guild::SendEventPlayerLeft(Member* leaver, Member* remover, bool isRemoved)
eventPacket.RemoverVirtualRealmAddress = GetVirtualRealmAddress();
}
- BroadcastPacket(eventPacket.Write());
+ eventPacket.Write();
+
+ Player* leaverPlayer = leaver->FindConnectedPlayer();
+
+ // Notify the removed member of club removal.
+ if (leaverPlayer)
+ {
+ leaverPlayer->SendDirectMessage(eventPacket.GetRawPacket());
+
+ // Unsubscribe the removed player from the club to ensure interface updates.
+ club::v1::UnsubscribeNotification unsubscribeNotification;
+ unsubscribeNotification.set_club_id(GetId());
+ Battlenet::WorldserverService<club::v1::ClubListener>(leaverPlayer->GetSession()).OnUnsubscribe(&unsubscribeNotification, true, true);
+
+ // Finally notify the client about leaving the club.
+ club::v1::membership::ClubRemovedNotification clubRemovedNotification;
+ clubRemovedNotification.set_club_id(GetId());
+ clubRemovedNotification.set_reason(isRemoved
+ ? club::v1::ClubRemovedReason::CLUB_REMOVED_REASON_MEMBER_KICKED
+ : club::v1::ClubRemovedReason::CLUB_REMOVED_REASON_MEMBER_LEFT);
+ clubRemovedNotification.set_allocated_member_id(Battlenet::Services::ClubMembershipService::CreateClubMemberId(leaver->GetGUID()).release());
+ Battlenet::WorldserverService<club::v1::membership::ClubMembershipListener>(leaverPlayer->GetSession()).OnClubRemoved(&clubRemovedNotification, true, true);
+ }
+
+ club::v1::MemberRemovedNotification memberRemovedNotification;
+ memberRemovedNotification.set_club_id(GetId());
+
+ club::v1::MemberRemovedAssignment* removedMemberAssignment = memberRemovedNotification.add_member();
+ removedMemberAssignment->set_allocated_id(Battlenet::Services::ClubMembershipService::CreateClubMemberId(leaver->GetGUID()).release());
+ removedMemberAssignment->set_reason(isRemoved
+ ? club::v1::ClubRemovedReason::CLUB_REMOVED_REASON_MEMBER_KICKED
+ : club::v1::ClubRemovedReason::CLUB_REMOVED_REASON_MEMBER_LEFT);
+
+ // We have to send old guild and new club packets so we use a custom broadcast loop here.
+ BroadcastWorker([&](Player const* member)
+ {
+ // Notify other guild members.
+ member->SendDirectMessage(eventPacket.GetRawPacket());
+ Battlenet::WorldserverService<::bgs::protocol::club::v1::ClubListener>(member->GetSession()).OnMemberRemoved(&memberRemovedNotification, true, true);
+ }, leaverPlayer);
}
void Guild::SendEventPresenceChanged(WorldSession* session, bool loggedOn, bool broadcast) const
@@ -2819,7 +2904,58 @@ bool Guild::AddMember(CharacterDatabaseTransaction trans, ObjectGuid guid, Optio
joinNotificationPacket.Guid = guid;
joinNotificationPacket.Name = name;
joinNotificationPacket.VirtualRealmAddress = GetVirtualRealmAddress();
- BroadcastPacket(joinNotificationPacket.Write());
+ joinNotificationPacket.Write();
+
+ // Notify the added member with new club data.
+ if (player)
+ {
+ player->SendDirectMessage(joinNotificationPacket.GetRawPacket());
+
+ club::v1::membership::ClubAddedNotification clubAddedNotification;
+ clubAddedNotification.mutable_membership()->set_allocated_member_id(Battlenet::Services::ClubMembershipService::CreateClubMemberId(guid).release());
+
+ club::v1::ClubDescription* guildClub = clubAddedNotification.mutable_membership()->mutable_club();
+ guildClub->set_id(GetId());
+ guildClub->set_allocated_type(Battlenet::Services::ClubService::CreateGuildClubType().release());
+ guildClub->set_name(GetName());
+ guildClub->set_privacy_level(club::v1::PrivacyLevel::PRIVACY_LEVEL_OPEN);
+ guildClub->set_visibility_level(club::v1::VISIBILITY_LEVEL_PRIVATE);
+ guildClub->set_member_count(GetMembersCount());
+
+ // Set the club owner, guild master in this case.
+ club::v1::MemberDescription* guildLeaderDescription = guildClub->add_leader();
+ guildLeaderDescription->set_allocated_id(Battlenet::Services::ClubMembershipService::CreateClubMemberId(GetLeaderGUID()).release());
+
+ // Date is in microseconds.
+ guildClub->set_creation_time(
+ std::chrono::duration_cast<std::chrono::microseconds>(SystemTimePoint::clock::from_time_t(GetCreatedDate()).time_since_epoch()).count());
+ guildClub->set_timezone("");
+ guildClub->set_locale("");
+
+ Battlenet::WorldserverService<club::v1::membership::ClubMembershipListener>(player->GetSession()).OnClubAdded(&clubAddedNotification, true, true);
+ }
+
+ club::v1::MemberAddedNotification memberAddedNotification;
+ memberAddedNotification.set_club_id(GetId());
+
+ club::v1::Member* addedMember = memberAddedNotification.add_member();
+ addedMember->set_allocated_id(Battlenet::Services::ClubMembershipService::CreateClubMemberId(guid).release());
+ if (HasAnyRankRight(member.GetRankId(), GuildRankRights(GR_RIGHT_OFFCHATLISTEN | GR_RIGHT_OFFCHATSPEAK)))
+ addedMember->add_role(AsUnderlyingType(ClubRoleIdentifier::Moderator));
+ else
+ addedMember->add_role(AsUnderlyingType(ClubRoleIdentifier::Member));
+ addedMember->set_presence_level(club::v1::PresenceLevel::PRESENCE_LEVEL_RICH);
+ addedMember->set_whisper_level(club::v1::WhisperLevel::WHISPER_LEVEL_OPEN);
+ addedMember->set_note("");
+ addedMember->set_active(member.IsOnline());
+
+ // We have to send old guild and new club packets so we use a custom broadcast loop here.
+ BroadcastWorker([&](Player const* otherMember)
+ {
+ // Notify other online guild members.
+ otherMember->SendDirectMessage(joinNotificationPacket.GetRawPacket());
+ Battlenet::WorldserverService<club::v1::ClubListener>(otherMember->GetSession()).OnMemberAdded(&memberAddedNotification, true, true);
+ }, player);
// Call scripts if member was succesfully added (and stored to database)
sScriptMgr->OnGuildAddMember(this, player, AsUnderlyingType(*rankId));
@@ -3002,6 +3138,11 @@ bool Guild::_HasRankRight(Player const* player, uint32 right) const
return false;
}
+bool Guild::HasAnyRankRight(GuildRankId rankId, GuildRankRights rights) const
+{
+ return (_GetRankRights(rankId) & rights) != GR_RIGHT_NONE;
+}
+
void Guild::_DeleteMemberFromDB(CharacterDatabaseTransaction trans, ObjectGuid::LowType lowguid)
{
CharacterDatabasePreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_DEL_GUILD_MEMBER);
@@ -3579,7 +3720,25 @@ void Guild::SendGuildRanksUpdate(ObjectGuid setterGuid, ObjectGuid targetGuid, G
rankChange.Other = targetGuid;
rankChange.RankID = AsUnderlyingType(rank);
rankChange.Promote = (rank < member->GetRankId());
- BroadcastPacket(rankChange.Write());
+ rankChange.Write();
+
+ club::v1::MemberRoleChangedNotification memberRoleChangeNotification;
+ memberRoleChangeNotification.set_club_id(GetId());
+
+ club::v1::RoleAssignment* changedRoleAssignment = memberRoleChangeNotification.add_assignment();
+ changedRoleAssignment->set_allocated_member_id(Battlenet::Services::ClubMembershipService::CreateClubMemberId(targetGuid).release());
+ if (rank == GuildRankId::GuildMaster)
+ changedRoleAssignment->add_role(AsUnderlyingType(ClubRoleIdentifier::Owner));
+ else if (HasAnyRankRight(rank, GuildRankRights(GR_RIGHT_OFFCHATLISTEN | GR_RIGHT_OFFCHATSPEAK)))
+ changedRoleAssignment->add_role(AsUnderlyingType(ClubRoleIdentifier::Moderator));
+ else
+ changedRoleAssignment->add_role(AsUnderlyingType(ClubRoleIdentifier::Member));
+
+ BroadcastWorker([&](Player const* memberPlayer)
+ {
+ memberPlayer->SendDirectMessage(rankChange.GetRawPacket());
+ Battlenet::WorldserverService<club::v1::ClubListener>(memberPlayer->GetSession()).OnMemberRoleChanged(&memberRoleChangeNotification, true, true);
+ });
CharacterDatabaseTransaction trans;
member->ChangeRank(trans, rank);
diff --git a/src/server/game/Guilds/Guild.h b/src/server/game/Guilds/Guild.h
index f8aacf775c5..10384f091d1 100644
--- a/src/server/game/Guilds/Guild.h
+++ b/src/server/game/Guilds/Guild.h
@@ -73,6 +73,24 @@ enum GuildMemberData
GUILD_MEMBER_DATA_LEVEL,
};
+// Base Club/Community roles. Do not change.
+enum class ClubRoleIdentifier : uint32
+{
+ Owner = 1,
+ Leader = 2,
+ Moderator = 3,
+ Member = 4
+};
+
+// Base Club/Community chat stream types. Do not change.
+enum class ClubStreamType : uint32
+{
+ General = 0,
+ Guild = 1,
+ Officer = 2,
+ Other = 3
+};
+
enum class GuildRankId : uint8
{
GuildMaster = 0
@@ -308,7 +326,7 @@ using SlotIds = std::set<uint8>;
class TC_GAME_API Guild
{
- private:
+ public:
// Class representing guild member
class Member
{
@@ -401,6 +419,7 @@ class TC_GAME_API Guild
uint32 m_weekReputation;
};
+ private:
// Base class for event entries
class LogEntry
{
@@ -813,10 +832,10 @@ class TC_GAME_API Guild
void MassInviteToEvent(WorldSession* session, uint32 minLevel, uint32 maxLevel, GuildRankOrder minRank);
template<class Do>
- void BroadcastWorker(Do& _do, Player* except = nullptr)
+ void BroadcastWorker(Do&& _do, Player const* except = nullptr) const
{
- for (auto itr = m_members.begin(); itr != m_members.end(); ++itr)
- if (Player* player = itr->second.FindConnectedPlayer())
+ for (auto const& [_, member] : m_members)
+ if (Player* player = member.FindConnectedPlayer())
if (player != except)
_do(player);
}
@@ -828,6 +847,7 @@ class TC_GAME_API Guild
bool ChangeMemberRank(CharacterDatabaseTransaction trans, ObjectGuid guid, GuildRankId newRank);
bool IsMember(ObjectGuid guid) const;
uint32 GetMembersCount() const { return uint32(m_members.size()); }
+ std::unordered_map<ObjectGuid, Member> const& GetMembers() const { return m_members; }
uint64 GetMemberAvailableMoneyForRepairItems(ObjectGuid guid) const;
std::vector<Player*> GetMembersTrackingCriteria(uint32 criteriaId) const;
@@ -881,19 +901,24 @@ class TC_GAME_API Guild
RankInfo const* GetRankInfo(GuildRankOrder rankOrder) const;
RankInfo* GetRankInfo(GuildRankOrder rankOrder);
bool _HasRankRight(Player const* player, uint32 right) const;
+ public:
+ bool HasAnyRankRight(GuildRankId rankId, GuildRankRights rights) const;
+ private:
inline GuildRankId _GetLowestRankId() const { return m_ranks.back().GetId(); }
inline uint8 _GetPurchasedTabsSize() const { return uint8(m_bankTabs.size()); }
inline BankTab* GetBankTab(uint8 tabId) { return tabId < m_bankTabs.size() ? &m_bankTabs[tabId] : nullptr; }
inline BankTab const* GetBankTab(uint8 tabId) const { return tabId < m_bankTabs.size() ? &m_bankTabs[tabId] : nullptr; }
+ public:
inline Member const* GetMember(ObjectGuid const& guid) const
{
auto itr = m_members.find(guid);
return (itr != m_members.end()) ? &itr->second : nullptr;
}
+ private:
inline Member* GetMember(ObjectGuid const& guid)
{
auto itr = m_members.find(guid);
diff --git a/src/server/game/Handlers/CharacterHandler.cpp b/src/server/game/Handlers/CharacterHandler.cpp
index bc673388aac..149b0ad914a 100644
--- a/src/server/game/Handlers/CharacterHandler.cpp
+++ b/src/server/game/Handlers/CharacterHandler.cpp
@@ -1469,6 +1469,15 @@ void WorldSession::SendFeatureSystemStatus()
features.VoiceEnabled = false;
features.BrowserEnabled = false; // Has to be false, otherwise client will crash if "Customer Support" is opened
+ // Enable guilds only.
+ // This is required to restore old guild channel behavior for GMs.
+ // The new club streams do not support sending messages through the guild channel when you are not in a guild.
+ features.ClubsEnabled = true;
+ features.ClubsBattleNetClubTypeAllowed = false;
+ features.ClubsCharacterClubTypeAllowed = false;
+ features.ClubsPresenceUpdateEnabled = true;
+ features.HiddenUIClubsPresenceUpdateTimer = 60000;
+
features.EuropaTicketSystemStatus.emplace();
features.EuropaTicketSystemStatus->ThrottleState.MaxTries = 10;
features.EuropaTicketSystemStatus->ThrottleState.PerMilliseconds = 60000;
diff --git a/src/server/game/Handlers/ChatHandler.cpp b/src/server/game/Handlers/ChatHandler.cpp
index 5111e6f03ac..e1c3b74622c 100644
--- a/src/server/game/Handlers/ChatHandler.cpp
+++ b/src/server/game/Handlers/ChatHandler.cpp
@@ -143,15 +143,15 @@ void WorldSession::HandleChatMessageEmoteOpcode(WorldPackets::Chat::ChatMessageE
HandleChatMessage(CHAT_MSG_EMOTE, LANG_UNIVERSAL, chatMessageEmote.Text);
}
-void WorldSession::HandleChatMessage(ChatMsg type, Language lang, std::string msg, std::string target /*= ""*/, Optional<ObjectGuid> channelGuid /*= {}*/)
+ChatMessageResult WorldSession::HandleChatMessage(ChatMsg type, Language lang, std::string msg, std::string target /*= ""*/, Optional<ObjectGuid> channelGuid /*= {}*/)
{
Player* sender = GetPlayer();
- if (lang == LANG_UNIVERSAL && type != CHAT_MSG_EMOTE)
+ if (lang == LANG_UNIVERSAL && type != CHAT_MSG_EMOTE && type != CHAT_MSG_GUILD && type != CHAT_MSG_OFFICER)
{
TC_LOG_ERROR("entities.player.cheat", "CMSG_MESSAGECHAT: Possible hacking-attempt: {} tried to send a message in universal language", GetPlayerInfo());
SendNotification(LANG_UNKNOWN_LANGUAGE);
- return;
+ return ChatMessageResult::DisallowedLanguage;
}
// prevent talking at unknown language (cheating)
@@ -159,7 +159,7 @@ void WorldSession::HandleChatMessage(ChatMsg type, Language lang, std::string ms
if (languageData.begin() == languageData.end())
{
SendNotification(LANG_UNKNOWN_LANGUAGE);
- return;
+ return ChatMessageResult::InvalidLanguage;
}
if (std::none_of(languageData.begin(), languageData.end(),
@@ -169,7 +169,7 @@ void WorldSession::HandleChatMessage(ChatMsg type, Language lang, std::string ms
if (!sender->HasAuraTypeWithMiscvalue(SPELL_AURA_COMPREHEND_LANGUAGE, lang))
{
SendNotification(LANG_NOT_LEARNED_LANGUAGE);
- return;
+ return ChatMessageResult::LanguageNotLearned;
}
}
@@ -213,7 +213,7 @@ void WorldSession::HandleChatMessage(ChatMsg type, Language lang, std::string ms
{
std::string timeStr = secsToTimeString(m_muteTime - GameTime::GetGameTime());
SendNotification(GetTrinityString(LANG_WAIT_BEFORE_SPEAKING), timeStr.c_str());
- return;
+ return ChatMessageResult::Muted;
}
if (type != CHAT_MSG_AFK && type != CHAT_MSG_DND)
@@ -222,25 +222,25 @@ void WorldSession::HandleChatMessage(ChatMsg type, Language lang, std::string ms
if (sender->HasAura(GM_SILENCE_AURA) && type != CHAT_MSG_WHISPER)
{
SendNotification(GetTrinityString(LANG_GM_SILENCE), sender->GetName().c_str());
- return;
+ return ChatMessageResult::SilencedByGM;
}
if (msg.size() > 511)
- return;
+ return ChatMessageResult::MessageTooLong;
if (msg.empty())
- return;
+ return ChatMessageResult::MessageEmpty;
if (ChatHandler(this).ParseCommands(msg.c_str()))
- return;
+ return ChatMessageResult::HandledCommand;
// do message validity checks
if (!ValidateMessage(GetPlayer(), msg))
- return;
+ return ChatMessageResult::MessageHasInvalidCharacters;
// validate hyperlinks
if (!ValidateHyperlinksAndMaybeKick(msg))
- return;
+ return ChatMessageResult::MalformedHyperlinks;
switch (type)
{
@@ -248,12 +248,12 @@ void WorldSession::HandleChatMessage(ChatMsg type, Language lang, std::string ms
{
// Prevent cheating
if (!sender->IsAlive())
- return;
+ return ChatMessageResult::PlayerDead;
if (sender->GetLevel() < sWorld->getIntConfig(CONFIG_CHAT_SAY_LEVEL_REQ))
{
SendNotification(GetTrinityString(LANG_SAY_REQ), sWorld->getIntConfig(CONFIG_CHAT_SAY_LEVEL_REQ));
- return;
+ return ChatMessageResult::LevelTooLow;
}
sender->Say(msg, lang);
@@ -263,12 +263,12 @@ void WorldSession::HandleChatMessage(ChatMsg type, Language lang, std::string ms
{
// Prevent cheating
if (!sender->IsAlive())
- return;
+ return ChatMessageResult::PlayerDead;
if (sender->GetLevel() < sWorld->getIntConfig(CONFIG_CHAT_EMOTE_LEVEL_REQ))
{
SendNotification(GetTrinityString(LANG_SAY_REQ), sWorld->getIntConfig(CONFIG_CHAT_EMOTE_LEVEL_REQ));
- return;
+ return ChatMessageResult::LevelTooLow;
}
sender->TextEmote(msg);
@@ -278,12 +278,12 @@ void WorldSession::HandleChatMessage(ChatMsg type, Language lang, std::string ms
{
// Prevent cheating
if (!sender->IsAlive())
- return;
+ return ChatMessageResult::PlayerDead;
if (sender->GetLevel() < sWorld->getIntConfig(CONFIG_CHAT_YELL_LEVEL_REQ))
{
SendNotification(GetTrinityString(LANG_SAY_REQ), sWorld->getIntConfig(CONFIG_CHAT_YELL_LEVEL_REQ));
- return;
+ return ChatMessageResult::LevelTooLow;
}
sender->Yell(msg, lang);
@@ -304,7 +304,7 @@ void WorldSession::HandleChatMessage(ChatMsg type, Language lang, std::string ms
if (!receiver || (lang != LANG_ADDON && !receiver->isAcceptWhispers() && receiver->GetSession()->HasPermission(rbac::RBAC_PERM_CAN_FILTER_WHISPERS) && !receiver->IsInWhisperWhiteList(sender->GetGUID())))
{
SendChatPlayerNotfoundNotice(target);
- return;
+ return ChatMessageResult::NoWhisperTarget;
}
// Apply checks only if receiver is not already in whitelist and if receiver is not a GM with ".whisper on"
@@ -313,20 +313,20 @@ void WorldSession::HandleChatMessage(ChatMsg type, Language lang, std::string ms
if (!sender->IsGameMaster() && sender->GetLevel() < sWorld->getIntConfig(CONFIG_CHAT_WHISPER_LEVEL_REQ))
{
SendNotification(GetTrinityString(LANG_WHISPER_REQ), sWorld->getIntConfig(CONFIG_CHAT_WHISPER_LEVEL_REQ));
- return;
+ return ChatMessageResult::LevelTooLow;
}
if (GetPlayer()->GetEffectiveTeam() != receiver->GetEffectiveTeam() && !HasPermission(rbac::RBAC_PERM_TWO_SIDE_INTERACTION_CHAT))
{
SendChatPlayerNotfoundNotice(target);
- return;
+ return ChatMessageResult::WhisperTargetWrongFaction;
}
}
if (GetPlayer()->HasAura(1852) && !receiver->IsGameMaster())
{
SendNotification(GetTrinityString(LANG_GM_SILENCE), GetPlayer()->GetName().c_str());
- return;
+ return ChatMessageResult::SilencedByGM;
}
// If player is a Gamemaster and doesn't accept whisper, we auto-whitelist every player that the Gamemaster is talking to
@@ -346,7 +346,7 @@ void WorldSession::HandleChatMessage(ChatMsg type, Language lang, std::string ms
{
group = sender->GetGroup();
if (!group || group->isBGGroup())
- return;
+ return ChatMessageResult::NotInGroup;
}
if (group->IsLeader(GetPlayer()->GetGUID()))
@@ -389,7 +389,7 @@ void WorldSession::HandleChatMessage(ChatMsg type, Language lang, std::string ms
{
Group* group = GetPlayer()->GetGroup();
if (!group || !group->isRaidGroup() || group->isBGGroup())
- return;
+ return ChatMessageResult::NotInGroup;
if (group->IsLeader(GetPlayer()->GetGUID()))
type = CHAT_MSG_RAID_LEADER;
@@ -404,8 +404,16 @@ void WorldSession::HandleChatMessage(ChatMsg type, Language lang, std::string ms
case CHAT_MSG_RAID_WARNING:
{
Group* group = GetPlayer()->GetGroup();
- if (!group || !(group->isRaidGroup() || sWorld->getBoolConfig(CONFIG_CHAT_PARTY_RAID_WARNINGS)) || !(group->IsLeader(GetPlayer()->GetGUID()) || group->IsAssistant(GetPlayer()->GetGUID())) || group->isBGGroup())
- return;
+ if (!group)
+ return ChatMessageResult::NotInGroup;
+
+ if (group->isRaidGroup())
+ {
+ if (!group->IsLeader(GetPlayer()->GetGUID()) && !group->IsAssistant(GetPlayer()->GetGUID()))
+ return ChatMessageResult::NotLeaderOrAssistant;
+ }
+ else if (!sWorld->getBoolConfig(CONFIG_CHAT_PARTY_RAID_WARNINGS))
+ return ChatMessageResult::RaidWarningInPartyDisabled;
sScriptMgr->OnPlayerChat(GetPlayer(), type, lang, msg, group);
@@ -422,7 +430,7 @@ void WorldSession::HandleChatMessage(ChatMsg type, Language lang, std::string ms
if (sender->GetLevel() < sWorld->getIntConfig(CONFIG_CHAT_CHANNEL_LEVEL_REQ))
{
SendNotification(GetTrinityString(LANG_CHANNEL_REQ), sWorld->getIntConfig(CONFIG_CHAT_CHANNEL_LEVEL_REQ));
- return;
+ return ChatMessageResult::LevelTooLow;
}
}
@@ -433,7 +441,7 @@ void WorldSession::HandleChatMessage(ChatMsg type, Language lang, std::string ms
{
if (ChatChannelsEntry const* chatChannel = sChatChannelsStore.LookupEntry(chn->GetChannelId()))
if (chatChannel->GetFlags().HasFlag(ChatChannelFlags::ReadOnly))
- return;
+ return ChatMessageResult::ChannelIsReadOnly;
sScriptMgr->OnPlayerChat(sender, type, lang, msg, chn);
chn->Say(sender->GetGUID(), msg, lang);
@@ -444,7 +452,7 @@ void WorldSession::HandleChatMessage(ChatMsg type, Language lang, std::string ms
{
Group* group = GetPlayer()->GetGroup();
if (!group)
- return;
+ return ChatMessageResult::NotInGroup;
if (group->IsLeader(GetPlayer()->GetGUID()))
type = CHAT_MSG_INSTANCE_CHAT_LEADER;
@@ -460,6 +468,8 @@ void WorldSession::HandleChatMessage(ChatMsg type, Language lang, std::string ms
TC_LOG_ERROR("network", "CHAT: unknown message type {}, lang: {}", type, lang);
break;
}
+
+ return ChatMessageResult::Ok;
}
void WorldSession::HandleChatAddonMessageOpcode(WorldPackets::Chat::ChatAddonMessage& chatAddonMessage)
diff --git a/src/server/game/Miscellaneous/SharedDefines.h b/src/server/game/Miscellaneous/SharedDefines.h
index 7b34e1a08a1..2ff3a7c77b5 100644
--- a/src/server/game/Miscellaneous/SharedDefines.h
+++ b/src/server/game/Miscellaneous/SharedDefines.h
@@ -5980,6 +5980,29 @@ enum ChatLinkColors : uint32
CHAT_LINK_COLOR_TRANSMOG = 0xffff80ff,
};
+enum class ChatMessageResult : uint32
+{
+ Ok,
+ HandledCommand,
+ DisallowedLanguage,
+ InvalidLanguage,
+ LanguageNotLearned,
+ Muted,
+ SilencedByGM,
+ MessageTooLong,
+ MessageEmpty,
+ MessageHasInvalidCharacters,
+ MalformedHyperlinks,
+ PlayerDead,
+ LevelTooLow,
+ NoWhisperTarget,
+ WhisperTargetWrongFaction,
+ NotInGroup,
+ NotLeaderOrAssistant,
+ RaidWarningInPartyDisabled,
+ ChannelIsReadOnly
+};
+
// Values from ItemPetFood (power of (value-1) used for compare with CreatureFamilyEntry.PetFoodMask
enum PetDiet
{
diff --git a/src/server/game/Server/Packets/BattlenetPackets.cpp b/src/server/game/Server/Packets/BattlenetPackets.cpp
index f72ab913fd2..95b740fbd65 100644
--- a/src/server/game/Server/Packets/BattlenetPackets.cpp
+++ b/src/server/game/Server/Packets/BattlenetPackets.cpp
@@ -16,6 +16,7 @@
*/
#include "BattlenetPackets.h"
+#include "PacketUtilities.h"
ByteBuffer& operator<<(ByteBuffer& data, WorldPackets::Battlenet::MethodCall const& method)
{
@@ -78,9 +79,15 @@ void WorldPackets::Battlenet::Request::Read()
_worldPacket >> Method;
_worldPacket >> protoSize;
- Data.Resize(protoSize);
- _worldPacket.read(Data.GetWritePointer(), Data.GetRemainingSpace());
- Data.WriteCompleted(protoSize);
+ if (protoSize > 0xFFFF)
+ throw PacketArrayMaxCapacityException(protoSize, 0xFFFF);
+
+ if (protoSize)
+ {
+ Data.Resize(protoSize);
+ _worldPacket.read(Data.GetWritePointer(), Data.GetRemainingSpace());
+ Data.WriteCompleted(protoSize);
+ }
}
void WorldPackets::Battlenet::ChangeRealmTicket::Read()
diff --git a/src/server/game/Server/Packets/CharacterPackets.cpp b/src/server/game/Server/Packets/CharacterPackets.cpp
index 2a14e107077..cb89c8c3045 100644
--- a/src/server/game/Server/Packets/CharacterPackets.cpp
+++ b/src/server/game/Server/Packets/CharacterPackets.cpp
@@ -16,6 +16,7 @@
*/
#include "CharacterPackets.h"
+#include "ClubUtils.h"
#include "DB2Stores.h"
#include "Field.h"
#include "ObjectMgr.h"
@@ -103,6 +104,7 @@ EnumCharactersResult::CharacterInfo::CharacterInfo(Field* fields)
// "character_declinedname.genitive"
Guid = ObjectGuid::Create<HighGuid::Player>(fields[0].GetUInt64());
+ GuildClubMemberID = ::Battlenet::Services::Clubs::CreateClubMemberId(Guid);
Name = fields[1].GetString();
RaceID = fields[2].GetUInt8();
ClassID = fields[3].GetUInt8();
diff --git a/src/server/game/Server/Packets/QueryPackets.cpp b/src/server/game/Server/Packets/QueryPackets.cpp
index ccc9ec8ba94..10a1b336a5f 100644
--- a/src/server/game/Server/Packets/QueryPackets.cpp
+++ b/src/server/game/Server/Packets/QueryPackets.cpp
@@ -18,6 +18,7 @@
#include "QueryPackets.h"
#include "BattlenetAccountMgr.h"
#include "CharacterCache.h"
+#include "ClubUtils.h"
#include "ObjectMgr.h"
#include "Player.h"
#include "World.h"
@@ -200,6 +201,7 @@ bool PlayerGuidLookupData::Initialize(ObjectGuid const& guid, Player const* play
IsDeleted = characterInfo->IsDeleted;
GuidActual = guid;
+ GuildClubMemberID = ::Battlenet::Services::Clubs::CreateClubMemberId(guid);
VirtualRealmAddress = GetVirtualRealmAddress();
return true;
diff --git a/src/server/game/Server/WorldSession.h b/src/server/game/Server/WorldSession.h
index a1b5b5524aa..5b7257367f2 100644
--- a/src/server/game/Server/WorldSession.h
+++ b/src/server/game/Server/WorldSession.h
@@ -1552,7 +1552,7 @@ class TC_GAME_API WorldSession
void HandleChatMessageOpcode(WorldPackets::Chat::ChatMessage& chatMessage);
void HandleChatMessageWhisperOpcode(WorldPackets::Chat::ChatMessageWhisper& chatMessageWhisper);
void HandleChatMessageChannelOpcode(WorldPackets::Chat::ChatMessageChannel& chatMessageChannel);
- void HandleChatMessage(ChatMsg type, Language lang, std::string msg, std::string target = "", Optional<ObjectGuid> channelGuid = {});
+ ChatMessageResult HandleChatMessage(ChatMsg type, Language lang, std::string msg, std::string target = "", Optional<ObjectGuid> channelGuid = {});
void HandleChatAddonMessageOpcode(WorldPackets::Chat::ChatAddonMessage& chatAddonMessage);
void HandleChatAddonMessageTargetedOpcode(WorldPackets::Chat::ChatAddonMessageTargeted& chatAddonMessageTargeted);
void HandleChatAddonMessage(ChatMsg type, std::string prefix, std::string text, bool isLogged, std::string target = "", Optional<ObjectGuid> channelGuid = {});
diff --git a/src/server/game/Services/ClubMembershipService.cpp b/src/server/game/Services/ClubMembershipService.cpp
new file mode 100644
index 00000000000..419d56f29ef
--- /dev/null
+++ b/src/server/game/Services/ClubMembershipService.cpp
@@ -0,0 +1,84 @@
+/*
+ * This file is part of the TrinityCore Project. See AUTHORS file for Copyright information
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include "ClubMembershipService.h"
+#include "BattlenetRpcErrorCodes.h"
+#include "CharacterCache.h"
+#include "ClubService.h"
+#include "ClubUtils.h"
+#include "Guild.h"
+#include "Player.h"
+
+namespace Battlenet::Services
+{
+ClubMembershipService::ClubMembershipService(WorldSession* session) : BaseService(session) { }
+
+uint32 ClubMembershipService::HandleSubscribe(club::v1::membership::SubscribeRequest const* /*request*/, club::v1::membership::SubscribeResponse* response,
+ std::function<void(ServiceBase*, uint32, google::protobuf::Message const*)>& /*continuation*/)
+{
+ Player const* player = _session->GetPlayer();
+
+ if (!player)
+ return ERROR_INTERNAL;
+
+ Guild const* guild = player->GetGuild();
+
+ if (!guild)
+ return ERROR_OK;
+
+ club::v1::ClubMembershipDescription* description = response->mutable_state()->add_description();
+ description->set_allocated_member_id(CreateClubMemberId(player->GetGUID()).release());
+
+ club::v1::ClubDescription* club = description->mutable_club();
+ club->set_id(guild->GetId());
+ club->set_allocated_type(ClubService::CreateGuildClubType().release());
+ club->set_name(guild->GetName());
+ club->set_privacy_level(club::v1::PrivacyLevel::PRIVACY_LEVEL_OPEN);
+ club->set_visibility_level(club::v1::VISIBILITY_LEVEL_PRIVATE);
+ club->set_member_count(guild->GetMembersCount());
+ club->set_creation_time(
+ std::chrono::duration_cast<std::chrono::microseconds>(SystemTimePoint::clock::from_time_t(guild->GetCreatedDate()).time_since_epoch()).count());
+
+ // Not setting these can cause issues.
+ club->set_timezone("");
+ club->set_locale("");
+
+ club::v1::MemberDescription* leader = club->add_leader();
+
+ leader->set_allocated_id(CreateClubMemberId(guild->GetLeaderGUID()).release());
+
+ response->mutable_state()->mutable_mention_view()->set_last_read_time(0);
+ response->mutable_state()->mutable_mention_view()->set_last_message_time(0);
+
+ return ERROR_OK;
+}
+
+uint32 ClubMembershipService::HandleUnsubscribe(club::v1::membership::UnsubscribeRequest const* /*request*/, NoData* /*response*/,
+ std::function<void(ServiceBase*, uint32, google::protobuf::Message const*)>& /*continuation*/)
+{
+ // We just have to signal the client that the unsubscribe request came through.
+ return ERROR_OK;
+}
+
+std::unique_ptr<club::v1::MemberId> ClubMembershipService::CreateClubMemberId(ObjectGuid guid)
+{
+ std::unique_ptr<club::v1::MemberId> id = std::make_unique<club::v1::MemberId>();
+ id->mutable_account_id()->set_id(sCharacterCache->GetCharacterAccountIdByGuid(guid));
+ id->set_unique_id(Clubs::CreateClubMemberId(guid));
+ return id;
+}
+}
diff --git a/src/server/game/Services/ClubMembershipService.h b/src/server/game/Services/ClubMembershipService.h
new file mode 100644
index 00000000000..f914f8e25cd
--- /dev/null
+++ b/src/server/game/Services/ClubMembershipService.h
@@ -0,0 +1,40 @@
+/*
+ * This file is part of the TrinityCore Project. See AUTHORS file for Copyright information
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef ClubMembershipService_h__
+#define ClubMembershipService_h__
+
+#include "WorldserverService.h"
+#include "club_membership_service.pb.h"
+
+namespace Battlenet::Services
+{
+class ClubMembershipService : public WorldserverService<club::v1::membership::ClubMembershipService>
+{
+ typedef WorldserverService<club::v1::membership::ClubMembershipService> BaseService;
+
+public:
+ ClubMembershipService(WorldSession* session);
+
+ uint32 HandleSubscribe(club::v1::membership::SubscribeRequest const* request, club::v1::membership::SubscribeResponse* response, std::function<void(ServiceBase*, uint32, ::google::protobuf::Message const*)>& continuation) override;
+ uint32 HandleUnsubscribe(club::v1::membership::UnsubscribeRequest const* request, NoData* response, std::function<void(ServiceBase*, uint32, ::google::protobuf::Message const*)>& continuation) override;
+
+ static std::unique_ptr<club::v1::MemberId> CreateClubMemberId(ObjectGuid guid);
+};
+}
+
+#endif // ClubMembershipService_h__
diff --git a/src/server/game/Services/ClubService.cpp b/src/server/game/Services/ClubService.cpp
new file mode 100644
index 00000000000..99df493c2c3
--- /dev/null
+++ b/src/server/game/Services/ClubService.cpp
@@ -0,0 +1,391 @@
+/*
+ * This file is part of the TrinityCore Project. See AUTHORS file for Copyright information
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include "ClubService.h"
+#include "BattlenetRpcErrorCodes.h"
+#include "ClubMembershipService.h"
+#include "GameTime.h"
+#include "Guild.h"
+#include "Player.h"
+#include "SocialMgr.h"
+#include "club_listener.pb.h"
+
+namespace Battlenet::Services
+{
+ClubService::ClubService(WorldSession* session) : BaseService(session) { }
+
+uint32 ClubService::HandleGetClubType(club::v1::GetClubTypeRequest const* request, club::v1::GetClubTypeResponse* response,
+ std::function<void(ServiceBase*, uint32, google::protobuf::Message const*)>& /*continuation*/)
+{
+ // We only support guilds for now.
+ if (request->type().name() == "guild")
+ {
+ response->set_allocated_type(CreateGuildClubType().release());
+ return ERROR_OK;
+ }
+
+ return ERROR_NOT_IMPLEMENTED;
+}
+
+uint32 ClubService::HandleSubscribe(club::v1::SubscribeRequest const* /*request*/, NoData* /*response*/,
+ std::function<void(ServiceBase*, uint32, google::protobuf::Message const*)>& /*continuation*/)
+{
+ Player* player = _session->GetPlayer();
+
+ if (!player)
+ return ERROR_INTERNAL;
+
+ Guild const* guild = player->GetGuild();
+
+ if (!guild)
+ return ERROR_CLUB_NO_CLUB;
+
+ // Subscibe the client to it's own guild club.
+ club::v1::SubscribeNotification subscribeNotification;
+
+ Guild::Member const* guildMember = guild->GetMember(player->GetGUID());
+
+ if (!guildMember)
+ return ERROR_CLUB_NOT_MEMBER;
+
+ Guild::Member const* guildLeader = guild->GetMember(guild->GetLeaderGUID());
+
+ if (!guildLeader)
+ return ERROR_CLUB_NO_SUCH_MEMBER;
+
+ subscribeNotification.set_club_id(guild->GetId());
+ subscribeNotification.set_allocated_agent_id(ClubMembershipService::CreateClubMemberId(player->GetGUID()).release());
+
+ club::v1::Club* guildClub = subscribeNotification.mutable_club();
+
+ guildClub->set_id(guild->GetId());
+ guildClub->set_allocated_type(CreateGuildClubType().release());
+ guildClub->set_name(guild->GetName());
+
+ // These are not related to normal guild functionality so we hardcode them for now.
+ guildClub->set_privacy_level(club::v1::PrivacyLevel::PRIVACY_LEVEL_OPEN);
+ guildClub->set_visibility_level(club::v1::VISIBILITY_LEVEL_PRIVATE);
+
+ guildClub->set_member_count(guild->GetMembersCount());
+
+ // Set the club leader, guild master in this case.
+ club::v1::MemberDescription* guildLeaderDescription = guildClub->add_leader();
+
+ guildLeaderDescription->mutable_id()->mutable_account_id()->set_id(guildLeader->GetAccountId());
+ guildLeaderDescription->mutable_id()->set_unique_id(guildLeader->GetGUID().GetCounter());
+
+ club::v1::Member* subscriber = subscribeNotification.mutable_member();
+
+ // The member sending the notification data.
+ subscriber->set_allocated_id(ClubMembershipService::CreateClubMemberId(player->GetGUID()).release());
+
+ // Community/Club default roles have slightly different values.
+ // Also this is required to set the current leader/guild master symbol in the interface.
+ // 1 = Owner, 4 = Member. Once communities are fully implemented these will go into a new database table.
+ if (guildMember->IsRank(GuildRankId::GuildMaster))
+ subscriber->add_role(AsUnderlyingType(ClubRoleIdentifier::Owner));
+ else if (guild->HasAnyRankRight(guildMember->GetRankId(), GuildRankRights(GR_RIGHT_OFFCHATLISTEN | GR_RIGHT_OFFCHATSPEAK)))
+ subscriber->add_role(AsUnderlyingType(ClubRoleIdentifier::Moderator));
+ else
+ subscriber->add_role(AsUnderlyingType(ClubRoleIdentifier::Member));
+
+ subscriber->set_presence_level(club::v1::PRESENCE_LEVEL_RICH);
+ subscriber->set_whisper_level(club::v1::WHISPER_LEVEL_OPEN);
+
+ // Member is online and active.
+ subscriber->set_active(true);
+
+ WorldserverService<club::v1::ClubListener>(_session).OnSubscribe(&subscribeNotification, true, true);
+
+ // Notify the client about the changed club state.
+ club::v1::SubscriberStateChangedNotification subscriberStateChangedNotification;
+
+ subscriberStateChangedNotification.set_club_id(guild->GetId());
+
+ club::v1::SubscriberStateAssignment* assignment = subscriberStateChangedNotification.add_assignment();
+
+ assignment->set_allocated_member_id(ClubMembershipService::CreateClubMemberId(player->GetGUID()).release());
+
+ // Member is online and active.
+ assignment->set_active(true);
+
+ WorldserverService<club::v1::ClubListener>(_session).OnSubscriberStateChanged(&subscriberStateChangedNotification, true, true);
+
+ return ERROR_OK;
+}
+
+uint32 ClubService::HandleGetMembers(club::v1::GetMembersRequest const* /*request*/, club::v1::GetMembersResponse* response,
+ std::function<void(ServiceBase*, uint32, google::protobuf::Message const*)>& /*continuation*/)
+{
+ Player* player = _session->GetPlayer();
+
+ if (!player)
+ return ERROR_INTERNAL;
+
+ Guild const* guild = player->GetGuild();
+
+ if (!guild)
+ return ERROR_CLUB_NO_CLUB;
+
+ for (auto const& [guid, member] : guild->GetMembers())
+ {
+ club::v1::Member* clubMember = response->add_member();
+
+ clubMember->set_allocated_id(ClubMembershipService::CreateClubMemberId(guid).release());
+
+ // Community/Club default roles have slightly different values.
+ // When communities are implemented those are going to be database fields.
+ if (member.IsRank(GuildRankId::GuildMaster))
+ clubMember->add_role(AsUnderlyingType(ClubRoleIdentifier::Owner));
+ else if (guild->HasAnyRankRight(member.GetRankId(), GuildRankRights(GR_RIGHT_OFFCHATLISTEN | GR_RIGHT_OFFCHATSPEAK)))
+ clubMember->add_role(AsUnderlyingType(ClubRoleIdentifier::Moderator));
+ else
+ clubMember->add_role(AsUnderlyingType(ClubRoleIdentifier::Member));
+
+ clubMember->set_presence_level(club::v1::PresenceLevel::PRESENCE_LEVEL_RICH);
+ clubMember->set_whisper_level(club::v1::WhisperLevel::WHISPER_LEVEL_OPEN);
+ clubMember->set_note(member.GetPublicNote());
+ clubMember->set_active(member.IsOnline());
+ }
+
+ return ERROR_OK;
+}
+
+uint32 ClubService::HandleGetStreams(club::v1::GetStreamsRequest const* /*request*/, club::v1::GetStreamsResponse* response,
+ std::function<void(ServiceBase*, uint32, google::protobuf::Message const*)>& /*continuation*/)
+{
+ Player* player = _session->GetPlayer();
+
+ if (!player)
+ return ERROR_INTERNAL;
+
+ Guild const* guild = player->GetGuild();
+
+ if (!guild)
+ return ERROR_CLUB_NO_CLUB;
+
+ // General guild channel.
+ club::v1::Stream* generalGuildChannelStream = response->add_stream();
+
+ generalGuildChannelStream->set_club_id(guild->GetId());
+ generalGuildChannelStream->set_id(AsUnderlyingType(ClubStreamType::Guild));
+
+ v2::Attribute* generalStreamAttribute = generalGuildChannelStream->add_attribute();
+
+ generalStreamAttribute->set_name("global_strings_tag");
+ generalStreamAttribute->mutable_value()->set_string_value("COMMUNITIES_GUILD_GENERAL_CHANNEL_NAME");
+
+ generalGuildChannelStream->set_name("Guild");
+
+ // All roles got access to this channel.
+ // Club roles are currently guild role + 1.
+ // With a complete club/community system those will be handled differently.
+ generalGuildChannelStream->mutable_access()->add_role(AsUnderlyingType(ClubRoleIdentifier::Owner));
+ generalGuildChannelStream->mutable_access()->add_role(AsUnderlyingType(ClubRoleIdentifier::Leader));
+ generalGuildChannelStream->mutable_access()->add_role(AsUnderlyingType(ClubRoleIdentifier::Moderator));
+ generalGuildChannelStream->mutable_access()->add_role(AsUnderlyingType(ClubRoleIdentifier::Member));
+
+ // No voice support.
+ generalGuildChannelStream->set_voice_level(club::v1::StreamVoiceLevel::VOICE_LEVEL_DISABLED);
+
+ // Officer guild channel.
+ club::v1::Stream* officerGuildChannelStream = response->add_stream();
+
+ officerGuildChannelStream->set_club_id(guild->GetId());
+ officerGuildChannelStream->set_id(AsUnderlyingType(ClubStreamType::Officer));
+
+ v2::Attribute* officerStreamAttribute = officerGuildChannelStream->add_attribute();
+
+ officerStreamAttribute->set_name("global_strings_tag");
+ officerStreamAttribute->mutable_value()->set_string_value("COMMUNITIES_GUILD_OFFICER_CHANNEL_NAME");
+
+ officerGuildChannelStream->set_name("Officer");
+
+ // All roles got access to this channel.
+ // Club roles are currently guild role + 1.
+ // With a complete club/community system those will be handled differently.
+ officerGuildChannelStream->mutable_access()->add_role(AsUnderlyingType(ClubRoleIdentifier::Owner));
+ officerGuildChannelStream->mutable_access()->add_role(AsUnderlyingType(ClubRoleIdentifier::Leader));
+ officerGuildChannelStream->mutable_access()->add_role(AsUnderlyingType(ClubRoleIdentifier::Moderator));
+
+ // No voice support.
+ officerGuildChannelStream->set_voice_level(club::v1::StreamVoiceLevel::VOICE_LEVEL_DISABLED);
+
+ // Enable channel view
+ club::v1::StreamView* generalView = response->add_view();
+
+ generalView->set_club_id(guild->GetId());
+ generalView->set_stream_id(AsUnderlyingType(ClubStreamType::Guild));
+
+ club::v1::StreamView* officerView = response->add_view();
+
+ officerView->set_club_id(guild->GetId());
+ officerView->set_stream_id(AsUnderlyingType(ClubStreamType::Officer));
+
+ return ERROR_OK;
+}
+
+uint32 ClubService::HandleSubscribeStream(club::v1::SubscribeStreamRequest const* request, NoData* /*response*/,
+ std::function<void(ServiceBase*, uint32, google::protobuf::Message const*)>& /*continuation*/)
+{
+ Player const* player = _session->GetPlayer();
+
+ if (!player)
+ return ERROR_INTERNAL;
+
+ Guild const* guild = player->GetGuild();
+
+ if (!guild)
+ return ERROR_CLUB_NO_CLUB;
+
+ // Basic sanity check until full communities are implemented.
+ // 1 - Guild, 2 - Officer chat stream.
+ if (request->stream_id().empty() || (request->stream_id().Get(0) != AsUnderlyingType(ClubStreamType::Guild) && request->stream_id().Get(0) != AsUnderlyingType(ClubStreamType::Officer)))
+ return ERROR_CLUB_STREAM_NO_STREAM;
+
+ return ERROR_OK;
+}
+
+uint32 ClubService::HandleUnsubscribeStream(club::v1::UnsubscribeStreamRequest const* /*request*/, NoData* /*response*/,
+ std::function<void(ServiceBase*, uint32, google::protobuf::Message const*)>& /*continuation*/)
+{
+ // We just have to signal the client that the unsubscribe request came through.
+ return ERROR_OK;
+}
+
+uint32 ClubService::HandleSetStreamFocus(club::v1::SetStreamFocusRequest const* /*request*/, NoData* /*response*/,
+ std::function<void(ServiceBase*, uint32, google::protobuf::Message const*)>& /*continuation*/)
+{
+ Player const* player = _session->GetPlayer();
+
+ if (!player)
+ return ERROR_INTERNAL;
+
+ Guild const* guild = player->GetGuild();
+
+ if (!guild)
+ return ERROR_CLUB_NOT_MEMBER;
+
+ return ERROR_OK;
+}
+
+uint32 ClubService::HandleAdvanceStreamViewTime(club::v1::AdvanceStreamViewTimeRequest const* /*request*/, NoData* /*response*/,
+ std::function<void(ServiceBase*, uint32, google::protobuf::Message const*)>& /*continuation*/)
+{
+ Player const* player = _session->GetPlayer();
+
+ if (!player)
+ return ERROR_INTERNAL;
+
+ Guild const* guild = player->GetGuild();
+
+ if (!guild)
+ return ERROR_CLUB_NOT_MEMBER;
+
+ return ERROR_OK;
+}
+
+uint32 ClubService::HandleCreateMessage(club::v1::CreateMessageRequest const* request, club::v1::CreateMessageResponse* response,
+ std::function<void(ServiceBase*, uint32, google::protobuf::Message const*)>& continuation)
+{
+ // Basic sanity check until full communities are implemented.
+ // 1 - Guild, 2 - Officer chat stream.
+ if (request->stream_id() != AsUnderlyingType(ClubStreamType::Guild) && request->stream_id() != AsUnderlyingType(ClubStreamType::Officer))
+ return ERROR_CLUB_STREAM_NO_STREAM;
+
+ // Just some sanity checks. We do not care about the requested stream for now since we only have two.
+ Player const* player = _session->GetPlayer();
+
+ if (!player)
+ return ERROR_INTERNAL;
+
+ Guild const* guild = player->GetGuild();
+
+ if (!guild)
+ return ERROR_CLUB_NO_CLUB;
+
+ GuildRankRights requiredRights = { };
+ ChatMessageResult result = { };
+
+ switch (ClubStreamType(request->stream_id()))
+ {
+ case ClubStreamType::Guild:
+ requiredRights = GR_RIGHT_GCHATLISTEN;
+ result = _session->HandleChatMessage(CHAT_MSG_GUILD, LANG_UNIVERSAL, request->options().content());
+ break;
+ case ClubStreamType::Officer:
+ requiredRights = GR_RIGHT_OFFCHATLISTEN;
+ result = _session->HandleChatMessage(CHAT_MSG_OFFICER, LANG_UNIVERSAL, request->options().content());
+ break;
+ default:
+ return ERROR_CLUB_STREAM_NO_STREAM;
+ }
+
+ if (result == ChatMessageResult::Ok)
+ {
+ std::chrono::microseconds messageTime = std::chrono::duration_cast<std::chrono::microseconds>(GameTime::GetSystemTime().time_since_epoch());
+
+ FillStreamMessage(response->mutable_message(), request->options().content(), messageTime, player->GetGUID());
+
+ club::v1::StreamMessageAddedNotification messageAddedNotification;
+ messageAddedNotification.set_allocated_agent_id(ClubMembershipService::CreateClubMemberId(player->GetGUID()).release());
+ messageAddedNotification.set_club_id(guild->GetId());
+ messageAddedNotification.set_stream_id(request->stream_id());
+ FillStreamMessage(messageAddedNotification.mutable_message(), request->options().content(), messageTime, player->GetGUID());
+
+ guild->BroadcastWorker([&](Player const* receiver)
+ {
+ Guild::Member const* receiverMember = guild->GetMember(receiver->GetGUID());
+ if (!guild->HasAnyRankRight(receiverMember->GetRankId(), requiredRights))
+ return;
+
+ if (receiver->GetSocial()->HasIgnore(player->GetGUID(), _session->GetAccountGUID()))
+ return;
+
+ WorldserverService<club::v1::ClubListener>(receiver->GetSession()).OnStreamMessageAdded(&messageAddedNotification, true, true);
+ }, player);
+
+ return ERROR_OK;
+ }
+
+ // If the message is empty there should never be a response to message request.
+ continuation = nullptr;
+
+ return ERROR_CLUB_STREAM_NO_SUCH_MESSAGE;
+}
+
+std::unique_ptr<club::v1::UniqueClubType> ClubService::CreateGuildClubType()
+{
+ std::unique_ptr<club::v1::UniqueClubType> type = std::make_unique<club::v1::UniqueClubType>();
+ type->set_program(5730135);
+ type->set_name("guild");
+ return type;
+}
+
+void ClubService::FillStreamMessage(club::v1::StreamMessage* message, std::string_view msg, std::chrono::microseconds messageTime, ObjectGuid author)
+{
+ message->mutable_id()->set_epoch(messageTime.count());
+ message->mutable_id()->set_position(0);
+
+ message->mutable_author()->set_allocated_id(ClubMembershipService::CreateClubMemberId(author).release());
+
+ club::v1::ContentChain* contentChain = message->add_content_chain();
+
+ contentChain->set_content(msg.data(), msg.size());
+ contentChain->set_edit_time(messageTime.count());
+}
+}
diff --git a/src/server/game/Services/ClubService.h b/src/server/game/Services/ClubService.h
new file mode 100644
index 00000000000..8a7072bc5d0
--- /dev/null
+++ b/src/server/game/Services/ClubService.h
@@ -0,0 +1,51 @@
+/*
+ * This file is part of the TrinityCore Project. See AUTHORS file for Copyright information
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef ClubService_h__
+#define ClubService_h__
+
+#include "WorldserverService.h"
+#include "club_service.pb.h"
+
+namespace Battlenet::Services
+{
+class ClubService : public WorldserverService<club::v1::ClubService>
+{
+ typedef WorldserverService<club::v1::ClubService> BaseService;
+
+public:
+
+ ClubService(WorldSession* session);
+
+ uint32 HandleGetClubType(club::v1::GetClubTypeRequest const* request, club::v1::GetClubTypeResponse* response, std::function<void(ServiceBase*, uint32, ::google::protobuf::Message const*)>& continuation) override;
+ uint32 HandleSubscribe(club::v1::SubscribeRequest const* request, NoData* response, std::function<void(ServiceBase*, uint32, ::google::protobuf::Message const*)>& continuation) override;
+ uint32 HandleGetMembers(club::v1::GetMembersRequest const* request, club::v1::GetMembersResponse* response, std::function<void(ServiceBase*, uint32, ::google::protobuf::Message const*)>& continuation) override;
+ uint32 HandleGetStreams(club::v1::GetStreamsRequest const* request, club::v1::GetStreamsResponse* response, std::function<void(ServiceBase*, uint32, ::google::protobuf::Message const*)>& continuation) override;
+ uint32 HandleSubscribeStream(club::v1::SubscribeStreamRequest const* request, NoData* response, std::function<void(ServiceBase*, uint32, ::google::protobuf::Message const*)>& continuation) override;
+ uint32 HandleUnsubscribeStream(club::v1::UnsubscribeStreamRequest const* request, NoData* response, std::function<void(ServiceBase*, uint32, ::google::protobuf::Message const*)>& continuation) override;
+ uint32 HandleSetStreamFocus(club::v1::SetStreamFocusRequest const* request, NoData* response, std::function<void(ServiceBase*, uint32, ::google::protobuf::Message const*)>& continuation) override;
+ uint32 HandleAdvanceStreamViewTime(club::v1::AdvanceStreamViewTimeRequest const* request, NoData* response, std::function<void(ServiceBase*, uint32, ::google::protobuf::Message const*)>& continuation) override;
+ uint32 HandleCreateMessage(club::v1::CreateMessageRequest const* request, club::v1::CreateMessageResponse* response, std::function<void(ServiceBase*, uint32, ::google::protobuf::Message const*)>& continuation) override;
+
+ static std::unique_ptr<club::v1::UniqueClubType> CreateGuildClubType();
+
+private:
+ static void FillStreamMessage(club::v1::StreamMessage* message, std::string_view msg, std::chrono::microseconds messageTime, ObjectGuid author);
+};
+}
+
+#endif // ClubService_h__
diff --git a/src/server/game/Services/ClubUtils.cpp b/src/server/game/Services/ClubUtils.cpp
new file mode 100644
index 00000000000..7147b2367b1
--- /dev/null
+++ b/src/server/game/Services/ClubUtils.cpp
@@ -0,0 +1,25 @@
+/*
+ * This file is part of the TrinityCore Project. See AUTHORS file for Copyright information
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include "ClubUtils.h"
+#include "Realm.h"
+#include "World.h"
+
+uint64 Battlenet::Services::Clubs::CreateClubMemberId(ObjectGuid guid)
+{
+ return guid.GetCounter() | (uint64(realm.Id.Realm & 0xFFF) << 48);
+}
diff --git a/src/server/game/Services/ClubUtils.h b/src/server/game/Services/ClubUtils.h
new file mode 100644
index 00000000000..719c8295867
--- /dev/null
+++ b/src/server/game/Services/ClubUtils.h
@@ -0,0 +1,28 @@
+/*
+ * This file is part of the TrinityCore Project. See AUTHORS file for Copyright information
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef TRINITYCORE_CLUB_UTILS_H
+#define TRINITYCORE_CLUB_UTILS_H
+
+#include "ObjectGuid.h"
+
+namespace Battlenet::Services::Clubs
+{
+uint64 CreateClubMemberId(ObjectGuid guid);
+}
+
+#endif // TRINITYCORE_CLUB_UTILS_H
diff --git a/src/server/game/Services/WorldserverGameUtilitiesService.h b/src/server/game/Services/WorldserverGameUtilitiesService.h
index 46e729eae22..2d7832686b3 100644
--- a/src/server/game/Services/WorldserverGameUtilitiesService.h
+++ b/src/server/game/Services/WorldserverGameUtilitiesService.h
@@ -23,8 +23,6 @@
namespace Battlenet
{
- class Session;
-
namespace Services
{
class GameUtilitiesService : public WorldserverService<game_utilities::v1::GameUtilitiesService>
diff --git a/src/server/game/Services/WorldserverServiceDispatcher.cpp b/src/server/game/Services/WorldserverServiceDispatcher.cpp
index 77177139790..62e25e6e326 100644
--- a/src/server/game/Services/WorldserverServiceDispatcher.cpp
+++ b/src/server/game/Services/WorldserverServiceDispatcher.cpp
@@ -21,8 +21,8 @@ Battlenet::WorldserverServiceDispatcher::WorldserverServiceDispatcher()
{
AddService<WorldserverService<account::v1::AccountService>>();
AddService<WorldserverService<authentication::v1::AuthenticationService>>();
- AddService<WorldserverService<club::v1::membership::ClubMembershipService>>();
- AddService<WorldserverService<club::v1::ClubService>>();
+ AddService<Services::ClubMembershipService>();
+ AddService<Services::ClubService>();
AddService<WorldserverService<connection::v1::ConnectionService>>();
AddService<WorldserverService<friends::v1::FriendsService>>();
AddService<Services::GameUtilitiesService>();
diff --git a/src/server/game/Services/WorldserverServiceDispatcher.h b/src/server/game/Services/WorldserverServiceDispatcher.h
index c40d2c883ab..70e76aacc3f 100644
--- a/src/server/game/Services/WorldserverServiceDispatcher.h
+++ b/src/server/game/Services/WorldserverServiceDispatcher.h
@@ -26,8 +26,8 @@
#include "challenge_service.pb.h"
#include "club_listener.pb.h"
#include "club_membership_listener.pb.h"
-#include "club_membership_service.pb.h"
-#include "club_service.pb.h"
+#include "ClubMembershipService.h"
+#include "ClubService.h"
#include "connection_service.pb.h"
#include "friends_service.pb.h"
#include "WorldserverGameUtilitiesService.h"
diff --git a/src/server/proto/BattlenetRpcErrorCodes.h b/src/server/proto/BattlenetRpcErrorCodes.h
index 1f7e0b56ebf..5b25bfebb4b 100644
--- a/src/server/proto/BattlenetRpcErrorCodes.h
+++ b/src/server/proto/BattlenetRpcErrorCodes.h
@@ -30,44 +30,28 @@ enum BattlenetRpcErrorCode : uint32
ERROR_NOT_STARTED = 0x00000005,
ERROR_IN_PROGRESS = 0x00000006,
ERROR_INVALID_ARGS = 0x00000007,
- ERROR_INVALID_SUBSCRIBER = 0x00000008,
- ERROR_WAITING_FOR_DEPENDENCY = 0x00000009,
ERROR_NO_AUTH = 0x0000000A,
ERROR_PARENTAL_CONTROL_RESTRICTION = 0x0000000B,
ERROR_NO_GAME_ACCOUNT = 0x0000000C,
ERROR_NOT_IMPLEMENTED = 0x0000000D,
- ERROR_OBJECT_REMOVED = 0x0000000E,
- ERROR_INVALID_ENTITY_ID = 0x0000000F,
- ERROR_INVALID_ENTITY_ACCOUNT_ID = 0x00000010,
- ERROR_INVALID_ENTITY_GAME_ACCOUNT_ID = 0x00000011,
ERROR_INVALID_AGENT_ID = 0x00000013,
ERROR_INVALID_TARGET_ID = 0x00000014,
- ERROR_MODULE_NOT_LOADED = 0x00000015,
- ERROR_MODULE_NO_ENTRY_POINT = 0x00000016,
- ERROR_MODULE_SIGNATURE_INCORRECT = 0x00000017,
- ERROR_MODULE_CREATE_FAILED = 0x00000018,
ERROR_NO_PROGRAM = 0x00000019,
ERROR_API_NOT_READY = 0x0000001B,
ERROR_BAD_VERSION = 0x0000001C,
ERROR_ATTRIBUTE_TOO_MANY_ATTRIBUTES_SET = 0x0000001D,
ERROR_ATTRIBUTE_MAX_SIZE_EXCEEDED = 0x0000001E,
ERROR_ATTRIBUTE_QUOTA_EXCEEDED = 0x0000001F,
- ERROR_SERVER_POOL_SERVER_DISAPPEARED = 0x00000020,
ERROR_SERVER_IS_PRIVATE = 0x00000021,
ERROR_DISABLED = 0x00000022,
- ERROR_MODULE_NOT_FOUND = 0x00000024,
ERROR_SERVER_BUSY = 0x00000025,
ERROR_NO_BATTLETAG = 0x00000026,
- ERROR_INCOMPLETE_PROFANITY_FILTERS = 0x00000027,
ERROR_INVALID_REGION = 0x00000028,
ERROR_EXISTS_ALREADY = 0x00000029,
- ERROR_INVALID_SERVER_THUMBPRINT = 0x0000002A,
ERROR_PHONE_LOCK = 0x0000002B,
ERROR_SQUELCHED = 0x0000002C,
ERROR_TARGET_OFFLINE = 0x0000002D,
ERROR_BAD_SERVER = 0x0000002E,
- ERROR_NO_COOKIE = 0x0000002F,
- ERROR_EXPIRED_COOKIE = 0x00000030,
ERROR_TOKEN_NOT_FOUND = 0x00000031,
ERROR_GAME_ACCOUNT_NO_TIME = 0x00000032,
ERROR_GAME_ACCOUNT_NO_PLAN = 0x00000033,
@@ -77,13 +61,17 @@ enum BattlenetRpcErrorCode : uint32
ERROR_GAME_ACCOUNT_CANCELLED = 0x00000037,
ERROR_GAME_ACCOUNT_CREATION_DISABLED = 0x00000038,
ERROR_GAME_ACCOUNT_LOCKED = 0x00000039,
-
+ ERROR_GAME_ACCOUNT_PHONE_LOCK = 0x0000003A,
+ ERROR_GAME_ACCOUNT_BILLING_LOCK = 0x0000003B,
ERROR_SESSION_DUPLICATE = 0x0000003C,
ERROR_SESSION_DISCONNECTED = 0x0000003D,
ERROR_SESSION_DATA_CHANGED = 0x0000003E,
ERROR_SESSION_UPDATE_FAILED = 0x0000003F,
ERROR_SESSION_NOT_FOUND = 0x00000040,
-
+ ERROR_SESSION_FREE_PLAY_NOT_SUPPORTED = 0x00000041,
+ ERROR_SESSION_SUBSCRIPTION_ADDED = 0x00000042,
+ ERROR_SESSION_CONSUMPTION_TIME_ADDED = 0x00000043,
+ ERROR_SESSION_TOKEN_NOT_FOUND = 0x00000044,
ERROR_ADMIN_KICK = 0x00000046,
ERROR_UNPLANNED_MAINTENANCE = 0x00000047,
ERROR_PLANNED_MAINTENANCE = 0x00000048,
@@ -99,42 +87,29 @@ enum BattlenetRpcErrorCode : uint32
ERROR_LOCALE_RESTRICTED_KO = 0x00000053,
ERROR_LOCALE_RESTRICTED_TW = 0x00000054,
ERROR_LOCALE_RESTRICTED = 0x00000055,
- ERROR_ACCOUNT_NEEDS_MAINTENANCE = 0x00000056,
- ERROR_MODULE_API_ERROR = 0x00000057,
- ERROR_MODULE_BAD_CACHE_HANDLE = 0x00000058,
- ERROR_MODULE_ALREADY_LOADED = 0x00000059,
- ERROR_NETWORK_BLACKLISTED = 0x0000005A,
+ ERROR_NETWORK_BLOCKLISTED = 0x0000005A,
ERROR_EVENT_PROCESSOR_SLOW = 0x0000005B,
ERROR_SERVER_SHUTTING_DOWN = 0x0000005C,
ERROR_NETWORK_NOT_PRIVILEGED = 0x0000005D,
ERROR_TOO_MANY_OUTSTANDING_REQUESTS = 0x0000005E,
- ERROR_NO_ACCOUNT_REGISTERED = 0x0000005F,
ERROR_BATTLENET_ACCOUNT_BANNED = 0x00000060,
-
- ERROR_OK_DEPRECATED = 0x00000064,
ERROR_SERVER_IN_MODE_ZOMBIE = 0x00000065,
+ ERROR_AGENT_IS_BLOCKING_TARGET = 0x00000066,
+ ERROR_TARGET_IS_BLOCKING_AGENT = 0x00000067,
+ ERROR_FEATURE_UNAVAILABLE = 0x00000068,
+ ERROR_BROKEN_PROMISE = 0x00000069,
+ ERROR_UNINITIALIZED_EXPECTED = 0x0000006A,
+ ERROR_NO_SSL_CONNECTION = 0x0000006B,
+ ERROR_SERVICE_NOT_READY = 0x0000006E,
- ERROR_LOGON_MODULE_REQUIRED = 0x000001F4,
- ERROR_LOGON_MODULE_NOT_CONFIGURED = 0x000001F5,
- ERROR_LOGON_MODULE_TIMEOUT = 0x000001F6,
- ERROR_LOGON_AGREEMENT_REQUIRED = 0x000001FE,
- ERROR_LOGON_AGREEMENT_NOT_CONFIGURED = 0x000001FF,
-
- ERROR_LOGON_INVALID_SERVER_PROOF = 0x00000208,
ERROR_LOGON_WEB_VERIFY_TIMEOUT = 0x00000209,
ERROR_LOGON_INVALID_AUTH_TOKEN = 0x0000020A,
-
- ERROR_CHALLENGE_SMS_TOO_SOON = 0x00000258,
- ERROR_CHALLENGE_SMS_THROTTLED = 0x00000259,
- ERROR_CHALLENGE_SMS_TEMP_OUTAGE = 0x0000025A,
- ERROR_CHALLENGE_NO_CHALLENGE = 0x0000025B,
- ERROR_CHALLENGE_NOT_PICKED = 0x0000025C,
- ERROR_CHALLENGE_ALREADY_PICKED = 0x0000025D,
- ERROR_CHALLENGE_IN_PROGRESS = 0x0000025E,
+ ERROR_LOGON_TASSADAR_REQUEST_FAILED = 0x0000020B,
ERROR_CONFIG_FORMAT_INVALID = 0x000002BC,
ERROR_CONFIG_NOT_FOUND = 0x000002BD,
ERROR_CONFIG_RETRIEVE_FAILED = 0x000002BE,
+ ERROR_CONFIG_DUMP_FAILED = 0x000002BF,
ERROR_NETWORK_MODULE_BUSY = 0x000003E8,
ERROR_NETWORK_MODULE_CANT_RESOLVE_ADDRESS = 0x000003E9,
@@ -153,12 +128,10 @@ enum BattlenetRpcErrorCode : uint32
ERROR_NETWORK_MODULE_NO_SSL_COMMON_NAME_FOR_CERTIFICATE = 0x000003F6,
ERROR_NETWORK_MODULE_SSL_COMMON_NAME_DOES_NOT_MATCH_REMOTE_ENDPOINT = 0x000003F7,
ERROR_NETWORK_MODULE_SOCKET_CLOSED = 0x000003F8,
- ERROR_NETWORK_MODULE_SSL_PEER_IS_NOT_REGISTERED_IN_CERTBUNDLE = 0x000003F9,
- ERROR_NETWORK_MODULE_SSL_INITIALIZE_LOW_FIRST = 0x000003FA,
- ERROR_NETWORK_MODULE_SSL_CERT_BUNDLE_READ_ERROR = 0x000003FB,
- ERROR_NETWORK_MODULE_NO_CERT_BUNDLE = 0x000003FC,
- ERROR_NETWORK_MODULE_FAILED_TO_DOWNLOAD_CERT_BUNDLE = 0x000003FD,
ERROR_NETWORK_MODULE_NOT_READY_TO_READ = 0x000003FE,
+ ERROR_NETWORK_MODULE_SSL_CERT_CHAIN_VALIDATION_FAILED = 0x000003FF,
+ ERROR_NETWORK_MODULE_NETWORK_DOWN = 0x00000401,
+ ERROR_NETWORK_MODULE_SSL_INITIALIZATION_FAILED = 0x00000402,
ERROR_NETWORK_MODULE_OPENSSL_X509_OK = 0x000004B0,
ERROR_NETWORK_MODULE_OPENSSL_X509_UNABLE_TO_GET_ISSUER_CERT = 0x000004B1,
@@ -200,6 +173,7 @@ enum BattlenetRpcErrorCode : uint32
ERROR_NETWORK_MODULE_SCHANNEL_CANNOT_FIND_INTERFACE = 0x00000517,
ERROR_NETWORK_MODULE_SCHANNEL_INIT_FAIL = 0x00000518,
ERROR_NETWORK_MODULE_SCHANNEL_FUNCTION_CALL_FAIL = 0x00000519,
+ ERROR_NETWORK_MODULE_SCHANNEL_HANDSHAKE_FAILURE = 0x0000051A,
ERROR_NETWORK_MODULE_SCHANNEL_X509_UNABLE_TO_GET_ISSUER_CERT = 0x00000546,
ERROR_NETWORK_MODULE_SCHANNEL_X509_TIME_INVALID = 0x00000547,
ERROR_NETWORK_MODULE_SCHANNEL_X509_SIGNATURE_INVALID = 0x00000548,
@@ -207,24 +181,31 @@ enum BattlenetRpcErrorCode : uint32
ERROR_NETWORK_MODULE_SCHANNEL_X509_SELF_SIGNED_LEAF_CERTIFICATE = 0x0000054A,
ERROR_NETWORK_MODULE_SCHANNEL_X509_UNHANDLED_ERROR = 0x0000054B,
ERROR_NETWORK_MODULE_SCHANNEL_X509_SELF_SIGNED_CERT_IN_CHAIN = 0x0000054C,
-
ERROR_WEBSOCKET_HANDSHAKE = 0x00000578,
-
ERROR_NETWORK_MODULE_DURANGO_UNKNOWN = 0x000005DC,
ERROR_NETWORK_MODULE_DURANGO_MALFORMED_HOST_NAME = 0x000005DD,
ERROR_NETWORK_MODULE_DURANGO_INVALID_CONNECTION_RESPONSE = 0x000005DE,
ERROR_NETWORK_MODULE_DURANGO_INVALID_CA_CERT = 0x000005DF,
+ ERROR_NETWORK_MODULE_DARWINSSL_FUNCTION_CALL_FAIL = 0x00000640,
+ ERROR_NETWORK_MODULE_DARWINSSL_X509_NEVER_TRUST = 0x00000672,
+ ERROR_NETWORK_MODULE_DARWINSSL_X509_UNKNOWN_ERROR = 0x00000676,
+ ERROR_NETWORK_MODULE_SCE_SSL_CONTEXT_ALLOCATE_FAILED = 0x000006A4,
+ ERROR_NETWORK_MODULE_SCE_SSL_CONNECTION_ALLOCATE_FAILED = 0x000006A5,
+ ERROR_NETWORK_MODULE_SCE_SSL_SET_VERIFY_OPTION_FAILED = 0x000006A6,
+ ERROR_NETWORK_MODULE_SCE_SSL_HANDSHAKE_FAILED = 0x000006A7,
+
+ ERROR_SDK_MESSAGE_HANDLER_NOT_FOUND = 0x0000076C,
+ ERROR_SDK_TASSADAR_CLIENT_INVALID_INPUT = 0x00000776,
+ ERROR_SDK_TASSADAR_SERVER_ERROR = 0x00000777,
+ ERROR_SDK_TASSADAR_SERVER_MAINTENANCE = 0x00000778,
ERROR_RPC_WRITE_FAILED = 0x00000BB8,
- ERROR_RPC_SERVICE_NOT_BOUND = 0x00000BB9,
ERROR_RPC_TOO_MANY_REQUESTS = 0x00000BBA,
ERROR_RPC_PEER_UNKNOWN = 0x00000BBB,
ERROR_RPC_PEER_UNAVAILABLE = 0x00000BBC,
ERROR_RPC_PEER_DISCONNECTED = 0x00000BBD,
ERROR_RPC_REQUEST_TIMED_OUT = 0x00000BBE,
- ERROR_RPC_CONNECTION_TIMED_OUT = 0x00000BBF,
ERROR_RPC_MALFORMED_RESPONSE = 0x00000BC0,
- ERROR_RPC_ACCESS_DENIED = 0x00000BC1,
ERROR_RPC_INVALID_SERVICE = 0x00000BC2,
ERROR_RPC_INVALID_METHOD = 0x00000BC3,
ERROR_RPC_INVALID_OBJECT = 0x00000BC4,
@@ -234,30 +215,25 @@ enum BattlenetRpcErrorCode : uint32
ERROR_RPC_SERVER_ERROR = 0x00000BC8,
ERROR_RPC_SHUTDOWN = 0x00000BC9,
ERROR_RPC_DISCONNECT = 0x00000BCA,
- ERROR_RPC_DISCONNECT_IDLE = 0x00000BCB,
ERROR_RPC_PROTOCOL_ERROR = 0x00000BCC,
ERROR_RPC_NOT_READY = 0x00000BCD,
ERROR_RPC_FORWARD_FAILED = 0x00000BCE,
- ERROR_RPC_ENCRYPTION_FAILED = 0x00000BCF,
ERROR_RPC_INVALID_ADDRESS = 0x00000BD0,
ERROR_RPC_METHOD_DISABLED = 0x00000BD1,
ERROR_RPC_SHARD_NOT_FOUND = 0x00000BD2,
ERROR_RPC_INVALID_CONNECTION_ID = 0x00000BD3,
ERROR_RPC_NOT_CONNECTED = 0x00000BD4,
ERROR_RPC_INVALID_CONNECTION_STATE = 0x00000BD5,
- ERROR_RPC_SERVICE_ALREADY_REGISTERED = 0x00000BD6,
-
- ERROR_PRESENCE_INVALID_FIELD_ID = 0x00000FA0,
- ERROR_PRESENCE_NO_VALID_SUBSCRIBERS = 0x00000FA1,
- ERROR_PRESENCE_ALREADY_SUBSCRIBED = 0x00000FA2,
- ERROR_PRESENCE_CONSUMER_NOT_FOUND = 0x00000FA3,
- ERROR_PRESENCE_CONSUMER_IS_NULL = 0x00000FA4,
- ERROR_PRESENCE_TEMPORARY_OUTAGE = 0x00000FA5,
+ ERROR_RPC_CONNECTION_UNREACHABLE = 0x00000BD7,
+ ERROR_RPC_NO_BUFFER_SPACE = 0x00000BD8,
+ ERROR_RPC_HTTP_PROBE = 0x00000BD9,
+ ERROR_RPC_CLIENT_ID_REQUIRED = 0x00000BDA,
+ ERROR_RPC_CONNECTION_REPLACED = 0x00000BDB,
+ ERROR_RPC_INVALID_ROUTE = 0x00000BDC,
+
ERROR_PRESENCE_TOO_MANY_SUBSCRIPTIONS = 0x00000FA6,
- ERROR_PRESENCE_SUBSCRIPTION_CANCELLED = 0x00000FA7,
- ERROR_PRESENCE_RICH_PRESENCE_PARSE_ERROR = 0x00000FA8,
- ERROR_PRESENCE_RICH_PRESENCE_XML_ERROR = 0x00000FA9,
- ERROR_PRESENCE_RICH_PRESENCE_LOAD_ERROR = 0x00000FAA,
+ ERROR_PRESENCE_NO_RECORD = 0x00000FAB,
+ ERROR_PRESENCE_NO_CHANGE = 0x00000FAC,
ERROR_FRIENDS_TOO_MANY_SENT_INVITATIONS = 0x00001389,
ERROR_FRIENDS_TOO_MANY_RECEIVED_INVITATIONS = 0x0000138A,
@@ -265,7 +241,6 @@ enum BattlenetRpcErrorCode : uint32
ERROR_FRIENDS_FRIENDSHIP_DOES_NOT_EXIST = 0x0000138C,
ERROR_FRIENDS_INVITATION_ALREADY_EXISTS = 0x0000138D,
ERROR_FRIENDS_INVALID_INVITATION = 0x0000138E,
- ERROR_FRIENDS_ALREADY_SUBSCRIBED = 0x0000138F,
ERROR_FRIENDS_ACCOUNT_BLOCKED = 0x00001391,
ERROR_FRIENDS_NOT_SUBSCRIBED = 0x00001392,
ERROR_FRIENDS_INVALID_ROLE_ID = 0x00001393,
@@ -274,11 +249,20 @@ enum BattlenetRpcErrorCode : uint32
ERROR_FRIENDS_UPDATE_FRIEND_STATE_FAILED = 0x00001396,
ERROR_FRIENDS_INVITEE_AT_MAX_FRIENDS = 0x00001397,
ERROR_FRIENDS_INVITER_AT_MAX_FRIENDS = 0x00001398,
+ ERROR_FRIENDS_INVITER_IS_BLOCKED_BY_INVITEE = 0x00001399,
+ ERROR_FRIENDS_RECEIVED_INVITATION_UNDELIVERABLE = 0x0000139A,
+ ERROR_FRIENDS_MUTED = 0x0000139B,
+ ERROR_FRIENDS_RECEIVED_INVITATION_IGNORED = 0x0000139C,
+ ERROR_FRIENDS_TRANSACTION_ALREADY_EXISTS = 0x0000139D,
+ ERROR_FRIENDS_MERGED_FRIENDS_ABOVE_LIMIT = 0x0000139E,
ERROR_PLATFORM_STORAGE_FILE_WRITE_DENIED = 0x00001770,
ERROR_WHISPER_UNDELIVERABLE = 0x00001B58,
ERROR_WHISPER_MAX_SIZE_EXCEEDED = 0x00001B59,
+ ERROR_WHISPER_ALREADY_REGISTERED = 0x00001B5A,
+ ERROR_WHISPER_DROPPED = 0x00001B5B,
+ ERROR_WHISPER_QUOTA_EXCEEDED = 0x00001B5C,
ERROR_USER_MANAGER_ALREADY_BLOCKED = 0x00001F40,
ERROR_USER_MANAGER_NOT_BLOCKED = 0x00001F41,
@@ -292,73 +276,88 @@ enum BattlenetRpcErrorCode : uint32
ERROR_USER_MANAGER_UNBLOCK_ENTITY_FAILED = 0x00001F51,
ERROR_USER_MANAGER_CANNOT_BLOCK_FRIEND = 0x00001F53,
- ERROR_SOCIAL_NETWORK_DB_EXCEPTION = 0x00002328,
- ERROR_SOCIAL_NETWORK_DENIAL_FROM_PROVIDER = 0x00002329,
- ERROR_SOCIAL_NETWORK_INVALID_SNS_ID = 0x0000232A,
- ERROR_SOCIAL_NETWORK_CANT_SEND_TO_PROVIDER = 0x0000232B,
- ERROR_SOCIAL_NETWORK_EX_COMM_FAILED = 0x0000232C,
- ERROR_SOCIAL_NETWORK_DISABLED = 0x0000232D,
- ERROR_SOCIAL_NETWORK_MISSING_REQUEST_PARAM = 0x0000232E,
- ERROR_SOCIAL_NETWORK_UNSUPPORTED_OAUTH_VERSION = 0x0000232F,
+ ERROR_SOCIAL_NETWORK_OAUTH_EXCEPTION = 0x00002328,
+ ERROR_SOCIAL_NETWORK_INVALID_SNS_ID = 0x00002329,
+ ERROR_SOCIAL_NETWORK_CANT_SEND_TO_PROVIDER = 0x0000232A,
+ ERROR_SOCIAL_NETWORK_DISABLED = 0x0000232B,
+ ERROR_SOCIAL_NETWORK_MISSING_REQUEST_PARAM = 0x0000232C,
+ ERROR_SOCIAL_NETWORK_NO_ACCOUNT_DATA = 0x0000232D,
+ ERROR_SOCIAL_NETWORK_NO_TOKEN = 0x0000232E,
+ ERROR_SOCIAL_NETWORK_MISSING_DATA_FROM_PROVIDER = 0x0000232F,
+ ERROR_SOCIAL_NETWORK_RESPONSE_NOT_PARSABLE = 0x00002330,
+ ERROR_SOCIAL_NETWORK_TOKEN_PERMISSION_DENIED = 0x00002331,
+ ERROR_SOCIAL_NETWORK_DENIAL_FROM_PROVIDER = 0x00002332,
ERROR_CHANNEL_FULL = 0x00002710,
ERROR_CHANNEL_NO_CHANNEL = 0x00002711,
ERROR_CHANNEL_NOT_MEMBER = 0x00002712,
ERROR_CHANNEL_ALREADY_MEMBER = 0x00002713,
ERROR_CHANNEL_NO_SUCH_MEMBER = 0x00002714,
- ERROR_CHANNEL_INVALID_CHANNEL_ID = 0x00002716,
ERROR_CHANNEL_NO_SUCH_INVITATION = 0x00002718,
ERROR_CHANNEL_TOO_MANY_INVITATIONS = 0x00002719,
ERROR_CHANNEL_INVITATION_ALREADY_EXISTS = 0x0000271A,
- ERROR_CHANNEL_INVALID_CHANNEL_SIZE = 0x0000271B,
ERROR_CHANNEL_INVALID_ROLE_ID = 0x0000271C,
ERROR_CHANNEL_ROLE_NOT_ASSIGNABLE = 0x0000271D,
ERROR_CHANNEL_INSUFFICIENT_PRIVILEGES = 0x0000271E,
ERROR_CHANNEL_INSUFFICIENT_PRIVACY_LEVEL = 0x0000271F,
ERROR_CHANNEL_INVALID_PRIVACY_LEVEL = 0x00002720,
ERROR_CHANNEL_TOO_MANY_CHANNELS_JOINED = 0x00002721,
- ERROR_CHANNEL_INVITATION_ALREADY_SUBSCRIBED = 0x00002722,
ERROR_CHANNEL_INVALID_CHANNEL_DELEGATE = 0x00002723,
ERROR_CHANNEL_SLOT_ALREADY_RESERVED = 0x00002724,
- ERROR_CHANNEL_SLOT_NOT_RESERVED = 0x00002725,
ERROR_CHANNEL_NO_RESERVED_SLOTS_AVAILABLE = 0x00002726,
ERROR_CHANNEL_INVALID_ROLE_SET = 0x00002727,
- ERROR_CHANNEL_REQUIRE_FRIEND_VALIDATION = 0x00002728,
- ERROR_CHANNEL_MEMBER_OFFLINE = 0x00002729,
ERROR_CHANNEL_RECEIVED_TOO_MANY_INVITATIONS = 0x0000272A,
ERROR_CHANNEL_INVITATION_INVALID_GAME_ACCOUNT_SELECTED = 0x0000272B,
- ERROR_CHANNEL_UNREACHABLE = 0x0000272C,
ERROR_CHANNEL_INVITATION_NOT_SUBSCRIBED = 0x0000272D,
- ERROR_CHANNEL_INVALID_MESSAGE_SIZE = 0x0000272E,
- ERROR_CHANNEL_MAX_MESSAGE_SIZE_EXCEEDED = 0x0000272F,
- ERROR_CHANNEL_CONFIG_NOT_FOUND = 0x00002730,
ERROR_CHANNEL_INVALID_CHANNEL_TYPE = 0x00002731,
-
- ERROR_LOCAL_STORAGE_FILE_OPEN_ERROR = 0x00002AF8,
- ERROR_LOCAL_STORAGE_FILE_CREATE_ERROR = 0x00002AF9,
- ERROR_LOCAL_STORAGE_FILE_READ_ERROR = 0x00002AFA,
- ERROR_LOCAL_STORAGE_FILE_WRITE_ERROR = 0x00002AFB,
- ERROR_LOCAL_STORAGE_FILE_DELETE_ERROR = 0x00002AFC,
- ERROR_LOCAL_STORAGE_FILE_COPY_ERROR = 0x00002AFD,
- ERROR_LOCAL_STORAGE_FILE_DECOMPRESS_ERROR = 0x00002AFE,
- ERROR_LOCAL_STORAGE_FILE_HASH_MISMATCH = 0x00002AFF,
- ERROR_LOCAL_STORAGE_FILE_USAGE_MISMATCH = 0x00002B00,
- ERROR_LOCAL_STORAGE_DATABASE_INIT_ERROR = 0x00002B01,
- ERROR_LOCAL_STORAGE_DATABASE_NEEDS_REBUILD = 0x00002B02,
- ERROR_LOCAL_STORAGE_DATABASE_INSERT_ERROR = 0x00002B03,
- ERROR_LOCAL_STORAGE_DATABASE_LOOKUP_ERROR = 0x00002B04,
- ERROR_LOCAL_STORAGE_DATABASE_UPDATE_ERROR = 0x00002B05,
- ERROR_LOCAL_STORAGE_DATABASE_DELETE_ERROR = 0x00002B06,
- ERROR_LOCAL_STORAGE_DATABASE_SHRINK_ERROR = 0x00002B07,
- ERROR_LOCAL_STORAGE_CACHE_CRAWL_ERROR = 0x00002B08,
- ERROR_LOCAL_STORAGE_DATABASE_INDEX_TRIGGER_ERROR = 0x00002B09,
- ERROR_LOCAL_STORAGE_DATABASE_REBUILD_IN_PROGRESS = 0x00002B0A,
- ERROR_LOCAL_STORAGE_OK_BUT_NOT_IN_CACHE = 0x00002B0B,
- ERROR_LOCAL_STORAGE_DATABASE_REBUILD_INTERRUPTED = 0x00002B0D,
- ERROR_LOCAL_STORAGE_DATABASE_NOT_INITIALIZED = 0x00002B0E,
- ERROR_LOCAL_STORAGE_DIRECTORY_CREATE_ERROR = 0x00002B0F,
- ERROR_LOCAL_STORAGE_FILEKEY_NOT_FOUND = 0x00002B10,
- ERROR_LOCAL_STORAGE_NOT_AVAILABLE_ON_SERVER = 0x00002B11,
+ ERROR_CHANNEL_INVALID_INDEX = 0x00002732,
+ ERROR_CHANNEL_MEMBERSHIP_NOT_SUBSCRIBED = 0x00002733,
+ ERROR_CHANNEL_ALREADY_SUBSCRIBED = 0x00002734,
+
+ ERROR_CLUB_FULL = 0x00002AF8,
+ ERROR_CLUB_NO_CLUB = 0x00002AF9,
+ ERROR_CLUB_NOT_MEMBER = 0x00002AFA,
+ ERROR_CLUB_ALREADY_MEMBER = 0x00002AFB,
+ ERROR_CLUB_NO_SUCH_MEMBER = 0x00002AFC,
+ ERROR_CLUB_NO_SUCH_INVITATION = 0x00002B00,
+ ERROR_CLUB_INVITATION_ALREADY_EXISTS = 0x00002B02,
+ ERROR_CLUB_INVALID_ROLE_ID = 0x00002B04,
+ ERROR_CLUB_INSUFFICIENT_PRIVILEGES = 0x00002B06,
+ ERROR_CLUB_INSUFFICIENT_PRIVACY_LEVEL = 0x00002B07,
+ ERROR_CLUB_INVALID_PRIVACY_LEVEL = 0x00002B08,
+ ERROR_CLUB_TOO_MANY_CLUBS_JOINED = 0x00002B09,
+ ERROR_CLUB_INVALID_ROLE_SET = 0x00002B0F,
+ ERROR_CLUB_NOT_SUBSCRIBED = 0x00002B15,
+ ERROR_CLUB_INVALID_CLUB_TYPE = 0x00002B19,
+ ERROR_CLUB_VOICE_FULL = 0x00002B1A,
+ ERROR_CLUB_MEMBER_SUBSCRIPTIONS_AT_MAX = 0x00002B1B,
+ ERROR_CLUB_SUGGESTION_ALREADY_EXISTS = 0x00002B20,
+ ERROR_CLUB_SUGGESTION_COUNT_AT_MAX = 0x00002B21,
+ ERROR_CLUB_NO_SUCH_SUGGESTION = 0x00002B22,
+ ERROR_CLUB_STREAM_NO_STREAM = 0x00002B5C,
+ ERROR_CLUB_STREAM_INVALID_NAME = 0x00002B5D,
+ ERROR_CLUB_STREAM_COUNT_AT_MIN = 0x00002B5E,
+ ERROR_CLUB_STREAM_COUNT_AT_MAX = 0x00002B5F,
+ ERROR_CLUB_STREAM_INVALID_VOICE_LEVEL = 0x00002B60,
+ ERROR_CLUB_STREAM_NO_SUCH_MESSAGE = 0x00002B61,
+ ERROR_CLUB_INVALID_AVATAR = 0x00002B75,
+ ERROR_CLUB_MEMBER_HAS_REQUIRED_ROLE = 0x00002B76,
+ ERROR_CLUB_INVALID_ROLE_CHANGE_REQUEST = 0x00002B77,
+ ERROR_CLUB_SENT_INVITATION_COUNT_AT_MAX = 0x00002B8E,
+ ERROR_CLUB_RECEIVED_INVITATION_COUNT_AT_MAX = 0x00002B8F,
+ ERROR_CLUB_TARGET_IS_BANNED = 0x00002B90,
+ ERROR_CLUB_NO_SUCH_BANNED_TARGET = 0x00002B91,
+ ERROR_CLUB_BAN_ALREADY_EXISTS = 0x00002B92,
+ ERROR_CLUB_BAN_COUNT_AT_MAX = 0x00002B93,
+ ERROR_CLUB_TICKET_COUNT_AT_MAX = 0x00002BA2,
+ ERROR_CLUB_TICKET_NO_SUCH_TICKET = 0x00002BA3,
+ ERROR_CLUB_TICKET_HAS_CONSUMED_ALLOWED_REDEEM_COUNT = 0x00002BA4,
+
+ ERROR_CLUB_MEMBERSHIP_SUBSCRIPTIONS_AT_MAX = 0x00002E19,
+ ERROR_CLUB_MEMBERSHIP_PUSH_NOTIFICATION_REGISTRATIONS_AT_MAX = 0x00002E1A,
+ ERROR_CLUB_TAG_ALREADY_EXISTS = 0x00002E1B,
+ ERROR_CLUB_TAG_NO_SUCH_TAG = 0x00002E1C,
+ ERROR_CLUB_TAG_TOO_MANY_TAGS = 0x00002E1D,
ERROR_REGISTRY_CREATE_KEY_ERROR = 0x00002EE0,
ERROR_REGISTRY_OPEN_KEY_ERROR = 0x00002EE1,
@@ -368,18 +367,10 @@ enum BattlenetRpcErrorCode : uint32
ERROR_REGISTRY_DELETE_ERROR = 0x00002EE5,
ERROR_REGISTRY_ENCRYPT_ERROR = 0x00002EE6,
ERROR_REGISTRY_DECRYPT_ERROR = 0x00002EE7,
- ERROR_REGISTRY_KEY_SIZE_ERROR = 0x00002EE8,
ERROR_REGISTRY_VALUE_SIZE_ERROR = 0x00002EE9,
ERROR_REGISTRY_NOT_FOUND = 0x00002EEB,
ERROR_REGISTRY_MALFORMED_STRING = 0x00002EEC,
- ERROR_INTERFACE_ALREADY_CONNECTED = 0x000032C8,
- ERROR_INTERFACE_NOT_READY = 0x000032C9,
- ERROR_INTERFACE_OPTION_KEY_TOO_LARGE = 0x000032CA,
- ERROR_INTERFACE_OPTION_VALUE_TOO_LARGE = 0x000032CB,
- ERROR_INTERFACE_OPTION_KEY_INVALID_UTF8_STRING = 0x000032CC,
- ERROR_INTERFACE_OPTION_VALUE_INVALID_UTF8_STRING = 0x000032CD,
-
ERROR_HTTP_COULDNT_RESOLVE = 0x000036B0,
ERROR_HTTP_COULDNT_CONNECT = 0x000036B1,
ERROR_HTTP_TIMEOUT = 0x000036B2,
@@ -390,21 +381,55 @@ enum BattlenetRpcErrorCode : uint32
ERROR_HTTP_TOO_MANY_REDIRECTS = 0x000036B7,
ERROR_HTTP_COULDNT_OPEN_FILE = 0x000036B8,
ERROR_HTTP_COULDNT_CREATE_FILE = 0x000036B9,
- ERROR_HTTP_COULDNT_READ_FILE = 0x000036BA,
ERROR_HTTP_COULDNT_RENAME_FILE = 0x000036BB,
ERROR_HTTP_COULDNT_CREATE_DIRECTORY = 0x000036BC,
ERROR_HTTP_CURL_IS_NOT_READY = 0x000036BD,
- ERROR_HTTP_CANCELLED = 0x000036BE,
+ ERROR_HTTP_CANCELED = 0x000036BE,
+ ERROR_HTTP_SEND_FAILED = 0x000036BF,
+ ERROR_HTTP_RECV_FAILED = 0x000036C0,
+ ERROR_HTTP_MALFORMED_REPLY = 0x000036C1,
+ ERROR_HTTP_ACCESS_DENIED = 0x000036C2,
+ ERROR_HTTP_MALFORMED_POST = 0x000036C3,
+ ERROR_HTTP_INVALID_CERT = 0x000036C4,
+ ERROR_HTTP_INVALID_CA_CERT = 0x000036C5,
+ ERROR_HTTP_SSL_CONNECT_FAILED = 0x000036C6,
+ ERROR_HTTP_PROTOCOL_FAILED = 0x000036C7,
ERROR_HTTP_FILE_NOT_FOUND = 0x00003844,
+ ERROR_HTTP_OAUTH2_DISCOVERY_FAILED = 0x000038A5,
+ ERROR_HTTP_OAUTH2_TOKEN_REFRESH_FAILED = 0x000038A6,
+ ERROR_HTTP_OAUTH2_TOKEN_STORAGE_FAILED = 0x000038A7,
+ ERROR_HTTP_OAUTH2_TOKEN_EXCHANGE_FAILED = 0x000038A8,
+ ERROR_HTTP_OAUTH2_INVALID_CONTEXT = 0x000038A9,
+
+ ERROR_ASTERION_GENERAL_RUNTIME = 0x00003A98,
+ ERROR_ASTERION_THROTTLED = 0x00003A99,
+ ERROR_ASTERION_SHARD_NOT_FOUND = 0x00003A9A,
+ ERROR_ASTERION_INVALID_PARAMETER = 0x00003A9B,
+ ERROR_ASTERION_REMOTE_REGION_UNAVAILABLE = 0x00003A9D,
+ ERROR_ASTERION_DEDUCT_RECORD_DUPLICATED = 0x00003A9F,
+ ERROR_ASTERION_DEDUCT_RECORD_MINIMUM_GAMETIME = 0x00003AA0,
+ ERROR_ASTERION_DEDUCT_RECORD_INVALID_STOP_TIME = 0x00003AA1,
+ ERROR_ASTERION_TIMED_OUT = 0x00003AA2,
+ ERROR_ASTERION_TOO_MANY_OUTSTANDING_REQUESTS = 0x00003AA3,
+ ERROR_ASTERION_DEDUCT_RECORD_ANOTHER_IN_PROGRESS = 0x00003AA4,
+
+ ERROR_ASTERION_UNAVAILABLE = 0x00003E7F,
+
+ ERROR_EVENT_VIEW_IS_FULL = 0x00003E80,
+
+ ERROR_VOICE_ACCOUNT_NOT_FOUND = 0x00004268,
+ ERROR_VOICE_TOKEN_ALREADY_USED = 0x00004269,
+ ERROR_VOICE_VERSION_NOT_SUPPORTED = 0x0000426A,
+ ERROR_VOICE_INVALID_VERSION = 0x0000426B,
+ ERROR_VOICE_SECRET_KEY_STORAGE_FAILURE = 0x0000426C,
+
ERROR_ACCOUNT_MISSING_CONFIG = 0x00004650,
ERROR_ACCOUNT_DATA_NOT_FOUND = 0x00004651,
ERROR_ACCOUNT_ALREADY_SUBSCRIBED = 0x00004652,
ERROR_ACCOUNT_NOT_SUBSCRIBED = 0x00004653,
ERROR_ACCOUNT_FAILED_TO_PARSE_TIMEZONE_DATA = 0x00004654,
- ERROR_ACCOUNT_LOAD_FAILED = 0x00004655,
- ERROR_ACCOUNT_LOAD_CANCELLED = 0x00004656,
ERROR_ACCOUNT_DATABASE_INVALIDATE_FAILED = 0x00004657,
ERROR_ACCOUNT_CACHE_INVALIDATE_FAILED = 0x00004658,
ERROR_ACCOUNT_SUBSCRIPTION_PENDING = 0x00004659,
@@ -413,40 +438,20 @@ enum BattlenetRpcErrorCode : uint32
ERROR_ACCOUNT_UNDERAGE = 0x0000465C,
ERROR_ACCOUNT_IDENTITY_CHECK_PENDING = 0x0000465D,
ERROR_ACCOUNT_IDENTITY_UNVERIFIED = 0x0000465E,
-
- ERROR_DATABASE_BINDING_COUNT_MISMATCH = 0x00004A38,
- ERROR_DATABASE_BINDING_PARSE_FAIL = 0x00004A39,
- ERROR_DATABASE_RESULTSET_COLUMNS_MISMATCH = 0x00004A3A,
- ERROR_DATABASE_DEADLOCK = 0x00004A3B,
- ERROR_DATABASE_DUPLICATE_KEY = 0x00004A3C,
- ERROR_DATABASE_CANNOT_CONNECT = 0x00004A3D,
- ERROR_DATABASE_STATEMENT_FAILED = 0x00004A3E,
- ERROR_DATABASE_TRANSACTION_NOT_STARTED = 0x00004A3F,
- ERROR_DATABASE_TRANSACTION_NOT_ENDED = 0x00004A40,
- ERROR_DATABASE_TRANSACTION_LEAK = 0x00004A41,
- ERROR_DATABASE_TRANSACTION_STATE_BAD = 0x00004A42,
- ERROR_DATABASE_SERVER_GONE = 0x00004A43,
- ERROR_DATABASE_QUERY_TIMEOUT = 0x00004A44,
- ERROR_DATABASE_BINDING_NOT_NULLABLE = 0x00004A9C,
- ERROR_DATABASE_BINDING_INVALID_INTEGER = 0x00004A9D,
- ERROR_DATABASE_BINDING_INVALID_FLOAT = 0x00004A9E,
- ERROR_DATABASE_BINDING_INVALID_TEMPORAL = 0x00004A9F,
- ERROR_DATABASE_BINDING_INVALID_PROTOBUF = 0x00004AA0,
-
- ERROR_PARTY_INVALID_PARTY_ID = 0x00004E20,
- ERROR_PARTY_ALREADY_IN_PARTY = 0x00004E21,
- ERROR_PARTY_NOT_IN_PARTY = 0x00004E22,
- ERROR_PARTY_INVITATION_UNDELIVERABLE = 0x00004E23,
- ERROR_PARTY_INVITATION_ALREADY_EXISTS = 0x00004E24,
- ERROR_PARTY_TOO_MANY_PARTY_INVITATIONS = 0x00004E25,
- ERROR_PARTY_TOO_MANY_RECEIVED_INVITATIONS = 0x00004E26,
- ERROR_PARTY_NO_SUCH_TYPE = 0x00004E27,
+ ERROR_ACCOUNT_IGR = 0x0000465F,
+ ERROR_GAME_ACCOUNT_CREATE_NEED_NATIONAL_ID = 0x00004660,
+ ERROR_GAME_ACCOUNT_CREATE_BLOCKED = 0x00004661,
+ ERROR_GAME_ACCOUNT_DETACHED = 0x00004662,
+ ERROR_GAME_ACCOUNT_CREATE_TOO_MANY_GAME_ACCOUNT = 0x00004663,
+ ERROR_SUBSCRIBER_NO_NEED_TO_UPDATE = 0x00004664,
+ ERROR_ACCOUNT_MOBILE_NUMBER_REQUIRED = 0x00004665,
+ ERROR_ACCOUNT_MOBILE_NUMBER_ALREADY_USED = 0x00004666,
+ ERROR_ACCOUNT_DATA_NOT_EXISTS_IN_CACHE = 0x00004667,
+ ERROR_ACCOUNT_INVALID_IDENTITY_DATA = 0x00004668,
ERROR_GAMES_NO_SUCH_FACTORY = 0x000055F0,
ERROR_GAMES_NO_SUCH_GAME = 0x000055F1,
ERROR_GAMES_NO_SUCH_REQUEST = 0x000055F2,
- ERROR_GAMES_NO_SUCH_PARTY_MEMBER = 0x000055F3,
-
ERROR_RESOURCES_OFFLINE = 0x000059D8,
ERROR_GAME_SERVER_CREATE_GAME_REFUSED = 0x00005DC0,
@@ -470,11 +475,8 @@ enum BattlenetRpcErrorCode : uint32
ERROR_GAME_MASTER_REGISTER_FAILED = 0x000061AB,
ERROR_GAME_MASTER_NO_GAME_SERVER = 0x000061AC,
ERROR_GAME_MASTER_NO_UTILITY_SERVER = 0x000061AD,
- ERROR_GAME_MASTER_NO_GAME_VERSION = 0x000061AE,
ERROR_GAME_MASTER_GAME_JOIN_FAILED = 0x000061AF,
- ERROR_GAME_MASTER_ALREADY_REGISTERED = 0x000061B0,
ERROR_GAME_MASTER_NO_FACTORY = 0x000061B1,
- ERROR_GAME_MASTER_MULTIPLE_GAME_VERSIONS = 0x000061B2,
ERROR_GAME_MASTER_INVALID_PLAYER = 0x000061B3,
ERROR_GAME_MASTER_INVALID_GAME_REQUEST = 0x000061B4,
ERROR_GAME_MASTER_INSUFFICIENT_PRIVILEGES = 0x000061B5,
@@ -488,43 +490,50 @@ enum BattlenetRpcErrorCode : uint32
ERROR_GAME_MASTER_INVALID_TEAM_ID = 0x000061BD,
ERROR_GAME_MASTER_CREATION_IN_PROGRESS = 0x000061BE,
- ERROR_NOTIFICATION_INVALID_CLIENT_ID = 0x00006590,
- ERROR_NOTIFICATION_DUPLICATE_NAME = 0x00006591,
- ERROR_NOTIFICATION_NAME_NOT_FOUND = 0x00006592,
- ERROR_NOTIFICATION_INVALID_SERVER = 0x00006593,
ERROR_NOTIFICATION_QUOTA_EXCEEDED = 0x00006594,
ERROR_NOTIFICATION_INVALID_NOTIFICATION_TYPE = 0x00006595,
ERROR_NOTIFICATION_UNDELIVERABLE = 0x00006596,
ERROR_NOTIFICATION_UNDELIVERABLE_TEMPORARY = 0x00006597,
- ERROR_ACHIEVEMENTS_NOTHING_TO_UPDATE = 0x00006D60,
- ERROR_ACHIEVEMENTS_INVALID_PARAMS = 0x00006D61,
- ERROR_ACHIEVEMENTS_NOT_REGISTERED = 0x00006D62,
- ERROR_ACHIEVEMENTS_NOT_READY = 0x00006D63,
- ERROR_ACHIEVEMENTS_FAILED_TO_PARSE_STATIC_DATA = 0x00006D64,
- ERROR_ACHIEVEMENTS_UNKNOWN_ID = 0x00006D65,
- ERROR_ACHIEVEMENTS_MISSING_SNAPSHOT = 0x00006D66,
- ERROR_ACHIEVEMENTS_ALREADY_REGISTERED = 0x00006D67,
- ERROR_ACHIEVEMENTS_TOO_MANY_REGISTRATIONS = 0x00006D68,
- ERROR_ACHIEVEMENTS_ALREADY_IN_PROGRESS = 0x00006D69,
- ERROR_ACHIEVEMENTS_TEMPORARY_OUTAGE = 0x00006D6A,
- ERROR_ACHIEVEMENTS_INVALID_PROGRAMID = 0x00006D6B,
- ERROR_ACHIEVEMENTS_MISSING_RECORD = 0x00006D6C,
- ERROR_ACHIEVEMENTS_REGISTRATION_PENDING = 0x00006D6D,
- ERROR_ACHIEVEMENTS_ENTITY_ID_NOT_FOUND = 0x00006D6E,
- ERROR_ACHIEVEMENTS_ACHIEVEMENT_ID_NOT_FOUND = 0x00006D6F,
- ERROR_ACHIEVEMENTS_CRITERIA_ID_NOT_FOUND = 0x00006D70,
- ERROR_ACHIEVEMENTS_STATIC_DATA_MISMATCH = 0x00006D71,
- ERROR_ACHIEVEMENTS_WRONG_THREAD = 0x00006D72,
- ERROR_ACHIEVEMENTS_CALLBACK_IS_NULL = 0x00006D73,
- ERROR_ACHIEVEMENTS_AUTO_REGISTER_PENDING = 0x00006D74,
- ERROR_ACHIEVEMENTS_NOT_INITIALIZED = 0x00006D75,
- ERROR_ACHIEVEMENTS_ACHIEVEMENT_ID_ALREADY_EXISTS = 0x00006D76,
- ERROR_ACHIEVEMENTS_FAILED_TO_DOWNLOAD_STATIC_DATA = 0x00006D77,
- ERROR_ACHIEVEMENTS_STATIC_DATA_NOT_FOUND = 0x00006D78,
+ ERROR_LEADERBOARD_RULE_NOT_FOUND = 0x00006D61,
+ ERROR_LEADERBOARD_NOT_FOUND = 0x00006D62,
+ ERROR_LEADERBOARD_INVALID_ENTITY_ID = 0x00006D64,
+ ERROR_LEADERBOARD_INVALID_GAME_ACCOUNT = 0x00006D65,
+ ERROR_LEADERBOARD_INVALID_TIMESTAMP = 0x00006D66,
+ ERROR_LEADERBOARD_INVALID_TAGS = 0x00006D67,
+ ERROR_LEADERBOARD_INVALID_PAYLOAD = 0x00006D69,
+ ERROR_LEADERBOARD_INVALID_TITLE_ID = 0x00006D6A,
+ ERROR_LEADERBOARD_INVALID_RULE_NAME = 0x00006D6B,
+ ERROR_LEADERBOARD_INVALID_REQUEST = 0x00006D6C,
+ ERROR_LEADERBOARD_INVALID_SCORES = 0x00006D6D,
+ ERROR_LEADERBOARD_INVALID_FIELD_FORMAT = 0x00006D6E,
+ ERROR_LEADERBOARD_ACCOUNT_NOT_FOUND = 0x00006D6F,
+ ERROR_LEADERBOARD_RANKS_NOT_FOUND = 0x00006D70,
+ ERROR_LEADERBOARD_INVALID_BATCH_SUBMIT_RANKS_REQUEST = 0x00006D71,
+
+ ERROR_MATCHMAKING_MATCHMAKER_NOT_FOUND = 0x00007530,
+ ERROR_MATCHMAKING_MATCHMAKER_DECOMMISSIONED = 0x00007531,
+ ERROR_MATCHMAKING_GAMESERVER_NOT_FOUND = 0x00007532,
+ ERROR_MATCHMAKING_30003 = 0x00007533,
+ ERROR_MATCHMAKING_MATCHMAKER_ALREADY_REGISTERED = 0x00007534,
+ ERROR_MATCHMAKING_GAMESERVER_ALREADY_REGISTERED = 0x00007535,
+ ERROR_MATCHMAKING_REQUEST_ID_NOT_FOUND = 0x00007536,
+ ERROR_MATCHMAKING_INSUFFICIENT_PARTY_PRIVILEGES = 0x00007537,
+ ERROR_MATCHMAKING_EVENT_QUEUE_FULL = 0x00007538,
+ ERROR_MATCHMAKING_CANCEL_NOT_ALLOWED = 0x00007539,
+ ERROR_MATCHMAKING_PLAYER_NOT_CONNECTED = 0x0000753A,
+ ERROR_MATCHMAKING_EVENT_CANCELED = 0x0000753B,
+ ERROR_MATCHMAKING_GAMESERVER_FULL = 0x0000753C,
+ ERROR_MATCHMAKING_INVALID_RESPONSE = 0x0000753D,
+ ERROR_MATCHMAKING_MATCHMAKER_INVALID_CONNECTION = 0x0000753E,
+
+ ERROR_MATCHMAKING_SERVER_ALREADY_IN_GAME = 0x00007918,
+ ERROR_MATCHMAKING_SERVER_INVALID_GAME = 0x00007919,
+ ERROR_MATCHMAKING_SERVER_INVALID_PLAYER = 0x0000791A,
+ ERROR_MATCHMAKING_SERVER_GAME_FULL = 0x0000791B,
+ ERROR_MATCHMAKING_SERVER_UNKNOWN_REQUEST_ID = 0x0000791C,
ERROR_GAME_UTILITY_SERVER_VARIABLE_REQUEST_REFUSED = 0x000084D1,
- ERROR_GAME_UTILITY_SERVER_WRONG_NUMBER_OF_VARIABLES_RETURNED = 0x000084D2,
ERROR_GAME_UTILITY_SERVER_CLIENT_REQUEST_REFUSED = 0x000084D3,
ERROR_GAME_UTILITY_SERVER_PRESENCE_CHANNEL_CREATED_REFUSED = 0x000084D4,
ERROR_GAME_UTILITY_SERVER_VARIABLE_REQUEST_REFUSED_TRANSIENT = 0x00008502,
@@ -535,31 +544,34 @@ enum BattlenetRpcErrorCode : uint32
ERROR_GAME_UTILITY_SERVER_CLIENT_REQUEST_REFUSED_BUSY = 0x00008535,
ERROR_GAME_UTILITY_SERVER_PRESENCE_CHANNEL_CREATED_REFUSED_BUSY = 0x00008536,
ERROR_GAME_UTILITY_SERVER_SERVER_REQUEST_REFUSED_BUSY = 0x00008537,
- ERROR_GAME_UTILITY_SERVER_NO_SERVER = 0x00008598,
- ERROR_IDENTITY_INSUFFICIENT_DATA = 0x0000A028,
- ERROR_IDENTITY_TOO_MANY_RESULTS = 0x0000A029,
- ERROR_IDENTITY_BAD_ID = 0x0000A02A,
- ERROR_IDENTITY_NO_ACCOUNT_BLOB = 0x0000A02B,
+ ERROR_GAME_UTILITY_SERVER_REQUEST_REFUSED = 0x00008567,
+ ERROR_GAME_UTILITY_SERVER_REQUEST_REFUSED_BUSY = 0x00008568,
+ ERROR_GAME_UTILITY_SERVER_REQUEST_REFUSED_TRANSIENT = 0x00008569,
+ ERROR_GAME_UTILITY_SERVER_NO_SERVER = 0x00008598,
+ ERROR_GAME_UTILITY_SERVER_VERSION_MISMATCH = 0x0000859A,
+ ERROR_GAME_UTILITY_SERVER_TIMED_OUT = 0x0000859B,
+
+ ERROR_SESSION_ADMIN_KICK = 0x00009C44,
+ ERROR_SESSION_ABANDONED = 0x00009C48,
+ ERROR_SESSION_CAIS_PLAYTIME_EXCEEDED = 0x00009C4B,
+ ERROR_SESSION_CAIS_CURFEW = 0x00009C4C,
+ ERROR_SESSION_INVALID_NID = 0x00009C4E,
+ ERROR_SESSION_QUEUE_DUPLICATED = 0x00009C4F,
+ ERROR_SESSION_QUEUE_ADMIN_KICK = 0x00009C51,
+ ERROR_SESSION_KEY_EXPIRED = 0x00009C52,
+ ERROR_SESSION_TOKEN_EXPIRED = 0x00009C53,
- ERROR_RISK_CHALLENGE_ACTION = 0x0000A410,
- ERROR_RISK_DELAY_ACTION = 0x0000A411,
ERROR_RISK_THROTTLE_ACTION = 0x0000A412,
ERROR_RISK_ACCOUNT_LOCKED = 0x0000A413,
- ERROR_RISK_CS_DENIED = 0x0000A414,
ERROR_RISK_DISCONNECT_ACCOUNT = 0x0000A415,
ERROR_RISK_CHECK_SKIPPED = 0x0000A416,
ERROR_REPORT_UNAVAILABLE = 0x0000AFC8,
- ERROR_REPORT_TOO_LARGE = 0x0000AFC9,
+ ERROR_REPORT_UNKNOWN_PROGRAM = 0x0000AFC9,
ERROR_REPORT_UNKNOWN_TYPE = 0x0000AFCA,
- ERROR_REPORT_ATTRIBUTE_INVALID = 0x0000AFCB,
ERROR_REPORT_ATTRIBUTE_QUOTA_EXCEEDED = 0x0000AFCC,
ERROR_REPORT_UNCONFIRMED = 0x0000AFCD,
- ERROR_REPORT_NOT_CONNECTED = 0x0000AFCE,
- ERROR_REPORT_REJECTED = 0x0000AFCF,
- ERROR_REPORT_TOO_MANY_REQUESTS = 0x0000AFD0,
-
ERROR_ACCOUNT_ALREADY_REGISTERD = 0x0000BB80,
ERROR_ACCOUNT_NOT_REGISTERED = 0x0000BB81,
ERROR_ACCOUNT_REGISTRATION_PENDING = 0x0000BB82,