feat(Core/Player): Implement ACCOUNT_FLAG_TRIAL (#26064)

Co-authored-by: Ludwig <sudlud@users.noreply.github.com>
Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
Kitzunu
2026-06-16 16:08:01 +02:00
committed by GitHub
parent 1e39a1bc1f
commit edf34ed6d9
14 changed files with 281 additions and 7 deletions
@@ -132,6 +132,13 @@ void WorldSession::HandleAuctionSellItem(WorldPacket& recvData)
return;
}
if (sWorld->getBoolConfig(CONFIG_TRIAL_RESTRICTION_AUCTION) && IsTrialAccount())
{
SendAuctionCommandResult(0, AUCTION_SELL_ITEM, ERR_AUCTION_RESTRICTED_ACCOUNT);
recvData.rfinish();
return;
}
for (uint32 i = 0; i < itemsCount; ++i)
{
recvData >> itemGUIDs[i];
@@ -426,6 +433,12 @@ void WorldSession::HandleAuctionPlaceBid(WorldPacket& recvData)
if (!auctionId || !price)
return; //check for cheaters
if (sWorld->getBoolConfig(CONFIG_TRIAL_RESTRICTION_AUCTION) && IsTrialAccount())
{
SendAuctionCommandResult(0, AUCTION_PLACE_BID, ERR_AUCTION_RESTRICTED_ACCOUNT);
return;
}
Creature* creature = GetPlayer()->GetNPCIfCanInteractWith(auctioneer, UNIT_NPC_FLAG_AUCTIONEER);
if (!creature)
{
@@ -578,6 +591,12 @@ void WorldSession::HandleAuctionRemoveItem(WorldPacket& recvData)
recvData >> auctioneer;
recvData >> auctionId;
if (sWorld->getBoolConfig(CONFIG_TRIAL_RESTRICTION_AUCTION) && IsTrialAccount())
{
SendAuctionCommandResult(0, AUCTION_CANCEL, ERR_AUCTION_RESTRICTED_ACCOUNT);
return;
}
Creature* creature = GetPlayer()->GetNPCIfCanInteractWith(auctioneer, UNIT_NPC_FLAG_AUCTIONEER);
if (!creature)
{
+28
View File
@@ -34,6 +34,7 @@
#include "Opcodes.h"
#include "Player.h"
#include "ScriptMgr.h"
#include "SocialMgr.h"
#include "SpellAuraEffects.h"
#include "SpellAuras.h"
#include "Util.h"
@@ -112,6 +113,18 @@ void WorldSession::HandleMessagechatOpcode(WorldPacket& recvData)
}
}
// Trial accounts cannot speak in chat channels or guild/officer chat. Whisper is handled later.
// Addon traffic (LANG_ADDON) is excluded; it carries the Warden Lua check response over guild chat.
if (sWorld->getBoolConfig(CONFIG_TRIAL_RESTRICTION_CHAT) && IsTrialAccount() && lang != LANG_ADDON
&& (type == CHAT_MSG_CHANNEL || type == CHAT_MSG_GUILD || type == CHAT_MSG_OFFICER))
{
WorldPacket data;
ChatHandler::BuildChatPacket(data, CHAT_MSG_RESTRICTED, LANG_UNIVERSAL, sender, sender, "");
SendPacket(&data);
recvData.rfinish();
return;
}
// pussywizard: chatting on most chat types requires 2 hours played to prevent spam/abuse
if (!HasPermission(rbac::RBAC_PERM_SKIP_CHECK_CHAT_CHANNEL_REQ))
{
@@ -398,6 +411,17 @@ void WorldSession::HandleMessagechatOpcode(WorldPacket& recvData)
return;
}
// Trial accounts can only whisper players who have them on their friend list, or players who whispered them first.
if (sWorld->getBoolConfig(CONFIG_TRIAL_RESTRICTION_CHAT) && IsTrialAccount() && receiver != sender
&& !receiver->GetSocial()->HasFriend(sender->GetGUID())
&& !sender->IsInWhisperWhiteList(receiver->GetGUID()))
{
WorldPacket data;
ChatHandler::BuildChatPacket(data, CHAT_MSG_RESTRICTED, LANG_UNIVERSAL, sender, sender, "");
SendPacket(&data);
return;
}
if (!sWorld->getBoolConfig(CONFIG_ALLOW_TWO_SIDE_INTERACTION_CHAT) && senderIsPlayer && receiverIsPlayer)
if (GetPlayer()->GetTeamId() != receiver->GetTeamId())
{
@@ -417,6 +441,10 @@ void WorldSession::HandleMessagechatOpcode(WorldPacket& recvData)
(HasPermission(rbac::RBAC_PERM_CAN_FILTER_WHISPERS) && !sender->isAcceptWhispers() && !sender->IsInWhisperWhiteList(receiver->GetGUID())))
sender->AddWhisperWhiteList(receiver->GetGUID());
// Allow a trial-account recipient to whisper back without being on the sender's friend list.
if (receiver->GetSession()->IsTrialAccount() && !receiver->IsInWhisperWhiteList(sender->GetGUID()))
receiver->AddWhisperWhiteList(sender->GetGUID());
GetPlayer()->Whisper(msg, Language(lang), receiver);
}
break;
+40 -2
View File
@@ -89,6 +89,12 @@ void WorldSession::HandleGroupInviteOpcode(WorldPacket& recvData)
if (!sScriptMgr->OnPlayerCanGroupInvite(invitingPlayer, membername))
return;
if (sWorld->getBoolConfig(CONFIG_TRIAL_RESTRICTION_PARTY) && IsTrialAccount())
{
SendPartyResult(PARTY_OP_INVITE, membername, ERR_INVITE_RESTRICTED);
return;
}
if (invitingPlayer->IsSpectator() || invitedPlayer->IsSpectator())
{
SendPartyResult(PARTY_OP_INVITE, membername, ERR_INVITE_RESTRICTED);
@@ -244,6 +250,40 @@ void WorldSession::HandleGroupAcceptOpcode(WorldPacket& recvData)
if (!sScriptMgr->OnPlayerCanGroupAccept(GetPlayer(), group))
return;
Player* leader = ObjectAccessor::FindConnectedPlayer(group->GetLeaderGUID());
// Trial accounts cannot join a group whose existing members are above the trial level cap.
if (sWorld->getBoolConfig(CONFIG_TRIAL_RESTRICTION_PARTY) && IsTrialAccount())
{
if (uint32 trialLevelCap = sWorld->getIntConfig(CONFIG_TRIAL_LEVEL_CAP))
{
uint8 leaderLevel = leader ? leader->GetLevel() : sCharacterCache->GetCharacterLevelByGuid(group->GetLeaderGUID());
if (leaderLevel > trialLevelCap)
{
SendPartyResult(PARTY_OP_INVITE, "", ERR_INVITE_RESTRICTED);
return;
}
for (auto const& slot : group->GetMemberSlots())
{
if (slot.guid == GetPlayer()->GetGUID())
continue;
uint8 memberLevel = 0;
if (Player* member = ObjectAccessor::FindConnectedPlayer(slot.guid))
memberLevel = member->GetLevel();
else
memberLevel = sCharacterCache->GetCharacterLevelByGuid(slot.guid);
if (memberLevel > trialLevelCap)
{
SendPartyResult(PARTY_OP_INVITE, "", ERR_INVITE_RESTRICTED);
return;
}
}
}
}
if (group->GetLeaderGUID() == GetPlayer()->GetGUID())
{
LOG_ERROR("network.opcode", "HandleGroupAcceptOpcode: player {} ({}) tried to accept an invite to his own group",
@@ -258,8 +298,6 @@ void WorldSession::HandleGroupAcceptOpcode(WorldPacket& recvData)
return;
}
Player* leader = ObjectAccessor::FindConnectedPlayer(group->GetLeaderGUID());
// Forming a new group, create it
if (!group->IsCreated())
{
@@ -21,6 +21,7 @@
#include "Log.h"
#include "ObjectMgr.h"
#include "SocialMgr.h"
#include "World.h"
#include "WorldSession.h"
void WorldSession::HandleGuildQueryOpcode(WorldPackets::Guild::QueryGuildInfo& query)
@@ -59,6 +60,14 @@ void WorldSession::HandleGuildAcceptOpcode(WorldPackets::Guild::AcceptGuildInvit
{
LOG_DEBUG("guild", "CMSG_GUILD_ACCEPT [{}]", GetPlayer()->GetName());
if (sWorld->getBoolConfig(CONFIG_TRIAL_RESTRICTION_GUILD) && IsTrialAccount())
{
Guild::SendCommandResult(this, GUILD_COMMAND_INVITE, ERR_GUILD_PERMISSIONS);
GetPlayer()->SetGuildIdInvited(0);
GetPlayer()->SetInGuild(0);
return;
}
if (!GetPlayer()->GetGuildId())
if (Guild* guild = sGuildMgr->GetGuildById(GetPlayer()->GetGuildIdInvited()))
guild->HandleAcceptMember(this);
+6
View File
@@ -117,6 +117,12 @@ void WorldSession::HandleSendMail(WorldPacket& recvData)
Player* player = _player;
if (sWorld->getBoolConfig(CONFIG_TRIAL_RESTRICTION_MAIL) && IsTrialAccount())
{
player->SendMailResult(0, MAIL_SEND, MAIL_ERR_DISABLED_FOR_TRIAL_ACC);
return;
}
if (player->GetLevel() < sWorld->getIntConfig(CONFIG_MAIL_LEVEL_REQ))
{
ChatHandler(this).SendNotification(LANG_MAIL_SENDER_REQ, sWorld->getIntConfig(CONFIG_MAIL_LEVEL_REQ));
@@ -84,6 +84,12 @@ void WorldSession::HandlePetitionBuyOpcode(WorldPacket& recvData)
if (_player->GetGuildId())
return;
if (sWorld->getBoolConfig(CONFIG_TRIAL_RESTRICTION_GUILD) && IsTrialAccount())
{
Guild::SendCommandResult(this, GUILD_COMMAND_CREATE, ERR_GUILD_PERMISSIONS);
return;
}
charterid = GUILD_CHARTER;
cost = sWorld->getIntConfig(CONFIG_CHARTER_COST_GUILD);
type = GUILD_CHARTER_TYPE;
@@ -455,6 +461,12 @@ void WorldSession::HandlePetitionSignOpcode(WorldPacket& recvData)
return;
}
if (sWorld->getBoolConfig(CONFIG_TRIAL_RESTRICTION_GUILD) && IsTrialAccount())
{
Guild::SendCommandResult(this, GUILD_COMMAND_INVITE, ERR_GUILD_PERMISSIONS);
return;
}
if (_player->GetGuildId())
{
Guild::SendCommandResult(this, GUILD_COMMAND_INVITE, ERR_ALREADY_IN_GUILD_S, _player->GetName());
@@ -678,6 +690,12 @@ void WorldSession::HandleTurnInPetitionOpcode(WorldPacket& recvData)
// Petition type (guild/arena) specific checks
if (type == GUILD_CHARTER_TYPE)
{
if (sWorld->getBoolConfig(CONFIG_TRIAL_RESTRICTION_GUILD) && IsTrialAccount())
{
Guild::SendCommandResult(this, GUILD_COMMAND_CREATE, ERR_GUILD_PERMISSIONS);
return;
}
// Check if player is already in a guild
if (_player->GetGuildId())
{
+14
View File
@@ -675,6 +675,13 @@ void WorldSession::HandleInitiateTradeOpcode(WorldPacket& recvPacket)
return;
}
if (sWorld->getBoolConfig(CONFIG_TRIAL_RESTRICTION_TRADE) && IsTrialAccount())
{
info.Status = TRADE_STATUS_TRIAL_ACCOUNT;
SendTradeStatus(info);
return;
}
if (GetPlayer()->IsSpectator())
return;
@@ -722,6 +729,13 @@ void WorldSession::HandleInitiateTradeOpcode(WorldPacket& recvPacket)
return;
}
if (sWorld->getBoolConfig(CONFIG_TRIAL_RESTRICTION_TRADE) && pOther->GetSession()->IsTrialAccount())
{
info.Status = TRADE_STATUS_TRIAL_ACCOUNT;
SendTradeStatus(info);
return;
}
if (pOther->GetTeamId() != _player->GetTeamId() &&
!GetPlayer()->GetSession()->HasPermission(rbac::RBAC_PERM_ALLOW_TWO_SIDE_TRADE))
{